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};
102 /********************************************************
104 *********************************************************/
105 unsigned char MCS_rate_2R23A[16] = {
106 0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
107 unsigned char MCS_rate_1R23A[16] = {
108 0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
110 /********************************************************
111 ChannelPlan definitions
112 *********************************************************/
114 static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
115 {{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 */
116 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
117 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
118 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
119 {{10, 11, 12, 13}, 4}, /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
120 {{}, 0}, /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */
123 static struct rt_channel_plan_5g RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
124 {{}, 0}, /* 0x00, RT_CHANNEL_DOMAIN_5G_NULL */
125 {{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 */
126 {{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 */
127 {{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 */
128 {{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 */
129 {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9}, /* 0x05, RT_CHANNEL_DOMAIN_5G_FCC2 */
130 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13}, /* 0x06, RT_CHANNEL_DOMAIN_5G_FCC3 */
131 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12}, /* 0x07, RT_CHANNEL_DOMAIN_5G_FCC4 */
132 {{149, 153, 157, 161, 165}, 5}, /* 0x08, RT_CHANNEL_DOMAIN_5G_FCC5 */
133 {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, /* 0x09, RT_CHANNEL_DOMAIN_5G_FCC6 */
134 {{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 */
135 {{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 */
136 {{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 */
137 {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, /* 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 */
138 {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11}, /* 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 */
139 {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 15}, /* 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 */
140 {{56, 60, 64, 149, 153, 157, 161, 165}, 8}, /* 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 */
142 /* Driver self defined for old channel plan Compatible , Remember to modify if have new channel plan definition ===== */
143 {{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 */
144 {{36, 40, 44, 48}, 4}, /* 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS */
145 {{36, 40, 44, 48, 149, 153, 157, 161}, 8}, /* 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS */
148 static struct rt_channel_plan_map RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
149 /* 0x00 ~ 0x1F , Old Define ===== */
150 {0x02, 0x11}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
151 {0x02, 0x0A}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
152 {0x01, 0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
153 {0x01, 0x00}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
154 {0x01, 0x00}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
155 {0x03, 0x00}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */
156 {0x03, 0x00}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
157 {0x01, 0x09}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
158 {0x03, 0x09}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
159 {0x03, 0x00}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
160 {0x00, 0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
161 {0x02, 0x0F}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
162 {0x01, 0x08}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
163 {0x02, 0x06}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
164 {0x02, 0x0B}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
165 {0x02, 0x09}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
166 {0x01, 0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
167 {0x02, 0x05}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
168 {0x01, 0x12}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
169 {0x00, 0x04}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
170 {0x02, 0x10}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
171 {0x00, 0x12}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
172 {0x00, 0x13}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
173 {0x03, 0x12}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
174 {0x05, 0x08}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
175 {0x02, 0x08}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
176 {0x00, 0x00}, /* 0x1A, */
177 {0x00, 0x00}, /* 0x1B, */
178 {0x00, 0x00}, /* 0x1C, */
179 {0x00, 0x00}, /* 0x1D, */
180 {0x00, 0x00}, /* 0x1E, */
181 {0x05, 0x04}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
182 /* 0x20 ~ 0x7F , New Define ===== */
183 {0x00, 0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
184 {0x01, 0x00}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
185 {0x02, 0x00}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
186 {0x03, 0x00}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
187 {0x04, 0x00}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
188 {0x02, 0x04}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
189 {0x00, 0x01}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
190 {0x03, 0x0C}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
191 {0x00, 0x0B}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
192 {0x00, 0x05}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
193 {0x00, 0x00}, /* 0x2A, */
194 {0x00, 0x00}, /* 0x2B, */
195 {0x00, 0x00}, /* 0x2C, */
196 {0x00, 0x00}, /* 0x2D, */
197 {0x00, 0x00}, /* 0x2E, */
198 {0x00, 0x00}, /* 0x2F, */
199 {0x00, 0x06}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
200 {0x00, 0x07}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
201 {0x00, 0x08}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
202 {0x00, 0x09}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
203 {0x02, 0x0A}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
204 {0x00, 0x02}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
205 {0x00, 0x03}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
206 {0x03, 0x0D}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
207 {0x03, 0x0E}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
208 {0x02, 0x0F}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
209 {0x00, 0x00}, /* 0x3A, */
210 {0x00, 0x00}, /* 0x3B, */
211 {0x00, 0x00}, /* 0x3C, */
212 {0x00, 0x00}, /* 0x3D, */
213 {0x00, 0x00}, /* 0x3E, */
214 {0x00, 0x00}, /* 0x3F, */
215 {0x02, 0x10}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
216 {0x03, 0x00}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */
219 static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03, 0x02}; /* use the conbination for max channel numbers */
221 static struct fwevent wlanevents[] =
223 {0, rtw_dummy_event_callback23a}, /*0*/
231 {0, &rtw_survey_event_cb23a}, /*8*/
232 {sizeof (struct surveydone_event), &rtw_surveydone_event_callback23a}, /*9*/
234 {0, &rtw23a_joinbss_event_cb}, /*10*/
235 {sizeof(struct stassoc_event), &rtw_stassoc_event_callback23a},
236 {sizeof(struct stadel_event), &rtw_stadel_event_callback23a},
237 {0, &rtw_atimdone_event_callback23a},
238 {0, rtw_dummy_event_callback23a},
243 {0, rtw23a_fwdbg_event_callback},
247 {0, &rtw_cpwm_event_callback23a},
252 static void rtw_correct_TSF(struct rtw_adapter *padapter)
254 hw_var_set_correct_tsf(padapter);
258 rtw_update_TSF(struct mlme_ext_priv *pmlmeext, struct ieee80211_mgmt *mgmt)
260 pmlmeext->TSFValue = get_unaligned_le64(&mgmt->u.beacon.timestamp);
264 * Search the @param channel_num in given @param channel_set
265 * @ch_set: the given channel set
266 * @ch: the given channel number
268 * return the index of channel_num in channel_set, -1 if not found
270 int rtw_ch_set_search_ch23a(struct rt_channel_info *ch_set, const u32 ch)
273 for (i = 0; ch_set[i]. ChannelNum != 0; i++) {
274 if (ch == ch_set[i].ChannelNum)
278 if (i >= ch_set[i].ChannelNum)
283 /****************************************************************************
285 Following are the initialization functions for WiFi MLME
287 *****************************************************************************/
289 int init_hw_mlme_ext23a(struct rtw_adapter *padapter)
291 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
293 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
294 pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
298 static void init_mlme_ext_priv23a_value(struct rtw_adapter* padapter)
300 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
301 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
302 unsigned char mixed_datarate[NumRates] = {
303 _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
304 _9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_,
305 _48M_RATE_, _54M_RATE_, 0xff};
306 unsigned char mixed_basicrate[NumRates] = {
307 _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
308 _12M_RATE_, _24M_RATE_, 0xff,};
310 atomic_set(&pmlmeext->event_seq, 0);
311 /* reset to zero when disconnect at client mode */
312 pmlmeext->mgnt_seq = 0;
314 pmlmeext->cur_channel = padapter->registrypriv.channel;
315 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
316 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
320 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
322 memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
323 memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
325 if (pmlmeext->cur_channel > 14)
326 pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
328 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
330 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
331 pmlmeext->sitesurvey_res.channel_idx = 0;
332 pmlmeext->sitesurvey_res.bss_cnt = 0;
333 pmlmeext->scan_abort = false;
335 pmlmeinfo->state = WIFI_FW_NULL_STATE;
336 pmlmeinfo->reauth_count = 0;
337 pmlmeinfo->reassoc_count = 0;
338 pmlmeinfo->link_count = 0;
339 pmlmeinfo->auth_seq = 0;
340 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
341 pmlmeinfo->key_index = 0;
344 pmlmeinfo->enc_algo = _NO_PRIVACY_;
345 pmlmeinfo->authModeToggle = 0;
347 memset(pmlmeinfo->chg_txt, 0, 128);
349 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
350 pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
352 pmlmeinfo->dialogToken = 0;
354 pmlmeext->action_public_rxseq = 0xffff;
355 pmlmeext->action_public_dialog_token = 0xff;
358 static int has_channel(struct rt_channel_info *channel_set,
359 u8 chanset_size, u8 chan) {
362 for (i = 0; i < chanset_size; i++) {
363 if (channel_set[i].ChannelNum == chan)
370 static void init_channel_list(struct rtw_adapter *padapter,
371 struct rt_channel_info *channel_set,
373 struct p2p_channels *channel_list) {
375 struct p2p_oper_class_map op_class[] = {
376 { IEEE80211G, 81, 1, 13, 1, BW20 },
377 { IEEE80211G, 82, 14, 14, 1, BW20 },
378 { IEEE80211A, 115, 36, 48, 4, BW20 },
379 { IEEE80211A, 116, 36, 44, 8, BW40PLUS },
380 { IEEE80211A, 117, 40, 48, 8, BW40MINUS },
381 { IEEE80211A, 124, 149, 161, 4, BW20 },
382 { IEEE80211A, 125, 149, 169, 4, BW20 },
383 { IEEE80211A, 126, 149, 157, 8, BW40PLUS },
384 { IEEE80211A, 127, 153, 161, 8, BW40MINUS },
385 { -1, 0, 0, 0, 0, BW20 }
392 for (op = 0; op_class[op].op_class; op++) {
394 struct p2p_oper_class_map *o = &op_class[op];
395 struct p2p_reg_class *reg = NULL;
397 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
398 if (!has_channel(channel_set, chanset_size, ch))
401 if ((0 == padapter->registrypriv.ht_enable) &&
405 if ((0 == (padapter->registrypriv.cbw40_enable & BIT(1))) &&
406 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
410 reg = &channel_list->reg_class[cla];
412 reg->reg_class = o->op_class;
415 reg->channel[reg->channels] = ch;
419 channel_list->reg_classes = cla;
422 static u8 init_channel_set(struct rtw_adapter* padapter, u8 cplan,
423 struct rt_channel_info *c_set)
426 u8 b5GBand = false, b2_4GBand = false;
427 u8 Index2G = 0, Index5G = 0;
429 memset(c_set, 0, sizeof(struct rt_channel_info) * MAX_CHANNEL_NUM);
431 if (cplan >= RT_CHANNEL_DOMAIN_MAX &&
432 cplan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) {
433 DBG_8723A("ChannelPlan ID %x error !!!!!\n", cplan);
437 if (padapter->registrypriv.wireless_mode & WIRELESS_11G) {
439 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == cplan)
440 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
442 Index2G = RTW_ChannelPlanMap[cplan].Index2G;
445 if (padapter->registrypriv.wireless_mode & WIRELESS_11A) {
447 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == cplan)
448 Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
450 Index5G = RTW_ChannelPlanMap[cplan].Index5G;
454 for (i = 0; i < RTW_ChannelPlan2G[Index2G].Len; i++) {
455 c_set[ch_size].ChannelNum =
456 RTW_ChannelPlan2G[Index2G].Channel[i];
458 if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == cplan) ||
459 /* Channel 1~11 is active, and 12~14 is passive */
460 RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G == cplan) {
461 if (c_set[ch_size].ChannelNum >= 1 &&
462 c_set[ch_size].ChannelNum <= 11)
463 c_set[ch_size].ScanType = SCAN_ACTIVE;
464 else if (c_set[ch_size].ChannelNum >= 12 &&
465 c_set[ch_size].ChannelNum <= 14)
466 c_set[ch_size].ScanType = SCAN_PASSIVE;
467 } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == cplan ||
468 RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == cplan ||
469 RT_CHANNEL_DOMAIN_2G_WORLD == Index2G) {
470 /* channel 12~13, passive scan */
471 if (c_set[ch_size].ChannelNum <= 11)
472 c_set[ch_size].ScanType = SCAN_ACTIVE;
474 c_set[ch_size].ScanType = SCAN_PASSIVE;
476 c_set[ch_size].ScanType = SCAN_ACTIVE;
483 for (i = 0; i < RTW_ChannelPlan5G[Index5G].Len; i++) {
484 if (RTW_ChannelPlan5G[Index5G].Channel[i] <= 48 ||
485 RTW_ChannelPlan5G[Index5G].Channel[i] >= 149) {
486 c_set[ch_size].ChannelNum =
487 RTW_ChannelPlan5G[Index5G].Channel[i];
488 if (RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == cplan) {
489 /* passive scan for all 5G channels */
490 c_set[ch_size].ScanType =
493 c_set[ch_size].ScanType =
495 DBG_8723A("%s(): channel_set[%d].ChannelNum = "
496 "%d\n", __func__, ch_size,
497 c_set[ch_size].ChannelNum);
506 int init_mlme_ext_priv23a(struct rtw_adapter* padapter)
509 struct registry_priv* pregistrypriv = &padapter->registrypriv;
510 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
511 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
512 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
514 pmlmeext->padapter = padapter;
516 init_mlme_ext_priv23a_value(padapter);
517 pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
519 init_mlme_ext_timer23a(padapter);
521 #ifdef CONFIG_8723AU_AP_MODE
522 init_mlme_ap_info23a(padapter);
525 pmlmeext->max_chan_nums = init_channel_set(padapter,
526 pmlmepriv->ChannelPlan,
527 pmlmeext->channel_set);
528 init_channel_list(padapter, pmlmeext->channel_set,
529 pmlmeext->max_chan_nums, &pmlmeext->channel_list);
531 pmlmeext->chan_scan_time = SURVEY_TO;
532 pmlmeext->mlmeext_init = true;
534 pmlmeext->active_keep_alive_check = true;
538 void free_mlme_ext_priv23a (struct mlme_ext_priv *pmlmeext)
540 struct rtw_adapter *padapter = pmlmeext->padapter;
545 if (padapter->bDriverStopped == true) {
546 del_timer_sync(&pmlmeext->survey_timer);
547 del_timer_sync(&pmlmeext->link_timer);
548 /* del_timer_sync(&pmlmeext->ADDBA_timer); */
553 _mgt_dispatcher23a(struct rtw_adapter *padapter, struct mlme_handler *ptable,
554 struct recv_frame *precv_frame)
556 struct sk_buff *skb = precv_frame->pkt;
557 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
560 /* receive the frames that ra(a1) is my address
561 or ra(a1) is bc address. */
562 if (!ether_addr_equal(hdr->addr1, myid(&padapter->eeprompriv))&&
563 !is_broadcast_ether_addr(hdr->addr1))
566 ptable->func(padapter, precv_frame);
570 void mgt_dispatcher23a(struct rtw_adapter *padapter,
571 struct recv_frame *precv_frame)
573 struct mlme_handler *ptable;
574 #ifdef CONFIG_8723AU_AP_MODE
575 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
576 #endif /* CONFIG_8723AU_AP_MODE */
577 struct sk_buff *skb = precv_frame->pkt;
578 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
579 struct sta_info *psta;
583 if (!ieee80211_is_mgmt(mgmt->frame_control))
586 /* receive the frames that ra(a1) is my address or ra(a1) is
588 if (!ether_addr_equal(mgmt->da, myid(&padapter->eeprompriv)) &&
589 !is_broadcast_ether_addr(mgmt->da))
592 ptable = mlme_sta_tbl;
594 stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
598 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
599 ("Currently we do not support reserved sub-fr-type ="
605 psta = rtw_get_stainfo23a(&padapter->stapriv, mgmt->sa);
608 if (ieee80211_has_retry(mgmt->frame_control)) {
609 if (precv_frame->attrib.seq_num ==
610 psta->RxMgmtFrameSeqNum) {
611 /* drop the duplicate management frame */
612 DBG_8723A("Drop duplicate management frame "
613 "with seq_num = %d.\n",
614 precv_frame->attrib.seq_num);
618 psta->RxMgmtFrameSeqNum = precv_frame->attrib.seq_num;
621 #ifdef CONFIG_8723AU_AP_MODE
624 case IEEE80211_STYPE_AUTH:
625 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
626 ptable->func = &OnAuth23a;
628 ptable->func = &OnAuth23aClient23a;
630 case IEEE80211_STYPE_ASSOC_REQ:
631 case IEEE80211_STYPE_REASSOC_REQ:
632 _mgt_dispatcher23a(padapter, ptable, precv_frame);
634 case IEEE80211_STYPE_PROBE_REQ:
635 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
636 _mgt_dispatcher23a(padapter, ptable, precv_frame);
638 _mgt_dispatcher23a(padapter, ptable, precv_frame);
640 case IEEE80211_STYPE_BEACON:
641 _mgt_dispatcher23a(padapter, ptable, precv_frame);
643 case IEEE80211_STYPE_ACTION:
644 /* if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) */
645 _mgt_dispatcher23a(padapter, ptable, precv_frame);
648 _mgt_dispatcher23a(padapter, ptable, precv_frame);
652 _mgt_dispatcher23a(padapter, ptable, precv_frame);
656 /****************************************************************************
658 Following are the callback functions for each subtype of the management frames
660 *****************************************************************************/
663 OnProbeReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
666 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
667 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
668 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
669 struct wlan_bssid_ex *cur = &pmlmeinfo->network;
670 struct sk_buff *skb = precv_frame->pkt;
671 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
674 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
677 if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
678 !check_fwstate(pmlmepriv,
679 WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE))
682 if (unlikely(!ieee80211_is_probe_req(mgmt->frame_control))) {
683 printk(KERN_WARNING "%s: Received non probe request frame\n",
688 len -= offsetof(struct ieee80211_mgmt, u.probe_req.variable);
690 ie = cfg80211_find_ie(WLAN_EID_SSID, mgmt->u.probe_req.variable, len);
692 /* check (wildcard) SSID */
696 if ((ie[1] && memcmp(ie + 2, cur->Ssid.ssid, cur->Ssid.ssid_len)) ||
697 (ie[1] == 0 && pmlmeinfo->hidden_ssid_mode)) {
701 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
702 pmlmepriv->cur_network.join_res)
703 issue_probersp23a(padapter, mgmt->sa, false);
710 OnProbeRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
712 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
714 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
715 report_survey_event23a(padapter, precv_frame);
723 OnBeacon23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
726 struct sta_info *psta;
727 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
728 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
729 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
730 struct sta_priv *pstapriv = &padapter->stapriv;
731 struct sk_buff *skb = precv_frame->pkt;
732 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
733 u8 *pframe = skb->data;
734 int pkt_len = skb->len;
735 struct wlan_bssid_ex *pbss;
741 pie = mgmt->u.beacon.variable;
742 pie_len = pkt_len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
743 p = rtw_get_ie23a(pie, WLAN_EID_EXT_SUPP_RATES, &ielen, pie_len);
744 if (p && ielen > 0) {
745 if (p[1 + ielen] == 0x2D && p[2 + ielen] != 0x2D) {
746 /* Invalid value 0x2D is detected in Extended Supported
747 * Rates (ESR) IE. Try to fix the IE length to avoid
748 * failed Beacon parsing.
750 DBG_8723A("[WIFIDBG] Error in ESR IE is detected in "
751 "Beacon of BSSID: %pM. Fix the length of "
752 "ESR IE to avoid failed Beacon parsing.\n",
758 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
759 report_survey_event23a(padapter, precv_frame);
763 if (!ether_addr_equal(mgmt->bssid,
764 get_my_bssid23a(&pmlmeinfo->network)))
767 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
768 /* we should update current network before auth,
769 or some IE is wrong */
770 pbss = (struct wlan_bssid_ex *)
771 kmalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
773 if (collect_bss_info23a(padapter, precv_frame, pbss) ==
776 &pmlmepriv->cur_network.network, pbss,
778 rtw_get_bcn_info23a(&pmlmepriv->cur_network);
783 /* check the vendor of the assoc AP */
784 pmlmeinfo->assoc_AP_vendor =
785 check_assoc_AP23a((u8 *)&mgmt->u.beacon, pkt_len -
786 offsetof(struct ieee80211_mgmt, u));
788 /* update TSF Value */
789 rtw_update_TSF(pmlmeext, mgmt);
792 start_clnt_auth23a(padapter);
797 if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) &&
798 (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
799 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
801 ret = rtw_check_bcn_info23a(padapter, mgmt, pkt_len);
803 DBG_8723A_LEVEL(_drv_always_, "ap has changed, "
805 receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress, 65535);
808 /* update WMM, ERP in the beacon */
809 /* todo: the timer is used instead of
810 the number of the beacon received */
811 if ((sta_rx_pkts(psta) & 0xf) == 0) {
812 /* DBG_8723A("update_bcn_info\n"); */
813 update_beacon23a_info(padapter, pframe,
817 } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
818 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
820 /* update WMM, ERP in the beacon */
821 /* todo: the timer is used instead of the
822 number of the beacon received */
823 if ((sta_rx_pkts(psta) & 0xf) == 0) {
824 /* DBG_8723A("update_bcn_info\n"); */
825 update_beacon23a_info(padapter, pframe,
829 /* allocate a new CAM entry for IBSS station */
830 cam_idx = allocate_fw_sta_entry23a(padapter);
831 if (cam_idx == NUM_STA)
834 /* get supported rate */
835 if (update_sta_support_rate23a(padapter, pie, pie_len,
837 pmlmeinfo->FW_sta_info[cam_idx].status = 0;
841 /* update TSF Value */
842 rtw_update_TSF(pmlmeext, mgmt);
844 /* report sta add event */
845 report_add_sta_event23a(padapter, mgmt->sa,
856 OnAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
858 #ifdef CONFIG_8723AU_AP_MODE
859 static struct sta_info stat;
860 struct sta_info *pstat = NULL;
861 struct sta_priv *pstapriv = &padapter->stapriv;
862 struct security_priv *psecuritypriv = &padapter->securitypriv;
863 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
864 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
865 struct sk_buff *skb = precv_frame->pkt;
866 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
870 u16 auth_mode, seq, algorithm;
871 int status, len = skb->len;
873 if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
876 DBG_8723A("+OnAuth23a\n");
880 auth_mode = psecuritypriv->dot11AuthAlgrthm;
882 pframe = mgmt->u.auth.variable;
883 len = skb->len - offsetof(struct ieee80211_mgmt, u.auth.variable);
885 seq = le16_to_cpu(mgmt->u.auth.auth_transaction);
886 algorithm = le16_to_cpu(mgmt->u.auth.auth_alg);
888 DBG_8723A("auth alg =%x, seq =%X\n", algorithm, seq);
890 if (auth_mode == 2 &&
891 psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
892 psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
895 /* rx a shared-key auth but shared not enabled, or */
896 /* rx a open-system auth but shared-key is enabled */
897 if ((algorithm != WLAN_AUTH_OPEN && auth_mode == 0) ||
898 (algorithm == WLAN_AUTH_OPEN && auth_mode == 1)) {
899 DBG_8723A("auth rejected due to bad alg [alg =%d, auth_mib "
900 "=%d] %02X%02X%02X%02X%02X%02X\n",
901 algorithm, auth_mode,
902 sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
904 status = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
909 if (rtw_access_ctrl23a(padapter, sa) == false) {
910 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
914 pstat = rtw_get_stainfo23a(pstapriv, sa);
916 /* allocate a new one */
917 DBG_8723A("going to alloc stainfo for sa ="MAC_FMT"\n",
919 pstat = rtw_alloc_stainfo23a(pstapriv, sa);
921 DBG_8723A(" Exceed the upper limit of supported "
923 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
927 pstat->state = WIFI_FW_AUTH_NULL;
930 /* pstat->flags = 0; */
931 /* pstat->capability = 0; */
933 spin_lock_bh(&pstapriv->asoc_list_lock);
934 if (!list_empty(&pstat->asoc_list)) {
935 list_del_init(&pstat->asoc_list);
936 pstapriv->asoc_list_cnt--;
937 if (pstat->expire_to > 0) {
938 /* TODO: STA re_auth within expire_to */
941 spin_unlock_bh(&pstapriv->asoc_list_lock);
944 /* TODO: STA re_auth and auth timeout */
948 spin_lock_bh(&pstapriv->auth_list_lock);
949 if (list_empty(&pstat->auth_list)) {
950 list_add_tail(&pstat->auth_list, &pstapriv->auth_list);
951 pstapriv->auth_list_cnt++;
953 spin_unlock_bh(&pstapriv->auth_list_lock);
955 if (pstat->auth_seq == 0)
956 pstat->expire_to = pstapriv->auth_to;
958 if ((pstat->auth_seq + 1) != seq) {
959 DBG_8723A("(1)auth rejected because out of seq [rx_seq =%d, "
960 "exp_seq =%d]!\n", seq, pstat->auth_seq+1);
961 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
965 if (algorithm == WLAN_AUTH_OPEN && (auth_mode == 0 || auth_mode == 2)) {
967 pstat->state &= ~WIFI_FW_AUTH_NULL;
968 pstat->state |= WIFI_FW_AUTH_SUCCESS;
969 pstat->expire_to = pstapriv->assoc_to;
970 pstat->authalg = algorithm;
972 DBG_8723A("(2)auth rejected because out of seq "
973 "[rx_seq =%d, exp_seq =%d]!\n",
974 seq, pstat->auth_seq+1);
975 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
978 } else { /* shared system or auto authentication */
980 /* prepare for the challenging txt... */
981 pstat->state &= ~WIFI_FW_AUTH_NULL;
982 pstat->state |= WIFI_FW_AUTH_STATE;
983 pstat->authalg = algorithm;
985 } else if (seq == 3) {
986 /* checking for challenging txt... */
987 DBG_8723A("checking for challenging txt...\n");
989 p = cfg80211_find_ie(WLAN_EID_CHALLENGE, pframe, len);
990 if (!p || p[1] <= 0) {
991 DBG_8723A("auth rejected because challenge "
993 status = WLAN_STATUS_CHALLENGE_FAIL;
997 if (!memcmp(p + 2, pstat->chg_txt, 128)) {
998 pstat->state &= ~WIFI_FW_AUTH_STATE;
999 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1000 /* challenging txt is correct... */
1001 pstat->expire_to = pstapriv->assoc_to;
1003 DBG_8723A("auth rejected because challenge "
1005 status = WLAN_STATUS_CHALLENGE_FAIL;
1009 DBG_8723A("(3)auth rejected because out of seq "
1010 "[rx_seq =%d, exp_seq =%d]!\n",
1011 seq, pstat->auth_seq+1);
1012 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1017 /* Now, we are going to issue_auth23a... */
1018 pstat->auth_seq = seq + 1;
1020 issue_auth23a(padapter, pstat, WLAN_STATUS_SUCCESS);
1022 if (pstat->state & WIFI_FW_AUTH_SUCCESS)
1023 pstat->auth_seq = 0;
1030 rtw_free_stainfo23a(padapter, pstat);
1033 memset((char *)pstat, '\0', sizeof(stat));
1034 pstat->auth_seq = 2;
1035 memcpy(pstat->hwaddr, sa, 6);
1037 issue_auth23a(padapter, pstat, (unsigned short)status);
1044 OnAuth23aClient23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1046 unsigned int seq, status, algthm;
1047 unsigned int go2asoc = 0;
1048 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1049 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1050 struct sk_buff *skb = precv_frame->pkt;
1051 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1054 int plen = skb->len;
1056 DBG_8723A("%s\n", __func__);
1058 /* check A1 matches or not */
1059 if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da))
1062 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
1065 pie = mgmt->u.auth.variable;
1066 plen -= offsetof(struct ieee80211_mgmt, u.auth.variable);
1068 algthm = le16_to_cpu(mgmt->u.auth.auth_alg);
1069 seq = le16_to_cpu(mgmt->u.auth.auth_transaction);
1070 status = le16_to_cpu(mgmt->u.auth.status_code);
1073 DBG_8723A("clnt auth fail, status: %d\n", status);
1074 /* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
1075 if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
1076 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1077 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
1079 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
1080 /* pmlmeinfo->reauth_count = 0; */
1083 set_link_timer(pmlmeext, 1);
1088 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
1089 /* legendary shared system */
1090 p = cfg80211_find_ie(WLAN_EID_CHALLENGE, pie, plen);
1093 /* DBG_8723A("marc: no challenge text?\n"); */
1097 memcpy((void *)(pmlmeinfo->chg_txt), p + 2, p[1]);
1098 pmlmeinfo->auth_seq = 3;
1099 issue_auth23a(padapter, NULL, 0);
1100 set_link_timer(pmlmeext, REAUTH_TO);
1107 } else if (seq == 4) {
1108 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1113 /* this is also illegal */
1114 /* DBG_8723A("marc: clnt auth failed due to illegal seq =%x\n",
1120 DBG_8723A_LEVEL(_drv_always_, "auth success, start assoc\n");
1121 start_clnt_assoc23a(padapter);
1127 /* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
1132 #ifdef CONFIG_8723AU_AP_MODE
1133 static int rtw_validate_vendor_specific_ies(const u8 *pos, int elen)
1137 /* first 3 bytes in vendor specific information element are the IEEE
1138 * OUI of the vendor. The following byte is used a vendor specific
1141 DBG_8723A("short vendor specific information element "
1142 "ignored (len =%i)\n", elen);
1146 oui = RTW_GET_BE24(pos);
1148 case WLAN_OUI_MICROSOFT:
1149 /* Microsoft/Wi-Fi information elements are further typed and
1153 /* Microsoft OUI (00:50:F2) with OUI Type 1:
1154 * real WPA information element */
1156 case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */
1158 DBG_8723A("short WME information element "
1159 "ignored (len =%i)\n", elen);
1163 case WME_OUI_SUBTYPE_INFORMATION_ELEMENT:
1164 case WME_OUI_SUBTYPE_PARAMETER_ELEMENT:
1166 case WME_OUI_SUBTYPE_TSPEC_ELEMENT:
1169 DBG_8723A("unknown WME information element "
1170 "ignored (subtype =%d len =%i)\n",
1176 /* Wi-Fi Protected Setup (WPS) IE */
1179 DBG_8723A("Unknown Microsoft information element "
1180 "ignored (type =%d len =%i)\n",
1188 case VENDOR_HT_CAPAB_OUI_TYPE:
1191 DBG_8723A("Unknown Broadcom information element "
1192 "ignored (type =%d len =%i)\n", pos[3], elen);
1198 DBG_8723A("unknown vendor specific information element "
1199 "ignored (vendor OUI %02x:%02x:%02x len =%i)\n",
1200 pos[0], pos[1], pos[2], elen);
1207 static int rtw_validate_frame_ies(const u8 *start, uint len)
1209 const u8 *pos = start;
1221 DBG_8723A("%s: IEEE 802.11 failed (id =%d elen =%d "
1222 "left =%i)\n", __func__, id, elen, left);
1228 case WLAN_EID_SUPP_RATES:
1229 case WLAN_EID_FH_PARAMS:
1230 case WLAN_EID_DS_PARAMS:
1231 case WLAN_EID_CF_PARAMS:
1233 case WLAN_EID_IBSS_PARAMS:
1234 case WLAN_EID_CHALLENGE:
1235 case WLAN_EID_ERP_INFO:
1236 case WLAN_EID_EXT_SUPP_RATES:
1237 case WLAN_EID_VENDOR_SPECIFIC:
1238 if (rtw_validate_vendor_specific_ies(pos, elen))
1242 case WLAN_EID_PWR_CAPABILITY:
1243 case WLAN_EID_SUPPORTED_CHANNELS:
1244 case WLAN_EID_MOBILITY_DOMAIN:
1245 case WLAN_EID_FAST_BSS_TRANSITION:
1246 case WLAN_EID_TIMEOUT_INTERVAL:
1247 case WLAN_EID_HT_CAPABILITY:
1248 case WLAN_EID_HT_OPERATION:
1251 DBG_8723A("%s IEEE 802.11 ignored unknown element "
1252 "(id =%d elen =%d)\n", __func__, id, elen);
1268 OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1270 #ifdef CONFIG_8723AU_AP_MODE
1271 u16 capab_info, listen_interval;
1272 struct sta_info *pstat;
1273 unsigned char reassoc;
1274 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
1275 int i, wpa_ie_len, left;
1276 unsigned char supportRate[16];
1278 unsigned short status = WLAN_STATUS_SUCCESS;
1279 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1280 struct security_priv *psecuritypriv = &padapter->securitypriv;
1281 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1282 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1283 struct wlan_bssid_ex *cur = &pmlmeinfo->network;
1284 struct sta_priv *pstapriv = &padapter->stapriv;
1285 struct sk_buff *skb = precv_frame->pkt;
1286 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1287 const u8 *pos, *p, *wpa_ie, *wps_ie;
1288 u8 *pframe = skb->data;
1289 uint pkt_len = skb->len;
1292 if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
1295 left = pkt_len - sizeof(struct ieee80211_hdr_3addr);
1296 if (ieee80211_is_assoc_req(mgmt->frame_control)) {
1298 pos = mgmt->u.assoc_req.variable;
1299 left -= offsetof(struct ieee80211_mgmt, u.assoc_req.variable);
1300 } else { /* WIFI_REASSOCREQ */
1302 pos = mgmt->u.reassoc_req.variable;
1303 left -= offsetof(struct ieee80211_mgmt, u.reassoc_req.variable);
1307 DBG_8723A("handle_assoc(reassoc =%d) - too short payload "
1308 "(len =%lu)\n", reassoc, (unsigned long)pkt_len);
1312 pstat = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1314 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
1315 goto asoc_class2_error;
1318 /* These two are located at the same offsets whether it's an
1319 * assoc_req or a reassoc_req */
1320 capab_info = get_unaligned_le16(&mgmt->u.assoc_req.capab_info);
1322 get_unaligned_le16(&mgmt->u.assoc_req.listen_interval);
1324 DBG_8723A("%s\n", __func__);
1326 /* check if this stat has been successfully authenticated/assocated */
1327 if (!(pstat->state & WIFI_FW_AUTH_SUCCESS)) {
1328 if (!(pstat->state & WIFI_FW_ASSOC_SUCCESS)) {
1329 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
1330 goto asoc_class2_error;
1332 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
1333 pstat->state |= WIFI_FW_ASSOC_STATE;
1336 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
1337 pstat->state |= WIFI_FW_ASSOC_STATE;
1340 pstat->capability = capab_info;
1342 /* now parse all ieee802_11 ie to point to elems */
1344 if (rtw_validate_frame_ies(pos, left)) {
1345 DBG_8723A("STA " MAC_FMT " sent invalid association request\n",
1346 MAC_ARG(pstat->hwaddr));
1347 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1348 goto OnAssocReq23aFail;
1351 /* now we should check all the fields... */
1353 p = cfg80211_find_ie(WLAN_EID_SSID, pos, left);
1354 if (!p || p[1] == 0) {
1355 /* broadcast ssid, however it is not allowed in assocreq */
1356 DBG_8723A("STA " MAC_FMT " sent invalid association request "
1357 "lacking an SSID\n", MAC_ARG(pstat->hwaddr));
1358 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1359 goto OnAssocReq23aFail;
1361 /* check if ssid match */
1362 if (memcmp(p + 2, cur->Ssid.ssid, cur->Ssid.ssid_len))
1363 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1365 if (p[1] != cur->Ssid.ssid_len)
1366 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1369 if (status != WLAN_STATUS_SUCCESS)
1370 goto OnAssocReq23aFail;
1372 /* check if the supported rate is ok */
1373 p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, pos, left);
1375 DBG_8723A("Rx a sta assoc-req which supported rate is "
1377 /* use our own rate set as statoin used */
1378 /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
1379 /* supportRateNum = AP_BSSRATE_LEN; */
1381 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1382 goto OnAssocReq23aFail;
1384 memcpy(supportRate, p + 2, p[1]);
1385 supportRateNum = p[1];
1387 p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, pos, left);
1389 if (supportRateNum <= sizeof(supportRate)) {
1390 memcpy(supportRate+supportRateNum, p + 2, p[1]);
1391 supportRateNum += p[1];
1396 /* todo: mask supportRate between AP & STA -> move to update raid */
1397 /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */
1399 /* update station supportRate */
1400 pstat->bssratelen = supportRateNum;
1401 memcpy(pstat->bssrateset, supportRate, supportRateNum);
1402 Update23aTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
1404 /* check RSN/WPA/WPS */
1405 pstat->dot8021xalg = 0;
1407 pstat->wpa_group_cipher = 0;
1408 pstat->wpa2_group_cipher = 0;
1409 pstat->wpa_pairwise_cipher = 0;
1410 pstat->wpa2_pairwise_cipher = 0;
1411 memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
1413 wpa_ie = cfg80211_find_ie(WLAN_EID_RSN, pos, left);
1415 wpa_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1416 WLAN_OUI_TYPE_MICROSOFT_WPA,
1419 int group_cipher = 0, pairwise_cipher = 0;
1421 wpa_ie_len = wpa_ie[1];
1422 if (psecuritypriv->wpa_psk & BIT(1)) {
1423 r = rtw_parse_wpa2_ie23a(wpa_ie, wpa_ie_len + 2,
1425 &pairwise_cipher, NULL);
1426 if (r == _SUCCESS) {
1427 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1428 pstat->wpa_psk |= BIT(1);
1430 pstat->wpa2_group_cipher = group_cipher &
1431 psecuritypriv->wpa2_group_cipher;
1432 pstat->wpa2_pairwise_cipher = pairwise_cipher &
1433 psecuritypriv->wpa2_pairwise_cipher;
1435 status = WLAN_STATUS_INVALID_IE;
1436 } else if (psecuritypriv->wpa_psk & BIT(0)) {
1437 r = rtw_parse_wpa_ie23a(wpa_ie, wpa_ie_len + 2,
1438 &group_cipher, &pairwise_cipher,
1440 if (r == _SUCCESS) {
1441 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1442 pstat->wpa_psk |= BIT(0);
1444 pstat->wpa_group_cipher = group_cipher &
1445 psecuritypriv->wpa_group_cipher;
1446 pstat->wpa_pairwise_cipher = pairwise_cipher &
1447 psecuritypriv->wpa_pairwise_cipher;
1449 status = WLAN_STATUS_INVALID_IE;
1454 if (wpa_ie && status == WLAN_STATUS_SUCCESS) {
1455 if (!pstat->wpa_group_cipher)
1456 status = WLAN_STATUS_INVALID_GROUP_CIPHER;
1458 if (!pstat->wpa_pairwise_cipher)
1459 status = WLAN_STATUS_INVALID_PAIRWISE_CIPHER;
1463 if (status != WLAN_STATUS_SUCCESS)
1464 goto OnAssocReq23aFail;
1466 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
1468 wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1469 WLAN_OUI_TYPE_MICROSOFT_WPS,
1474 DBG_8723A("STA included WPS IE in (Re)Association "
1475 "Request - assume WPS is used\n");
1476 pstat->flags |= WLAN_STA_WPS;
1478 DBG_8723A("STA did not include WPA/RSN IE in (Re)"
1479 "Association Request - possible WPS use\n");
1480 pstat->flags |= WLAN_STA_MAYBE_WPS;
1483 /* AP support WPA/RSN, and sta is going to do WPS, but AP
1485 /* that the selected registrar of AP is _FLASE */
1486 if (psecuritypriv->wpa_psk > 0 &&
1487 pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS)) {
1488 if (pmlmepriv->wps_beacon_ie) {
1489 u8 selected_registrar = 0;
1491 rtw_get_wps_attr_content23a(
1492 pmlmepriv->wps_beacon_ie,
1493 pmlmepriv->wps_beacon_ie_len,
1494 WPS_ATTR_SELECTED_REGISTRAR,
1495 &selected_registrar, NULL);
1497 if (!selected_registrar) {
1498 DBG_8723A("selected_registrar is false,"
1499 "or AP is not ready to do "
1502 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1503 goto OnAssocReq23aFail;
1510 if (psecuritypriv->wpa_psk == 0) {
1511 DBG_8723A("STA " MAC_FMT ": WPA/RSN IE in association "
1512 "request, but AP don't support WPA/RSN\n",
1513 MAC_ARG(pstat->hwaddr));
1515 status = WLAN_STATUS_INVALID_IE;
1517 goto OnAssocReq23aFail;
1521 DBG_8723A("STA included WPS IE in (Re)Association "
1522 "Request - WPS is used\n");
1523 pstat->flags |= WLAN_STA_WPS;
1526 copy_len = ((wpa_ie_len + 2) > sizeof(pstat->wpa_ie)) ?
1527 sizeof(pstat->wpa_ie) : (wpa_ie_len + 2);
1531 memcpy(pstat->wpa_ie, wpa_ie - 2, copy_len);
1534 /* check if there is WMM IE & support WWM-PS */
1535 pstat->flags &= ~WLAN_STA_WME;
1536 pstat->qos_option = 0;
1537 pstat->qos_info = 0;
1538 pstat->has_legacy_ac = true;
1539 pstat->uapsd_vo = 0;
1540 pstat->uapsd_vi = 0;
1541 pstat->uapsd_be = 0;
1542 pstat->uapsd_bk = 0;
1543 if (pmlmepriv->qospriv.qos_option) {
1544 const u8 *end = pos + left;
1549 p = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, p, left);
1551 if (!memcmp(p + 2, WMM_IE, 6)) {
1552 pstat->flags |= WLAN_STA_WME;
1554 pstat->qos_option = 1;
1555 pstat->qos_info = *(p + 8);
1558 (pstat->qos_info >> 5) & 0x3;
1560 if ((pstat->qos_info & 0xf) != 0xf)
1561 pstat->has_legacy_ac = true;
1563 pstat->has_legacy_ac = false;
1565 if (pstat->qos_info & 0xf) {
1566 if (pstat->qos_info & BIT(0))
1567 pstat->uapsd_vo = BIT(0)|BIT(1);
1569 pstat->uapsd_vo = 0;
1571 if (pstat->qos_info & BIT(1))
1572 pstat->uapsd_vi = BIT(0)|BIT(1);
1574 pstat->uapsd_vi = 0;
1576 if (pstat->qos_info & BIT(2))
1577 pstat->uapsd_bk = BIT(0)|BIT(1);
1579 pstat->uapsd_bk = 0;
1581 if (pstat->qos_info & BIT(3))
1582 pstat->uapsd_be = BIT(0)|BIT(1);
1584 pstat->uapsd_be = 0;
1597 /* save HT capabilities in the sta object */
1598 memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap));
1599 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pos, left);
1601 if (p && p[1] >= sizeof(struct ieee80211_ht_cap)) {
1602 pstat->flags |= WLAN_STA_HT;
1604 pstat->flags |= WLAN_STA_WME;
1606 memcpy(&pstat->htpriv.ht_cap, p + 2,
1607 sizeof(struct ieee80211_ht_cap));
1609 pstat->flags &= ~WLAN_STA_HT;
1611 if (pmlmepriv->htpriv.ht_option == false && pstat->flags & WLAN_STA_HT){
1612 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1613 goto OnAssocReq23aFail;
1616 if (pstat->flags & WLAN_STA_HT &&
1617 (pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP ||
1618 pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP)) {
1619 DBG_8723A("HT: " MAC_FMT " tried to use TKIP with HT "
1620 "association\n", MAC_ARG(pstat->hwaddr));
1622 /* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */
1623 /* goto OnAssocReq23aFail; */
1626 pstat->flags |= WLAN_STA_NONERP;
1627 for (i = 0; i < pstat->bssratelen; i++) {
1628 if ((pstat->bssrateset[i] & 0x7f) > 22) {
1629 pstat->flags &= ~WLAN_STA_NONERP;
1634 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1635 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
1637 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1639 if (status != WLAN_STATUS_SUCCESS)
1640 goto OnAssocReq23aFail;
1642 /* TODO: identify_proprietary_vendor_ie(); */
1643 /* Realtek proprietary IE */
1644 /* identify if this is Broadcom sta */
1645 /* identify if this is ralink sta */
1646 /* Customer proprietary IE */
1648 /* get a unique AID */
1649 if (pstat->aid > 0) {
1650 DBG_8723A(" old AID %d\n", pstat->aid);
1652 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
1653 if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
1656 if (pstat->aid > NUM_STA)
1657 pstat->aid = NUM_STA;
1658 if (pstat->aid > pstapriv->max_num_sta) {
1662 DBG_8723A(" no room for more AIDs\n");
1664 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1666 goto OnAssocReq23aFail;
1668 pstapriv->sta_aid[pstat->aid - 1] = pstat;
1669 DBG_8723A("allocate new AID = (%d)\n", pstat->aid);
1673 pstat->state &= ~WIFI_FW_ASSOC_STATE;
1674 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
1676 spin_lock_bh(&pstapriv->auth_list_lock);
1677 if (!list_empty(&pstat->auth_list)) {
1678 list_del_init(&pstat->auth_list);
1679 pstapriv->auth_list_cnt--;
1681 spin_unlock_bh(&pstapriv->auth_list_lock);
1683 spin_lock_bh(&pstapriv->asoc_list_lock);
1684 if (list_empty(&pstat->asoc_list)) {
1685 pstat->expire_to = pstapriv->expire_to;
1686 list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list);
1687 pstapriv->asoc_list_cnt++;
1689 spin_unlock_bh(&pstapriv->asoc_list_lock);
1691 /* now the station is qualified to join our BSS... */
1692 if (pstat && pstat->state & WIFI_FW_ASSOC_SUCCESS &&
1693 status == WLAN_STATUS_SUCCESS) {
1694 #ifdef CONFIG_8723AU_AP_MODE
1695 /* 1 bss_cap_update & sta_info_update23a */
1696 bss_cap_update_on_sta_join23a(padapter, pstat);
1697 sta_info_update23a(padapter, pstat);
1699 /* issue assoc rsp before notify station join event. */
1700 if (ieee80211_is_assoc_req(mgmt->frame_control))
1701 issue_asocrsp23a(padapter, status, pstat,
1704 issue_asocrsp23a(padapter, status, pstat,
1707 /* 2 - report to upper layer */
1708 DBG_8723A("indicate_sta_join_event to upper layer - hostapd\n");
1709 rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
1711 /* 3-(1) report sta add event */
1712 report_add_sta_event23a(padapter, pstat->hwaddr, pstat->aid);
1720 #ifdef CONFIG_8723AU_AP_MODE
1721 issue_deauth23a(padapter, mgmt->sa, status);
1727 #ifdef CONFIG_8723AU_AP_MODE
1729 if (ieee80211_is_assoc_req(mgmt->frame_control))
1730 issue_asocrsp23a(padapter, status, pstat, WIFI_ASSOCRSP);
1732 issue_asocrsp23a(padapter, status, pstat, WIFI_REASSOCRSP);
1735 #endif /* CONFIG_8723AU_AP_MODE */
1741 OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1743 struct ndis_802_11_var_ies *pIE;
1744 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1745 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1746 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1747 struct sk_buff *skb = precv_frame->pkt;
1748 struct ieee80211_mgmt *pmgmt = (struct ieee80211_mgmt *) skb->data;
1750 unsigned short status;
1751 u8 *pframe = skb->data;
1752 int pkt_len = skb->len;
1754 DBG_8723A("%s\n", __func__);
1756 /* check A1 matches or not */
1757 if (!ether_addr_equal(myid(&padapter->eeprompriv), pmgmt->da))
1760 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
1763 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1766 del_timer_sync(&pmlmeext->link_timer);
1769 status = le16_to_cpu(pmgmt->u.assoc_resp.status_code);
1771 DBG_8723A("assoc reject, status code: %d\n", status);
1772 pmlmeinfo->state = WIFI_FW_NULL_STATE;
1774 goto report_assoc_result;
1777 /* get capabilities */
1778 pmlmeinfo->capability = le16_to_cpu(pmgmt->u.assoc_resp.capab_info);
1781 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
1784 res = pmlmeinfo->aid = le16_to_cpu(pmgmt->u.assoc_resp.aid) & 0x3fff;
1786 /* following are moved to join event callback function */
1787 /* to handle HT, WMM, rate adaptive, update MAC reg */
1788 /* for not to handle the synchronous IO in the tasklet */
1789 for (i = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
1791 pIE = (struct ndis_802_11_var_ies *)(pframe + i);
1793 switch (pIE->ElementID)
1795 case WLAN_EID_VENDOR_SPECIFIC:
1796 if (!memcmp(pIE->data, WMM_PARA_OUI23A, 6))/* WMM */
1797 WMM_param_handler23a(padapter, pIE);
1800 case WLAN_EID_HT_CAPABILITY: /* HT caps */
1801 HT_caps_handler23a(padapter, pIE);
1804 case WLAN_EID_HT_OPERATION: /* HT info */
1805 HT_info_handler23a(padapter, pIE);
1808 case WLAN_EID_ERP_INFO:
1809 ERP_IE_handler23a(padapter, pIE);
1815 i += (pIE->Length + 2);
1818 pmlmeinfo->state &= ~WIFI_FW_ASSOC_STATE;
1819 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
1821 /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
1822 UpdateBrateTbl23a(padapter, pmlmeinfo->network.SupportedRates);
1824 report_assoc_result:
1825 pmlmepriv->assoc_rsp_len = 0;
1827 kfree(pmlmepriv->assoc_rsp);
1828 pmlmepriv->assoc_rsp = kmalloc(pkt_len, GFP_ATOMIC);
1829 if (pmlmepriv->assoc_rsp) {
1830 memcpy(pmlmepriv->assoc_rsp, pframe, pkt_len);
1831 pmlmepriv->assoc_rsp_len = pkt_len;
1834 kfree(pmlmepriv->assoc_rsp);
1836 report_join_res23a(padapter, res);
1842 OnDeAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1844 unsigned short reason;
1845 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1846 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1847 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1848 struct sk_buff *skb = precv_frame->pkt;
1849 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1851 if (!ether_addr_equal(mgmt->bssid,
1852 get_my_bssid23a(&pmlmeinfo->network)))
1855 reason = le16_to_cpu(mgmt->u.deauth.reason_code);
1857 DBG_8723A("%s Reason code(%d)\n", __func__, reason);
1859 #ifdef CONFIG_8723AU_AP_MODE
1860 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
1861 struct sta_info *psta;
1862 struct sta_priv *pstapriv = &padapter->stapriv;
1864 DBG_8723A_LEVEL(_drv_always_, "ap recv deauth reason code(%d) "
1865 "sta:%pM\n", reason, mgmt->sa);
1867 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1871 spin_lock_bh(&pstapriv->asoc_list_lock);
1872 if (!list_empty(&psta->asoc_list)) {
1873 list_del_init(&psta->asoc_list);
1874 pstapriv->asoc_list_cnt--;
1875 updated = ap_free_sta23a(padapter, psta,
1878 spin_unlock_bh(&pstapriv->asoc_list_lock);
1880 associated_clients_update23a(padapter, updated);
1887 DBG_8723A_LEVEL(_drv_always_, "sta recv deauth reason code(%d) "
1888 "sta:%pM\n", reason, mgmt->bssid);
1890 receive_disconnect23a(padapter, mgmt->bssid, reason);
1892 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1898 OnDisassoc23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1900 unsigned short reason;
1901 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1902 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1903 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1904 struct sk_buff *skb = precv_frame->pkt;
1905 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1907 if (!ether_addr_equal(mgmt->bssid,
1908 get_my_bssid23a(&pmlmeinfo->network)))
1911 reason = le16_to_cpu(mgmt->u.disassoc.reason_code);
1913 DBG_8723A("%s Reason code(%d)\n", __func__, reason);
1915 #ifdef CONFIG_8723AU_AP_MODE
1916 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1917 struct sta_info *psta;
1918 struct sta_priv *pstapriv = &padapter->stapriv;
1920 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason code(%d)"
1921 " sta:%pM\n", reason, mgmt->sa);
1923 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1927 spin_lock_bh(&pstapriv->asoc_list_lock);
1928 if (!list_empty(&psta->asoc_list)) {
1929 list_del_init(&psta->asoc_list);
1930 pstapriv->asoc_list_cnt--;
1931 updated = ap_free_sta23a(padapter, psta,
1934 spin_unlock_bh(&pstapriv->asoc_list_lock);
1936 associated_clients_update23a(padapter, updated);
1943 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason "
1944 "code(%d) sta:%pM\n", reason, mgmt->bssid);
1946 receive_disconnect23a(padapter, mgmt->bssid, reason);
1948 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1953 OnAtim23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1955 DBG_8723A("%s\n", __func__);
1960 on_action_spct23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1966 OnAction23a_qos(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1972 OnAction23a_dls(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1977 static int OnAction23a_back23a(struct rtw_adapter *padapter,
1978 struct recv_frame *precv_frame)
1981 struct sta_info *psta = NULL;
1982 struct recv_reorder_ctrl *preorder_ctrl;
1983 unsigned char category, action;
1984 unsigned short tid, status, capab, params, reason_code = 0;
1985 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1986 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1987 struct sk_buff *skb = precv_frame->pkt;
1988 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1989 struct sta_priv *pstapriv = &padapter->stapriv;
1991 /* check RA matches or not */
1992 if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da))
1995 DBG_8723A("%s\n", __func__);
1997 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1998 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
2002 psta = rtw_get_stainfo23a(pstapriv, addr);
2007 category = mgmt->u.action.category;
2008 if (category == WLAN_CATEGORY_BACK) { /* representing Block Ack */
2009 if (!pmlmeinfo->HT_enable)
2011 /* action_code is located in the same place for all
2012 action events, so pick any */
2013 action = mgmt->u.action.u.wme_action.action_code;
2014 DBG_8723A("%s, action =%d\n", __func__, action);
2016 case WLAN_ACTION_ADDBA_REQ: /* ADDBA request */
2017 memcpy(&pmlmeinfo->ADDBA_req,
2018 &mgmt->u.action.u.addba_req.dialog_token,
2019 sizeof(struct ADDBA_request));
2020 process_addba_req23a(padapter,
2021 (u8 *)&pmlmeinfo->ADDBA_req, addr);
2022 if (pmlmeinfo->bAcceptAddbaReq == true)
2023 issue_action_BA23a(padapter, addr,
2024 WLAN_ACTION_ADDBA_RESP, 0);
2026 /* reject ADDBA Req */
2027 issue_action_BA23a(padapter, addr,
2028 WLAN_ACTION_ADDBA_RESP, 37);
2031 case WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
2032 status = get_unaligned_le16(
2033 &mgmt->u.action.u.addba_resp.status);
2034 capab = get_unaligned_le16(
2035 &mgmt->u.action.u.addba_resp.capab);
2036 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
2037 if (status == 0) { /* successful */
2038 DBG_8723A("agg_enable for TID =%d\n", tid);
2039 psta->htpriv.agg_enable_bitmap |= 1 << tid;
2040 psta->htpriv.candidate_tid_bitmap &=
2043 psta->htpriv.agg_enable_bitmap &= ~CHKBIT(tid);
2046 case WLAN_ACTION_DELBA: /* DELBA */
2047 params = get_unaligned_le16(
2048 &mgmt->u.action.u.delba.params);
2051 if (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) {
2052 preorder_ctrl = &psta->recvreorder_ctrl[tid];
2053 preorder_ctrl->enable = false;
2054 preorder_ctrl->indicate_seq = 0xffff;
2056 psta->htpriv.agg_enable_bitmap &= ~(1 << tid);
2057 psta->htpriv.candidate_tid_bitmap &=
2060 reason_code = get_unaligned_le16(
2061 &mgmt->u.action.u.delba.reason_code);
2062 DBG_8723A("%s(): DELBA: %x(%x)\n", __func__,
2063 pmlmeinfo->agg_enable_bitmap, reason_code);
2064 /* todo: how to notify the host while receiving
2074 static s32 rtw_action_public_decache(struct recv_frame *recv_frame, s32 token)
2076 struct rtw_adapter *adapter = recv_frame->adapter;
2077 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
2078 struct sk_buff *skb = recv_frame->pkt;
2079 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2082 seq_ctrl = ((recv_frame->attrib.seq_num&0xffff) << 4) |
2083 (recv_frame->attrib.frag_num & 0xf);
2085 if (ieee80211_has_retry(hdr->frame_control)) {
2087 if ((seq_ctrl == mlmeext->action_public_rxseq) &&
2088 (token == mlmeext->action_public_dialog_token)) {
2089 DBG_8723A(FUNC_ADPT_FMT" seq_ctrl = 0x%x, "
2090 "rxseq = 0x%x, token:%d\n",
2091 FUNC_ADPT_ARG(adapter), seq_ctrl,
2092 mlmeext->action_public_rxseq, token);
2096 if (seq_ctrl == mlmeext->action_public_rxseq) {
2097 DBG_8723A(FUNC_ADPT_FMT" seq_ctrl = 0x%x, "
2099 FUNC_ADPT_ARG(adapter), seq_ctrl,
2100 mlmeext->action_public_rxseq);
2106 mlmeext->action_public_rxseq = seq_ctrl;
2109 mlmeext->action_public_dialog_token = token;
2114 static unsigned int on_action_public23a_p2p(struct recv_frame *precv_frame)
2116 struct sk_buff *skb = precv_frame->pkt;
2117 u8 *pframe = skb->data;
2121 frame_body = (unsigned char *)
2122 (pframe + sizeof(struct ieee80211_hdr_3addr));
2124 dialogToken = frame_body[7];
2126 if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
2132 static unsigned int on_action_public23a_vendor(struct recv_frame *precv_frame)
2134 unsigned int ret = _FAIL;
2135 struct sk_buff *skb = precv_frame->pkt;
2136 u8 *pframe = skb->data;
2137 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2139 if (!memcmp(frame_body + 2, P2P_OUI23A, 4)) {
2140 ret = on_action_public23a_p2p(precv_frame);
2147 on_action_public23a_default(struct recv_frame *precv_frame, u8 action)
2149 unsigned int ret = _FAIL;
2150 struct sk_buff *skb = precv_frame->pkt;
2151 u8 *pframe = skb->data;
2152 uint frame_len = skb->len;
2153 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2155 struct rtw_adapter *adapter = precv_frame->adapter;
2159 token = frame_body[2];
2161 if (rtw_action_public_decache(precv_frame, token) == _FAIL)
2164 cnt += sprintf((msg+cnt), "%s(token:%u)",
2165 action_public_str23a(action), token);
2166 rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
2174 static int on_action_public23a(struct rtw_adapter *padapter,
2175 struct recv_frame *precv_frame)
2177 unsigned int ret = _FAIL;
2178 struct sk_buff *skb = precv_frame->pkt;
2179 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2180 u8 *pframe = skb->data;
2181 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2182 u8 category, action;
2184 /* check RA matches or not */
2185 if (!ether_addr_equal(myid(&padapter->eeprompriv), hdr->addr1))
2188 category = frame_body[0];
2189 if (category != WLAN_CATEGORY_PUBLIC)
2192 action = frame_body[1];
2194 case ACT_PUBLIC_VENDOR:
2195 ret = on_action_public23a_vendor(precv_frame);
2198 ret = on_action_public23a_default(precv_frame, action);
2207 OnAction23a_ht(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2213 OnAction23a_wmm(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2219 OnAction23a_p2p(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2225 OnAction23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2229 struct action_handler *ptable;
2230 struct sk_buff *skb = precv_frame->pkt;
2231 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
2233 category = mgmt->u.action.category;
2236 i < sizeof(OnAction23a_tbl) / sizeof(struct action_handler); i++) {
2237 ptable = &OnAction23a_tbl[i];
2239 if (category == ptable->num)
2240 ptable->func(padapter, precv_frame);
2246 static int DoReserved23a(struct rtw_adapter *padapter,
2247 struct recv_frame *precv_frame)
2252 struct xmit_frame *alloc_mgtxmitframe23a(struct xmit_priv *pxmitpriv)
2254 struct xmit_frame *pmgntframe;
2255 struct xmit_buf *pxmitbuf;
2257 pmgntframe = rtw_alloc_xmitframe23a_ext(pxmitpriv);
2260 DBG_8723A(FUNC_ADPT_FMT" alloc xmitframe fail\n",
2261 FUNC_ADPT_ARG(pxmitpriv->adapter));
2265 pxmitbuf = rtw_alloc_xmitbuf23a_ext(pxmitpriv);
2267 DBG_8723A(FUNC_ADPT_FMT" alloc xmitbuf fail\n",
2268 FUNC_ADPT_ARG(pxmitpriv->adapter));
2269 rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
2274 pmgntframe->frame_tag = MGNT_FRAMETAG;
2275 pmgntframe->pxmitbuf = pxmitbuf;
2276 pmgntframe->buf_addr = pxmitbuf->pbuf;
2277 pxmitbuf->priv_data = pmgntframe;
2283 /****************************************************************************
2285 Following are some TX fuctions for WiFi MLME
2287 *****************************************************************************/
2289 void update_mgnt_tx_rate23a(struct rtw_adapter *padapter, u8 rate)
2291 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2293 pmlmeext->tx_rate = rate;
2294 DBG_8723A("%s(): rate = %x\n", __func__, rate);
2297 void update_mgntframe_attrib23a(struct rtw_adapter *padapter,
2298 struct pkt_attrib *pattrib)
2300 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2302 memset((u8 *)pattrib, 0, sizeof(struct pkt_attrib));
2304 pattrib->hdrlen = 24;
2305 pattrib->nr_frags = 1;
2306 pattrib->priority = 7;
2307 pattrib->mac_id = 0;
2308 pattrib->qsel = 0x12;
2310 pattrib->pktlen = 0;
2312 if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
2313 pattrib->raid = 6;/* b mode */
2315 pattrib->raid = 5;/* a/g mode */
2317 pattrib->encrypt = _NO_PRIVACY_;
2318 pattrib->bswenc = false;
2320 pattrib->qos_en = false;
2321 pattrib->ht_en = false;
2322 pattrib->bwmode = HT_CHANNEL_WIDTH_20;
2323 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2324 pattrib->sgi = false;
2326 pattrib->seqnum = pmlmeext->mgnt_seq;
2328 pattrib->retry_ctrl = true;
2331 void dump_mgntframe23a(struct rtw_adapter *padapter,
2332 struct xmit_frame *pmgntframe)
2334 if (padapter->bSurpriseRemoved == true ||
2335 padapter->bDriverStopped == true)
2338 rtw_hal_mgnt_xmit23a(padapter, pmgntframe);
2341 s32 dump_mgntframe23a_and_wait(struct rtw_adapter *padapter,
2342 struct xmit_frame *pmgntframe, int timeout_ms)
2346 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2347 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
2348 struct submit_ctx sctx;
2350 if (padapter->bSurpriseRemoved == true ||
2351 padapter->bDriverStopped == true)
2354 rtw_sctx_init23a(&sctx, timeout_ms);
2355 pxmitbuf->sctx = &sctx;
2357 ret = rtw_hal_mgnt_xmit23a(padapter, pmgntframe);
2359 if (ret == _SUCCESS)
2360 ret = rtw_sctx_wait23a(&sctx);
2362 spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL);
2363 pxmitbuf->sctx = NULL;
2364 spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL);
2369 s32 dump_mgntframe23a_and_wait_ack23a(struct rtw_adapter *padapter,
2370 struct xmit_frame *pmgntframe)
2373 u32 timeout_ms = 500;/* 500ms */
2374 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2376 if (padapter->bSurpriseRemoved == true ||
2377 padapter->bDriverStopped == true)
2380 mutex_lock(&pxmitpriv->ack_tx_mutex);
2381 pxmitpriv->ack_tx = true;
2383 pmgntframe->ack_report = 1;
2384 if (rtw_hal_mgnt_xmit23a(padapter, pmgntframe) == _SUCCESS) {
2385 ret = rtw_ack_tx_wait23a(pxmitpriv, timeout_ms);
2388 pxmitpriv->ack_tx = false;
2389 mutex_unlock(&pxmitpriv->ack_tx_mutex);
2394 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
2402 ssid_ie = rtw_get_ie23a(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
2404 /* DBG_8723A("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n",
2405 __func__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
2407 if (ssid_ie && ssid_len_ori > 0) {
2408 switch (hidden_ssid_mode)
2411 next_ie = ssid_ie + 2 + ssid_len_ori;
2414 remain_len = ies_len -(next_ie-ies);
2417 memcpy(ssid_ie+2, next_ie, remain_len);
2418 len_diff -= ssid_len_ori;
2422 memset(&ssid_ie[2], 0, ssid_len_ori);
2432 void issue_beacon23a(struct rtw_adapter *padapter, int timeout_ms)
2434 struct xmit_frame *pmgntframe;
2435 struct pkt_attrib *pattrib;
2436 unsigned char *pframe;
2437 struct ieee80211_hdr *pwlanhdr;
2439 unsigned int rate_len;
2440 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2441 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2442 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2443 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2444 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
2445 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2451 /* DBG_8723A("%s\n", __func__); */
2453 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL) {
2454 DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
2457 #ifdef CONFIG_8723AU_AP_MODE
2458 spin_lock_bh(&pmlmepriv->bcn_update_lock);
2461 /* update attribute */
2462 pattrib = &pmgntframe->attrib;
2463 update_mgntframe_attrib23a(padapter, pattrib);
2464 pattrib->qsel = 0x10;
2466 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2468 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2469 pwlanhdr = (struct ieee80211_hdr *)pframe;
2471 fctrl = &pwlanhdr->frame_control;
2474 ether_addr_copy(pwlanhdr->addr1, bc_addr);
2475 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
2476 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(cur_network));
2478 SetSeqNum(pwlanhdr, 0 /*pmlmeext->mgnt_seq*/);
2479 /* pmlmeext->mgnt_seq++; */
2480 SetFrameSubType(pframe, WIFI_BEACON);
2482 pframe += sizeof(struct ieee80211_hdr_3addr);
2483 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
2485 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
2486 /* DBG_8723A("ie len =%d\n", cur_network->IELength); */
2487 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2488 len_diff = update_hidden_ssid(pframe + _BEACON_IE_OFFSET_,
2489 cur_network->IELength -
2491 pmlmeinfo->hidden_ssid_mode);
2492 pframe += (cur_network->IELength+len_diff);
2493 pattrib->pktlen += (cur_network->IELength+len_diff);
2495 wps_ie = rtw_get_wps_ie23a(pmgntframe->buf_addr + TXDESC_OFFSET+
2496 sizeof (struct ieee80211_hdr_3addr) +
2497 _BEACON_IE_OFFSET_, pattrib->pktlen -
2498 sizeof (struct ieee80211_hdr_3addr) -
2499 _BEACON_IE_OFFSET_, NULL,
2501 if (wps_ie && wps_ielen > 0) {
2502 rtw_get_wps_attr_content23a(wps_ie, wps_ielen,
2503 WPS_ATTR_SELECTED_REGISTRAR,
2507 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
2509 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
2514 /* below for ad-hoc mode */
2516 /* timestamp will be inserted by hardware */
2518 pattrib->pktlen += 8;
2520 /* beacon interval: 2 bytes */
2522 memcpy(pframe, (unsigned char *)
2523 rtw_get_beacon_interval23a_from_ie(cur_network->IEs), 2);
2526 pattrib->pktlen += 2;
2528 /* capability info: 2 bytes */
2530 memcpy(pframe, (unsigned char *)
2531 rtw_get_capability23a_from_ie(cur_network->IEs), 2);
2534 pattrib->pktlen += 2;
2537 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
2538 cur_network->Ssid.ssid_len,
2539 cur_network->Ssid.ssid, &pattrib->pktlen);
2541 /* supported rates... */
2542 rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
2543 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2544 ((rate_len > 8)? 8: rate_len),
2545 cur_network->SupportedRates, &pattrib->pktlen);
2547 /* DS parameter set */
2548 pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)
2549 &cur_network->Configuration.DSConfig,
2552 /* if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
2556 /* IBSS Parameter Set... */
2557 /* ATIMWindow = cur->Configuration.ATIMWindow; */
2559 pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
2560 (unsigned char *)&ATIMWindow,
2564 pframe = rtw_set_ie23a(pframe, WLAN_EID_ERP_INFO, 1,
2565 &erpinfo, &pattrib->pktlen);
2568 /* EXTERNDED SUPPORTED RATE */
2570 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2572 cur_network->SupportedRates + 8,
2575 /* todo:HT for adhoc */
2579 #ifdef CONFIG_8723AU_AP_MODE
2580 pmlmepriv->update_bcn = false;
2582 spin_unlock_bh(&pmlmepriv->bcn_update_lock);
2585 if ((pattrib->pktlen + TXDESC_SIZE) > 512) {
2586 DBG_8723A("beacon frame too large\n");
2590 pattrib->last_txcmdsz = pattrib->pktlen;
2592 /* DBG_8723A("issue bcn_sz =%d\n", pattrib->last_txcmdsz); */
2594 dump_mgntframe23a_and_wait(padapter, pmgntframe, timeout_ms);
2596 dump_mgntframe23a(padapter, pmgntframe);
2599 void issue_probersp23a(struct rtw_adapter *padapter, unsigned char *da,
2600 u8 is_valid_p2p_probereq)
2602 struct xmit_frame *pmgntframe;
2603 struct pkt_attrib *pattrib;
2604 unsigned char *pframe;
2605 struct ieee80211_hdr *pwlanhdr;
2607 unsigned char *mac, *bssid;
2608 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2609 #ifdef CONFIG_8723AU_AP_MODE
2614 int ssid_ielen_diff;
2617 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2619 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2620 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2621 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
2622 unsigned int rate_len;
2624 /* DBG_8723A("%s\n", __func__); */
2626 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2628 DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
2632 /* update attribute */
2633 pattrib = &pmgntframe->attrib;
2634 update_mgntframe_attrib23a(padapter, pattrib);
2636 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2638 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
2639 pwlanhdr = (struct ieee80211_hdr *)pframe;
2641 mac = myid(&padapter->eeprompriv);
2642 bssid = cur_network->MacAddress;
2644 fctrl = &pwlanhdr->frame_control;
2646 ether_addr_copy(pwlanhdr->addr1, da);
2647 ether_addr_copy(pwlanhdr->addr2, mac);
2648 ether_addr_copy(pwlanhdr->addr3, bssid);
2650 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2651 pmlmeext->mgnt_seq++;
2652 SetFrameSubType(fctrl, WIFI_PROBERSP);
2654 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
2655 pattrib->pktlen = pattrib->hdrlen;
2656 pframe += pattrib->hdrlen;
2658 if (cur_network->IELength > MAX_IE_SZ)
2661 #ifdef CONFIG_8723AU_AP_MODE
2662 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
2663 pwps_ie = rtw_get_wps_ie23a(cur_network->IEs +
2665 cur_network->IELength -
2666 _FIXED_IE_LENGTH_, NULL,
2669 /* inerset & update wps_probe_resp_ie */
2670 if (pmlmepriv->wps_probe_resp_ie && pwps_ie && wps_ielen > 0) {
2671 uint wps_offset, remainder_ielen;
2674 wps_offset = (uint)(pwps_ie - cur_network->IEs);
2676 premainder_ie = pwps_ie + wps_ielen;
2678 remainder_ielen = cur_network->IELength - wps_offset -
2681 memcpy(pframe, cur_network->IEs, wps_offset);
2682 pframe += wps_offset;
2683 pattrib->pktlen += wps_offset;
2685 /* to get ie data len */
2686 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];
2687 if (wps_offset + wps_ielen + 2 <= MAX_IE_SZ) {
2688 memcpy(pframe, pmlmepriv->wps_probe_resp_ie,
2690 pframe += wps_ielen+2;
2691 pattrib->pktlen += wps_ielen+2;
2694 if (wps_offset + wps_ielen + 2 + remainder_ielen <=
2696 memcpy(pframe, premainder_ie, remainder_ielen);
2697 pframe += remainder_ielen;
2698 pattrib->pktlen += remainder_ielen;
2701 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2702 pframe += cur_network->IELength;
2703 pattrib->pktlen += cur_network->IELength;
2706 /* retrieve SSID IE from cur_network->Ssid */
2707 ies = pmgntframe->buf_addr + TXDESC_OFFSET +
2708 sizeof(struct ieee80211_hdr_3addr);
2710 ssid_ie = rtw_get_ie23a(ies + _FIXED_IE_LENGTH_, WLAN_EID_SSID,
2712 pframe - ies - _FIXED_IE_LENGTH_);
2714 ssid_ielen_diff = cur_network->Ssid.ssid_len - ssid_ielen;
2716 if (ssid_ie && cur_network->Ssid.ssid_len) {
2717 uint remainder_ielen;
2719 remainder_ie = ssid_ie + 2;
2720 remainder_ielen = pframe - remainder_ie;
2722 DBG_8723A_LEVEL(_drv_warning_, FUNC_ADPT_FMT
2723 " remainder_ielen > MAX_IE_SZ\n",
2724 FUNC_ADPT_ARG(padapter));
2725 if (remainder_ielen > MAX_IE_SZ)
2726 remainder_ielen = MAX_IE_SZ;
2728 memcpy(buf, remainder_ie, remainder_ielen);
2729 memcpy(remainder_ie + ssid_ielen_diff, buf,
2731 *(ssid_ie + 1) = cur_network->Ssid.ssid_len;
2732 memcpy(ssid_ie + 2, cur_network->Ssid.ssid,
2733 cur_network->Ssid.ssid_len);
2735 pframe += ssid_ielen_diff;
2736 pattrib->pktlen += ssid_ielen_diff;
2742 /* timestamp will be inserted by hardware */
2744 pattrib->pktlen += 8;
2746 /* beacon interval: 2 bytes */
2748 memcpy(pframe, (unsigned char *)
2749 rtw_get_beacon_interval23a_from_ie(cur_network->IEs), 2);
2752 pattrib->pktlen += 2;
2754 /* capability info: 2 bytes */
2756 memcpy(pframe, (unsigned char *)
2757 rtw_get_capability23a_from_ie(cur_network->IEs), 2);
2760 pattrib->pktlen += 2;
2762 /* below for ad-hoc mode */
2765 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
2766 cur_network->Ssid.ssid_len,
2767 cur_network->Ssid.ssid,
2770 /* supported rates... */
2771 rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
2772 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2773 ((rate_len > 8)? 8: rate_len),
2774 cur_network->SupportedRates,
2777 /* DS parameter set */
2778 pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1,
2780 &cur_network->Configuration.DSConfig,
2783 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
2786 /* IBSS Parameter Set... */
2787 /* ATIMWindow = cur->Configuration.ATIMWindow; */
2789 pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
2790 (unsigned char *)&ATIMWindow,
2794 pframe = rtw_set_ie23a(pframe, WLAN_EID_ERP_INFO, 1,
2795 &erpinfo, &pattrib->pktlen);
2798 /* EXTERNDED SUPPORTED RATE */
2800 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2802 cur_network->SupportedRates + 8,
2805 /* todo:HT for adhoc */
2808 pattrib->last_txcmdsz = pattrib->pktlen;
2810 dump_mgntframe23a(padapter, pmgntframe);
2815 static int _issue_probereq23a(struct rtw_adapter *padapter,
2816 struct cfg80211_ssid *pssid, u8 *da, int wait_ack)
2819 struct xmit_frame *pmgntframe;
2820 struct pkt_attrib *pattrib;
2821 unsigned char *pframe;
2822 struct ieee80211_hdr *pwlanhdr;
2825 unsigned char bssrate[NumRates];
2826 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2827 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2828 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2829 int bssrate_len = 0;
2830 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2832 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
2833 ("+issue_probereq23a\n"));
2835 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
2838 /* update attribute */
2839 pattrib = &pmgntframe->attrib;
2840 update_mgntframe_attrib23a(padapter, pattrib);
2842 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2844 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2845 pwlanhdr = (struct ieee80211_hdr *)pframe;
2847 mac = myid(&padapter->eeprompriv);
2849 fctrl = &pwlanhdr->frame_control;
2853 /* unicast probe request frame */
2854 ether_addr_copy(pwlanhdr->addr1, da);
2855 ether_addr_copy(pwlanhdr->addr3, da);
2857 /* broadcast probe request frame */
2858 ether_addr_copy(pwlanhdr->addr1, bc_addr);
2859 ether_addr_copy(pwlanhdr->addr3, bc_addr);
2862 ether_addr_copy(pwlanhdr->addr2, mac);
2864 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2865 pmlmeext->mgnt_seq++;
2866 SetFrameSubType(pframe, WIFI_PROBEREQ);
2868 pframe += sizeof (struct ieee80211_hdr_3addr);
2869 pattrib->pktlen = sizeof (struct ieee80211_hdr_3addr);
2872 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID, pssid->ssid_len,
2873 pssid->ssid, &pattrib->pktlen);
2875 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID, 0, NULL,
2878 get_rate_set23a(padapter, bssrate, &bssrate_len);
2880 if (bssrate_len > 8) {
2881 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
2882 bssrate, &pattrib->pktlen);
2883 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2884 (bssrate_len - 8), (bssrate + 8),
2887 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2888 bssrate_len, bssrate, &pattrib->pktlen);
2891 /* add wps_ie for wps2.0 */
2892 if (pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie) {
2893 memcpy(pframe, pmlmepriv->wps_probe_req_ie,
2894 pmlmepriv->wps_probe_req_ie_len);
2895 pframe += pmlmepriv->wps_probe_req_ie_len;
2896 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
2899 pattrib->last_txcmdsz = pattrib->pktlen;
2901 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
2902 ("issuing probe_req, tx_len =%d\n", pattrib->last_txcmdsz));
2905 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
2907 dump_mgntframe23a(padapter, pmgntframe);
2915 inline void issue_probereq23a(struct rtw_adapter *padapter,
2916 struct cfg80211_ssid *pssid, u8 *da)
2918 _issue_probereq23a(padapter, pssid, da, false);
2921 int issue_probereq23a_ex23a(struct rtw_adapter *padapter,
2922 struct cfg80211_ssid *pssid, u8 *da,
2923 int try_cnt, int wait_ms)
2927 unsigned long start = jiffies;
2930 ret = _issue_probereq23a(padapter, pssid, da,
2931 wait_ms > 0 ? true : false);
2935 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
2938 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
2941 } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
2948 if (try_cnt && wait_ms) {
2950 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d "
2951 "in %u ms\n", FUNC_ADPT_ARG(padapter),
2952 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
2953 ret == _SUCCESS?", acked":"", i, try_cnt,
2954 jiffies_to_msecs(jiffies - start));
2956 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
2957 FUNC_ADPT_ARG(padapter),
2958 rtw_get_oper_ch23a(padapter),
2959 ret == _SUCCESS?", acked":"", i, try_cnt,
2960 jiffies_to_msecs(jiffies - start));
2966 /* if psta == NULL, indiate we are station(client) now... */
2967 void issue_auth23a(struct rtw_adapter *padapter, struct sta_info *psta,
2968 unsigned short status)
2970 struct xmit_frame *pmgntframe;
2971 struct pkt_attrib *pattrib;
2972 unsigned char *pframe;
2973 struct ieee80211_hdr *pwlanhdr;
2976 unsigned short val16;
2977 int use_shared_key = 0;
2978 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2979 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2980 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2982 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
2985 /* update attribute */
2986 pattrib = &pmgntframe->attrib;
2987 update_mgntframe_attrib23a(padapter, pattrib);
2989 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2991 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2992 pwlanhdr = (struct ieee80211_hdr *)pframe;
2994 fctrl = &pwlanhdr->frame_control;
2997 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2998 pmlmeext->mgnt_seq++;
2999 SetFrameSubType(pframe, WIFI_AUTH);
3001 pframe += sizeof(struct ieee80211_hdr_3addr);
3002 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3004 if (psta) { /* for AP mode */
3005 #ifdef CONFIG_8723AU_AP_MODE
3007 ether_addr_copy(pwlanhdr->addr1, psta->hwaddr);
3008 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3009 ether_addr_copy(pwlanhdr->addr3, myid(&padapter->eeprompriv));
3011 /* setting auth algo number */
3012 val16 = (u16)psta->authalg;
3014 if (status != WLAN_STATUS_SUCCESS)
3018 val16 = cpu_to_le16(val16);
3022 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_ALGM_NUM_,
3023 (unsigned char *)&val16,
3026 /* setting auth seq number */
3027 val16 = (u16)psta->auth_seq;
3028 val16 = cpu_to_le16(val16);
3029 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_SEQ_NUM_,
3030 (unsigned char *)&val16,
3033 /* setting status code... */
3035 val16 = cpu_to_le16(val16);
3036 pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
3037 (unsigned char *)&val16,
3040 /* added challenging text... */
3041 if ((psta->auth_seq == 2) &&
3042 (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
3043 pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
3044 psta->chg_txt, &pattrib->pktlen);
3047 ether_addr_copy(pwlanhdr->addr1,
3048 get_my_bssid23a(&pmlmeinfo->network));
3049 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3050 ether_addr_copy(pwlanhdr->addr3,
3051 get_my_bssid23a(&pmlmeinfo->network));
3053 /* setting auth algo number */
3054 /* 0:OPEN System, 1:Shared key */
3055 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;
3057 val16 = cpu_to_le16(val16);
3060 /* DBG_8723A("%s auth_algo = %s auth_seq =%d\n", __func__,
3061 (pmlmeinfo->auth_algo == 0)?"OPEN":"SHARED",
3062 pmlmeinfo->auth_seq); */
3064 /* setting IV for auth seq #3 */
3065 if ((pmlmeinfo->auth_seq == 3) &&
3066 (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
3067 (use_shared_key == 1)) {
3068 /* DBG_8723A("==> iv(%d), key_index(%d)\n",
3069 pmlmeinfo->iv, pmlmeinfo->key_index); */
3070 val32 = ((pmlmeinfo->iv++) |
3071 (pmlmeinfo->key_index << 30));
3072 val32 = cpu_to_le32(val32);
3073 pframe = rtw_set_fixed_ie23a(pframe, 4,
3074 (unsigned char *)&val32,
3077 pattrib->iv_len = 4;
3080 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_ALGM_NUM_,
3081 (unsigned char *)&val16,
3084 /* setting auth seq number */
3085 val16 = pmlmeinfo->auth_seq;
3086 val16 = cpu_to_le16(val16);
3087 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_SEQ_NUM_,
3088 (unsigned char *)&val16,
3091 /* setting status code... */
3093 val16 = cpu_to_le16(val16);
3094 pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
3095 (unsigned char *)&val16,
3098 /* then checking to see if sending challenging text... */
3099 if ((pmlmeinfo->auth_seq == 3) &&
3100 (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
3101 (use_shared_key == 1)) {
3102 pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
3108 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
3110 pattrib->encrypt = _WEP40_;
3112 pattrib->icv_len = 4;
3114 pattrib->pktlen += pattrib->icv_len;
3118 pattrib->last_txcmdsz = pattrib->pktlen;
3120 rtw_wep_encrypt23a(padapter, pmgntframe);
3121 DBG_8723A("%s\n", __func__);
3122 dump_mgntframe23a(padapter, pmgntframe);
3127 void issue_asocrsp23a(struct rtw_adapter *padapter, unsigned short status,
3128 struct sta_info *pstat, int pkt_type)
3130 #ifdef CONFIG_8723AU_AP_MODE
3131 struct xmit_frame *pmgntframe;
3132 struct ieee80211_hdr *pwlanhdr;
3133 struct pkt_attrib *pattrib;
3134 unsigned char *pframe;
3136 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3137 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3138 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3139 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3140 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
3142 u8 *ie = pnetwork->IEs;
3144 DBG_8723A("%s\n", __func__);
3146 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3150 /* update attribute */
3151 pattrib = &pmgntframe->attrib;
3152 update_mgntframe_attrib23a(padapter, pattrib);
3154 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3156 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3157 pwlanhdr = (struct ieee80211_hdr *)pframe;
3159 pwlanhdr->frame_control = 0;
3161 ether_addr_copy(pwlanhdr->addr1, pstat->hwaddr);
3162 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3163 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3165 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3166 pmlmeext->mgnt_seq++;
3167 if (pkt_type == WIFI_ASSOCRSP || pkt_type == WIFI_REASSOCRSP)
3168 SetFrameSubType(pwlanhdr, pkt_type);
3172 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
3173 pattrib->pktlen += pattrib->hdrlen;
3174 pframe += pattrib->hdrlen;
3177 val = *(unsigned short *)rtw_get_capability23a_from_ie(ie);
3179 pframe = rtw_set_fixed_ie23a(pframe, _CAPABILITY_,
3180 (unsigned char *)&val, &pattrib->pktlen);
3182 status = cpu_to_le16(status);
3183 pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
3184 (unsigned char *)&status,
3187 val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
3188 pframe = rtw_set_fixed_ie23a(pframe, _ASOC_ID_, (unsigned char *)&val,
3191 if (pstat->bssratelen <= 8) {
3192 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
3193 pstat->bssratelen, pstat->bssrateset,
3196 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
3197 pstat->bssrateset, &pattrib->pktlen);
3198 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
3199 pstat->bssratelen - 8,
3200 pstat->bssrateset + 8, &pattrib->pktlen);
3203 if (pstat->flags & WLAN_STA_HT && pmlmepriv->htpriv.ht_option) {
3204 /* FILL HT CAP INFO IE */
3205 /* p = hostapd_eid_ht_capabilities_info(hapd, p); */
3206 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
3207 ie + _BEACON_IE_OFFSET_,
3208 pnetwork->IELength -_BEACON_IE_OFFSET_);
3210 memcpy(pframe, p, p[1] + 2);
3211 pframe += (p[1] + 2);
3212 pattrib->pktlen += (p[1] + 2);
3215 /* FILL HT ADD INFO IE */
3216 /* p = hostapd_eid_ht_operation(hapd, p); */
3217 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
3218 ie + _BEACON_IE_OFFSET_,
3219 pnetwork->IELength - _BEACON_IE_OFFSET_);
3220 if (p && p[1] > 0) {
3221 memcpy(pframe, p, p[1] + 2);
3222 pframe += (p[1] + 2);
3223 pattrib->pktlen += (p[1] + 2);
3228 if (pstat->flags & WLAN_STA_WME && pmlmepriv->qospriv.qos_option) {
3229 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02,
3233 for (p = ie + _BEACON_IE_OFFSET_; ; p += (ie_len + 2)) {
3234 p = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, p,
3235 pnetwork->IELength -
3236 _BEACON_IE_OFFSET_ - (ie_len + 2));
3241 if (p && !memcmp(p + 2, WMM_PARA_IE, 6)) {
3242 memcpy(pframe, p, ie_len + 2);
3243 pframe += (ie_len + 2);
3244 pattrib->pktlen += (ie_len + 2);
3249 if (!p || ie_len == 0)
3254 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) {
3255 pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
3256 REALTEK_96B_IE23A, &pattrib->pktlen);
3259 /* add WPS IE ie for wps 2.0 */
3260 if (pmlmepriv->wps_assoc_resp_ie &&
3261 pmlmepriv->wps_assoc_resp_ie_len > 0) {
3262 memcpy(pframe, pmlmepriv->wps_assoc_resp_ie,
3263 pmlmepriv->wps_assoc_resp_ie_len);
3265 pframe += pmlmepriv->wps_assoc_resp_ie_len;
3266 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
3269 pattrib->last_txcmdsz = pattrib->pktlen;
3271 dump_mgntframe23a(padapter, pmgntframe);
3275 void issue_assocreq23a(struct rtw_adapter *padapter)
3278 struct xmit_frame *pmgntframe;
3279 struct pkt_attrib *pattrib;
3280 unsigned char *pframe;
3282 struct ieee80211_hdr *pwlanhdr;
3284 unsigned int i, j, index = 0;
3285 unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
3286 struct ndis_802_11_var_ies *pIE;
3287 struct registry_priv *pregpriv = &padapter->registrypriv;
3288 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3289 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3290 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3291 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3292 int bssrate_len = 0, sta_bssrate_len = 0, pie_len;
3295 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3299 /* update attribute */
3300 pattrib = &pmgntframe->attrib;
3301 update_mgntframe_attrib23a(padapter, pattrib);
3303 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3305 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
3306 pwlanhdr = (struct ieee80211_hdr *)pframe;
3308 fctrl = &pwlanhdr->frame_control;
3310 ether_addr_copy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network));
3311 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3312 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3314 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3315 pmlmeext->mgnt_seq++;
3316 SetFrameSubType(pframe, WIFI_ASSOCREQ);
3318 pframe += sizeof(struct ieee80211_hdr_3addr);
3319 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3323 rtw_get_capability23a_from_ie(pmlmeinfo->network.IEs), 2);
3326 pattrib->pktlen += 2;
3328 /* listen interval */
3329 /* todo: listen interval for power saving */
3330 put_unaligned_le16(3, pframe);
3332 pattrib->pktlen += 2;
3335 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
3336 pmlmeinfo->network.Ssid.ssid_len,
3337 pmlmeinfo->network.Ssid.ssid, &pattrib->pktlen);
3339 /* supported rate & extended supported rate */
3341 get_rate_set23a(padapter, sta_bssrate, &sta_bssrate_len);
3342 /* DBG_8723A("sta_bssrate_len =%d\n", sta_bssrate_len); */
3344 /* for JAPAN, channel 14 can only uses B Mode(CCK) */
3345 if (pmlmeext->cur_channel == 14)
3346 sta_bssrate_len = 4;
3348 /* for (i = 0; i < sta_bssrate_len; i++) { */
3349 /* DBG_8723A("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
3352 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3353 if (pmlmeinfo->network.SupportedRates[i] == 0)
3355 DBG_8723A("network.SupportedRates[%d]=%02X\n", i,
3356 pmlmeinfo->network.SupportedRates[i]);
3359 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3360 if (pmlmeinfo->network.SupportedRates[i] == 0)
3363 /* Check if the AP's supported rates are also
3364 supported by STA. */
3365 for (j = 0; j < sta_bssrate_len; j++) {
3366 /* Avoid the proprietary data rate (22Mbps) of
3367 Handlink WSG-4000 AP */
3368 if ((pmlmeinfo->network.SupportedRates[i] |
3369 IEEE80211_BASIC_RATE_MASK) ==
3370 (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) {
3371 /* DBG_8723A("match i = %d, j =%d\n", i, j); */
3376 if (j == sta_bssrate_len) {
3377 /* the rate is not supported by STA */
3378 DBG_8723A("%s(): the rate[%d]=%02X is not supported by "
3379 "STA!\n", __func__, i,
3380 pmlmeinfo->network.SupportedRates[i]);
3382 /* the rate is supported by STA */
3383 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
3387 bssrate_len = index;
3388 DBG_8723A("bssrate_len = %d\n", bssrate_len);
3390 if (bssrate_len == 0) {
3391 rtw_free_xmitbuf23a(pxmitpriv, pmgntframe->pxmitbuf);
3392 rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
3393 goto exit; /* don't connect to AP if no joint supported rate */
3396 if (bssrate_len > 8) {
3397 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
3398 bssrate, &pattrib->pktlen);
3399 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
3400 (bssrate_len - 8), (bssrate + 8),
3403 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
3404 bssrate_len, bssrate, &pattrib->pktlen);
3407 pie = pmlmeinfo->network.IEs + sizeof(struct ndis_802_11_fixed_ies);
3408 pie_len = pmlmeinfo->network.IELength -
3409 sizeof(struct ndis_802_11_fixed_ies);
3411 p = cfg80211_find_ie(WLAN_EID_RSN, pie, pie_len);
3413 pframe = rtw_set_ie23a(pframe, WLAN_EID_RSN, p[1], p + 2,
3417 if (padapter->mlmepriv.htpriv.ht_option == true) {
3418 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pie, pie_len);
3420 if (p && !is_ap_in_tkip23a(padapter)) {
3421 memcpy(&pmlmeinfo->HT_caps, p + 2,
3422 sizeof(struct HT_caps_element));
3424 /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
3425 if (pregpriv->cbw40_enable == 0) {
3426 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &= (~(BIT(6) | BIT(1)));
3428 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= BIT(1);
3431 /* todo: disable SM power save mode */
3432 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |=
3435 rf_type = rtl8723a_get_rf_type(padapter);
3436 /* switch (pregpriv->rf_config) */
3439 /* RX STBC One spatial stream */
3440 if (pregpriv->rx_stbc)
3441 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);
3443 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R23A, 16);
3449 /* enable for 2.4/5 GHz */
3450 if (pregpriv->rx_stbc == 0x3 ||
3451 (pmlmeext->cur_wireless_mode &
3453 /* enable for 2.4GHz */
3454 pregpriv->rx_stbc == 0x1) ||
3455 (pmlmeext->cur_wireless_mode &
3457 pregpriv->rx_stbc == 0x2) ||
3458 /* enable for 5GHz */
3459 pregpriv->wifi_spec == 1) {
3460 DBG_8723A("declare supporting RX "
3462 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0200);/* RX STBC two spatial stream */
3464 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R23A, 16);
3467 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info =
3468 cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
3470 #ifdef CONFIG_8723AU_BT_COEXIST
3471 if (BT_1Ant(padapter) == true) {
3473 pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para &= (u8)~IEEE80211_HT_AMPDU_PARM_FACTOR;
3474 /* pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para |= MAX_AMPDU_FACTOR_8K */
3478 pframe = rtw_set_ie23a(pframe, WLAN_EID_HT_CAPABILITY,
3479 p[1], (u8 *)&pmlmeinfo->HT_caps,
3484 /* vendor specific IE, such as WPA, WMM, WPS */
3485 for (i = sizeof(struct ndis_802_11_fixed_ies);
3486 i < pmlmeinfo->network.IELength;) {
3487 pIE = (struct ndis_802_11_var_ies *)
3488 (pmlmeinfo->network.IEs + i);
3490 switch (pIE->ElementID)
3492 case WLAN_EID_VENDOR_SPECIFIC:
3493 if (!memcmp(pIE->data, RTW_WPA_OUI23A_TYPE, 4) ||
3494 !memcmp(pIE->data, WMM_OUI23A, 4) ||
3495 !memcmp(pIE->data, WPS_OUI23A, 4)) {
3496 if (!padapter->registrypriv.wifi_spec) {
3497 /* Commented by Kurt 20110629 */
3498 /* In some older APs, WPS handshake */
3499 /* would be fail if we append vender
3500 extensions informations to AP */
3501 if (!memcmp(pIE->data, WPS_OUI23A, 4))
3504 pframe = rtw_set_ie23a(pframe,
3505 WLAN_EID_VENDOR_SPECIFIC,
3506 pIE->Length, pIE->data,
3515 i += pIE->Length + 2;
3518 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
3519 pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
3520 REALTEK_96B_IE23A, &pattrib->pktlen);
3522 pattrib->last_txcmdsz = pattrib->pktlen;
3523 dump_mgntframe23a(padapter, pmgntframe);
3528 pmlmepriv->assoc_req_len = 0;
3529 if (ret == _SUCCESS) {
3530 kfree(pmlmepriv->assoc_req);
3531 pmlmepriv->assoc_req = kmalloc(pattrib->pktlen, GFP_ATOMIC);
3532 if (pmlmepriv->assoc_req) {
3533 memcpy(pmlmepriv->assoc_req, pwlanhdr, pattrib->pktlen);
3534 pmlmepriv->assoc_req_len = pattrib->pktlen;
3537 kfree(pmlmepriv->assoc_req);
3542 /* when wait_ack is ture, this function shoule be called at process context */
3543 static int _issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3544 unsigned int power_mode, int wait_ack)
3547 struct xmit_frame *pmgntframe;
3548 struct pkt_attrib *pattrib;
3549 unsigned char *pframe;
3550 struct ieee80211_hdr *pwlanhdr;
3552 struct xmit_priv *pxmitpriv;
3553 struct mlme_ext_priv *pmlmeext;
3554 struct mlme_ext_info *pmlmeinfo;
3556 /* DBG_8723A("%s:%d\n", __func__, power_mode); */
3561 pxmitpriv = &padapter->xmitpriv;
3562 pmlmeext = &padapter->mlmeextpriv;
3563 pmlmeinfo = &pmlmeext->mlmext_info;
3565 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3568 /* update attribute */
3569 pattrib = &pmgntframe->attrib;
3570 update_mgntframe_attrib23a(padapter, pattrib);
3571 pattrib->retry_ctrl = false;
3573 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3575 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3576 pwlanhdr = (struct ieee80211_hdr *)pframe;
3578 fctrl = &pwlanhdr->frame_control;
3581 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3583 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
3589 ether_addr_copy(pwlanhdr->addr1, da);
3590 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3591 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3593 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3594 pmlmeext->mgnt_seq++;
3595 SetFrameSubType(pframe, WIFI_DATA_NULL);
3597 pframe += sizeof(struct ieee80211_hdr_3addr);
3598 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3600 pattrib->last_txcmdsz = pattrib->pktlen;
3603 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3605 dump_mgntframe23a(padapter, pmgntframe);
3613 /* when wait_ms >0 , this function shoule be called at process context */
3614 /* da == NULL for station mode */
3615 int issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3616 unsigned int power_mode, int try_cnt, int wait_ms)
3620 unsigned long start = jiffies;
3621 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3622 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3624 /* da == NULL, assum it's null data for sta to ap*/
3626 da = get_my_bssid23a(&pmlmeinfo->network);
3629 ret = _issue_nulldata23a(padapter, da, power_mode,
3630 wait_ms > 0 ? true : false);
3634 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3637 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3640 } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
3647 if (try_cnt && wait_ms) {
3649 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d "
3650 "in %u ms\n", FUNC_ADPT_ARG(padapter),
3651 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3652 ret == _SUCCESS?", acked":"", i, try_cnt,
3653 jiffies_to_msecs(jiffies - start));
3655 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
3656 FUNC_ADPT_ARG(padapter),
3657 rtw_get_oper_ch23a(padapter),
3658 ret == _SUCCESS?", acked":"", i, try_cnt,
3659 jiffies_to_msecs(jiffies - start));
3665 /* when wait_ack is ture, this function shoule be called at process context */
3666 static int _issue_qos_nulldata23a(struct rtw_adapter *padapter,
3667 unsigned char *da, u16 tid, int wait_ack)
3670 struct xmit_frame *pmgntframe;
3671 struct pkt_attrib *pattrib;
3672 unsigned char *pframe;
3673 struct ieee80211_hdr *pwlanhdr;
3676 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3677 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3678 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3680 DBG_8723A("%s\n", __func__);
3682 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3685 /* update attribute */
3686 pattrib = &pmgntframe->attrib;
3687 update_mgntframe_attrib23a(padapter, pattrib);
3689 pattrib->hdrlen += 2;
3690 pattrib->qos_en = true;
3692 pattrib->ack_policy = 0;
3695 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3697 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3698 pwlanhdr = (struct ieee80211_hdr *)pframe;
3700 fctrl = &pwlanhdr->frame_control;
3703 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3705 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
3711 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
3713 SetPriority(qc, tid);
3715 SetEOSP(qc, pattrib->eosp);
3717 SetAckpolicy(qc, pattrib->ack_policy);
3719 ether_addr_copy(pwlanhdr->addr1, da);
3720 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3721 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3723 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3724 pmlmeext->mgnt_seq++;
3725 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
3727 pframe += sizeof(struct ieee80211_qos_hdr);
3728 pattrib->pktlen = sizeof(struct ieee80211_qos_hdr);
3730 pattrib->last_txcmdsz = pattrib->pktlen;
3733 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3735 dump_mgntframe23a(padapter, pmgntframe);
3743 /* when wait_ms >0 , this function shoule be called at process context */
3744 /* da == NULL for station mode */
3745 int issue_qos_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3746 u16 tid, int try_cnt, int wait_ms)
3750 unsigned long start = jiffies;
3751 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3752 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3754 /* da == NULL, assum it's null data for sta to ap*/
3756 da = get_my_bssid23a(&pmlmeinfo->network);
3759 ret = _issue_qos_nulldata23a(padapter, da, tid,
3760 wait_ms > 0 ? true : false);
3764 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3767 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3769 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
3776 if (try_cnt && wait_ms) {
3778 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d "
3779 "in %u ms\n", FUNC_ADPT_ARG(padapter),
3780 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3781 ret == _SUCCESS?", acked":"", i, try_cnt,
3782 jiffies_to_msecs(jiffies - start));
3784 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
3785 FUNC_ADPT_ARG(padapter),
3786 rtw_get_oper_ch23a(padapter),
3787 ret == _SUCCESS?", acked":"", i, try_cnt,
3788 jiffies_to_msecs(jiffies - start));
3794 static int _issue_deauth23a(struct rtw_adapter *padapter, unsigned char *da,
3795 unsigned short reason, u8 wait_ack)
3797 struct xmit_frame *pmgntframe;
3798 struct pkt_attrib *pattrib;
3799 unsigned char *pframe;
3800 struct ieee80211_hdr *pwlanhdr;
3802 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3803 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3804 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3807 /* DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
3809 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3812 /* update attribute */
3813 pattrib = &pmgntframe->attrib;
3814 update_mgntframe_attrib23a(padapter, pattrib);
3815 pattrib->retry_ctrl = false;
3817 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3819 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3820 pwlanhdr = (struct ieee80211_hdr *)pframe;
3822 fctrl = &pwlanhdr->frame_control;
3825 ether_addr_copy(pwlanhdr->addr1, da);
3826 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3827 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3829 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3830 pmlmeext->mgnt_seq++;
3831 SetFrameSubType(pframe, WIFI_DEAUTH);
3833 pframe += sizeof(struct ieee80211_hdr_3addr);
3834 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3836 reason = cpu_to_le16(reason);
3837 pframe = rtw_set_fixed_ie23a(pframe, WLAN_REASON_PREV_AUTH_NOT_VALID,
3838 (unsigned char *)&reason,
3841 pattrib->last_txcmdsz = pattrib->pktlen;
3844 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3846 dump_mgntframe23a(padapter, pmgntframe);
3854 int issue_deauth23a(struct rtw_adapter *padapter, unsigned char *da,
3855 unsigned short reason)
3857 DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
3858 return _issue_deauth23a(padapter, da, reason, false);
3861 int issue_deauth23a_ex23a(struct rtw_adapter *padapter, u8 *da,
3862 unsigned short reason, int try_cnt, int wait_ms)
3866 unsigned long start = jiffies;
3869 ret = _issue_deauth23a(padapter, da, reason,
3870 wait_ms >0 ? true : false);
3874 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3877 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3880 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
3887 if (try_cnt && wait_ms) {
3889 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d "
3890 "in %u ms\n", FUNC_ADPT_ARG(padapter),
3891 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3892 ret == _SUCCESS?", acked":"", i, try_cnt,
3893 jiffies_to_msecs(jiffies - start));
3895 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
3896 FUNC_ADPT_ARG(padapter),
3897 rtw_get_oper_ch23a(padapter),
3898 ret == _SUCCESS?", acked":"", i, try_cnt,
3899 jiffies_to_msecs(jiffies - start));
3905 void issue_action_spct_ch_switch23a(struct rtw_adapter *padapter,
3906 u8 *ra, u8 new_ch, u8 ch_offset)
3908 struct xmit_frame *pmgntframe;
3909 struct pkt_attrib *pattrib;
3910 unsigned char *pframe;
3911 struct ieee80211_hdr *pwlanhdr;
3913 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3914 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3915 u8 category, action;
3917 DBG_8723A(FUNC_NDEV_FMT" ra ="MAC_FMT", ch:%u, offset:%u\n",
3918 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra),
3921 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3924 /* update attribute */
3925 pattrib = &pmgntframe->attrib;
3926 update_mgntframe_attrib23a(padapter, pattrib);
3928 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3930 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3931 pwlanhdr = (struct ieee80211_hdr *)pframe;
3933 fctrl = &pwlanhdr->frame_control;
3936 ether_addr_copy(pwlanhdr->addr1, ra); /* RA */
3937 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv)); /* TA */
3938 ether_addr_copy(pwlanhdr->addr3, ra); /* DA = RA */
3940 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3941 pmlmeext->mgnt_seq++;
3942 SetFrameSubType(pframe, WIFI_ACTION);
3944 pframe += sizeof(struct ieee80211_hdr_3addr);
3945 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3947 /* category, action */
3948 category = WLAN_CATEGORY_SPECTRUM_MGMT;
3949 action = WLAN_ACTION_SPCT_CHL_SWITCH;
3951 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
3952 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
3954 pframe = rtw_set_ie23a_ch_switch (pframe, &pattrib->pktlen, 0,
3956 pframe = rtw_set_ie23a_secondary_ch_offset(pframe, &pattrib->pktlen,
3957 hal_ch_offset_to_secondary_ch_offset23a(ch_offset));
3959 pattrib->last_txcmdsz = pattrib->pktlen;
3961 dump_mgntframe23a(padapter, pmgntframe);
3964 void issue_action_BA23a(struct rtw_adapter *padapter,
3965 const unsigned char *raddr,
3966 unsigned char action, unsigned short status)
3968 u8 category = WLAN_CATEGORY_BACK;
3972 u16 BA_timeout_value;
3973 u16 BA_starting_seqctrl;
3974 int max_rx_ampdu_factor;
3975 struct xmit_frame *pmgntframe;
3976 struct pkt_attrib *pattrib;
3978 struct ieee80211_hdr *pwlanhdr;
3980 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3981 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3982 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3983 struct sta_info *psta;
3984 struct sta_priv *pstapriv = &padapter->stapriv;
3985 struct registry_priv *pregpriv = &padapter->registrypriv;
3986 #ifdef CONFIG_8723AU_BT_COEXIST
3987 u8 tendaAPMac[] = {0xC8, 0x3A, 0x35};
3990 DBG_8723A("%s, category =%d, action =%d, status =%d\n",
3991 __func__, category, action, status);
3993 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3996 /* update attribute */
3997 pattrib = &pmgntframe->attrib;
3998 update_mgntframe_attrib23a(padapter, pattrib);
4000 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4002 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4003 pwlanhdr = (struct ieee80211_hdr *)pframe;
4005 fctrl = &pwlanhdr->frame_control;
4008 /* memcpy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN); */
4009 ether_addr_copy(pwlanhdr->addr1, raddr);
4010 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
4011 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
4013 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4014 pmlmeext->mgnt_seq++;
4015 SetFrameSubType(pframe, WIFI_ACTION);
4017 pframe += sizeof(struct ieee80211_hdr_3addr);
4018 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
4020 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
4021 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
4023 status = cpu_to_le16(status);
4030 case 0: /* ADDBA req */
4032 pmlmeinfo->dialogToken++;
4033 } while (pmlmeinfo->dialogToken == 0);
4034 pframe = rtw_set_fixed_ie23a(pframe, 1, &pmlmeinfo->dialogToken,
4037 #ifdef CONFIG_8723AU_BT_COEXIST
4038 if ((BT_1Ant(padapter) == true) &&
4039 ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
4040 memcmp(raddr, tendaAPMac, 3))) {
4041 /* A-MSDU NOT Supported */
4043 /* immediate Block Ack */
4044 BA_para_set |= (1 << 1) &
4045 IEEE80211_ADDBA_PARAM_POLICY_MASK;
4047 BA_para_set |= (status << 2) &
4048 IEEE80211_ADDBA_PARAM_TID_MASK;
4049 /* max buffer size is 8 MSDU */
4050 BA_para_set |= (8 << 6) &
4051 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4055 /* immediate ack & 64 buffer size */
4056 BA_para_set = (0x1002 | ((status & 0xf) << 2));
4058 BA_para_set = cpu_to_le16(BA_para_set);
4059 pframe = rtw_set_fixed_ie23a(pframe, 2,
4060 (unsigned char *)&BA_para_set,
4063 BA_timeout_value = 5000;/* 5ms */
4064 BA_timeout_value = cpu_to_le16(BA_timeout_value);
4065 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)
4069 /* if ((psta = rtw_get_stainfo23a(pstapriv,
4070 pmlmeinfo->network.MacAddress)) != NULL) */
4071 if ((psta = rtw_get_stainfo23a(pstapriv, raddr))) {
4072 start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1;
4074 DBG_8723A("BA_starting_seqctrl = %d for TID =%d\n",
4075 start_seq, status & 0x07);
4077 psta->BA_starting_seqctrl[status & 0x07] = start_seq;
4079 BA_starting_seqctrl = start_seq << 4;
4082 BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
4083 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)&BA_starting_seqctrl, &pattrib->pktlen);
4086 case 1: /* ADDBA rsp */
4087 pframe = rtw_set_fixed_ie23a(pframe, 1, &pmlmeinfo->ADDBA_req.dialog_token, &pattrib->pktlen);
4088 pframe = rtw_set_fixed_ie23a(pframe, 2,
4089 (unsigned char *)&status,
4091 rtw_hal_get_def_var23a(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
4092 &max_rx_ampdu_factor);
4093 if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_64K)
4094 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
4095 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_32K)
4096 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800); /* 32 buffer size */
4097 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_16K)
4098 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0400); /* 16 buffer size */
4099 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_8K)
4100 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0200); /* 8 buffer size */
4102 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
4104 #ifdef CONFIG_8723AU_BT_COEXIST
4105 if ((BT_1Ant(padapter) == true) &&
4106 ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
4107 memcmp(raddr, tendaAPMac, 3))) {
4108 /* max buffer size is 8 MSDU */
4109 BA_para_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4110 BA_para_set |= (8 << 6) &
4111 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4115 if (pregpriv->ampdu_amsdu == 0)/* disabled */
4116 BA_para_set = cpu_to_le16(BA_para_set & ~BIT(0));
4117 else if (pregpriv->ampdu_amsdu == 1)/* enabled */
4118 BA_para_set = cpu_to_le16(BA_para_set | BIT(0));
4120 BA_para_set = cpu_to_le16(BA_para_set);
4122 pframe = rtw_set_fixed_ie23a(pframe, 2,
4123 (unsigned char *)&BA_para_set,
4125 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)&pmlmeinfo->ADDBA_req.BA_timeout_value, &pattrib->pktlen);
4128 BA_para_set = (status & 0x1F) << 3;
4129 BA_para_set = cpu_to_le16(BA_para_set);
4130 pframe = rtw_set_fixed_ie23a(pframe, 2,
4131 (unsigned char *)&BA_para_set,
4134 reason_code = 37;/* Requested from peer STA as it does not
4135 want to use the mechanism */
4136 reason_code = cpu_to_le16(reason_code);
4137 pframe = rtw_set_fixed_ie23a(pframe, 2,
4138 (unsigned char *)&reason_code,
4146 pattrib->last_txcmdsz = pattrib->pktlen;
4148 dump_mgntframe23a(padapter, pmgntframe);
4151 static void issue_action_BSSCoexistPacket(struct rtw_adapter *padapter)
4153 struct list_head *plist, *phead, *ptmp;
4154 unsigned char category, action;
4155 struct xmit_frame *pmgntframe;
4156 struct pkt_attrib *pattrib;
4158 struct ieee80211_hdr *pwlanhdr;
4160 struct wlan_network *pnetwork;
4161 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4162 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4163 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4164 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4165 struct rtw_queue *queue = &pmlmepriv->scanned_queue;
4166 u8 InfoContent[16] = {0};
4170 if (pmlmepriv->num_FortyMHzIntolerant == 0 ||
4171 pmlmepriv->num_sta_no_ht == 0)
4174 if (pmlmeinfo->bwmode_updated)
4177 DBG_8723A("%s\n", __func__);
4179 category = WLAN_CATEGORY_PUBLIC;
4180 action = ACT_PUBLIC_BSSCOEXIST;
4182 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
4186 /* update attribute */
4187 pattrib = &pmgntframe->attrib;
4188 update_mgntframe_attrib23a(padapter, pattrib);
4190 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4192 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
4193 pwlanhdr = (struct ieee80211_hdr *)pframe;
4195 fctrl = &pwlanhdr->frame_control;
4198 ether_addr_copy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network));
4199 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
4200 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
4202 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4203 pmlmeext->mgnt_seq++;
4204 SetFrameSubType(pframe, WIFI_ACTION);
4206 pframe += sizeof(struct ieee80211_hdr_3addr);
4207 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
4209 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
4210 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
4212 if (pmlmepriv->num_FortyMHzIntolerant > 0) {
4213 u8 iedata = BIT(2);/* 20 MHz BSS Width Request */
4215 pframe = rtw_set_ie23a(pframe, WLAN_EID_BSS_COEX_2040, 1,
4216 &iedata, &pattrib->pktlen);
4219 if (pmlmepriv->num_sta_no_ht <= 0)
4222 memset(ICS, 0, sizeof(ICS));
4224 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
4226 phead = get_list_head(queue);
4227 plist = phead->next;
4229 list_for_each_safe(plist, ptmp, phead) {
4231 struct wlan_bssid_ex *pbss_network;
4233 pnetwork = container_of(plist, struct wlan_network, list);
4235 pbss_network = &pnetwork->network;
4237 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
4238 pbss_network->IEs + _FIXED_IE_LENGTH_,
4239 pbss_network->IELength -_FIXED_IE_LENGTH_);
4240 if (!p || !p[1]) { /* non-HT */
4241 if (pbss_network->Configuration.DSConfig <= 0 ||
4242 pbss_network->Configuration.DSConfig > 14)
4245 ICS[0][pbss_network->Configuration.DSConfig] = 1;
4253 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
4255 for (i = 0; i < 8;i++) {
4256 if (ICS[i][0] == 1) {
4260 /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */
4263 for (j = 1; j <= 14; j++) {
4264 if (ICS[i][j] == 1) {
4266 /* channel number */
4273 pframe = rtw_set_ie23a(pframe,
4274 EID_BSSIntolerantChlReport, k,
4275 InfoContent, &pattrib->pktlen);
4280 pattrib->last_txcmdsz = pattrib->pktlen;
4282 dump_mgntframe23a(padapter, pmgntframe);
4285 unsigned int send_delba23a(struct rtw_adapter *padapter, u8 initiator, u8 *addr)
4287 struct sta_priv *pstapriv = &padapter->stapriv;
4288 struct sta_info *psta = NULL;
4289 /* struct recv_reorder_ctrl *preorder_ctrl; */
4290 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4291 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4294 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
4295 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
4298 psta = rtw_get_stainfo23a(pstapriv, addr);
4302 if (initiator == 0) { /* recipient */
4303 for (tid = 0; tid < MAXTID; tid++) {
4304 if (psta->recvreorder_ctrl[tid].enable == true) {
4305 DBG_8723A("rx agg disable tid(%d)\n", tid);
4306 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
4307 psta->recvreorder_ctrl[tid].enable = false;
4308 psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
4311 } else if (initiator == 1) { /* originator */
4312 for (tid = 0; tid < MAXTID; tid++) {
4313 if (psta->htpriv.agg_enable_bitmap & BIT(tid)) {
4314 DBG_8723A("tx agg disable tid(%d)\n", tid);
4315 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
4316 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
4317 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
4325 unsigned int send_beacon23a(struct rtw_adapter *padapter)
4330 unsigned long start = jiffies;
4331 unsigned int passing_time;
4333 rtl8723a_bcn_valid(padapter);
4335 issue_beacon23a(padapter, 100);
4339 bxmitok = rtl8723a_get_bcn_valid(padapter);
4341 } while ((poll % 10) != 0 && bxmitok == false &&
4342 !padapter->bSurpriseRemoved &&
4343 !padapter->bDriverStopped);
4345 } while (!bxmitok && issue<100 && !padapter->bSurpriseRemoved &&
4346 !padapter->bDriverStopped);
4348 if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
4351 passing_time = jiffies_to_msecs(jiffies - start);
4354 DBG_8723A("%s fail! %u ms\n", __func__, passing_time);
4358 if (passing_time > 100 || issue > 3)
4359 DBG_8723A("%s success, issue:%d, poll:%d, %u ms\n",
4360 __func__, issue, poll, passing_time);
4365 /****************************************************************************
4367 Following are some utitity fuctions for WiFi MLME
4369 *****************************************************************************/
4371 bool IsLegal5GChannel(struct rtw_adapter *Adapter, u8 channel)
4375 u8 Channel_5G[45] = {36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
4376 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
4377 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
4379 for (i = 0; i < sizeof(Channel_5G); i++)
4380 if (channel == Channel_5G[i])
4385 void site_survey23a(struct rtw_adapter *padapter)
4387 unsigned char survey_channel = 0;
4388 enum rt_scan_type ScanType = SCAN_PASSIVE;
4389 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4390 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4391 struct rtw_ieee80211_channel *ch;
4393 if (pmlmeext->sitesurvey_res.channel_idx <
4394 pmlmeext->sitesurvey_res.ch_num) {
4395 ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
4396 survey_channel = ch->hw_value;
4397 ScanType = (ch->flags & IEEE80211_CHAN_NO_IR) ?
4398 SCAN_PASSIVE : SCAN_ACTIVE;
4401 if (survey_channel != 0) {
4402 /* PAUSE 4-AC Queue when site_survey23a */
4403 if (pmlmeext->sitesurvey_res.channel_idx == 0)
4404 set_channel_bwmode23a(padapter, survey_channel,
4405 HAL_PRIME_CHNL_OFFSET_DONT_CARE,
4406 HT_CHANNEL_WIDTH_20);
4408 SelectChannel23a(padapter, survey_channel);
4410 if (ScanType == SCAN_ACTIVE) /* obey the channel plan setting... */
4413 for (i = 0;i<RTW_SSID_SCAN_AMOUNT;i++) {
4414 if (pmlmeext->sitesurvey_res.ssid[i].ssid_len) {
4415 /* todo: to issue two probe req??? */
4416 issue_probereq23a(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
4417 /* msleep(SURVEY_TO>>1); */
4418 issue_probereq23a(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
4422 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
4423 /* todo: to issue two probe req??? */
4424 issue_probereq23a(padapter, NULL, NULL);
4425 /* msleep(SURVEY_TO>>1); */
4426 issue_probereq23a(padapter, NULL, NULL);
4430 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
4432 /* channel number is 0 or this channel is not valid. */
4433 pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
4435 /* switch back to the original channel */
4437 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
4438 pmlmeext->cur_ch_offset,
4439 pmlmeext->cur_bwmode);
4441 /* flush 4-AC Queue after site_survey23a */
4445 Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
4447 /* restore RX GAIN */
4448 rtl8723a_set_initial_gain(padapter, 0xff);
4449 /* turn on dynamic functions */
4450 rtl8723a_odm_support_ability_restore(padapter);
4452 if (is_client_associated_to_ap23a(padapter) == true)
4453 issue_nulldata23a(padapter, NULL, 0, 3, 500);
4455 rtl8723a_mlme_sitesurvey(padapter, 0);
4457 report_surveydone_event23a(padapter);
4459 pmlmeext->chan_scan_time = SURVEY_TO;
4460 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
4462 issue_action_BSSCoexistPacket(padapter);
4463 issue_action_BSSCoexistPacket(padapter);
4464 issue_action_BSSCoexistPacket(padapter);
4470 /* collect bss info from Beacon and Probe request/response frames. */
4471 u8 collect_bss_info23a(struct rtw_adapter *padapter,
4472 struct recv_frame *precv_frame,
4473 struct wlan_bssid_ex *bssid)
4477 struct sk_buff *skb = precv_frame->pkt;
4478 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
4479 unsigned int length;
4481 struct registry_priv *pregistrypriv = &padapter->registrypriv;
4482 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4483 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4486 length = skb->len - sizeof(struct ieee80211_hdr_3addr);
4488 if (length > MAX_IE_SZ) {
4489 /* DBG_8723A("IE too long for survey event\n"); */
4493 memset(bssid, 0, sizeof(struct wlan_bssid_ex));
4495 if (ieee80211_is_beacon(mgmt->frame_control)) {
4496 bssid->reserved = 1;
4497 ie_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
4498 capab_info = mgmt->u.beacon.capab_info;
4499 } else if (ieee80211_is_probe_req(mgmt->frame_control)) {
4500 ie_offset = offsetof(struct ieee80211_mgmt,
4501 u.probe_req.variable);
4502 bssid->reserved = 2;
4504 } else if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4505 ie_offset = offsetof(struct ieee80211_mgmt,
4506 u.probe_resp.variable);
4507 bssid->reserved = 3;
4508 capab_info = mgmt->u.probe_resp.capab_info;
4510 bssid->reserved = 0;
4511 ie_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
4512 capab_info = mgmt->u.beacon.capab_info;
4514 ie_offset -= offsetof(struct ieee80211_mgmt, u);
4516 bssid->Length = offsetof(struct wlan_bssid_ex, IEs) + length;
4518 /* below is to copy the information element */
4519 bssid->IELength = length;
4520 memcpy(bssid->IEs, &mgmt->u, bssid->IELength);
4522 /* get the signal strength */
4523 /* in dBM.raw data */
4524 bssid->Rssi = precv_frame->attrib.phy_info.RecvSignalPower;
4525 bssid->PhyInfo.SignalQuality =
4526 precv_frame->attrib.phy_info.SignalQuality;/* in percentage */
4527 bssid->PhyInfo.SignalStrength =
4528 precv_frame->attrib.phy_info.SignalStrength;/* in percentage */
4531 p = cfg80211_find_ie(WLAN_EID_SSID, bssid->IEs + ie_offset,
4532 bssid->IELength - ie_offset);
4535 DBG_8723A("marc: cannot find SSID for survey event\n");
4539 if (p[1] > IEEE80211_MAX_SSID_LEN) {
4540 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4541 "event\n", __func__, __LINE__, p[1]);
4544 memcpy(bssid->Ssid.ssid, p + 2, p[1]);
4545 bssid->Ssid.ssid_len = p[1];
4547 memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
4549 /* checking rate info... */
4551 p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, bssid->IEs + ie_offset,
4552 bssid->IELength - ie_offset);
4554 if (p[1] > NDIS_802_11_LENGTH_RATES_EX) {
4555 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4556 "event\n", __func__, __LINE__, p[1]);
4559 memcpy(bssid->SupportedRates, p + 2, p[1]);
4563 p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, bssid->IEs + ie_offset,
4564 bssid->IELength - ie_offset);
4566 if (p[1] > (NDIS_802_11_LENGTH_RATES_EX-i)) {
4567 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4568 "event\n", __func__, __LINE__, p[1]);
4571 memcpy(bssid->SupportedRates + i, p + 2, p[1]);
4574 bssid->NetworkTypeInUse = Ndis802_11OFDM24;
4576 if (bssid->IELength < 12)
4579 /* Checking for DSConfig */
4580 p = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bssid->IEs + ie_offset,
4581 bssid->IELength - ie_offset);
4583 bssid->Configuration.DSConfig = 0;
4584 bssid->Configuration.Length = 0;
4587 bssid->Configuration.DSConfig = p[2];
4588 } else {/* In 5G, some ap do not have DSSET IE */
4589 /* checking HT info for channel */
4590 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
4591 bssid->IEs + ie_offset,
4592 bssid->IELength - ie_offset);
4594 struct HT_info_element *HT_info =
4595 (struct HT_info_element *)(p + 2);
4596 bssid->Configuration.DSConfig =
4597 HT_info->primary_channel;
4598 } else { /* use current channel */
4599 bssid->Configuration.DSConfig =
4600 rtw_get_oper_ch23a(padapter);
4604 if (ieee80211_is_probe_req(mgmt->frame_control)) {
4606 bssid->InfrastructureMode = Ndis802_11Infrastructure;
4607 ether_addr_copy(bssid->MacAddress, mgmt->sa);
4612 memcpy(&bssid->Configuration.BeaconPeriod,
4613 rtw_get_beacon_interval23a_from_ie(bssid->IEs), 2);
4614 bssid->Configuration.BeaconPeriod =
4615 le32_to_cpu(bssid->Configuration.BeaconPeriod);
4617 if (capab_info & BIT(0)) {
4618 bssid->InfrastructureMode = Ndis802_11Infrastructure;
4619 ether_addr_copy(bssid->MacAddress, mgmt->sa);
4621 bssid->InfrastructureMode = Ndis802_11IBSS;
4622 ether_addr_copy(bssid->MacAddress, mgmt->bssid);
4625 if (capab_info & BIT(4))
4630 bssid->Configuration.ATIMWindow = 0;
4632 /* 20/40 BSS Coexistence check */
4633 if (pregistrypriv->wifi_spec == 1 &&
4634 pmlmeinfo->bwmode_updated == false) {
4635 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4637 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
4638 bssid->IEs + ie_offset,
4639 bssid->IELength - ie_offset);
4640 if (p && p[1] > 0) {
4641 struct HT_caps_element *pHT_caps;
4642 pHT_caps = (struct HT_caps_element *)(p + 2);
4644 if (pHT_caps->u.HT_cap_element.HT_caps_info & BIT(14))
4645 pmlmepriv->num_FortyMHzIntolerant++;
4647 pmlmepriv->num_sta_no_ht++;
4651 /* mark bss info receving from nearby channel as SignalQuality 101 */
4652 if (bssid->Configuration.DSConfig != rtw_get_oper_ch23a(padapter))
4653 bssid->PhyInfo.SignalQuality = 101;
4658 void start_create_ibss23a(struct rtw_adapter* padapter)
4660 unsigned short caps;
4661 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4662 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4663 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
4664 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
4665 pmlmeinfo->bcn_interval = get_beacon_interval23a(pnetwork);
4667 /* update wireless mode */
4668 update_wireless_mode23a(padapter);
4670 /* udpate capability */
4671 caps = rtw_get_capability23a(pnetwork);
4672 update_capinfo23a(padapter, caps);
4673 if (caps&cap_IBSS) { /* adhoc master */
4674 rtl8723a_set_sec_cfg(padapter, 0xcf);
4676 /* switch channel */
4677 /* SelectChannel23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
4678 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4680 beacon_timing_control23a(padapter);
4682 /* set msr to WIFI_FW_ADHOC_STATE */
4683 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4684 Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
4687 if (send_beacon23a(padapter) == _FAIL)
4689 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("issuing beacon frame fail....\n"));
4691 report_join_res23a(padapter, -1);
4692 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4696 hw_var_set_bssid(padapter, padapter->registrypriv.dev_network.MacAddress);
4697 hw_var_set_mlme_join(padapter, 0);
4699 report_join_res23a(padapter, 1);
4700 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
4705 DBG_8723A("start_create_ibss23a, invalid cap:%x\n", caps);
4710 void start_clnt_join23a(struct rtw_adapter* padapter)
4712 unsigned short caps;
4714 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4715 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4716 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
4719 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
4720 pmlmeinfo->bcn_interval = get_beacon_interval23a(pnetwork);
4722 /* update wireless mode */
4723 update_wireless_mode23a(padapter);
4725 /* udpate capability */
4726 caps = rtw_get_capability23a(pnetwork);
4727 update_capinfo23a(padapter, caps);
4729 /* switch channel */
4730 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4732 Set_MSR23a(padapter, WIFI_FW_STATION_STATE);
4734 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ?
4737 rtl8723a_set_sec_cfg(padapter, val8);
4739 /* switch channel */
4740 /* set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
4742 /* here wait for receiving the beacon to start auth */
4743 /* and enable a timer */
4744 beacon_timeout = decide_wait_for_beacon_timeout23a(pmlmeinfo->bcn_interval);
4745 set_link_timer(pmlmeext, beacon_timeout);
4746 mod_timer(&padapter->mlmepriv.assoc_timer, jiffies +
4747 msecs_to_jiffies((REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) + beacon_timeout));
4748 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
4750 else if (caps&cap_IBSS) { /* adhoc client */
4751 Set_MSR23a(padapter, WIFI_FW_ADHOC_STATE);
4753 rtl8723a_set_sec_cfg(padapter, 0xcf);
4755 /* switch channel */
4756 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4758 beacon_timing_control23a(padapter);
4760 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4762 report_join_res23a(padapter, 1);
4766 /* DBG_8723A("marc: invalid cap:%x\n", caps); */
4771 void start_clnt_auth23a(struct rtw_adapter* padapter)
4773 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4774 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4776 del_timer_sync(&pmlmeext->link_timer);
4778 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
4779 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
4781 pmlmeinfo->auth_seq = 1;
4782 pmlmeinfo->reauth_count = 0;
4783 pmlmeinfo->reassoc_count = 0;
4784 pmlmeinfo->link_count = 0;
4785 pmlmeext->retry = 0;
4787 /* Because of AP's not receiving deauth before */
4788 /* AP may: 1)not response auth or 2)deauth us after link is complete */
4789 /* issue deauth before issuing auth to deal with the situation */
4790 /* Commented by Albert 2012/07/21 */
4791 /* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
4792 issue_deauth23a(padapter, (&pmlmeinfo->network)->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
4794 DBG_8723A_LEVEL(_drv_always_, "start auth\n");
4795 issue_auth23a(padapter, NULL, 0);
4797 set_link_timer(pmlmeext, REAUTH_TO);
4800 void start_clnt_assoc23a(struct rtw_adapter* padapter)
4802 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4803 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4805 del_timer_sync(&pmlmeext->link_timer);
4807 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
4808 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
4810 issue_assocreq23a(padapter);
4812 set_link_timer(pmlmeext, REASSOC_TO);
4815 unsigned int receive_disconnect23a(struct rtw_adapter *padapter, unsigned char *MacAddr, unsigned short reason)
4817 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4818 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4821 if (!ether_addr_equal(MacAddr, get_my_bssid23a(&pmlmeinfo->network)))
4824 DBG_8723A("%s\n", __func__);
4826 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
4828 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
4830 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4831 report_del_sta_event23a(padapter, MacAddr, reason);
4834 else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
4836 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4837 report_join_res23a(padapter, -2);
4844 static void process_80211d(struct rtw_adapter *padapter,
4845 struct wlan_bssid_ex *bssid)
4847 struct registry_priv *pregistrypriv;
4848 struct mlme_ext_priv *pmlmeext;
4849 struct rt_channel_info *chplan_new;
4853 pregistrypriv = &padapter->registrypriv;
4854 pmlmeext = &padapter->mlmeextpriv;
4856 /* Adjust channel plan by AP Country IE */
4857 if (pregistrypriv->enable80211d &&
4858 !pmlmeext->update_channel_plan_by_ap_done) {
4860 struct rt_channel_plan chplan_ap;
4861 struct rt_channel_info chplan_sta[MAX_CHANNEL_NUM];
4863 u8 fcn; /* first channel number */
4864 u8 noc; /* number of channel */
4867 ie = cfg80211_find_ie(WLAN_EID_COUNTRY,
4868 bssid->IEs + _FIXED_IE_LENGTH_,
4869 bssid->IELength - _FIXED_IE_LENGTH_);
4870 if (!ie || ie[1] < IEEE80211_COUNTRY_IE_MIN_LEN)
4877 memcpy(country, p, 3);
4881 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
4882 ("%s: 802.11d country =%s\n", __func__, country));
4885 while ((ie - p) >= 3) {
4890 for (j = 0; j < noc; j++) {
4892 channel = fcn + j; /* 2.4 GHz */
4894 channel = fcn + j * 4; /* 5 GHz */
4896 chplan_ap.Channel[i++] = channel;
4901 memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
4902 memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
4903 chplan_new = pmlmeext->channel_set;
4906 if (pregistrypriv->wireless_mode & WIRELESS_11G) {
4908 if (i == MAX_CHANNEL_NUM ||
4909 chplan_sta[i].ChannelNum == 0 ||
4910 chplan_sta[i].ChannelNum > 14)
4913 if (j == chplan_ap.Len ||
4914 chplan_ap.Channel[j] > 14)
4917 if (chplan_sta[i].ChannelNum ==
4918 chplan_ap.Channel[j]) {
4919 chplan_new[k].ChannelNum =
4920 chplan_ap.Channel[j];
4921 chplan_new[k].ScanType = SCAN_ACTIVE;
4925 } else if (chplan_sta[i].ChannelNum <
4926 chplan_ap.Channel[j]) {
4927 chplan_new[k].ChannelNum =
4928 chplan_sta[i].ChannelNum;
4929 chplan_new[k].ScanType =
4933 } else if (chplan_sta[i].ChannelNum >
4934 chplan_ap.Channel[j]) {
4935 chplan_new[k].ChannelNum =
4936 chplan_ap.Channel[j];
4937 chplan_new[k].ScanType =
4944 /* change AP not support channel to Passive scan */
4945 while (i < MAX_CHANNEL_NUM &&
4946 chplan_sta[i].ChannelNum != 0 &&
4947 chplan_sta[i].ChannelNum <= 14) {
4948 chplan_new[k].ChannelNum =
4949 chplan_sta[i].ChannelNum;
4950 chplan_new[k].ScanType = SCAN_PASSIVE;
4955 /* add channel AP supported */
4956 while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14){
4957 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4958 chplan_new[k].ScanType = SCAN_ACTIVE;
4963 /* keep original STA 2.4G channel plan */
4964 while (i < MAX_CHANNEL_NUM &&
4965 chplan_sta[i].ChannelNum != 0 &&
4966 chplan_sta[i].ChannelNum <= 14) {
4967 chplan_new[k].ChannelNum =
4968 chplan_sta[i].ChannelNum;
4969 chplan_new[k].ScanType = chplan_sta[i].ScanType;
4974 /* skip AP 2.4G channel plan */
4975 while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14)
4979 if (pregistrypriv->wireless_mode & WIRELESS_11A) {
4981 if (i == MAX_CHANNEL_NUM ||
4982 chplan_sta[i].ChannelNum == 0)
4985 if (j == chplan_ap.Len ||
4986 chplan_ap.Channel[j] == 0)
4989 if (chplan_sta[i].ChannelNum ==
4990 chplan_ap.Channel[j]) {
4991 chplan_new[k].ChannelNum =
4992 chplan_ap.Channel[j];
4993 chplan_new[k].ScanType = SCAN_ACTIVE;
4997 } else if (chplan_sta[i].ChannelNum <
4998 chplan_ap.Channel[j]) {
4999 chplan_new[k].ChannelNum =
5000 chplan_sta[i].ChannelNum;
5001 chplan_new[k].ScanType = SCAN_PASSIVE;
5004 } else if (chplan_sta[i].ChannelNum >
5005 chplan_ap.Channel[j]) {
5006 chplan_new[k].ChannelNum =
5007 chplan_ap.Channel[j];
5008 chplan_new[k].ScanType = SCAN_ACTIVE;
5014 /* change AP not support channel to Passive scan */
5015 while (i < MAX_CHANNEL_NUM &&
5016 chplan_sta[i].ChannelNum != 0) {
5017 chplan_new[k].ChannelNum =
5018 chplan_sta[i].ChannelNum;
5019 chplan_new[k].ScanType = SCAN_PASSIVE;
5024 /* add channel AP supported */
5025 while (j < chplan_ap.Len && chplan_ap.Channel[j] != 0) {
5026 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
5027 chplan_new[k].ScanType = SCAN_ACTIVE;
5032 /* keep original STA 5G channel plan */
5033 while (i < MAX_CHANNEL_NUM &&
5034 chplan_sta[i].ChannelNum != 0) {
5035 chplan_new[k].ChannelNum =
5036 chplan_sta[i].ChannelNum;
5037 chplan_new[k].ScanType = chplan_sta[i].ScanType;
5042 pmlmeext->update_channel_plan_by_ap_done = 1;
5045 /* If channel is used by AP, set channel scan type to active */
5046 channel = bssid->Configuration.DSConfig;
5047 chplan_new = pmlmeext->channel_set;
5049 while (i < MAX_CHANNEL_NUM && chplan_new[i].ChannelNum != 0) {
5050 if (chplan_new[i].ChannelNum == channel) {
5051 if (chplan_new[i].ScanType == SCAN_PASSIVE) {
5052 /* 5G Bnad 2, 3 (DFS) doesn't change
5054 if (channel >= 52 && channel <= 144)
5057 chplan_new[i].ScanType = SCAN_ACTIVE;
5058 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
5059 ("%s: change channel %d scan type "
5060 "from passive to active\n",
5061 __func__, channel));
5069 /****************************************************************************
5071 Following are the functions to report events
5073 *****************************************************************************/
5075 void report_survey_event23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
5077 struct cmd_obj *pcmd_obj;
5080 struct survey_event *psurvey_evt;
5081 struct C2HEvent_Header *pc2h_evt_hdr;
5082 struct mlme_ext_priv *pmlmeext;
5083 struct cmd_priv *pcmdpriv;
5088 pmlmeext = &padapter->mlmeextpriv;
5089 pcmdpriv = &padapter->cmdpriv;
5091 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5096 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
5097 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5103 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5104 pcmd_obj->cmdsz = cmdsz;
5105 pcmd_obj->parmbuf = pevtcmd;
5107 pcmd_obj->rsp = NULL;
5108 pcmd_obj->rspsz = 0;
5110 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5111 pc2h_evt_hdr->len = sizeof(struct survey_event);
5112 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
5113 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5115 psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5117 if (collect_bss_info23a(padapter, precv_frame, &psurvey_evt->bss) == _FAIL) {
5123 process_80211d(padapter, &psurvey_evt->bss);
5125 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5127 pmlmeext->sitesurvey_res.bss_cnt++;
5132 void report_surveydone_event23a(struct rtw_adapter *padapter)
5134 struct cmd_obj *pcmd_obj;
5137 struct surveydone_event *psurveydone_evt;
5138 struct C2HEvent_Header *pc2h_evt_hdr;
5139 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5140 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5142 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5147 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
5148 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5154 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5155 pcmd_obj->cmdsz = cmdsz;
5156 pcmd_obj->parmbuf = pevtcmd;
5158 pcmd_obj->rsp = NULL;
5159 pcmd_obj->rspsz = 0;
5161 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5162 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
5163 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
5164 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5166 psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5167 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
5169 DBG_8723A("survey done event(%x)\n", psurveydone_evt->bss_cnt);
5171 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5176 void report_join_res23a(struct rtw_adapter *padapter, int res)
5178 struct cmd_obj *pcmd_obj;
5181 struct joinbss_event *pjoinbss_evt;
5182 struct C2HEvent_Header *pc2h_evt_hdr;
5183 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5184 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5185 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5187 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5192 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
5193 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5199 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5200 pcmd_obj->cmdsz = cmdsz;
5201 pcmd_obj->parmbuf = pevtcmd;
5203 pcmd_obj->rsp = NULL;
5204 pcmd_obj->rspsz = 0;
5206 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5207 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
5208 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
5209 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5211 pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5212 memcpy((unsigned char *)&pjoinbss_evt->network.network,
5213 &pmlmeinfo->network, sizeof(struct wlan_bssid_ex));
5214 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
5216 DBG_8723A("report_join_res23a(%d)\n", res);
5218 rtw_joinbss_event_prehandle23a(padapter, (u8 *)&pjoinbss_evt->network);
5220 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5225 void report_del_sta_event23a(struct rtw_adapter *padapter, unsigned char* MacAddr, unsigned short reason)
5227 struct cmd_obj *pcmd_obj;
5230 struct sta_info *psta;
5232 struct stadel_event *pdel_sta_evt;
5233 struct C2HEvent_Header *pc2h_evt_hdr;
5234 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5235 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5237 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5242 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
5243 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5249 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5250 pcmd_obj->cmdsz = cmdsz;
5251 pcmd_obj->parmbuf = pevtcmd;
5253 pcmd_obj->rsp = NULL;
5254 pcmd_obj->rspsz = 0;
5256 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5257 pc2h_evt_hdr->len = sizeof(struct stadel_event);
5258 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
5259 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5261 pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5262 ether_addr_copy((unsigned char *)&pdel_sta_evt->macaddr, MacAddr);
5263 memcpy((unsigned char *)pdel_sta_evt->rsvd, (unsigned char *)&reason,
5266 psta = rtw_get_stainfo23a(&padapter->stapriv, MacAddr);
5268 mac_id = (int)psta->mac_id;
5272 pdel_sta_evt->mac_id = mac_id;
5274 DBG_8723A("report_del_sta_event23a: delete STA, mac_id =%d\n", mac_id);
5276 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5281 void report_add_sta_event23a(struct rtw_adapter *padapter, unsigned char* MacAddr, int cam_idx)
5283 struct cmd_obj *pcmd_obj;
5286 struct stassoc_event *padd_sta_evt;
5287 struct C2HEvent_Header *pc2h_evt_hdr;
5288 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5289 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5291 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5296 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
5297 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5303 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5304 pcmd_obj->cmdsz = cmdsz;
5305 pcmd_obj->parmbuf = pevtcmd;
5307 pcmd_obj->rsp = NULL;
5308 pcmd_obj->rspsz = 0;
5310 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5311 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
5312 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
5313 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5315 padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5316 ether_addr_copy((unsigned char *)&padd_sta_evt->macaddr, MacAddr);
5317 padd_sta_evt->cam_id = cam_idx;
5319 DBG_8723A("report_add_sta_event23a: add STA\n");
5321 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5326 /****************************************************************************
5328 Following are the event callback functions
5330 *****************************************************************************/
5332 /* for sta/adhoc mode */
5333 void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta)
5335 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5336 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5337 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5340 VCS_update23a(padapter, psta);
5343 if (pmlmepriv->htpriv.ht_option)
5345 psta->htpriv.ht_option = true;
5347 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
5349 if (support_short_GI23a(padapter, &pmlmeinfo->HT_caps))
5350 psta->htpriv.sgi = true;
5352 psta->qos_option = true;
5357 psta->htpriv.ht_option = false;
5359 psta->htpriv.ampdu_enable = false;
5361 psta->htpriv.sgi = false;
5362 psta->qos_option = false;
5365 psta->htpriv.bwmode = pmlmeext->cur_bwmode;
5366 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
5368 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
5369 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
5372 if (pmlmepriv->qospriv.qos_option)
5373 psta->qos_option = true;
5375 psta->state = _FW_LINKED;
5378 void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter, int join_res)
5380 struct sta_info *psta, *psta_bmc;
5381 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5382 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5383 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
5384 struct sta_priv *pstapriv = &padapter->stapriv;
5387 hw_var_set_mlme_join(padapter, 1);
5388 hw_var_set_bssid(padapter, null_addr);
5390 /* restore to initial setting. */
5391 update_tx_basic_rate23a(padapter,
5392 padapter->registrypriv.wireless_mode);
5394 goto exit_mlmeext_joinbss_event_callback23a;
5397 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
5400 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
5403 pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc;
5404 update_bmc_sta_support_rate23a(padapter, psta_bmc->mac_id);
5405 Update_RA_Entry23a(padapter, psta_bmc);
5409 /* turn on dynamic functions */
5410 rtl8723a_odm_support_ability_set(padapter, DYNAMIC_ALL_FUNC_ENABLE);
5412 /* update IOT-releated issue */
5413 update_IOT_info23a(padapter);
5415 HalSetBrateCfg23a(padapter, cur_network->SupportedRates);
5418 rtl8723a_set_beacon_interval(padapter, pmlmeinfo->bcn_interval);
5420 /* udpate capability */
5421 update_capinfo23a(padapter, pmlmeinfo->capability);
5423 /* WMM, Update EDCA param */
5424 WMMOnAssocRsp23a(padapter);
5427 HTOnAssocRsp23a(padapter);
5429 /* Set cur_channel&cur_bwmode&cur_ch_offset */
5430 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5432 psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
5433 if (psta) /* only for infra. mode */
5435 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5437 /* DBG_8723A("set_sta_rate23a\n"); */
5439 psta->wireless_mode = pmlmeext->cur_wireless_mode;
5441 /* set per sta rate after updating HT cap. */
5442 set_sta_rate23a(padapter, psta);
5445 hw_var_set_mlme_join(padapter, 2);
5447 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
5448 /* correcting TSF */
5449 rtw_correct_TSF(padapter);
5451 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5454 rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_CONNECT, 0);
5456 exit_mlmeext_joinbss_event_callback23a:
5457 DBG_8723A("=>%s\n", __func__);
5460 void mlmeext_sta_add_event_callback23a(struct rtw_adapter *padapter, struct sta_info *psta)
5462 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5463 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5465 DBG_8723A("%s\n", __func__);
5467 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
5469 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)/* adhoc master or sta_count>1 */
5473 else/* adhoc client */
5475 /* correcting TSF */
5476 rtw_correct_TSF(padapter);
5479 if (send_beacon23a(padapter) == _FAIL)
5481 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
5483 pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
5488 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
5492 hw_var_set_mlme_join(padapter, 2);
5495 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5497 /* rate radaptive */
5498 Update_RA_Entry23a(padapter, psta);
5500 /* update adhoc sta_info */
5501 update_sta_info23a(padapter, psta);
5504 void mlmeext_sta_del_event_callback23a(struct rtw_adapter *padapter)
5506 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5507 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5509 if (is_client_associated_to_ap23a(padapter) || is_IBSS_empty23a(padapter))
5511 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
5513 hw_var_set_mlme_disconnect(padapter);
5514 hw_var_set_bssid(padapter, null_addr);
5516 /* restore to initial setting. */
5517 update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
5519 /* switch to the 20M Hz mode after disconnect */
5520 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5521 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5523 /* SelectChannel23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
5524 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5526 flush_all_cam_entry23a(padapter);
5528 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5530 /* set MSR to no link state -> infra. mode */
5531 Set_MSR23a(padapter, _HW_STATE_STATION_);
5533 del_timer_sync(&pmlmeext->link_timer);
5537 static u8 chk_ap_is_alive(struct rtw_adapter *padapter, struct sta_info *psta)
5541 if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)) &&
5542 sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) &&
5543 sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
5548 sta_update_last_rx_pkts(psta);
5552 void linked_status_chk23a(struct rtw_adapter *padapter)
5555 struct sta_info *psta;
5556 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5557 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5558 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5559 struct sta_priv *pstapriv = &padapter->stapriv;
5561 rtw_hal_sreset_linked_status_check23a(padapter);
5563 if (is_client_associated_to_ap23a(padapter))
5565 /* linked infrastructure client mode */
5567 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
5572 if ((psta = rtw_get_stainfo23a(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
5574 bool is_p2p_enable = false;
5576 if (chk_ap_is_alive(padapter, psta) == false)
5579 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
5582 if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
5583 u8 backup_oper_channel = 0;
5585 /* switch to correct channel of current network before issue keep-alive frames */
5586 if (rtw_get_oper_ch23a(padapter) != pmlmeext->cur_channel) {
5587 backup_oper_channel = rtw_get_oper_ch23a(padapter);
5588 SelectChannel23a(padapter, pmlmeext->cur_channel);
5591 if (rx_chk != _SUCCESS)
5592 issue_probereq23a_ex23a(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1);
5594 if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) {
5595 tx_chk = issue_nulldata23a(padapter, psta->hwaddr, 0, 3, 1);
5596 /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
5597 if (tx_chk == _SUCCESS && !is_p2p_enable)
5601 /* back to the original operation channel */
5602 if (backup_oper_channel>0)
5603 SelectChannel23a(padapter, backup_oper_channel);
5606 if (rx_chk != _SUCCESS) {
5607 if (pmlmeext->retry == 0) {
5608 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5609 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5610 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5614 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf)
5615 tx_chk = issue_nulldata23a(padapter, NULL, 0, 1, 0);
5618 if (rx_chk == _FAIL) {
5620 if (pmlmeext->retry > rx_chk_limit) {
5621 DBG_8723A_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
5622 FUNC_ADPT_ARG(padapter));
5623 receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress,
5624 WLAN_REASON_EXPIRATION_CHK);
5628 pmlmeext->retry = 0;
5631 if (tx_chk == _FAIL) {
5632 pmlmeinfo->link_count &= 0xf;
5634 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
5635 pmlmeinfo->link_count = 0;
5638 } /* end of if ((psta = rtw_get_stainfo23a(pstapriv, passoc_res->network.MacAddress)) != NULL) */
5640 else if (is_client_associated_to_ibss23a(padapter))
5642 /* linked IBSS mode */
5643 /* for each assoc list entry to check the rx pkt counter */
5644 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
5646 if (pmlmeinfo->FW_sta_info[i].status == 1)
5648 psta = pmlmeinfo->FW_sta_info[i].psta;
5650 if (NULL == psta) continue;
5652 if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta))
5655 if (pmlmeinfo->FW_sta_info[i].retry<3)
5657 pmlmeinfo->FW_sta_info[i].retry++;
5661 pmlmeinfo->FW_sta_info[i].retry = 0;
5662 pmlmeinfo->FW_sta_info[i].status = 0;
5663 report_del_sta_event23a(padapter, psta->hwaddr,
5664 65535/* indicate disconnect caused by no rx */
5670 pmlmeinfo->FW_sta_info[i].retry = 0;
5671 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
5676 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5681 static void survey_timer_hdl(unsigned long data)
5683 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
5684 struct cmd_obj *ph2c;
5685 struct sitesurvey_parm *psurveyPara;
5686 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5687 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5689 /* issue rtw_sitesurvey_cmd23a */
5690 if (pmlmeext->sitesurvey_res.state > SCAN_START) {
5691 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
5692 pmlmeext->sitesurvey_res.channel_idx++;
5694 if (pmlmeext->scan_abort == true) {
5695 pmlmeext->sitesurvey_res.channel_idx =
5696 pmlmeext->sitesurvey_res.ch_num;
5697 DBG_8723A("%s idx:%d\n", __func__,
5698 pmlmeext->sitesurvey_res.channel_idx);
5700 pmlmeext->scan_abort = false;/* reset */
5703 ph2c = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5706 goto exit_survey_timer_hdl;
5708 psurveyPara = (struct sitesurvey_parm*)
5709 kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC);
5712 goto exit_survey_timer_hdl;
5715 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
5716 rtw_enqueue_cmd23a(pcmdpriv, ph2c);
5719 exit_survey_timer_hdl:
5723 static void link_timer_hdl(unsigned long data)
5725 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
5726 /* static unsigned int rx_pkt = 0; */
5727 /* static u64 tx_cnt = 0; */
5728 /* struct xmit_priv *pxmitpriv = &padapter->xmitpriv; */
5729 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5730 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5731 /* struct sta_priv *pstapriv = &padapter->stapriv; */
5733 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
5735 DBG_8723A("link_timer_hdl:no beacon while connecting\n");
5736 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5737 report_join_res23a(padapter, -3);
5739 else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE)
5742 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT)
5744 /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
5746 pmlmeinfo->state = 0;
5747 report_join_res23a(padapter, -1);
5752 /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
5753 /* pmlmeinfo->reauth_count = 0; */
5757 DBG_8723A("link_timer_hdl: auth timeout and try again\n");
5758 pmlmeinfo->auth_seq = 1;
5759 issue_auth23a(padapter, NULL, 0);
5760 set_link_timer(pmlmeext, REAUTH_TO);
5762 else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)
5764 /* re-assoc timer */
5765 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT)
5767 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5768 report_join_res23a(padapter, -2);
5772 DBG_8723A("link_timer_hdl: assoc timeout and try again\n");
5773 issue_assocreq23a(padapter);
5774 set_link_timer(pmlmeext, REASSOC_TO);
5780 static void addba_timer_hdl(unsigned long data)
5782 struct sta_info *psta = (struct sta_info *)data;
5783 struct ht_priv *phtpriv;
5788 phtpriv = &psta->htpriv;
5790 if ((phtpriv->ht_option == true) && (phtpriv->ampdu_enable == true))
5792 if (phtpriv->candidate_tid_bitmap)
5793 phtpriv->candidate_tid_bitmap = 0x0;
5798 void init_addba_retry_timer23a(struct sta_info *psta)
5800 setup_timer(&psta->addba_retry_timer, addba_timer_hdl,
5801 (unsigned long)psta);
5804 void init_mlme_ext_timer23a(struct rtw_adapter *padapter)
5806 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5808 setup_timer(&pmlmeext->survey_timer, survey_timer_hdl,
5809 (unsigned long)padapter);
5811 setup_timer(&pmlmeext->link_timer, link_timer_hdl,
5812 (unsigned long)padapter);
5815 u8 NULL_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5820 u8 setopmode_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5823 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5824 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5825 const struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
5827 if (psetop->mode == Ndis802_11APMode) {
5828 pmlmeinfo->state = WIFI_FW_AP_STATE;
5829 type = _HW_STATE_AP_;
5830 } else if (psetop->mode == Ndis802_11Infrastructure) {
5831 pmlmeinfo->state &= ~(BIT(0)|BIT(1));/* clear state */
5832 pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */
5833 type = _HW_STATE_STATION_;
5834 } else if (psetop->mode == Ndis802_11IBSS)
5835 type = _HW_STATE_ADHOC_;
5837 type = _HW_STATE_NOLINK_;
5839 hw_var_set_opmode(padapter, type);
5840 /* Set_NETYPE0_MSR(padapter, type); */
5845 u8 createbss_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5847 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5848 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5849 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5850 const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
5851 /* u32 initialgain; */
5853 if (pparm->InfrastructureMode == Ndis802_11APMode) {
5854 #ifdef CONFIG_8723AU_AP_MODE
5856 if (pmlmeinfo->state == WIFI_FW_AP_STATE)
5864 /* below is for ad-hoc master */
5865 if (pparm->InfrastructureMode == Ndis802_11IBSS) {
5866 rtw_joinbss_reset23a(padapter);
5868 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5869 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5870 pmlmeinfo->ERP_enable = 0;
5871 pmlmeinfo->WMM_enable = 0;
5872 pmlmeinfo->HT_enable = 0;
5873 pmlmeinfo->HT_caps_enable = 0;
5874 pmlmeinfo->HT_info_enable = 0;
5875 pmlmeinfo->agg_enable_bitmap = 0;
5876 pmlmeinfo->candidate_tid_bitmap = 0;
5878 /* disable dynamic functions, such as high power, DIG */
5879 rtl8723a_odm_support_ability_backup(padapter);
5881 rtl8723a_odm_support_ability_clr(padapter,
5882 DYNAMIC_FUNC_DISABLE);
5884 /* cancel link timer */
5885 del_timer_sync(&pmlmeext->link_timer);
5888 flush_all_cam_entry23a(padapter);
5890 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
5891 return H2C_PARAMETERS_ERROR;
5893 memcpy(pnetwork, pparm, sizeof(struct wlan_bssid_ex));
5895 start_create_ibss23a(padapter);
5901 u8 join_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5903 struct ndis_802_11_var_ies * pIE;
5904 struct registry_priv *pregpriv = &padapter->registrypriv;
5905 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5906 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5907 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5908 const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
5909 struct HT_info_element *pht_info;
5911 /* u32 initialgain; */
5914 /* check already connecting to AP or not */
5915 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
5917 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
5918 issue_deauth23a_ex23a(padapter, pnetwork->MacAddress,
5919 WLAN_REASON_DEAUTH_LEAVING, 5, 100);
5921 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5924 flush_all_cam_entry23a(padapter);
5926 del_timer_sync(&pmlmeext->link_timer);
5928 /* set MSR to nolink -> infra. mode */
5929 /* Set_MSR23a(padapter, _HW_STATE_NOLINK_); */
5930 Set_MSR23a(padapter, _HW_STATE_STATION_);
5932 hw_var_set_mlme_disconnect(padapter);
5935 rtw_joinbss_reset23a(padapter);
5937 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5938 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5939 pmlmeinfo->ERP_enable = 0;
5940 pmlmeinfo->WMM_enable = 0;
5941 pmlmeinfo->HT_enable = 0;
5942 pmlmeinfo->HT_caps_enable = 0;
5943 pmlmeinfo->HT_info_enable = 0;
5944 pmlmeinfo->agg_enable_bitmap = 0;
5945 pmlmeinfo->candidate_tid_bitmap = 0;
5946 pmlmeinfo->bwmode_updated = false;
5947 /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
5949 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
5950 return H2C_PARAMETERS_ERROR;
5952 memcpy(pnetwork, pbuf, sizeof(struct wlan_bssid_ex));
5954 /* Check AP vendor to move rtw_joinbss_cmd23a() */
5955 /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP23a(pnetwork->IEs,
5956 pnetwork->IELength); */
5958 for (i = sizeof(struct ndis_802_11_fixed_ies); i < pnetwork->IELength;)
5960 pIE = (struct ndis_802_11_var_ies *)(pnetwork->IEs + i);
5962 switch (pIE->ElementID)
5964 case WLAN_EID_VENDOR_SPECIFIC:/* Get WMM IE. */
5965 if (!memcmp(pIE->data, WMM_OUI23A, 4))
5966 pmlmeinfo->WMM_enable = 1;
5969 case WLAN_EID_HT_CAPABILITY: /* Get HT Cap IE. */
5970 pmlmeinfo->HT_caps_enable = 1;
5973 case WLAN_EID_HT_OPERATION: /* Get HT Info IE. */
5974 pmlmeinfo->HT_info_enable = 1;
5976 /* spec case only for cisco's ap because cisco's ap
5977 * issue assoc rsp using mcs rate @40MHz or @20MHz */
5978 pht_info = (struct HT_info_element *)(pIE->data);
5980 if ((pregpriv->cbw40_enable) &&
5981 (pht_info->infos[0] & BIT(2))) {
5982 /* switch to the 40M Hz mode according to AP */
5983 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
5984 switch (pht_info->infos[0] & 0x3)
5987 pmlmeext->cur_ch_offset =
5988 HAL_PRIME_CHNL_OFFSET_LOWER;
5992 pmlmeext->cur_ch_offset =
5993 HAL_PRIME_CHNL_OFFSET_UPPER;
5997 pmlmeext->cur_ch_offset =
5998 HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6002 DBG_8723A("set ch/bw before connected\n");
6010 i += (pIE->Length + 2);
6013 hw_var_set_bssid(padapter, pmlmeinfo->network.MacAddress);
6014 hw_var_set_mlme_join(padapter, 0);
6016 /* cancel link timer */
6017 del_timer_sync(&pmlmeext->link_timer);
6019 start_clnt_join23a(padapter);
6024 u8 disconnect_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6026 const struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
6027 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6028 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6029 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
6031 if (is_client_associated_to_ap23a(padapter))
6033 issue_deauth23a_ex23a(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
6036 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
6038 /* pmlmeinfo->state = WIFI_FW_NULL_STATE; */
6040 hw_var_set_mlme_disconnect(padapter);
6041 hw_var_set_bssid(padapter, null_addr);
6043 /* restore to initial setting. */
6044 update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
6046 if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
6047 ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
6048 rtl8723a_set_bcn_func(padapter, 0); /* Stop BCN */
6050 /* set MSR to no link state -> infra. mode */
6051 Set_MSR23a(padapter, _HW_STATE_STATION_);
6053 pmlmeinfo->state = WIFI_FW_NULL_STATE;
6055 /* switch to the 20M Hz mode after disconnect */
6056 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
6057 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6059 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
6061 flush_all_cam_entry23a(padapter);
6063 del_timer_sync(&pmlmeext->link_timer);
6065 rtw_free_uc_swdec_pending_queue23a(padapter);
6071 rtw_scan_ch_decision(struct rtw_adapter *padapter,
6072 struct rtw_ieee80211_channel *out, u32 out_num,
6073 const struct rtw_ieee80211_channel *in, u32 in_num)
6076 int scan_ch_num = 0;
6078 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6080 /* clear out first */
6081 memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
6083 /* acquire channels from in */
6085 for (i = 0;i<in_num;i++) {
6087 DBG_8723A(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
6088 if (in[i].hw_value && !(in[i].flags & IEEE80211_CHAN_DISABLED)
6089 && (set_idx = rtw_ch_set_search_ch23a(pmlmeext->channel_set, in[i].hw_value)) >= 0
6092 memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
6094 if (pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
6095 out[j].flags &= IEEE80211_CHAN_NO_IR;
6103 /* if out is empty, use channel_set as default */
6105 for (i = 0;i<pmlmeext->max_chan_nums;i++) {
6106 out[i].hw_value = pmlmeext->channel_set[i].ChannelNum;
6108 if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
6109 out[i].flags &= IEEE80211_CHAN_NO_IR;
6115 if (padapter->setband == GHZ_24) { /* 2.4G */
6116 for (i = 0; i < j ; i++) {
6117 if (out[i].hw_value > 35)
6119 sizeof(struct rtw_ieee80211_channel));
6124 } else if (padapter->setband == GHZ_50) { /* 5G */
6125 for (i = 0; i < j ; i++) {
6126 if (out[i].hw_value > 35) {
6127 memcpy(&out[scan_ch_num++], &out[i], sizeof(struct rtw_ieee80211_channel));
6137 u8 sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6139 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6140 const struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
6141 u8 bdelayscan = false;
6145 if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
6146 pmlmeext->sitesurvey_res.state = SCAN_START;
6147 pmlmeext->sitesurvey_res.bss_cnt = 0;
6148 pmlmeext->sitesurvey_res.channel_idx = 0;
6150 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
6151 if (pparm->ssid[i].ssid_len) {
6152 memcpy(pmlmeext->sitesurvey_res.ssid[i].ssid,
6153 pparm->ssid[i].ssid, IW_ESSID_MAX_SIZE);
6154 pmlmeext->sitesurvey_res.ssid[i].ssid_len =
6155 pparm->ssid[i].ssid_len;
6157 pmlmeext->sitesurvey_res.ssid[i].ssid_len = 0;
6161 pmlmeext->sitesurvey_res.ch_num =
6162 rtw_scan_ch_decision(padapter,
6163 pmlmeext->sitesurvey_res.ch,
6164 RTW_CHANNEL_SCAN_AMOUNT,
6165 pparm->ch, pparm->ch_num);
6167 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
6169 /* issue null data if associating to the AP */
6170 if (is_client_associated_to_ap23a(padapter)) {
6171 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
6173 /* switch to correct channel of current network
6174 before issue keep-alive frames */
6175 if (rtw_get_oper_ch23a(padapter) != pmlmeext->cur_channel)
6176 SelectChannel23a(padapter, pmlmeext->cur_channel);
6178 issue_nulldata23a(padapter, NULL, 1, 3, 500);
6184 /* delay 50ms to protect nulldata(1). */
6185 set_survey_timer(pmlmeext, 50);
6190 if ((pmlmeext->sitesurvey_res.state == SCAN_START) ||
6191 (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) {
6192 /* disable dynamic functions, such as high power, DIG */
6193 rtl8723a_odm_support_ability_backup(padapter);
6194 rtl8723a_odm_support_ability_clr(padapter,
6195 DYNAMIC_FUNC_DISABLE);
6197 /* config the initial gain under scaning, need to
6198 write the BB registers */
6199 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == true)
6204 rtl8723a_set_initial_gain(padapter, initialgain);
6206 /* set MSR to no link state */
6207 Set_MSR23a(padapter, _HW_STATE_NOLINK_);
6209 rtl8723a_mlme_sitesurvey(padapter, 1);
6211 pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
6214 site_survey23a(padapter);
6219 u8 setauth_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6221 const struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
6222 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6223 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6225 if (pparm->mode < 4)
6227 pmlmeinfo->auth_algo = pparm->mode;
6233 u8 setkey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6235 unsigned short ctrl;
6236 const struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
6237 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6238 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6239 unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
6241 /* main tx key for wep. */
6243 pmlmeinfo->key_index = pparm->keyid;
6246 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
6248 DBG_8723A_LEVEL(_drv_always_, "set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) "
6249 "keyid:%d\n", pparm->algorithm, pparm->keyid);
6250 rtl8723a_cam_write(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
6252 /* allow multicast packets to driver */
6253 rtl8723a_on_rcr_am(padapter);
6258 u8 set_stakey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6261 u8 cam_id;/* cam_entry */
6262 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6263 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6264 const struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
6267 /* 0~3 for default key */
6269 /* for concurrent mode (ap+sta): */
6270 /* default key is disable, using sw encrypt/decrypt */
6271 /* cam_entry = 4 for sta mode (macid = 0) */
6272 /* cam_entry(macid+3) = 5 ~ N for ap mode (aid = 1~N, macid = 2 ~N) */
6274 /* for concurrent mode (sta+sta): */
6275 /* default key is disable, using sw encrypt/decrypt */
6276 /* cam_entry = 4 mapping to macid = 0 */
6277 /* cam_entry = 5 mapping to macid = 2 */
6281 DBG_8723A_LEVEL(_drv_always_, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) camid:%d\n",
6282 pparm->algorithm, cam_id);
6283 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
6286 struct sta_info *psta;
6287 struct sta_priv *pstapriv = &padapter->stapriv;
6289 if (pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */
6291 clear_cam_entry23a(padapter, pparm->id);
6292 return H2C_SUCCESS_RSP;
6295 psta = rtw_get_stainfo23a(pstapriv, pparm->addr);
6298 ctrl = (BIT(15) | ((pparm->algorithm) << 2));
6300 DBG_8723A("r871x_set_stakey_hdl23a(): enc_algorithm =%d\n", pparm->algorithm);
6302 if ((psta->mac_id<1) || (psta->mac_id>(NUM_STA-4)))
6304 DBG_8723A("r871x_set_stakey_hdl23a():set_stakey failed, mac_id(aid) =%d\n", psta->mac_id);
6305 return H2C_REJECTED;
6308 cam_id = (psta->mac_id + 3);/* 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */
6310 DBG_8723A("Write CAM, mac_addr =%x:%x:%x:%x:%x:%x, cam_entry =%d\n", pparm->addr[0],
6311 pparm->addr[1], pparm->addr[2], pparm->addr[3], pparm->addr[4],
6312 pparm->addr[5], cam_id);
6314 rtl8723a_cam_write(padapter, cam_id, ctrl,
6315 pparm->addr, pparm->key);
6317 return H2C_SUCCESS_RSP;
6322 DBG_8723A("r871x_set_stakey_hdl23a(): sta has been free\n");
6323 return H2C_REJECTED;
6328 /* below for sta mode */
6330 if (pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */
6332 clear_cam_entry23a(padapter, pparm->id);
6336 ctrl = BIT(15) | ((pparm->algorithm) << 2);
6338 rtl8723a_cam_write(padapter, cam_id, ctrl, pparm->addr, pparm->key);
6340 pmlmeinfo->enc_algo = pparm->algorithm;
6345 u8 add_ba_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6347 const struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
6348 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6349 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6351 struct sta_info *psta = rtw_get_stainfo23a(&padapter->stapriv, pparm->addr);
6356 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) &&
6357 (pmlmeinfo->HT_enable)) ||
6358 ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
6359 issue_action_BA23a(padapter, pparm->addr,
6360 WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
6361 mod_timer(&psta->addba_retry_timer,
6362 jiffies + msecs_to_jiffies(ADDBA_TO));
6364 psta->htpriv.candidate_tid_bitmap &= ~CHKBIT(pparm->tid);
6369 u8 set_tx_beacon_cmd23a(struct rtw_adapter* padapter)
6371 struct cmd_obj *ph2c;
6372 struct Tx_Beacon_param *ptxBeacon_parm;
6373 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
6374 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6375 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6381 ph2c = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
6387 ptxBeacon_parm = (struct Tx_Beacon_param *)
6388 kzalloc(sizeof(struct Tx_Beacon_param), GFP_ATOMIC);
6389 if (!ptxBeacon_parm) {
6395 memcpy(&ptxBeacon_parm->network, &pmlmeinfo->network,
6396 sizeof(struct wlan_bssid_ex));
6398 len_diff = update_hidden_ssid(
6399 ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_,
6400 ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_,
6401 pmlmeinfo->hidden_ssid_mode);
6402 ptxBeacon_parm->network.IELength += len_diff;
6404 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
6406 res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
6415 u8 mlme_evt_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6417 u8 evt_code, evt_seq;
6419 const struct C2HEvent_Header *c2h;
6420 void (*event_callback)(struct rtw_adapter *dev, const u8 *pbuf);
6422 c2h = (struct C2HEvent_Header *)pbuf;
6427 /* checking if event code is valid */
6428 if (evt_code >= MAX_C2HEVT) {
6429 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nEvent Code(%d) mismatch!\n", evt_code));
6433 /* checking if event size match the event parm size */
6434 if ((wlanevents[evt_code].parmsize != 0) &&
6435 (wlanevents[evt_code].parmsize != evt_sz)) {
6436 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
6437 evt_code, wlanevents[evt_code].parmsize, evt_sz));
6441 event_callback = wlanevents[evt_code].event_callback;
6442 event_callback(padapter, pbuf + sizeof(struct C2HEvent_Header));
6449 u8 h2c_msg_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6452 return H2C_PARAMETERS_ERROR;
6457 u8 tx_beacon_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6459 if (send_beacon23a(padapter) == _FAIL)
6461 DBG_8723A("issue_beacon23a, fail!\n");
6462 return H2C_PARAMETERS_ERROR;
6464 #ifdef CONFIG_8723AU_AP_MODE
6465 else /* tx bc/mc frames after update TIM */
6467 struct sta_info *psta_bmc;
6468 struct list_head *plist, *phead, *ptmp;
6469 struct xmit_frame *pxmitframe;
6470 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6471 struct sta_priv *pstapriv = &padapter->stapriv;
6473 /* for BC/MC Frames */
6474 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
6478 if ((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0))
6480 msleep(10);/* 10ms, ATIM(HIQ) Windows */
6481 /* spin_lock_bh(&psta_bmc->sleep_q.lock); */
6482 spin_lock_bh(&pxmitpriv->lock);
6484 phead = get_list_head(&psta_bmc->sleep_q);
6486 list_for_each_safe(plist, ptmp, phead) {
6487 pxmitframe = container_of(plist,
6491 list_del_init(&pxmitframe->list);
6493 psta_bmc->sleepq_len--;
6494 if (psta_bmc->sleepq_len>0)
6495 pxmitframe->attrib.mdata = 1;
6497 pxmitframe->attrib.mdata = 0;
6499 pxmitframe->attrib.triggered = 1;
6501 pxmitframe->attrib.qsel = 0x11;/* HIQ */
6503 rtw_hal_xmit23aframe_enqueue(padapter, pxmitframe);
6506 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
6507 spin_unlock_bh(&pxmitpriv->lock);
6516 u8 set_ch_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6518 const struct set_ch_parm *set_ch_parm;
6519 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6522 return H2C_PARAMETERS_ERROR;
6524 set_ch_parm = (struct set_ch_parm *)pbuf;
6526 DBG_8723A(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
6527 FUNC_NDEV_ARG(padapter->pnetdev),
6528 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
6530 pmlmeext->cur_channel = set_ch_parm->ch;
6531 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
6532 pmlmeext->cur_bwmode = set_ch_parm->bw;
6534 set_channel_bwmode23a(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
6539 u8 set_chplan_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6541 const struct SetChannelPlan_param *setChannelPlan_param;
6542 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6545 return H2C_PARAMETERS_ERROR;
6547 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
6549 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
6550 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
6555 u8 led_blink_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6557 struct LedBlink_param *ledBlink_param;
6560 return H2C_PARAMETERS_ERROR;
6562 ledBlink_param = (struct LedBlink_param *)pbuf;
6567 u8 set_csa_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6569 return H2C_REJECTED;
6572 /* TDLS_WRCR : write RCR DATA BIT */
6573 /* TDLS_SD_PTI : issue peer traffic indication */
6574 /* TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure */
6575 /* TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame */
6576 /* TDLS_DONE_CH_SEN: channel sensing and report candidate channel */
6577 /* TDLS_OFF_CH : first time set channel to off channel */
6578 /* TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel */
6579 /* TDLS_P_OFF_CH : periodically go to off channel */
6580 /* TDLS_P_BASE_CH : periodically go back to base channel */
6581 /* TDLS_RS_RCR : restore RCR */
6582 /* TDLS_CKALV_PH1 : check alive timer phase1 */
6583 /* TDLS_CKALV_PH2 : check alive timer phase2 */
6584 /* TDLS_FREE_STA : free tdls sta */
6585 u8 tdls_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6587 return H2C_REJECTED;