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;
2438 unsigned short *fctrl;
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;
2606 unsigned short *fctrl;
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;
2823 unsigned short *fctrl;
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;
2974 unsigned short *fctrl;
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;
3283 unsigned short *fctrl;
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;
3551 unsigned short *fctrl;
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;
3674 unsigned short *fctrl, *qc;
3675 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3676 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3677 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3679 DBG_8723A("%s\n", __func__);
3681 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3684 /* update attribute */
3685 pattrib = &pmgntframe->attrib;
3686 update_mgntframe_attrib23a(padapter, pattrib);
3688 pattrib->hdrlen += 2;
3689 pattrib->qos_en = true;
3691 pattrib->ack_policy = 0;
3694 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3696 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3697 pwlanhdr = (struct ieee80211_hdr *)pframe;
3699 fctrl = &pwlanhdr->frame_control;
3702 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3704 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
3710 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
3712 SetPriority(qc, tid);
3714 SetEOSP(qc, pattrib->eosp);
3716 SetAckpolicy(qc, pattrib->ack_policy);
3718 ether_addr_copy(pwlanhdr->addr1, da);
3719 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3720 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3722 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3723 pmlmeext->mgnt_seq++;
3724 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
3726 pframe += sizeof(struct ieee80211_qos_hdr);
3727 pattrib->pktlen = sizeof(struct ieee80211_qos_hdr);
3729 pattrib->last_txcmdsz = pattrib->pktlen;
3732 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3734 dump_mgntframe23a(padapter, pmgntframe);
3742 /* when wait_ms >0 , this function shoule be called at process context */
3743 /* da == NULL for station mode */
3744 int issue_qos_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3745 u16 tid, int try_cnt, int wait_ms)
3749 unsigned long start = jiffies;
3750 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3751 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3753 /* da == NULL, assum it's null data for sta to ap*/
3755 da = get_my_bssid23a(&pmlmeinfo->network);
3758 ret = _issue_qos_nulldata23a(padapter, da, tid,
3759 wait_ms > 0 ? true : false);
3763 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3766 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3768 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
3775 if (try_cnt && wait_ms) {
3777 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d "
3778 "in %u ms\n", FUNC_ADPT_ARG(padapter),
3779 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3780 ret == _SUCCESS?", acked":"", i, try_cnt,
3781 jiffies_to_msecs(jiffies - start));
3783 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
3784 FUNC_ADPT_ARG(padapter),
3785 rtw_get_oper_ch23a(padapter),
3786 ret == _SUCCESS?", acked":"", i, try_cnt,
3787 jiffies_to_msecs(jiffies - start));
3793 static int _issue_deauth23a(struct rtw_adapter *padapter, unsigned char *da,
3794 unsigned short reason, u8 wait_ack)
3796 struct xmit_frame *pmgntframe;
3797 struct pkt_attrib *pattrib;
3798 unsigned char *pframe;
3799 struct ieee80211_hdr *pwlanhdr;
3800 unsigned short *fctrl;
3801 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3802 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3803 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3806 /* DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
3808 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3811 /* update attribute */
3812 pattrib = &pmgntframe->attrib;
3813 update_mgntframe_attrib23a(padapter, pattrib);
3814 pattrib->retry_ctrl = false;
3816 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3818 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3819 pwlanhdr = (struct ieee80211_hdr *)pframe;
3821 fctrl = &pwlanhdr->frame_control;
3824 ether_addr_copy(pwlanhdr->addr1, da);
3825 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3826 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3828 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3829 pmlmeext->mgnt_seq++;
3830 SetFrameSubType(pframe, WIFI_DEAUTH);
3832 pframe += sizeof(struct ieee80211_hdr_3addr);
3833 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3835 reason = cpu_to_le16(reason);
3836 pframe = rtw_set_fixed_ie23a(pframe, WLAN_REASON_PREV_AUTH_NOT_VALID,
3837 (unsigned char *)&reason,
3840 pattrib->last_txcmdsz = pattrib->pktlen;
3843 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3845 dump_mgntframe23a(padapter, pmgntframe);
3853 int issue_deauth23a(struct rtw_adapter *padapter, unsigned char *da,
3854 unsigned short reason)
3856 DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
3857 return _issue_deauth23a(padapter, da, reason, false);
3860 int issue_deauth23a_ex23a(struct rtw_adapter *padapter, u8 *da,
3861 unsigned short reason, int try_cnt, int wait_ms)
3865 unsigned long start = jiffies;
3868 ret = _issue_deauth23a(padapter, da, reason,
3869 wait_ms >0 ? true : false);
3873 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3876 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3879 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
3886 if (try_cnt && wait_ms) {
3888 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d "
3889 "in %u ms\n", FUNC_ADPT_ARG(padapter),
3890 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3891 ret == _SUCCESS?", acked":"", i, try_cnt,
3892 jiffies_to_msecs(jiffies - start));
3894 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
3895 FUNC_ADPT_ARG(padapter),
3896 rtw_get_oper_ch23a(padapter),
3897 ret == _SUCCESS?", acked":"", i, try_cnt,
3898 jiffies_to_msecs(jiffies - start));
3904 void issue_action_spct_ch_switch23a(struct rtw_adapter *padapter,
3905 u8 *ra, u8 new_ch, u8 ch_offset)
3907 struct xmit_frame *pmgntframe;
3908 struct pkt_attrib *pattrib;
3909 unsigned char *pframe;
3910 struct ieee80211_hdr *pwlanhdr;
3911 unsigned short *fctrl;
3912 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3913 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3914 u8 category, action;
3916 DBG_8723A(FUNC_NDEV_FMT" ra ="MAC_FMT", ch:%u, offset:%u\n",
3917 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra),
3920 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3923 /* update attribute */
3924 pattrib = &pmgntframe->attrib;
3925 update_mgntframe_attrib23a(padapter, pattrib);
3927 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3929 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3930 pwlanhdr = (struct ieee80211_hdr *)pframe;
3932 fctrl = &pwlanhdr->frame_control;
3935 ether_addr_copy(pwlanhdr->addr1, ra); /* RA */
3936 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv)); /* TA */
3937 ether_addr_copy(pwlanhdr->addr3, ra); /* DA = RA */
3939 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3940 pmlmeext->mgnt_seq++;
3941 SetFrameSubType(pframe, WIFI_ACTION);
3943 pframe += sizeof(struct ieee80211_hdr_3addr);
3944 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3946 /* category, action */
3947 category = WLAN_CATEGORY_SPECTRUM_MGMT;
3948 action = WLAN_ACTION_SPCT_CHL_SWITCH;
3950 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
3951 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
3953 pframe = rtw_set_ie23a_ch_switch (pframe, &pattrib->pktlen, 0,
3955 pframe = rtw_set_ie23a_secondary_ch_offset(pframe, &pattrib->pktlen,
3956 hal_ch_offset_to_secondary_ch_offset23a(ch_offset));
3958 pattrib->last_txcmdsz = pattrib->pktlen;
3960 dump_mgntframe23a(padapter, pmgntframe);
3963 void issue_action_BA23a(struct rtw_adapter *padapter,
3964 const unsigned char *raddr,
3965 unsigned char action, unsigned short status)
3967 u8 category = WLAN_CATEGORY_BACK;
3971 u16 BA_timeout_value;
3972 u16 BA_starting_seqctrl;
3973 int max_rx_ampdu_factor;
3974 struct xmit_frame *pmgntframe;
3975 struct pkt_attrib *pattrib;
3977 struct ieee80211_hdr *pwlanhdr;
3979 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3980 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3981 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3982 struct sta_info *psta;
3983 struct sta_priv *pstapriv = &padapter->stapriv;
3984 struct registry_priv *pregpriv = &padapter->registrypriv;
3985 #ifdef CONFIG_8723AU_BT_COEXIST
3986 u8 tendaAPMac[] = {0xC8, 0x3A, 0x35};
3989 DBG_8723A("%s, category =%d, action =%d, status =%d\n",
3990 __func__, category, action, status);
3992 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3995 /* update attribute */
3996 pattrib = &pmgntframe->attrib;
3997 update_mgntframe_attrib23a(padapter, pattrib);
3999 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4001 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4002 pwlanhdr = (struct ieee80211_hdr *)pframe;
4004 fctrl = &pwlanhdr->frame_control;
4007 /* memcpy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN); */
4008 ether_addr_copy(pwlanhdr->addr1, raddr);
4009 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
4010 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
4012 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4013 pmlmeext->mgnt_seq++;
4014 SetFrameSubType(pframe, WIFI_ACTION);
4016 pframe += sizeof(struct ieee80211_hdr_3addr);
4017 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
4019 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
4020 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
4022 status = cpu_to_le16(status);
4029 case 0: /* ADDBA req */
4031 pmlmeinfo->dialogToken++;
4032 } while (pmlmeinfo->dialogToken == 0);
4033 pframe = rtw_set_fixed_ie23a(pframe, 1, &pmlmeinfo->dialogToken,
4036 #ifdef CONFIG_8723AU_BT_COEXIST
4037 if ((BT_1Ant(padapter) == true) &&
4038 ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
4039 memcmp(raddr, tendaAPMac, 3))) {
4040 /* A-MSDU NOT Supported */
4042 /* immediate Block Ack */
4043 BA_para_set |= (1 << 1) &
4044 IEEE80211_ADDBA_PARAM_POLICY_MASK;
4046 BA_para_set |= (status << 2) &
4047 IEEE80211_ADDBA_PARAM_TID_MASK;
4048 /* max buffer size is 8 MSDU */
4049 BA_para_set |= (8 << 6) &
4050 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4054 /* immediate ack & 64 buffer size */
4055 BA_para_set = (0x1002 | ((status & 0xf) << 2));
4057 BA_para_set = cpu_to_le16(BA_para_set);
4058 pframe = rtw_set_fixed_ie23a(pframe, 2,
4059 (unsigned char *)&BA_para_set,
4062 BA_timeout_value = 5000;/* 5ms */
4063 BA_timeout_value = cpu_to_le16(BA_timeout_value);
4064 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)
4068 /* if ((psta = rtw_get_stainfo23a(pstapriv,
4069 pmlmeinfo->network.MacAddress)) != NULL) */
4070 if ((psta = rtw_get_stainfo23a(pstapriv, raddr))) {
4071 start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1;
4073 DBG_8723A("BA_starting_seqctrl = %d for TID =%d\n",
4074 start_seq, status & 0x07);
4076 psta->BA_starting_seqctrl[status & 0x07] = start_seq;
4078 BA_starting_seqctrl = start_seq << 4;
4081 BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
4082 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)&BA_starting_seqctrl, &pattrib->pktlen);
4085 case 1: /* ADDBA rsp */
4086 pframe = rtw_set_fixed_ie23a(pframe, 1, &pmlmeinfo->ADDBA_req.dialog_token, &pattrib->pktlen);
4087 pframe = rtw_set_fixed_ie23a(pframe, 2,
4088 (unsigned char *)&status,
4090 rtw_hal_get_def_var23a(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
4091 &max_rx_ampdu_factor);
4092 if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_64K)
4093 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
4094 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_32K)
4095 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800); /* 32 buffer size */
4096 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_16K)
4097 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0400); /* 16 buffer size */
4098 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_8K)
4099 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0200); /* 8 buffer size */
4101 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
4103 #ifdef CONFIG_8723AU_BT_COEXIST
4104 if ((BT_1Ant(padapter) == true) &&
4105 ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
4106 memcmp(raddr, tendaAPMac, 3))) {
4107 /* max buffer size is 8 MSDU */
4108 BA_para_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4109 BA_para_set |= (8 << 6) &
4110 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4114 if (pregpriv->ampdu_amsdu == 0)/* disabled */
4115 BA_para_set = cpu_to_le16(BA_para_set & ~BIT(0));
4116 else if (pregpriv->ampdu_amsdu == 1)/* enabled */
4117 BA_para_set = cpu_to_le16(BA_para_set | BIT(0));
4119 BA_para_set = cpu_to_le16(BA_para_set);
4121 pframe = rtw_set_fixed_ie23a(pframe, 2,
4122 (unsigned char *)&BA_para_set,
4124 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)&pmlmeinfo->ADDBA_req.BA_timeout_value, &pattrib->pktlen);
4127 BA_para_set = (status & 0x1F) << 3;
4128 BA_para_set = cpu_to_le16(BA_para_set);
4129 pframe = rtw_set_fixed_ie23a(pframe, 2,
4130 (unsigned char *)&BA_para_set,
4133 reason_code = 37;/* Requested from peer STA as it does not
4134 want to use the mechanism */
4135 reason_code = cpu_to_le16(reason_code);
4136 pframe = rtw_set_fixed_ie23a(pframe, 2,
4137 (unsigned char *)&reason_code,
4145 pattrib->last_txcmdsz = pattrib->pktlen;
4147 dump_mgntframe23a(padapter, pmgntframe);
4150 static void issue_action_BSSCoexistPacket(struct rtw_adapter *padapter)
4152 struct list_head *plist, *phead, *ptmp;
4153 unsigned char category, action;
4154 struct xmit_frame *pmgntframe;
4155 struct pkt_attrib *pattrib;
4157 struct ieee80211_hdr *pwlanhdr;
4158 unsigned short *fctrl;
4159 struct wlan_network *pnetwork;
4160 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4161 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4162 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4163 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4164 struct rtw_queue *queue = &pmlmepriv->scanned_queue;
4165 u8 InfoContent[16] = {0};
4169 if (pmlmepriv->num_FortyMHzIntolerant == 0 ||
4170 pmlmepriv->num_sta_no_ht == 0)
4173 if (pmlmeinfo->bwmode_updated)
4176 DBG_8723A("%s\n", __func__);
4178 category = WLAN_CATEGORY_PUBLIC;
4179 action = ACT_PUBLIC_BSSCOEXIST;
4181 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
4185 /* update attribute */
4186 pattrib = &pmgntframe->attrib;
4187 update_mgntframe_attrib23a(padapter, pattrib);
4189 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4191 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
4192 pwlanhdr = (struct ieee80211_hdr *)pframe;
4194 fctrl = &pwlanhdr->frame_control;
4197 ether_addr_copy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network));
4198 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
4199 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
4201 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4202 pmlmeext->mgnt_seq++;
4203 SetFrameSubType(pframe, WIFI_ACTION);
4205 pframe += sizeof(struct ieee80211_hdr_3addr);
4206 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
4208 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
4209 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
4211 if (pmlmepriv->num_FortyMHzIntolerant > 0) {
4212 u8 iedata = BIT(2);/* 20 MHz BSS Width Request */
4214 pframe = rtw_set_ie23a(pframe, WLAN_EID_BSS_COEX_2040, 1,
4215 &iedata, &pattrib->pktlen);
4218 if (pmlmepriv->num_sta_no_ht <= 0)
4221 memset(ICS, 0, sizeof(ICS));
4223 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
4225 phead = get_list_head(queue);
4226 plist = phead->next;
4228 list_for_each_safe(plist, ptmp, phead) {
4230 struct wlan_bssid_ex *pbss_network;
4232 pnetwork = container_of(plist, struct wlan_network, list);
4234 pbss_network = &pnetwork->network;
4236 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
4237 pbss_network->IEs + _FIXED_IE_LENGTH_,
4238 pbss_network->IELength -_FIXED_IE_LENGTH_);
4239 if (!p || !p[1]) { /* non-HT */
4240 if (pbss_network->Configuration.DSConfig <= 0 ||
4241 pbss_network->Configuration.DSConfig > 14)
4244 ICS[0][pbss_network->Configuration.DSConfig] = 1;
4252 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
4254 for (i = 0; i < 8;i++) {
4255 if (ICS[i][0] == 1) {
4259 /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */
4262 for (j = 1; j <= 14; j++) {
4263 if (ICS[i][j] == 1) {
4265 /* channel number */
4272 pframe = rtw_set_ie23a(pframe,
4273 EID_BSSIntolerantChlReport, k,
4274 InfoContent, &pattrib->pktlen);
4279 pattrib->last_txcmdsz = pattrib->pktlen;
4281 dump_mgntframe23a(padapter, pmgntframe);
4284 unsigned int send_delba23a(struct rtw_adapter *padapter, u8 initiator, u8 *addr)
4286 struct sta_priv *pstapriv = &padapter->stapriv;
4287 struct sta_info *psta = NULL;
4288 /* struct recv_reorder_ctrl *preorder_ctrl; */
4289 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4290 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4293 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
4294 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
4297 psta = rtw_get_stainfo23a(pstapriv, addr);
4301 if (initiator == 0) { /* recipient */
4302 for (tid = 0; tid < MAXTID; tid++) {
4303 if (psta->recvreorder_ctrl[tid].enable == true) {
4304 DBG_8723A("rx agg disable tid(%d)\n", tid);
4305 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
4306 psta->recvreorder_ctrl[tid].enable = false;
4307 psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
4310 } else if (initiator == 1) { /* originator */
4311 for (tid = 0; tid < MAXTID; tid++) {
4312 if (psta->htpriv.agg_enable_bitmap & BIT(tid)) {
4313 DBG_8723A("tx agg disable tid(%d)\n", tid);
4314 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
4315 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
4316 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
4324 unsigned int send_beacon23a(struct rtw_adapter *padapter)
4329 unsigned long start = jiffies;
4330 unsigned int passing_time;
4332 rtl8723a_bcn_valid(padapter);
4334 issue_beacon23a(padapter, 100);
4338 bxmitok = rtl8723a_get_bcn_valid(padapter);
4340 } while ((poll % 10) != 0 && bxmitok == false &&
4341 !padapter->bSurpriseRemoved &&
4342 !padapter->bDriverStopped);
4344 } while (!bxmitok && issue<100 && !padapter->bSurpriseRemoved &&
4345 !padapter->bDriverStopped);
4347 if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
4350 passing_time = jiffies_to_msecs(jiffies - start);
4353 DBG_8723A("%s fail! %u ms\n", __func__, passing_time);
4357 if (passing_time > 100 || issue > 3)
4358 DBG_8723A("%s success, issue:%d, poll:%d, %u ms\n",
4359 __func__, issue, poll, passing_time);
4364 /****************************************************************************
4366 Following are some utitity fuctions for WiFi MLME
4368 *****************************************************************************/
4370 bool IsLegal5GChannel(struct rtw_adapter *Adapter, u8 channel)
4374 u8 Channel_5G[45] = {36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
4375 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
4376 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
4378 for (i = 0; i < sizeof(Channel_5G); i++)
4379 if (channel == Channel_5G[i])
4384 void site_survey23a(struct rtw_adapter *padapter)
4386 unsigned char survey_channel = 0;
4387 enum rt_scan_type ScanType = SCAN_PASSIVE;
4388 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4389 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4390 struct rtw_ieee80211_channel *ch;
4392 if (pmlmeext->sitesurvey_res.channel_idx <
4393 pmlmeext->sitesurvey_res.ch_num) {
4394 ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
4395 survey_channel = ch->hw_value;
4396 ScanType = (ch->flags & IEEE80211_CHAN_NO_IR) ?
4397 SCAN_PASSIVE : SCAN_ACTIVE;
4400 if (survey_channel != 0) {
4401 /* PAUSE 4-AC Queue when site_survey23a */
4402 if (pmlmeext->sitesurvey_res.channel_idx == 0)
4403 set_channel_bwmode23a(padapter, survey_channel,
4404 HAL_PRIME_CHNL_OFFSET_DONT_CARE,
4405 HT_CHANNEL_WIDTH_20);
4407 SelectChannel23a(padapter, survey_channel);
4409 if (ScanType == SCAN_ACTIVE) /* obey the channel plan setting... */
4412 for (i = 0;i<RTW_SSID_SCAN_AMOUNT;i++) {
4413 if (pmlmeext->sitesurvey_res.ssid[i].ssid_len) {
4414 /* todo: to issue two probe req??? */
4415 issue_probereq23a(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
4416 /* msleep(SURVEY_TO>>1); */
4417 issue_probereq23a(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
4421 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
4422 /* todo: to issue two probe req??? */
4423 issue_probereq23a(padapter, NULL, NULL);
4424 /* msleep(SURVEY_TO>>1); */
4425 issue_probereq23a(padapter, NULL, NULL);
4429 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
4431 /* channel number is 0 or this channel is not valid. */
4432 pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
4434 /* switch back to the original channel */
4436 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
4437 pmlmeext->cur_ch_offset,
4438 pmlmeext->cur_bwmode);
4440 /* flush 4-AC Queue after site_survey23a */
4444 Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
4446 /* restore RX GAIN */
4447 rtl8723a_set_initial_gain(padapter, 0xff);
4448 /* turn on dynamic functions */
4449 rtl8723a_odm_support_ability_restore(padapter);
4451 if (is_client_associated_to_ap23a(padapter) == true)
4452 issue_nulldata23a(padapter, NULL, 0, 3, 500);
4454 rtl8723a_mlme_sitesurvey(padapter, 0);
4456 report_surveydone_event23a(padapter);
4458 pmlmeext->chan_scan_time = SURVEY_TO;
4459 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
4461 issue_action_BSSCoexistPacket(padapter);
4462 issue_action_BSSCoexistPacket(padapter);
4463 issue_action_BSSCoexistPacket(padapter);
4469 /* collect bss info from Beacon and Probe request/response frames. */
4470 u8 collect_bss_info23a(struct rtw_adapter *padapter,
4471 struct recv_frame *precv_frame,
4472 struct wlan_bssid_ex *bssid)
4476 struct sk_buff *skb = precv_frame->pkt;
4477 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
4478 unsigned int length;
4480 struct registry_priv *pregistrypriv = &padapter->registrypriv;
4481 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4482 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4485 length = skb->len - sizeof(struct ieee80211_hdr_3addr);
4487 if (length > MAX_IE_SZ) {
4488 /* DBG_8723A("IE too long for survey event\n"); */
4492 memset(bssid, 0, sizeof(struct wlan_bssid_ex));
4494 if (ieee80211_is_beacon(mgmt->frame_control)) {
4495 bssid->reserved = 1;
4496 ie_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
4497 capab_info = mgmt->u.beacon.capab_info;
4498 } else if (ieee80211_is_probe_req(mgmt->frame_control)) {
4499 ie_offset = offsetof(struct ieee80211_mgmt,
4500 u.probe_req.variable);
4501 bssid->reserved = 2;
4503 } else if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4504 ie_offset = offsetof(struct ieee80211_mgmt,
4505 u.probe_resp.variable);
4506 bssid->reserved = 3;
4507 capab_info = mgmt->u.probe_resp.capab_info;
4509 bssid->reserved = 0;
4510 ie_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
4511 capab_info = mgmt->u.beacon.capab_info;
4513 ie_offset -= offsetof(struct ieee80211_mgmt, u);
4515 bssid->Length = offsetof(struct wlan_bssid_ex, IEs) + length;
4517 /* below is to copy the information element */
4518 bssid->IELength = length;
4519 memcpy(bssid->IEs, &mgmt->u, bssid->IELength);
4521 /* get the signal strength */
4522 /* in dBM.raw data */
4523 bssid->Rssi = precv_frame->attrib.phy_info.RecvSignalPower;
4524 bssid->PhyInfo.SignalQuality =
4525 precv_frame->attrib.phy_info.SignalQuality;/* in percentage */
4526 bssid->PhyInfo.SignalStrength =
4527 precv_frame->attrib.phy_info.SignalStrength;/* in percentage */
4530 p = cfg80211_find_ie(WLAN_EID_SSID, bssid->IEs + ie_offset,
4531 bssid->IELength - ie_offset);
4534 DBG_8723A("marc: cannot find SSID for survey event\n");
4538 if (p[1] > IEEE80211_MAX_SSID_LEN) {
4539 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4540 "event\n", __func__, __LINE__, p[1]);
4543 memcpy(bssid->Ssid.ssid, p + 2, p[1]);
4544 bssid->Ssid.ssid_len = p[1];
4546 memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
4548 /* checking rate info... */
4550 p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, bssid->IEs + ie_offset,
4551 bssid->IELength - ie_offset);
4553 if (p[1] > NDIS_802_11_LENGTH_RATES_EX) {
4554 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4555 "event\n", __func__, __LINE__, p[1]);
4558 memcpy(bssid->SupportedRates, p + 2, p[1]);
4562 p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, bssid->IEs + ie_offset,
4563 bssid->IELength - ie_offset);
4565 if (p[1] > (NDIS_802_11_LENGTH_RATES_EX-i)) {
4566 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4567 "event\n", __func__, __LINE__, p[1]);
4570 memcpy(bssid->SupportedRates + i, p + 2, p[1]);
4573 bssid->NetworkTypeInUse = Ndis802_11OFDM24;
4575 if (bssid->IELength < 12)
4578 /* Checking for DSConfig */
4579 p = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bssid->IEs + ie_offset,
4580 bssid->IELength - ie_offset);
4582 bssid->Configuration.DSConfig = 0;
4583 bssid->Configuration.Length = 0;
4586 bssid->Configuration.DSConfig = p[2];
4587 } else {/* In 5G, some ap do not have DSSET IE */
4588 /* checking HT info for channel */
4589 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
4590 bssid->IEs + ie_offset,
4591 bssid->IELength - ie_offset);
4593 struct HT_info_element *HT_info =
4594 (struct HT_info_element *)(p + 2);
4595 bssid->Configuration.DSConfig =
4596 HT_info->primary_channel;
4597 } else { /* use current channel */
4598 bssid->Configuration.DSConfig =
4599 rtw_get_oper_ch23a(padapter);
4603 if (ieee80211_is_probe_req(mgmt->frame_control)) {
4605 bssid->InfrastructureMode = Ndis802_11Infrastructure;
4606 ether_addr_copy(bssid->MacAddress, mgmt->sa);
4611 memcpy(&bssid->Configuration.BeaconPeriod,
4612 rtw_get_beacon_interval23a_from_ie(bssid->IEs), 2);
4613 bssid->Configuration.BeaconPeriod =
4614 le32_to_cpu(bssid->Configuration.BeaconPeriod);
4616 if (capab_info & BIT(0)) {
4617 bssid->InfrastructureMode = Ndis802_11Infrastructure;
4618 ether_addr_copy(bssid->MacAddress, mgmt->sa);
4620 bssid->InfrastructureMode = Ndis802_11IBSS;
4621 ether_addr_copy(bssid->MacAddress, mgmt->bssid);
4624 if (capab_info & BIT(4))
4629 bssid->Configuration.ATIMWindow = 0;
4631 /* 20/40 BSS Coexistence check */
4632 if (pregistrypriv->wifi_spec == 1 &&
4633 pmlmeinfo->bwmode_updated == false) {
4634 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4636 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
4637 bssid->IEs + ie_offset,
4638 bssid->IELength - ie_offset);
4639 if (p && p[1] > 0) {
4640 struct HT_caps_element *pHT_caps;
4641 pHT_caps = (struct HT_caps_element *)(p + 2);
4643 if (pHT_caps->u.HT_cap_element.HT_caps_info & BIT(14))
4644 pmlmepriv->num_FortyMHzIntolerant++;
4646 pmlmepriv->num_sta_no_ht++;
4650 /* mark bss info receving from nearby channel as SignalQuality 101 */
4651 if (bssid->Configuration.DSConfig != rtw_get_oper_ch23a(padapter))
4652 bssid->PhyInfo.SignalQuality = 101;
4657 void start_create_ibss23a(struct rtw_adapter* padapter)
4659 unsigned short caps;
4660 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4661 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4662 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
4663 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
4664 pmlmeinfo->bcn_interval = get_beacon_interval23a(pnetwork);
4666 /* update wireless mode */
4667 update_wireless_mode23a(padapter);
4669 /* udpate capability */
4670 caps = rtw_get_capability23a(pnetwork);
4671 update_capinfo23a(padapter, caps);
4672 if (caps&cap_IBSS) { /* adhoc master */
4673 rtl8723a_set_sec_cfg(padapter, 0xcf);
4675 /* switch channel */
4676 /* SelectChannel23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
4677 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4679 beacon_timing_control23a(padapter);
4681 /* set msr to WIFI_FW_ADHOC_STATE */
4682 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4683 Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
4686 if (send_beacon23a(padapter) == _FAIL)
4688 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("issuing beacon frame fail....\n"));
4690 report_join_res23a(padapter, -1);
4691 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4695 hw_var_set_bssid(padapter, padapter->registrypriv.dev_network.MacAddress);
4696 hw_var_set_mlme_join(padapter, 0);
4698 report_join_res23a(padapter, 1);
4699 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
4704 DBG_8723A("start_create_ibss23a, invalid cap:%x\n", caps);
4709 void start_clnt_join23a(struct rtw_adapter* padapter)
4711 unsigned short caps;
4713 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4714 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4715 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
4718 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
4719 pmlmeinfo->bcn_interval = get_beacon_interval23a(pnetwork);
4721 /* update wireless mode */
4722 update_wireless_mode23a(padapter);
4724 /* udpate capability */
4725 caps = rtw_get_capability23a(pnetwork);
4726 update_capinfo23a(padapter, caps);
4728 /* switch channel */
4729 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4731 Set_MSR23a(padapter, WIFI_FW_STATION_STATE);
4733 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ?
4736 rtl8723a_set_sec_cfg(padapter, val8);
4738 /* switch channel */
4739 /* set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
4741 /* here wait for receiving the beacon to start auth */
4742 /* and enable a timer */
4743 beacon_timeout = decide_wait_for_beacon_timeout23a(pmlmeinfo->bcn_interval);
4744 set_link_timer(pmlmeext, beacon_timeout);
4745 mod_timer(&padapter->mlmepriv.assoc_timer, jiffies +
4746 msecs_to_jiffies((REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) + beacon_timeout));
4747 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
4749 else if (caps&cap_IBSS) { /* adhoc client */
4750 Set_MSR23a(padapter, WIFI_FW_ADHOC_STATE);
4752 rtl8723a_set_sec_cfg(padapter, 0xcf);
4754 /* switch channel */
4755 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4757 beacon_timing_control23a(padapter);
4759 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4761 report_join_res23a(padapter, 1);
4765 /* DBG_8723A("marc: invalid cap:%x\n", caps); */
4770 void start_clnt_auth23a(struct rtw_adapter* padapter)
4772 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4773 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4775 del_timer_sync(&pmlmeext->link_timer);
4777 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
4778 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
4780 pmlmeinfo->auth_seq = 1;
4781 pmlmeinfo->reauth_count = 0;
4782 pmlmeinfo->reassoc_count = 0;
4783 pmlmeinfo->link_count = 0;
4784 pmlmeext->retry = 0;
4786 /* Because of AP's not receiving deauth before */
4787 /* AP may: 1)not response auth or 2)deauth us after link is complete */
4788 /* issue deauth before issuing auth to deal with the situation */
4789 /* Commented by Albert 2012/07/21 */
4790 /* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
4791 issue_deauth23a(padapter, (&pmlmeinfo->network)->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
4793 DBG_8723A_LEVEL(_drv_always_, "start auth\n");
4794 issue_auth23a(padapter, NULL, 0);
4796 set_link_timer(pmlmeext, REAUTH_TO);
4799 void start_clnt_assoc23a(struct rtw_adapter* padapter)
4801 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4802 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4804 del_timer_sync(&pmlmeext->link_timer);
4806 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
4807 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
4809 issue_assocreq23a(padapter);
4811 set_link_timer(pmlmeext, REASSOC_TO);
4814 unsigned int receive_disconnect23a(struct rtw_adapter *padapter, unsigned char *MacAddr, unsigned short reason)
4816 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4817 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4820 if (!ether_addr_equal(MacAddr, get_my_bssid23a(&pmlmeinfo->network)))
4823 DBG_8723A("%s\n", __func__);
4825 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
4827 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
4829 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4830 report_del_sta_event23a(padapter, MacAddr, reason);
4833 else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
4835 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4836 report_join_res23a(padapter, -2);
4843 static void process_80211d(struct rtw_adapter *padapter,
4844 struct wlan_bssid_ex *bssid)
4846 struct registry_priv *pregistrypriv;
4847 struct mlme_ext_priv *pmlmeext;
4848 struct rt_channel_info *chplan_new;
4852 pregistrypriv = &padapter->registrypriv;
4853 pmlmeext = &padapter->mlmeextpriv;
4855 /* Adjust channel plan by AP Country IE */
4856 if (pregistrypriv->enable80211d &&
4857 !pmlmeext->update_channel_plan_by_ap_done) {
4859 struct rt_channel_plan chplan_ap;
4860 struct rt_channel_info chplan_sta[MAX_CHANNEL_NUM];
4862 u8 fcn; /* first channel number */
4863 u8 noc; /* number of channel */
4866 ie = cfg80211_find_ie(WLAN_EID_COUNTRY,
4867 bssid->IEs + _FIXED_IE_LENGTH_,
4868 bssid->IELength - _FIXED_IE_LENGTH_);
4869 if (!ie || ie[1] < IEEE80211_COUNTRY_IE_MIN_LEN)
4876 memcpy(country, p, 3);
4880 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
4881 ("%s: 802.11d country =%s\n", __func__, country));
4884 while ((ie - p) >= 3) {
4889 for (j = 0; j < noc; j++) {
4891 channel = fcn + j; /* 2.4 GHz */
4893 channel = fcn + j * 4; /* 5 GHz */
4895 chplan_ap.Channel[i++] = channel;
4900 memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
4901 memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
4902 chplan_new = pmlmeext->channel_set;
4905 if (pregistrypriv->wireless_mode & WIRELESS_11G) {
4907 if (i == MAX_CHANNEL_NUM ||
4908 chplan_sta[i].ChannelNum == 0 ||
4909 chplan_sta[i].ChannelNum > 14)
4912 if (j == chplan_ap.Len ||
4913 chplan_ap.Channel[j] > 14)
4916 if (chplan_sta[i].ChannelNum ==
4917 chplan_ap.Channel[j]) {
4918 chplan_new[k].ChannelNum =
4919 chplan_ap.Channel[j];
4920 chplan_new[k].ScanType = SCAN_ACTIVE;
4924 } else if (chplan_sta[i].ChannelNum <
4925 chplan_ap.Channel[j]) {
4926 chplan_new[k].ChannelNum =
4927 chplan_sta[i].ChannelNum;
4928 chplan_new[k].ScanType =
4932 } else if (chplan_sta[i].ChannelNum >
4933 chplan_ap.Channel[j]) {
4934 chplan_new[k].ChannelNum =
4935 chplan_ap.Channel[j];
4936 chplan_new[k].ScanType =
4943 /* change AP not support channel to Passive scan */
4944 while (i < MAX_CHANNEL_NUM &&
4945 chplan_sta[i].ChannelNum != 0 &&
4946 chplan_sta[i].ChannelNum <= 14) {
4947 chplan_new[k].ChannelNum =
4948 chplan_sta[i].ChannelNum;
4949 chplan_new[k].ScanType = SCAN_PASSIVE;
4954 /* add channel AP supported */
4955 while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14){
4956 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4957 chplan_new[k].ScanType = SCAN_ACTIVE;
4962 /* keep original STA 2.4G channel plan */
4963 while (i < MAX_CHANNEL_NUM &&
4964 chplan_sta[i].ChannelNum != 0 &&
4965 chplan_sta[i].ChannelNum <= 14) {
4966 chplan_new[k].ChannelNum =
4967 chplan_sta[i].ChannelNum;
4968 chplan_new[k].ScanType = chplan_sta[i].ScanType;
4973 /* skip AP 2.4G channel plan */
4974 while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14)
4978 if (pregistrypriv->wireless_mode & WIRELESS_11A) {
4980 if (i == MAX_CHANNEL_NUM ||
4981 chplan_sta[i].ChannelNum == 0)
4984 if (j == chplan_ap.Len ||
4985 chplan_ap.Channel[j] == 0)
4988 if (chplan_sta[i].ChannelNum ==
4989 chplan_ap.Channel[j]) {
4990 chplan_new[k].ChannelNum =
4991 chplan_ap.Channel[j];
4992 chplan_new[k].ScanType = SCAN_ACTIVE;
4996 } else if (chplan_sta[i].ChannelNum <
4997 chplan_ap.Channel[j]) {
4998 chplan_new[k].ChannelNum =
4999 chplan_sta[i].ChannelNum;
5000 chplan_new[k].ScanType = SCAN_PASSIVE;
5003 } else if (chplan_sta[i].ChannelNum >
5004 chplan_ap.Channel[j]) {
5005 chplan_new[k].ChannelNum =
5006 chplan_ap.Channel[j];
5007 chplan_new[k].ScanType = SCAN_ACTIVE;
5013 /* change AP not support channel to Passive scan */
5014 while (i < MAX_CHANNEL_NUM &&
5015 chplan_sta[i].ChannelNum != 0) {
5016 chplan_new[k].ChannelNum =
5017 chplan_sta[i].ChannelNum;
5018 chplan_new[k].ScanType = SCAN_PASSIVE;
5023 /* add channel AP supported */
5024 while (j < chplan_ap.Len && chplan_ap.Channel[j] != 0) {
5025 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
5026 chplan_new[k].ScanType = SCAN_ACTIVE;
5031 /* keep original STA 5G channel plan */
5032 while (i < MAX_CHANNEL_NUM &&
5033 chplan_sta[i].ChannelNum != 0) {
5034 chplan_new[k].ChannelNum =
5035 chplan_sta[i].ChannelNum;
5036 chplan_new[k].ScanType = chplan_sta[i].ScanType;
5041 pmlmeext->update_channel_plan_by_ap_done = 1;
5044 /* If channel is used by AP, set channel scan type to active */
5045 channel = bssid->Configuration.DSConfig;
5046 chplan_new = pmlmeext->channel_set;
5048 while (i < MAX_CHANNEL_NUM && chplan_new[i].ChannelNum != 0) {
5049 if (chplan_new[i].ChannelNum == channel) {
5050 if (chplan_new[i].ScanType == SCAN_PASSIVE) {
5051 /* 5G Bnad 2, 3 (DFS) doesn't change
5053 if (channel >= 52 && channel <= 144)
5056 chplan_new[i].ScanType = SCAN_ACTIVE;
5057 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
5058 ("%s: change channel %d scan type "
5059 "from passive to active\n",
5060 __func__, channel));
5068 /****************************************************************************
5070 Following are the functions to report events
5072 *****************************************************************************/
5074 void report_survey_event23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
5076 struct cmd_obj *pcmd_obj;
5079 struct survey_event *psurvey_evt;
5080 struct C2HEvent_Header *pc2h_evt_hdr;
5081 struct mlme_ext_priv *pmlmeext;
5082 struct cmd_priv *pcmdpriv;
5087 pmlmeext = &padapter->mlmeextpriv;
5088 pcmdpriv = &padapter->cmdpriv;
5090 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5095 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
5096 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5102 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5103 pcmd_obj->cmdsz = cmdsz;
5104 pcmd_obj->parmbuf = pevtcmd;
5106 pcmd_obj->rsp = NULL;
5107 pcmd_obj->rspsz = 0;
5109 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5110 pc2h_evt_hdr->len = sizeof(struct survey_event);
5111 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
5112 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5114 psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5116 if (collect_bss_info23a(padapter, precv_frame, &psurvey_evt->bss) == _FAIL) {
5122 process_80211d(padapter, &psurvey_evt->bss);
5124 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5126 pmlmeext->sitesurvey_res.bss_cnt++;
5131 void report_surveydone_event23a(struct rtw_adapter *padapter)
5133 struct cmd_obj *pcmd_obj;
5136 struct surveydone_event *psurveydone_evt;
5137 struct C2HEvent_Header *pc2h_evt_hdr;
5138 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5139 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5141 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5146 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
5147 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5153 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5154 pcmd_obj->cmdsz = cmdsz;
5155 pcmd_obj->parmbuf = pevtcmd;
5157 pcmd_obj->rsp = NULL;
5158 pcmd_obj->rspsz = 0;
5160 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5161 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
5162 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
5163 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5165 psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5166 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
5168 DBG_8723A("survey done event(%x)\n", psurveydone_evt->bss_cnt);
5170 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5175 void report_join_res23a(struct rtw_adapter *padapter, int res)
5177 struct cmd_obj *pcmd_obj;
5180 struct joinbss_event *pjoinbss_evt;
5181 struct C2HEvent_Header *pc2h_evt_hdr;
5182 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5183 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5184 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5186 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5191 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
5192 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5198 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5199 pcmd_obj->cmdsz = cmdsz;
5200 pcmd_obj->parmbuf = pevtcmd;
5202 pcmd_obj->rsp = NULL;
5203 pcmd_obj->rspsz = 0;
5205 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5206 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
5207 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
5208 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5210 pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5211 memcpy((unsigned char *)&pjoinbss_evt->network.network,
5212 &pmlmeinfo->network, sizeof(struct wlan_bssid_ex));
5213 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
5215 DBG_8723A("report_join_res23a(%d)\n", res);
5217 rtw_joinbss_event_prehandle23a(padapter, (u8 *)&pjoinbss_evt->network);
5219 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5224 void report_del_sta_event23a(struct rtw_adapter *padapter, unsigned char* MacAddr, unsigned short reason)
5226 struct cmd_obj *pcmd_obj;
5229 struct sta_info *psta;
5231 struct stadel_event *pdel_sta_evt;
5232 struct C2HEvent_Header *pc2h_evt_hdr;
5233 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5234 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5236 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5241 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
5242 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5248 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5249 pcmd_obj->cmdsz = cmdsz;
5250 pcmd_obj->parmbuf = pevtcmd;
5252 pcmd_obj->rsp = NULL;
5253 pcmd_obj->rspsz = 0;
5255 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5256 pc2h_evt_hdr->len = sizeof(struct stadel_event);
5257 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
5258 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5260 pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5261 ether_addr_copy((unsigned char *)&pdel_sta_evt->macaddr, MacAddr);
5262 memcpy((unsigned char *)pdel_sta_evt->rsvd, (unsigned char *)&reason,
5265 psta = rtw_get_stainfo23a(&padapter->stapriv, MacAddr);
5267 mac_id = (int)psta->mac_id;
5271 pdel_sta_evt->mac_id = mac_id;
5273 DBG_8723A("report_del_sta_event23a: delete STA, mac_id =%d\n", mac_id);
5275 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5280 void report_add_sta_event23a(struct rtw_adapter *padapter, unsigned char* MacAddr, int cam_idx)
5282 struct cmd_obj *pcmd_obj;
5285 struct stassoc_event *padd_sta_evt;
5286 struct C2HEvent_Header *pc2h_evt_hdr;
5287 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5288 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5290 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5295 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
5296 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5302 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5303 pcmd_obj->cmdsz = cmdsz;
5304 pcmd_obj->parmbuf = pevtcmd;
5306 pcmd_obj->rsp = NULL;
5307 pcmd_obj->rspsz = 0;
5309 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5310 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
5311 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
5312 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5314 padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5315 ether_addr_copy((unsigned char *)&padd_sta_evt->macaddr, MacAddr);
5316 padd_sta_evt->cam_id = cam_idx;
5318 DBG_8723A("report_add_sta_event23a: add STA\n");
5320 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5325 /****************************************************************************
5327 Following are the event callback functions
5329 *****************************************************************************/
5331 /* for sta/adhoc mode */
5332 void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta)
5334 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5335 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5336 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5339 VCS_update23a(padapter, psta);
5342 if (pmlmepriv->htpriv.ht_option)
5344 psta->htpriv.ht_option = true;
5346 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
5348 if (support_short_GI23a(padapter, &pmlmeinfo->HT_caps))
5349 psta->htpriv.sgi = true;
5351 psta->qos_option = true;
5356 psta->htpriv.ht_option = false;
5358 psta->htpriv.ampdu_enable = false;
5360 psta->htpriv.sgi = false;
5361 psta->qos_option = false;
5364 psta->htpriv.bwmode = pmlmeext->cur_bwmode;
5365 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
5367 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
5368 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
5371 if (pmlmepriv->qospriv.qos_option)
5372 psta->qos_option = true;
5374 psta->state = _FW_LINKED;
5377 void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter, int join_res)
5379 struct sta_info *psta, *psta_bmc;
5380 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5381 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5382 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
5383 struct sta_priv *pstapriv = &padapter->stapriv;
5386 hw_var_set_mlme_join(padapter, 1);
5387 hw_var_set_bssid(padapter, null_addr);
5389 /* restore to initial setting. */
5390 update_tx_basic_rate23a(padapter,
5391 padapter->registrypriv.wireless_mode);
5393 goto exit_mlmeext_joinbss_event_callback23a;
5396 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
5399 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
5402 pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc;
5403 update_bmc_sta_support_rate23a(padapter, psta_bmc->mac_id);
5404 Update_RA_Entry23a(padapter, psta_bmc);
5408 /* turn on dynamic functions */
5409 rtl8723a_odm_support_ability_set(padapter, DYNAMIC_ALL_FUNC_ENABLE);
5411 /* update IOT-releated issue */
5412 update_IOT_info23a(padapter);
5414 HalSetBrateCfg23a(padapter, cur_network->SupportedRates);
5417 rtl8723a_set_beacon_interval(padapter, pmlmeinfo->bcn_interval);
5419 /* udpate capability */
5420 update_capinfo23a(padapter, pmlmeinfo->capability);
5422 /* WMM, Update EDCA param */
5423 WMMOnAssocRsp23a(padapter);
5426 HTOnAssocRsp23a(padapter);
5428 /* Set cur_channel&cur_bwmode&cur_ch_offset */
5429 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5431 psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
5432 if (psta) /* only for infra. mode */
5434 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5436 /* DBG_8723A("set_sta_rate23a\n"); */
5438 psta->wireless_mode = pmlmeext->cur_wireless_mode;
5440 /* set per sta rate after updating HT cap. */
5441 set_sta_rate23a(padapter, psta);
5444 hw_var_set_mlme_join(padapter, 2);
5446 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
5447 /* correcting TSF */
5448 rtw_correct_TSF(padapter);
5450 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5453 rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_CONNECT, 0);
5455 exit_mlmeext_joinbss_event_callback23a:
5456 DBG_8723A("=>%s\n", __func__);
5459 void mlmeext_sta_add_event_callback23a(struct rtw_adapter *padapter, struct sta_info *psta)
5461 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5462 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5464 DBG_8723A("%s\n", __func__);
5466 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
5468 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)/* adhoc master or sta_count>1 */
5472 else/* adhoc client */
5474 /* correcting TSF */
5475 rtw_correct_TSF(padapter);
5478 if (send_beacon23a(padapter) == _FAIL)
5480 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
5482 pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
5487 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
5491 hw_var_set_mlme_join(padapter, 2);
5494 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5496 /* rate radaptive */
5497 Update_RA_Entry23a(padapter, psta);
5499 /* update adhoc sta_info */
5500 update_sta_info23a(padapter, psta);
5503 void mlmeext_sta_del_event_callback23a(struct rtw_adapter *padapter)
5505 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5506 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5508 if (is_client_associated_to_ap23a(padapter) || is_IBSS_empty23a(padapter))
5510 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
5512 hw_var_set_mlme_disconnect(padapter);
5513 hw_var_set_bssid(padapter, null_addr);
5515 /* restore to initial setting. */
5516 update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
5518 /* switch to the 20M Hz mode after disconnect */
5519 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5520 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5522 /* SelectChannel23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
5523 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5525 flush_all_cam_entry23a(padapter);
5527 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5529 /* set MSR to no link state -> infra. mode */
5530 Set_MSR23a(padapter, _HW_STATE_STATION_);
5532 del_timer_sync(&pmlmeext->link_timer);
5536 static u8 chk_ap_is_alive(struct rtw_adapter *padapter, struct sta_info *psta)
5540 if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)) &&
5541 sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) &&
5542 sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
5547 sta_update_last_rx_pkts(psta);
5551 void linked_status_chk23a(struct rtw_adapter *padapter)
5554 struct sta_info *psta;
5555 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5556 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5557 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5558 struct sta_priv *pstapriv = &padapter->stapriv;
5560 rtw_hal_sreset_linked_status_check23a(padapter);
5562 if (is_client_associated_to_ap23a(padapter))
5564 /* linked infrastructure client mode */
5566 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
5571 if ((psta = rtw_get_stainfo23a(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
5573 bool is_p2p_enable = false;
5575 if (chk_ap_is_alive(padapter, psta) == false)
5578 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
5581 if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
5582 u8 backup_oper_channel = 0;
5584 /* switch to correct channel of current network before issue keep-alive frames */
5585 if (rtw_get_oper_ch23a(padapter) != pmlmeext->cur_channel) {
5586 backup_oper_channel = rtw_get_oper_ch23a(padapter);
5587 SelectChannel23a(padapter, pmlmeext->cur_channel);
5590 if (rx_chk != _SUCCESS)
5591 issue_probereq23a_ex23a(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1);
5593 if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) {
5594 tx_chk = issue_nulldata23a(padapter, psta->hwaddr, 0, 3, 1);
5595 /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
5596 if (tx_chk == _SUCCESS && !is_p2p_enable)
5600 /* back to the original operation channel */
5601 if (backup_oper_channel>0)
5602 SelectChannel23a(padapter, backup_oper_channel);
5605 if (rx_chk != _SUCCESS) {
5606 if (pmlmeext->retry == 0) {
5607 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5608 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5609 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5613 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf)
5614 tx_chk = issue_nulldata23a(padapter, NULL, 0, 1, 0);
5617 if (rx_chk == _FAIL) {
5619 if (pmlmeext->retry > rx_chk_limit) {
5620 DBG_8723A_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
5621 FUNC_ADPT_ARG(padapter));
5622 receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress,
5623 WLAN_REASON_EXPIRATION_CHK);
5627 pmlmeext->retry = 0;
5630 if (tx_chk == _FAIL) {
5631 pmlmeinfo->link_count &= 0xf;
5633 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
5634 pmlmeinfo->link_count = 0;
5637 } /* end of if ((psta = rtw_get_stainfo23a(pstapriv, passoc_res->network.MacAddress)) != NULL) */
5639 else if (is_client_associated_to_ibss23a(padapter))
5641 /* linked IBSS mode */
5642 /* for each assoc list entry to check the rx pkt counter */
5643 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
5645 if (pmlmeinfo->FW_sta_info[i].status == 1)
5647 psta = pmlmeinfo->FW_sta_info[i].psta;
5649 if (NULL == psta) continue;
5651 if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta))
5654 if (pmlmeinfo->FW_sta_info[i].retry<3)
5656 pmlmeinfo->FW_sta_info[i].retry++;
5660 pmlmeinfo->FW_sta_info[i].retry = 0;
5661 pmlmeinfo->FW_sta_info[i].status = 0;
5662 report_del_sta_event23a(padapter, psta->hwaddr,
5663 65535/* indicate disconnect caused by no rx */
5669 pmlmeinfo->FW_sta_info[i].retry = 0;
5670 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
5675 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5680 static void survey_timer_hdl(unsigned long data)
5682 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
5683 struct cmd_obj *ph2c;
5684 struct sitesurvey_parm *psurveyPara;
5685 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5686 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5688 /* issue rtw_sitesurvey_cmd23a */
5689 if (pmlmeext->sitesurvey_res.state > SCAN_START) {
5690 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
5691 pmlmeext->sitesurvey_res.channel_idx++;
5693 if (pmlmeext->scan_abort == true) {
5694 pmlmeext->sitesurvey_res.channel_idx =
5695 pmlmeext->sitesurvey_res.ch_num;
5696 DBG_8723A("%s idx:%d\n", __func__,
5697 pmlmeext->sitesurvey_res.channel_idx);
5699 pmlmeext->scan_abort = false;/* reset */
5702 ph2c = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5705 goto exit_survey_timer_hdl;
5707 psurveyPara = (struct sitesurvey_parm*)
5708 kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC);
5711 goto exit_survey_timer_hdl;
5714 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
5715 rtw_enqueue_cmd23a(pcmdpriv, ph2c);
5718 exit_survey_timer_hdl:
5722 static void link_timer_hdl(unsigned long data)
5724 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
5725 /* static unsigned int rx_pkt = 0; */
5726 /* static u64 tx_cnt = 0; */
5727 /* struct xmit_priv *pxmitpriv = &padapter->xmitpriv; */
5728 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5729 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5730 /* struct sta_priv *pstapriv = &padapter->stapriv; */
5732 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
5734 DBG_8723A("link_timer_hdl:no beacon while connecting\n");
5735 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5736 report_join_res23a(padapter, -3);
5738 else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE)
5741 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT)
5743 /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
5745 pmlmeinfo->state = 0;
5746 report_join_res23a(padapter, -1);
5751 /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
5752 /* pmlmeinfo->reauth_count = 0; */
5756 DBG_8723A("link_timer_hdl: auth timeout and try again\n");
5757 pmlmeinfo->auth_seq = 1;
5758 issue_auth23a(padapter, NULL, 0);
5759 set_link_timer(pmlmeext, REAUTH_TO);
5761 else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)
5763 /* re-assoc timer */
5764 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT)
5766 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5767 report_join_res23a(padapter, -2);
5771 DBG_8723A("link_timer_hdl: assoc timeout and try again\n");
5772 issue_assocreq23a(padapter);
5773 set_link_timer(pmlmeext, REASSOC_TO);
5779 static void addba_timer_hdl(unsigned long data)
5781 struct sta_info *psta = (struct sta_info *)data;
5782 struct ht_priv *phtpriv;
5787 phtpriv = &psta->htpriv;
5789 if ((phtpriv->ht_option == true) && (phtpriv->ampdu_enable == true))
5791 if (phtpriv->candidate_tid_bitmap)
5792 phtpriv->candidate_tid_bitmap = 0x0;
5797 void init_addba_retry_timer23a(struct sta_info *psta)
5799 setup_timer(&psta->addba_retry_timer, addba_timer_hdl,
5800 (unsigned long)psta);
5803 void init_mlme_ext_timer23a(struct rtw_adapter *padapter)
5805 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5807 setup_timer(&pmlmeext->survey_timer, survey_timer_hdl,
5808 (unsigned long)padapter);
5810 setup_timer(&pmlmeext->link_timer, link_timer_hdl,
5811 (unsigned long)padapter);
5814 u8 NULL_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5819 u8 setopmode_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5822 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5823 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5824 const struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
5826 if (psetop->mode == Ndis802_11APMode) {
5827 pmlmeinfo->state = WIFI_FW_AP_STATE;
5828 type = _HW_STATE_AP_;
5829 } else if (psetop->mode == Ndis802_11Infrastructure) {
5830 pmlmeinfo->state &= ~(BIT(0)|BIT(1));/* clear state */
5831 pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */
5832 type = _HW_STATE_STATION_;
5833 } else if (psetop->mode == Ndis802_11IBSS)
5834 type = _HW_STATE_ADHOC_;
5836 type = _HW_STATE_NOLINK_;
5838 hw_var_set_opmode(padapter, type);
5839 /* Set_NETYPE0_MSR(padapter, type); */
5844 u8 createbss_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5846 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5847 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5848 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5849 const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
5850 /* u32 initialgain; */
5852 if (pparm->InfrastructureMode == Ndis802_11APMode) {
5853 #ifdef CONFIG_8723AU_AP_MODE
5855 if (pmlmeinfo->state == WIFI_FW_AP_STATE)
5863 /* below is for ad-hoc master */
5864 if (pparm->InfrastructureMode == Ndis802_11IBSS) {
5865 rtw_joinbss_reset23a(padapter);
5867 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5868 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5869 pmlmeinfo->ERP_enable = 0;
5870 pmlmeinfo->WMM_enable = 0;
5871 pmlmeinfo->HT_enable = 0;
5872 pmlmeinfo->HT_caps_enable = 0;
5873 pmlmeinfo->HT_info_enable = 0;
5874 pmlmeinfo->agg_enable_bitmap = 0;
5875 pmlmeinfo->candidate_tid_bitmap = 0;
5877 /* disable dynamic functions, such as high power, DIG */
5878 rtl8723a_odm_support_ability_backup(padapter);
5880 rtl8723a_odm_support_ability_clr(padapter,
5881 DYNAMIC_FUNC_DISABLE);
5883 /* cancel link timer */
5884 del_timer_sync(&pmlmeext->link_timer);
5887 flush_all_cam_entry23a(padapter);
5889 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
5890 return H2C_PARAMETERS_ERROR;
5892 memcpy(pnetwork, pparm, sizeof(struct wlan_bssid_ex));
5894 start_create_ibss23a(padapter);
5900 u8 join_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5902 struct ndis_802_11_var_ies * pIE;
5903 struct registry_priv *pregpriv = &padapter->registrypriv;
5904 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5905 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5906 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5907 const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
5908 struct HT_info_element *pht_info;
5910 /* u32 initialgain; */
5913 /* check already connecting to AP or not */
5914 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
5916 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
5917 issue_deauth23a_ex23a(padapter, pnetwork->MacAddress,
5918 WLAN_REASON_DEAUTH_LEAVING, 5, 100);
5920 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5923 flush_all_cam_entry23a(padapter);
5925 del_timer_sync(&pmlmeext->link_timer);
5927 /* set MSR to nolink -> infra. mode */
5928 /* Set_MSR23a(padapter, _HW_STATE_NOLINK_); */
5929 Set_MSR23a(padapter, _HW_STATE_STATION_);
5931 hw_var_set_mlme_disconnect(padapter);
5934 rtw_joinbss_reset23a(padapter);
5936 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5937 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5938 pmlmeinfo->ERP_enable = 0;
5939 pmlmeinfo->WMM_enable = 0;
5940 pmlmeinfo->HT_enable = 0;
5941 pmlmeinfo->HT_caps_enable = 0;
5942 pmlmeinfo->HT_info_enable = 0;
5943 pmlmeinfo->agg_enable_bitmap = 0;
5944 pmlmeinfo->candidate_tid_bitmap = 0;
5945 pmlmeinfo->bwmode_updated = false;
5946 /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
5948 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
5949 return H2C_PARAMETERS_ERROR;
5951 memcpy(pnetwork, pbuf, sizeof(struct wlan_bssid_ex));
5953 /* Check AP vendor to move rtw_joinbss_cmd23a() */
5954 /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP23a(pnetwork->IEs,
5955 pnetwork->IELength); */
5957 for (i = sizeof(struct ndis_802_11_fixed_ies); i < pnetwork->IELength;)
5959 pIE = (struct ndis_802_11_var_ies *)(pnetwork->IEs + i);
5961 switch (pIE->ElementID)
5963 case WLAN_EID_VENDOR_SPECIFIC:/* Get WMM IE. */
5964 if (!memcmp(pIE->data, WMM_OUI23A, 4))
5965 pmlmeinfo->WMM_enable = 1;
5968 case WLAN_EID_HT_CAPABILITY: /* Get HT Cap IE. */
5969 pmlmeinfo->HT_caps_enable = 1;
5972 case WLAN_EID_HT_OPERATION: /* Get HT Info IE. */
5973 pmlmeinfo->HT_info_enable = 1;
5975 /* spec case only for cisco's ap because cisco's ap
5976 * issue assoc rsp using mcs rate @40MHz or @20MHz */
5977 pht_info = (struct HT_info_element *)(pIE->data);
5979 if ((pregpriv->cbw40_enable) &&
5980 (pht_info->infos[0] & BIT(2))) {
5981 /* switch to the 40M Hz mode according to AP */
5982 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
5983 switch (pht_info->infos[0] & 0x3)
5986 pmlmeext->cur_ch_offset =
5987 HAL_PRIME_CHNL_OFFSET_LOWER;
5991 pmlmeext->cur_ch_offset =
5992 HAL_PRIME_CHNL_OFFSET_UPPER;
5996 pmlmeext->cur_ch_offset =
5997 HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6001 DBG_8723A("set ch/bw before connected\n");
6009 i += (pIE->Length + 2);
6012 hw_var_set_bssid(padapter, pmlmeinfo->network.MacAddress);
6013 hw_var_set_mlme_join(padapter, 0);
6015 /* cancel link timer */
6016 del_timer_sync(&pmlmeext->link_timer);
6018 start_clnt_join23a(padapter);
6023 u8 disconnect_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6025 const struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
6026 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6027 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6028 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
6030 if (is_client_associated_to_ap23a(padapter))
6032 issue_deauth23a_ex23a(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
6035 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
6037 /* pmlmeinfo->state = WIFI_FW_NULL_STATE; */
6039 hw_var_set_mlme_disconnect(padapter);
6040 hw_var_set_bssid(padapter, null_addr);
6042 /* restore to initial setting. */
6043 update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
6045 if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
6046 ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
6047 rtl8723a_set_bcn_func(padapter, 0); /* Stop BCN */
6049 /* set MSR to no link state -> infra. mode */
6050 Set_MSR23a(padapter, _HW_STATE_STATION_);
6052 pmlmeinfo->state = WIFI_FW_NULL_STATE;
6054 /* switch to the 20M Hz mode after disconnect */
6055 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
6056 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6058 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
6060 flush_all_cam_entry23a(padapter);
6062 del_timer_sync(&pmlmeext->link_timer);
6064 rtw_free_uc_swdec_pending_queue23a(padapter);
6070 rtw_scan_ch_decision(struct rtw_adapter *padapter,
6071 struct rtw_ieee80211_channel *out, u32 out_num,
6072 const struct rtw_ieee80211_channel *in, u32 in_num)
6075 int scan_ch_num = 0;
6077 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6079 /* clear out first */
6080 memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
6082 /* acquire channels from in */
6084 for (i = 0;i<in_num;i++) {
6086 DBG_8723A(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
6087 if (in[i].hw_value && !(in[i].flags & IEEE80211_CHAN_DISABLED)
6088 && (set_idx = rtw_ch_set_search_ch23a(pmlmeext->channel_set, in[i].hw_value)) >= 0
6091 memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
6093 if (pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
6094 out[j].flags &= IEEE80211_CHAN_NO_IR;
6102 /* if out is empty, use channel_set as default */
6104 for (i = 0;i<pmlmeext->max_chan_nums;i++) {
6105 out[i].hw_value = pmlmeext->channel_set[i].ChannelNum;
6107 if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
6108 out[i].flags &= IEEE80211_CHAN_NO_IR;
6114 if (padapter->setband == GHZ_24) { /* 2.4G */
6115 for (i = 0; i < j ; i++) {
6116 if (out[i].hw_value > 35)
6118 sizeof(struct rtw_ieee80211_channel));
6123 } else if (padapter->setband == GHZ_50) { /* 5G */
6124 for (i = 0; i < j ; i++) {
6125 if (out[i].hw_value > 35) {
6126 memcpy(&out[scan_ch_num++], &out[i], sizeof(struct rtw_ieee80211_channel));
6136 u8 sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6138 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6139 const struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
6140 u8 bdelayscan = false;
6144 if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
6145 pmlmeext->sitesurvey_res.state = SCAN_START;
6146 pmlmeext->sitesurvey_res.bss_cnt = 0;
6147 pmlmeext->sitesurvey_res.channel_idx = 0;
6149 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
6150 if (pparm->ssid[i].ssid_len) {
6151 memcpy(pmlmeext->sitesurvey_res.ssid[i].ssid,
6152 pparm->ssid[i].ssid, IW_ESSID_MAX_SIZE);
6153 pmlmeext->sitesurvey_res.ssid[i].ssid_len =
6154 pparm->ssid[i].ssid_len;
6156 pmlmeext->sitesurvey_res.ssid[i].ssid_len = 0;
6160 pmlmeext->sitesurvey_res.ch_num =
6161 rtw_scan_ch_decision(padapter,
6162 pmlmeext->sitesurvey_res.ch,
6163 RTW_CHANNEL_SCAN_AMOUNT,
6164 pparm->ch, pparm->ch_num);
6166 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
6168 /* issue null data if associating to the AP */
6169 if (is_client_associated_to_ap23a(padapter)) {
6170 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
6172 /* switch to correct channel of current network
6173 before issue keep-alive frames */
6174 if (rtw_get_oper_ch23a(padapter) != pmlmeext->cur_channel)
6175 SelectChannel23a(padapter, pmlmeext->cur_channel);
6177 issue_nulldata23a(padapter, NULL, 1, 3, 500);
6183 /* delay 50ms to protect nulldata(1). */
6184 set_survey_timer(pmlmeext, 50);
6189 if ((pmlmeext->sitesurvey_res.state == SCAN_START) ||
6190 (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) {
6191 /* disable dynamic functions, such as high power, DIG */
6192 rtl8723a_odm_support_ability_backup(padapter);
6193 rtl8723a_odm_support_ability_clr(padapter,
6194 DYNAMIC_FUNC_DISABLE);
6196 /* config the initial gain under scaning, need to
6197 write the BB registers */
6198 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == true)
6203 rtl8723a_set_initial_gain(padapter, initialgain);
6205 /* set MSR to no link state */
6206 Set_MSR23a(padapter, _HW_STATE_NOLINK_);
6208 rtl8723a_mlme_sitesurvey(padapter, 1);
6210 pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
6213 site_survey23a(padapter);
6218 u8 setauth_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6220 const struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
6221 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6222 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6224 if (pparm->mode < 4)
6226 pmlmeinfo->auth_algo = pparm->mode;
6232 u8 setkey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6234 unsigned short ctrl;
6235 const struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
6236 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6237 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6238 unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
6240 /* main tx key for wep. */
6242 pmlmeinfo->key_index = pparm->keyid;
6245 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
6247 DBG_8723A_LEVEL(_drv_always_, "set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) "
6248 "keyid:%d\n", pparm->algorithm, pparm->keyid);
6249 rtl8723a_cam_write(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
6251 /* allow multicast packets to driver */
6252 rtl8723a_on_rcr_am(padapter);
6257 u8 set_stakey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6260 u8 cam_id;/* cam_entry */
6261 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6262 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6263 const struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
6266 /* 0~3 for default key */
6268 /* for concurrent mode (ap+sta): */
6269 /* default key is disable, using sw encrypt/decrypt */
6270 /* cam_entry = 4 for sta mode (macid = 0) */
6271 /* cam_entry(macid+3) = 5 ~ N for ap mode (aid = 1~N, macid = 2 ~N) */
6273 /* for concurrent mode (sta+sta): */
6274 /* default key is disable, using sw encrypt/decrypt */
6275 /* cam_entry = 4 mapping to macid = 0 */
6276 /* cam_entry = 5 mapping to macid = 2 */
6280 DBG_8723A_LEVEL(_drv_always_, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) camid:%d\n",
6281 pparm->algorithm, cam_id);
6282 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
6285 struct sta_info *psta;
6286 struct sta_priv *pstapriv = &padapter->stapriv;
6288 if (pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */
6290 clear_cam_entry23a(padapter, pparm->id);
6291 return H2C_SUCCESS_RSP;
6294 psta = rtw_get_stainfo23a(pstapriv, pparm->addr);
6297 ctrl = (BIT(15) | ((pparm->algorithm) << 2));
6299 DBG_8723A("r871x_set_stakey_hdl23a(): enc_algorithm =%d\n", pparm->algorithm);
6301 if ((psta->mac_id<1) || (psta->mac_id>(NUM_STA-4)))
6303 DBG_8723A("r871x_set_stakey_hdl23a():set_stakey failed, mac_id(aid) =%d\n", psta->mac_id);
6304 return H2C_REJECTED;
6307 cam_id = (psta->mac_id + 3);/* 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */
6309 DBG_8723A("Write CAM, mac_addr =%x:%x:%x:%x:%x:%x, cam_entry =%d\n", pparm->addr[0],
6310 pparm->addr[1], pparm->addr[2], pparm->addr[3], pparm->addr[4],
6311 pparm->addr[5], cam_id);
6313 rtl8723a_cam_write(padapter, cam_id, ctrl,
6314 pparm->addr, pparm->key);
6316 return H2C_SUCCESS_RSP;
6321 DBG_8723A("r871x_set_stakey_hdl23a(): sta has been free\n");
6322 return H2C_REJECTED;
6327 /* below for sta mode */
6329 if (pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */
6331 clear_cam_entry23a(padapter, pparm->id);
6335 ctrl = BIT(15) | ((pparm->algorithm) << 2);
6337 rtl8723a_cam_write(padapter, cam_id, ctrl, pparm->addr, pparm->key);
6339 pmlmeinfo->enc_algo = pparm->algorithm;
6344 u8 add_ba_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6346 const struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
6347 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6348 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6350 struct sta_info *psta = rtw_get_stainfo23a(&padapter->stapriv, pparm->addr);
6355 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) &&
6356 (pmlmeinfo->HT_enable)) ||
6357 ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
6358 issue_action_BA23a(padapter, pparm->addr,
6359 WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
6360 mod_timer(&psta->addba_retry_timer,
6361 jiffies + msecs_to_jiffies(ADDBA_TO));
6363 psta->htpriv.candidate_tid_bitmap &= ~CHKBIT(pparm->tid);
6368 u8 set_tx_beacon_cmd23a(struct rtw_adapter* padapter)
6370 struct cmd_obj *ph2c;
6371 struct Tx_Beacon_param *ptxBeacon_parm;
6372 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
6373 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6374 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6380 ph2c = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
6386 ptxBeacon_parm = (struct Tx_Beacon_param *)
6387 kzalloc(sizeof(struct Tx_Beacon_param), GFP_ATOMIC);
6388 if (!ptxBeacon_parm) {
6394 memcpy(&ptxBeacon_parm->network, &pmlmeinfo->network,
6395 sizeof(struct wlan_bssid_ex));
6397 len_diff = update_hidden_ssid(
6398 ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_,
6399 ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_,
6400 pmlmeinfo->hidden_ssid_mode);
6401 ptxBeacon_parm->network.IELength += len_diff;
6403 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
6405 res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
6414 u8 mlme_evt_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6416 u8 evt_code, evt_seq;
6418 const uint *peventbuf;
6419 void (*event_callback)(struct rtw_adapter *dev, u8 *pbuf);
6420 struct evt_priv *pevt_priv = &padapter->evtpriv;
6422 peventbuf = (uint*)pbuf;
6423 evt_sz = (u16)(*peventbuf&0xffff);
6424 evt_seq = (u8)((*peventbuf>>24)&0x7f);
6425 evt_code = (u8)((*peventbuf>>16)&0xff);
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 atomic_inc(&pevt_priv->event_seq);
6446 event_callback = wlanevents[evt_code].event_callback;
6447 event_callback(padapter, (u8*)peventbuf);
6449 pevt_priv->evt_done_cnt++;
6457 u8 h2c_msg_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6460 return H2C_PARAMETERS_ERROR;
6465 u8 tx_beacon_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6467 if (send_beacon23a(padapter) == _FAIL)
6469 DBG_8723A("issue_beacon23a, fail!\n");
6470 return H2C_PARAMETERS_ERROR;
6472 #ifdef CONFIG_8723AU_AP_MODE
6473 else /* tx bc/mc frames after update TIM */
6475 struct sta_info *psta_bmc;
6476 struct list_head *plist, *phead, *ptmp;
6477 struct xmit_frame *pxmitframe;
6478 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6479 struct sta_priv *pstapriv = &padapter->stapriv;
6481 /* for BC/MC Frames */
6482 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
6486 if ((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0))
6488 msleep(10);/* 10ms, ATIM(HIQ) Windows */
6489 /* spin_lock_bh(&psta_bmc->sleep_q.lock); */
6490 spin_lock_bh(&pxmitpriv->lock);
6492 phead = get_list_head(&psta_bmc->sleep_q);
6494 list_for_each_safe(plist, ptmp, phead) {
6495 pxmitframe = container_of(plist,
6499 list_del_init(&pxmitframe->list);
6501 psta_bmc->sleepq_len--;
6502 if (psta_bmc->sleepq_len>0)
6503 pxmitframe->attrib.mdata = 1;
6505 pxmitframe->attrib.mdata = 0;
6507 pxmitframe->attrib.triggered = 1;
6509 pxmitframe->attrib.qsel = 0x11;/* HIQ */
6511 rtw_hal_xmit23aframe_enqueue(padapter, pxmitframe);
6514 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
6515 spin_unlock_bh(&pxmitpriv->lock);
6524 u8 set_ch_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6526 const struct set_ch_parm *set_ch_parm;
6527 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6530 return H2C_PARAMETERS_ERROR;
6532 set_ch_parm = (struct set_ch_parm *)pbuf;
6534 DBG_8723A(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
6535 FUNC_NDEV_ARG(padapter->pnetdev),
6536 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
6538 pmlmeext->cur_channel = set_ch_parm->ch;
6539 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
6540 pmlmeext->cur_bwmode = set_ch_parm->bw;
6542 set_channel_bwmode23a(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
6547 u8 set_chplan_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6549 const struct SetChannelPlan_param *setChannelPlan_param;
6550 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6553 return H2C_PARAMETERS_ERROR;
6555 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
6557 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
6558 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
6563 u8 led_blink_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6565 struct LedBlink_param *ledBlink_param;
6568 return H2C_PARAMETERS_ERROR;
6570 ledBlink_param = (struct LedBlink_param *)pbuf;
6575 u8 set_csa_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6577 return H2C_REJECTED;
6580 /* TDLS_WRCR : write RCR DATA BIT */
6581 /* TDLS_SD_PTI : issue peer traffic indication */
6582 /* TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure */
6583 /* TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame */
6584 /* TDLS_DONE_CH_SEN: channel sensing and report candidate channel */
6585 /* TDLS_OFF_CH : first time set channel to off channel */
6586 /* TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel */
6587 /* TDLS_P_OFF_CH : periodically go to off channel */
6588 /* TDLS_P_BASE_CH : periodically go back to base channel */
6589 /* TDLS_RS_RCR : restore RCR */
6590 /* TDLS_CKALV_PH1 : check alive timer phase1 */
6591 /* TDLS_CKALV_PH2 : check alive timer phase2 */
6592 /* TDLS_FREE_STA : free tdls sta */
6593 u8 tdls_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6595 return H2C_REJECTED;