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 static unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
100 /********************************************************
102 *********************************************************/
103 unsigned char MCS_rate_2R23A[16] = {
104 0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
105 unsigned char MCS_rate_1R23A[16] = {
106 0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
108 /********************************************************
109 ChannelPlan definitions
110 *********************************************************/
112 static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
113 {{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 */
114 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
115 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
116 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
117 {{10, 11, 12, 13}, 4}, /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
118 {{}, 0}, /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */
121 static struct rt_channel_plan_5g RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
122 {{}, 0}, /* 0x00, RT_CHANNEL_DOMAIN_5G_NULL */
123 {{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 */
124 {{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 */
125 {{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 */
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}, /* 0x04, RT_CHANNEL_DOMAIN_5G_FCC1 */
127 {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9}, /* 0x05, RT_CHANNEL_DOMAIN_5G_FCC2 */
128 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13}, /* 0x06, RT_CHANNEL_DOMAIN_5G_FCC3 */
129 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12}, /* 0x07, RT_CHANNEL_DOMAIN_5G_FCC4 */
130 {{149, 153, 157, 161, 165}, 5}, /* 0x08, RT_CHANNEL_DOMAIN_5G_FCC5 */
131 {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, /* 0x09, RT_CHANNEL_DOMAIN_5G_FCC6 */
132 {{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 */
133 {{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 */
134 {{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 */
135 {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, /* 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 */
136 {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11}, /* 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 */
137 {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 15}, /* 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 */
138 {{56, 60, 64, 149, 153, 157, 161, 165}, 8}, /* 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 */
140 /* Driver self defined for old channel plan Compatible , Remember to modify if have new channel plan definition ===== */
141 {{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 */
142 {{36, 40, 44, 48}, 4}, /* 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS */
143 {{36, 40, 44, 48, 149, 153, 157, 161}, 8}, /* 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS */
146 static struct rt_channel_plan_map RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
147 /* 0x00 ~ 0x1F , Old Define ===== */
148 {0x02, 0x11}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
149 {0x02, 0x0A}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
150 {0x01, 0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
151 {0x01, 0x00}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
152 {0x01, 0x00}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
153 {0x03, 0x00}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */
154 {0x03, 0x00}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
155 {0x01, 0x09}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
156 {0x03, 0x09}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
157 {0x03, 0x00}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
158 {0x00, 0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
159 {0x02, 0x0F}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
160 {0x01, 0x08}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
161 {0x02, 0x06}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
162 {0x02, 0x0B}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
163 {0x02, 0x09}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
164 {0x01, 0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
165 {0x02, 0x05}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
166 {0x01, 0x12}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
167 {0x00, 0x04}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
168 {0x02, 0x10}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
169 {0x00, 0x12}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
170 {0x00, 0x13}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
171 {0x03, 0x12}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
172 {0x05, 0x08}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
173 {0x02, 0x08}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
174 {0x00, 0x00}, /* 0x1A, */
175 {0x00, 0x00}, /* 0x1B, */
176 {0x00, 0x00}, /* 0x1C, */
177 {0x00, 0x00}, /* 0x1D, */
178 {0x00, 0x00}, /* 0x1E, */
179 {0x05, 0x04}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
180 /* 0x20 ~ 0x7F , New Define ===== */
181 {0x00, 0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
182 {0x01, 0x00}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
183 {0x02, 0x00}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
184 {0x03, 0x00}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
185 {0x04, 0x00}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
186 {0x02, 0x04}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
187 {0x00, 0x01}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
188 {0x03, 0x0C}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
189 {0x00, 0x0B}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
190 {0x00, 0x05}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
191 {0x00, 0x00}, /* 0x2A, */
192 {0x00, 0x00}, /* 0x2B, */
193 {0x00, 0x00}, /* 0x2C, */
194 {0x00, 0x00}, /* 0x2D, */
195 {0x00, 0x00}, /* 0x2E, */
196 {0x00, 0x00}, /* 0x2F, */
197 {0x00, 0x06}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
198 {0x00, 0x07}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
199 {0x00, 0x08}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
200 {0x00, 0x09}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
201 {0x02, 0x0A}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
202 {0x00, 0x02}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
203 {0x00, 0x03}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
204 {0x03, 0x0D}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
205 {0x03, 0x0E}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
206 {0x02, 0x0F}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
207 {0x00, 0x00}, /* 0x3A, */
208 {0x00, 0x00}, /* 0x3B, */
209 {0x00, 0x00}, /* 0x3C, */
210 {0x00, 0x00}, /* 0x3D, */
211 {0x00, 0x00}, /* 0x3E, */
212 {0x00, 0x00}, /* 0x3F, */
213 {0x02, 0x10}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
214 {0x03, 0x00}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */
217 static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03, 0x02}; /* use the conbination for max channel numbers */
219 static struct fwevent wlanevents[] =
221 {0, rtw_dummy_event_callback23a}, /*0*/
229 {0, &rtw_survey_event_cb23a}, /*8*/
230 {sizeof (struct surveydone_event), &rtw_surveydone_event_callback23a}, /*9*/
232 {0, &rtw23a_joinbss_event_cb}, /*10*/
233 {sizeof(struct stassoc_event), &rtw_stassoc_event_callback23a},
234 {sizeof(struct stadel_event), &rtw_stadel_event_callback23a},
235 {0, &rtw_atimdone_event_callback23a},
236 {0, rtw_dummy_event_callback23a},
241 {0, rtw23a_fwdbg_event_callback},
245 {0, &rtw_cpwm_event_callback23a},
250 static void rtw_correct_TSF(struct rtw_adapter *padapter)
252 hw_var_set_correct_tsf(padapter);
256 rtw_update_TSF(struct mlme_ext_priv *pmlmeext, struct ieee80211_mgmt *mgmt)
258 pmlmeext->TSFValue = get_unaligned_le64(&mgmt->u.beacon.timestamp);
262 * Search the @param channel_num in given @param channel_set
263 * @ch_set: the given channel set
264 * @ch: the given channel number
266 * return the index of channel_num in channel_set, -1 if not found
268 int rtw_ch_set_search_ch23a(struct rt_channel_info *ch_set, const u32 ch)
271 for (i = 0; ch_set[i]. ChannelNum != 0; i++) {
272 if (ch == ch_set[i].ChannelNum)
276 if (i >= ch_set[i].ChannelNum)
281 /****************************************************************************
283 Following are the initialization functions for WiFi MLME
285 *****************************************************************************/
287 int init_hw_mlme_ext23a(struct rtw_adapter *padapter)
289 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
291 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
292 pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
296 static void init_mlme_ext_priv23a_value(struct rtw_adapter* padapter)
298 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
299 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
300 unsigned char mixed_datarate[NumRates] = {
301 _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
302 _9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_,
303 _48M_RATE_, _54M_RATE_, 0xff};
304 unsigned char mixed_basicrate[NumRates] = {
305 _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
306 _12M_RATE_, _24M_RATE_, 0xff,};
308 atomic_set(&pmlmeext->event_seq, 0);
309 /* reset to zero when disconnect at client mode */
310 pmlmeext->mgnt_seq = 0;
312 pmlmeext->cur_channel = padapter->registrypriv.channel;
313 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
314 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
318 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
320 memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
321 memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
323 if (pmlmeext->cur_channel > 14)
324 pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
326 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
328 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
329 pmlmeext->sitesurvey_res.channel_idx = 0;
330 pmlmeext->sitesurvey_res.bss_cnt = 0;
331 pmlmeext->scan_abort = false;
333 pmlmeinfo->state = WIFI_FW_NULL_STATE;
334 pmlmeinfo->reauth_count = 0;
335 pmlmeinfo->reassoc_count = 0;
336 pmlmeinfo->link_count = 0;
337 pmlmeinfo->auth_seq = 0;
338 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
339 pmlmeinfo->key_index = 0;
342 pmlmeinfo->enc_algo = _NO_PRIVACY_;
343 pmlmeinfo->authModeToggle = 0;
345 memset(pmlmeinfo->chg_txt, 0, 128);
347 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
348 pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
350 pmlmeinfo->dialogToken = 0;
352 pmlmeext->action_public_rxseq = 0xffff;
353 pmlmeext->action_public_dialog_token = 0xff;
356 static int has_channel(struct rt_channel_info *channel_set,
357 u8 chanset_size, u8 chan) {
360 for (i = 0; i < chanset_size; i++) {
361 if (channel_set[i].ChannelNum == chan)
368 static void init_channel_list(struct rtw_adapter *padapter,
369 struct rt_channel_info *channel_set,
371 struct p2p_channels *channel_list) {
373 struct p2p_oper_class_map op_class[] = {
374 { IEEE80211G, 81, 1, 13, 1, BW20 },
375 { IEEE80211G, 82, 14, 14, 1, BW20 },
376 { IEEE80211A, 115, 36, 48, 4, BW20 },
377 { IEEE80211A, 116, 36, 44, 8, BW40PLUS },
378 { IEEE80211A, 117, 40, 48, 8, BW40MINUS },
379 { IEEE80211A, 124, 149, 161, 4, BW20 },
380 { IEEE80211A, 125, 149, 169, 4, BW20 },
381 { IEEE80211A, 126, 149, 157, 8, BW40PLUS },
382 { IEEE80211A, 127, 153, 161, 8, BW40MINUS },
383 { -1, 0, 0, 0, 0, BW20 }
390 for (op = 0; op_class[op].op_class; op++) {
392 struct p2p_oper_class_map *o = &op_class[op];
393 struct p2p_reg_class *reg = NULL;
395 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
396 if (!has_channel(channel_set, chanset_size, ch))
399 if ((0 == padapter->registrypriv.ht_enable) &&
403 if ((0 == (padapter->registrypriv.cbw40_enable & BIT(1))) &&
404 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
408 reg = &channel_list->reg_class[cla];
410 reg->reg_class = o->op_class;
413 reg->channel[reg->channels] = ch;
417 channel_list->reg_classes = cla;
420 static u8 init_channel_set(struct rtw_adapter* padapter, u8 cplan,
421 struct rt_channel_info *c_set)
424 u8 b5GBand = false, b2_4GBand = false;
425 u8 Index2G = 0, Index5G = 0;
427 memset(c_set, 0, sizeof(struct rt_channel_info) * MAX_CHANNEL_NUM);
429 if (cplan >= RT_CHANNEL_DOMAIN_MAX &&
430 cplan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) {
431 DBG_8723A("ChannelPlan ID %x error !!!!!\n", cplan);
435 if (padapter->registrypriv.wireless_mode & WIRELESS_11G) {
437 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == cplan)
438 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
440 Index2G = RTW_ChannelPlanMap[cplan].Index2G;
443 if (padapter->registrypriv.wireless_mode & WIRELESS_11A) {
445 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == cplan)
446 Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
448 Index5G = RTW_ChannelPlanMap[cplan].Index5G;
452 for (i = 0; i < RTW_ChannelPlan2G[Index2G].Len; i++) {
453 c_set[ch_size].ChannelNum =
454 RTW_ChannelPlan2G[Index2G].Channel[i];
456 if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == cplan) ||
457 /* Channel 1~11 is active, and 12~14 is passive */
458 RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G == cplan) {
459 if (c_set[ch_size].ChannelNum >= 1 &&
460 c_set[ch_size].ChannelNum <= 11)
461 c_set[ch_size].ScanType = SCAN_ACTIVE;
462 else if (c_set[ch_size].ChannelNum >= 12 &&
463 c_set[ch_size].ChannelNum <= 14)
464 c_set[ch_size].ScanType = SCAN_PASSIVE;
465 } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == cplan ||
466 RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == cplan ||
467 RT_CHANNEL_DOMAIN_2G_WORLD == Index2G) {
468 /* channel 12~13, passive scan */
469 if (c_set[ch_size].ChannelNum <= 11)
470 c_set[ch_size].ScanType = SCAN_ACTIVE;
472 c_set[ch_size].ScanType = SCAN_PASSIVE;
474 c_set[ch_size].ScanType = SCAN_ACTIVE;
481 for (i = 0; i < RTW_ChannelPlan5G[Index5G].Len; i++) {
482 if (RTW_ChannelPlan5G[Index5G].Channel[i] <= 48 ||
483 RTW_ChannelPlan5G[Index5G].Channel[i] >= 149) {
484 c_set[ch_size].ChannelNum =
485 RTW_ChannelPlan5G[Index5G].Channel[i];
486 if (RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == cplan) {
487 /* passive scan for all 5G channels */
488 c_set[ch_size].ScanType =
491 c_set[ch_size].ScanType =
493 DBG_8723A("%s(): channel_set[%d].ChannelNum = "
494 "%d\n", __func__, ch_size,
495 c_set[ch_size].ChannelNum);
504 int init_mlme_ext_priv23a(struct rtw_adapter* padapter)
507 struct registry_priv* pregistrypriv = &padapter->registrypriv;
508 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
509 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
510 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
512 pmlmeext->padapter = padapter;
514 init_mlme_ext_priv23a_value(padapter);
515 pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
517 init_mlme_ext_timer23a(padapter);
519 #ifdef CONFIG_8723AU_AP_MODE
520 init_mlme_ap_info23a(padapter);
523 pmlmeext->max_chan_nums = init_channel_set(padapter,
524 pmlmepriv->ChannelPlan,
525 pmlmeext->channel_set);
526 init_channel_list(padapter, pmlmeext->channel_set,
527 pmlmeext->max_chan_nums, &pmlmeext->channel_list);
529 pmlmeext->chan_scan_time = SURVEY_TO;
530 pmlmeext->mlmeext_init = true;
532 pmlmeext->active_keep_alive_check = true;
536 void free_mlme_ext_priv23a (struct mlme_ext_priv *pmlmeext)
538 struct rtw_adapter *padapter = pmlmeext->padapter;
543 if (padapter->bDriverStopped == true) {
544 del_timer_sync(&pmlmeext->survey_timer);
545 del_timer_sync(&pmlmeext->link_timer);
546 /* del_timer_sync(&pmlmeext->ADDBA_timer); */
551 _mgt_dispatcher23a(struct rtw_adapter *padapter, struct mlme_handler *ptable,
552 struct recv_frame *precv_frame)
554 struct sk_buff *skb = precv_frame->pkt;
555 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
558 /* receive the frames that ra(a1) is my address
559 or ra(a1) is bc address. */
560 if (!ether_addr_equal(hdr->addr1, myid(&padapter->eeprompriv))&&
561 !is_broadcast_ether_addr(hdr->addr1))
564 ptable->func(padapter, precv_frame);
568 void mgt_dispatcher23a(struct rtw_adapter *padapter,
569 struct recv_frame *precv_frame)
571 struct mlme_handler *ptable;
572 #ifdef CONFIG_8723AU_AP_MODE
573 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
574 #endif /* CONFIG_8723AU_AP_MODE */
575 struct sk_buff *skb = precv_frame->pkt;
576 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
577 struct sta_info *psta;
581 if (!ieee80211_is_mgmt(mgmt->frame_control))
584 /* receive the frames that ra(a1) is my address or ra(a1) is
586 if (!ether_addr_equal(mgmt->da, myid(&padapter->eeprompriv)) &&
587 !is_broadcast_ether_addr(mgmt->da))
590 ptable = mlme_sta_tbl;
592 stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
596 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
597 ("Currently we do not support reserved sub-fr-type ="
603 psta = rtw_get_stainfo23a(&padapter->stapriv, mgmt->sa);
606 if (ieee80211_has_retry(mgmt->frame_control)) {
607 if (precv_frame->attrib.seq_num ==
608 psta->RxMgmtFrameSeqNum) {
609 /* drop the duplicate management frame */
610 DBG_8723A("Drop duplicate management frame "
611 "with seq_num = %d.\n",
612 precv_frame->attrib.seq_num);
616 psta->RxMgmtFrameSeqNum = precv_frame->attrib.seq_num;
619 #ifdef CONFIG_8723AU_AP_MODE
622 case IEEE80211_STYPE_AUTH:
623 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
624 ptable->func = &OnAuth23a;
626 ptable->func = &OnAuth23aClient23a;
628 case IEEE80211_STYPE_ASSOC_REQ:
629 case IEEE80211_STYPE_REASSOC_REQ:
630 _mgt_dispatcher23a(padapter, ptable, precv_frame);
632 case IEEE80211_STYPE_PROBE_REQ:
633 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
634 _mgt_dispatcher23a(padapter, ptable, precv_frame);
636 _mgt_dispatcher23a(padapter, ptable, precv_frame);
638 case IEEE80211_STYPE_BEACON:
639 _mgt_dispatcher23a(padapter, ptable, precv_frame);
641 case IEEE80211_STYPE_ACTION:
642 /* if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) */
643 _mgt_dispatcher23a(padapter, ptable, precv_frame);
646 _mgt_dispatcher23a(padapter, ptable, precv_frame);
650 _mgt_dispatcher23a(padapter, ptable, precv_frame);
654 /****************************************************************************
656 Following are the callback functions for each subtype of the management frames
658 *****************************************************************************/
661 OnProbeReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
664 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
665 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
666 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
667 struct wlan_bssid_ex *cur = &pmlmeinfo->network;
668 struct sk_buff *skb = precv_frame->pkt;
669 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
672 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
675 if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
676 !check_fwstate(pmlmepriv,
677 WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE))
680 if (unlikely(!ieee80211_is_probe_req(mgmt->frame_control))) {
681 printk(KERN_WARNING "%s: Received non probe request frame\n",
686 len -= offsetof(struct ieee80211_mgmt, u.probe_req.variable);
688 ie = cfg80211_find_ie(WLAN_EID_SSID, mgmt->u.probe_req.variable, len);
690 /* check (wildcard) SSID */
694 if ((ie[1] && memcmp(ie + 2, cur->Ssid.ssid, cur->Ssid.ssid_len)) ||
695 (ie[1] == 0 && pmlmeinfo->hidden_ssid_mode)) {
699 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
700 pmlmepriv->cur_network.join_res)
701 issue_probersp23a(padapter, mgmt->sa, false);
708 OnProbeRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
710 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
712 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
713 report_survey_event23a(padapter, precv_frame);
721 OnBeacon23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
724 struct sta_info *psta;
725 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
726 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
727 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
728 struct sta_priv *pstapriv = &padapter->stapriv;
729 struct sk_buff *skb = precv_frame->pkt;
730 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
731 u8 *pframe = skb->data;
732 int pkt_len = skb->len;
733 struct wlan_bssid_ex *pbss;
739 pie = mgmt->u.beacon.variable;
740 pie_len = pkt_len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
741 p = rtw_get_ie23a(pie, WLAN_EID_EXT_SUPP_RATES, &ielen, pie_len);
742 if (p && ielen > 0) {
743 if (p[1 + ielen] == 0x2D && p[2 + ielen] != 0x2D) {
744 /* Invalid value 0x2D is detected in Extended Supported
745 * Rates (ESR) IE. Try to fix the IE length to avoid
746 * failed Beacon parsing.
748 DBG_8723A("[WIFIDBG] Error in ESR IE is detected in "
749 "Beacon of BSSID: %pM. Fix the length of "
750 "ESR IE to avoid failed Beacon parsing.\n",
756 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
757 report_survey_event23a(padapter, precv_frame);
761 if (!ether_addr_equal(mgmt->bssid,
762 get_my_bssid23a(&pmlmeinfo->network)))
765 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
766 /* we should update current network before auth,
767 or some IE is wrong */
768 pbss = (struct wlan_bssid_ex *)
769 kmalloc(sizeof(struct wlan_bssid_ex), GFP_ATOMIC);
771 if (collect_bss_info23a(padapter, precv_frame, pbss) ==
774 &pmlmepriv->cur_network.network, pbss,
776 rtw_get_bcn_info23a(&pmlmepriv->cur_network);
781 /* check the vendor of the assoc AP */
782 pmlmeinfo->assoc_AP_vendor =
783 check_assoc_AP23a((u8 *)&mgmt->u.beacon, pkt_len -
784 offsetof(struct ieee80211_mgmt, u));
786 /* update TSF Value */
787 rtw_update_TSF(pmlmeext, mgmt);
790 start_clnt_auth23a(padapter);
795 if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) &&
796 (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
797 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
799 ret = rtw_check_bcn_info23a(padapter, mgmt, pkt_len);
801 DBG_8723A_LEVEL(_drv_always_, "ap has changed, "
803 receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress, 65535);
806 /* update WMM, ERP in the beacon */
807 /* todo: the timer is used instead of
808 the number of the beacon received */
809 if ((sta_rx_pkts(psta) & 0xf) == 0) {
810 /* DBG_8723A("update_bcn_info\n"); */
811 update_beacon23a_info(padapter, pframe,
815 } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
816 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
818 /* update WMM, ERP in the beacon */
819 /* todo: the timer is used instead of the
820 number of the beacon received */
821 if ((sta_rx_pkts(psta) & 0xf) == 0) {
822 /* DBG_8723A("update_bcn_info\n"); */
823 update_beacon23a_info(padapter, pframe,
827 /* allocate a new CAM entry for IBSS station */
828 cam_idx = allocate_fw_sta_entry23a(padapter);
829 if (cam_idx == NUM_STA)
832 /* get supported rate */
833 if (update_sta_support_rate23a(padapter, pie, pie_len,
835 pmlmeinfo->FW_sta_info[cam_idx].status = 0;
839 /* update TSF Value */
840 rtw_update_TSF(pmlmeext, mgmt);
842 /* report sta add event */
843 report_add_sta_event23a(padapter, mgmt->sa,
854 OnAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
856 #ifdef CONFIG_8723AU_AP_MODE
857 static struct sta_info stat;
858 struct sta_info *pstat = NULL;
859 struct sta_priv *pstapriv = &padapter->stapriv;
860 struct security_priv *psecuritypriv = &padapter->securitypriv;
861 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
862 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
863 struct sk_buff *skb = precv_frame->pkt;
864 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
868 u16 auth_mode, seq, algorithm;
869 int status, len = skb->len;
871 if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
874 DBG_8723A("+OnAuth23a\n");
878 auth_mode = psecuritypriv->dot11AuthAlgrthm;
880 pframe = mgmt->u.auth.variable;
881 len = skb->len - offsetof(struct ieee80211_mgmt, u.auth.variable);
883 seq = le16_to_cpu(mgmt->u.auth.auth_transaction);
884 algorithm = le16_to_cpu(mgmt->u.auth.auth_alg);
886 DBG_8723A("auth alg =%x, seq =%X\n", algorithm, seq);
888 if (auth_mode == 2 &&
889 psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
890 psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
893 /* rx a shared-key auth but shared not enabled, or */
894 /* rx a open-system auth but shared-key is enabled */
895 if ((algorithm != WLAN_AUTH_OPEN && auth_mode == 0) ||
896 (algorithm == WLAN_AUTH_OPEN && auth_mode == 1)) {
897 DBG_8723A("auth rejected due to bad alg [alg =%d, auth_mib "
898 "=%d] %02X%02X%02X%02X%02X%02X\n",
899 algorithm, auth_mode,
900 sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
902 status = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
907 if (rtw_access_ctrl23a(padapter, sa) == false) {
908 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
912 pstat = rtw_get_stainfo23a(pstapriv, sa);
914 /* allocate a new one */
915 DBG_8723A("going to alloc stainfo for sa ="MAC_FMT"\n",
917 pstat = rtw_alloc_stainfo23a(pstapriv, sa, GFP_ATOMIC);
919 DBG_8723A(" Exceed the upper limit of supported "
921 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
925 pstat->state = WIFI_FW_AUTH_NULL;
928 /* pstat->flags = 0; */
929 /* pstat->capability = 0; */
931 spin_lock_bh(&pstapriv->asoc_list_lock);
932 if (!list_empty(&pstat->asoc_list)) {
933 list_del_init(&pstat->asoc_list);
934 pstapriv->asoc_list_cnt--;
935 if (pstat->expire_to > 0) {
936 /* TODO: STA re_auth within expire_to */
939 spin_unlock_bh(&pstapriv->asoc_list_lock);
942 /* TODO: STA re_auth and auth timeout */
946 spin_lock_bh(&pstapriv->auth_list_lock);
947 if (list_empty(&pstat->auth_list)) {
948 list_add_tail(&pstat->auth_list, &pstapriv->auth_list);
949 pstapriv->auth_list_cnt++;
951 spin_unlock_bh(&pstapriv->auth_list_lock);
953 if (pstat->auth_seq == 0)
954 pstat->expire_to = pstapriv->auth_to;
956 if ((pstat->auth_seq + 1) != seq) {
957 DBG_8723A("(1)auth rejected because out of seq [rx_seq =%d, "
958 "exp_seq =%d]!\n", seq, pstat->auth_seq+1);
959 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
963 if (algorithm == WLAN_AUTH_OPEN && (auth_mode == 0 || auth_mode == 2)) {
965 pstat->state &= ~WIFI_FW_AUTH_NULL;
966 pstat->state |= WIFI_FW_AUTH_SUCCESS;
967 pstat->expire_to = pstapriv->assoc_to;
968 pstat->authalg = algorithm;
970 DBG_8723A("(2)auth rejected because out of seq "
971 "[rx_seq =%d, exp_seq =%d]!\n",
972 seq, pstat->auth_seq+1);
973 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
976 } else { /* shared system or auto authentication */
978 /* prepare for the challenging txt... */
979 pstat->state &= ~WIFI_FW_AUTH_NULL;
980 pstat->state |= WIFI_FW_AUTH_STATE;
981 pstat->authalg = algorithm;
983 } else if (seq == 3) {
984 /* checking for challenging txt... */
985 DBG_8723A("checking for challenging txt...\n");
987 p = cfg80211_find_ie(WLAN_EID_CHALLENGE, pframe, len);
988 if (!p || p[1] <= 0) {
989 DBG_8723A("auth rejected because challenge "
991 status = WLAN_STATUS_CHALLENGE_FAIL;
995 if (!memcmp(p + 2, pstat->chg_txt, 128)) {
996 pstat->state &= ~WIFI_FW_AUTH_STATE;
997 pstat->state |= WIFI_FW_AUTH_SUCCESS;
998 /* challenging txt is correct... */
999 pstat->expire_to = pstapriv->assoc_to;
1001 DBG_8723A("auth rejected because challenge "
1003 status = WLAN_STATUS_CHALLENGE_FAIL;
1007 DBG_8723A("(3)auth rejected because out of seq "
1008 "[rx_seq =%d, exp_seq =%d]!\n",
1009 seq, pstat->auth_seq+1);
1010 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1015 /* Now, we are going to issue_auth23a... */
1016 pstat->auth_seq = seq + 1;
1018 issue_auth23a(padapter, pstat, WLAN_STATUS_SUCCESS);
1020 if (pstat->state & WIFI_FW_AUTH_SUCCESS)
1021 pstat->auth_seq = 0;
1028 rtw_free_stainfo23a(padapter, pstat);
1031 memset((char *)pstat, '\0', sizeof(stat));
1032 pstat->auth_seq = 2;
1033 memcpy(pstat->hwaddr, sa, 6);
1035 issue_auth23a(padapter, pstat, (unsigned short)status);
1042 OnAuth23aClient23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1044 unsigned int seq, status, algthm;
1045 unsigned int go2asoc = 0;
1046 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1047 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1048 struct sk_buff *skb = precv_frame->pkt;
1049 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1052 int plen = skb->len;
1054 DBG_8723A("%s\n", __func__);
1056 /* check A1 matches or not */
1057 if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da))
1060 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
1063 pie = mgmt->u.auth.variable;
1064 plen -= offsetof(struct ieee80211_mgmt, u.auth.variable);
1066 algthm = le16_to_cpu(mgmt->u.auth.auth_alg);
1067 seq = le16_to_cpu(mgmt->u.auth.auth_transaction);
1068 status = le16_to_cpu(mgmt->u.auth.status_code);
1071 DBG_8723A("clnt auth fail, status: %d\n", status);
1072 /* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
1073 if (status == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) {
1074 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1075 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
1077 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
1078 /* pmlmeinfo->reauth_count = 0; */
1081 set_link_timer(pmlmeext, 1);
1086 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
1087 /* legendary shared system */
1088 p = cfg80211_find_ie(WLAN_EID_CHALLENGE, pie, plen);
1091 /* DBG_8723A("marc: no challenge text?\n"); */
1095 memcpy((void *)(pmlmeinfo->chg_txt), p + 2, p[1]);
1096 pmlmeinfo->auth_seq = 3;
1097 issue_auth23a(padapter, NULL, 0);
1098 set_link_timer(pmlmeext, REAUTH_TO);
1105 } else if (seq == 4) {
1106 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1111 /* this is also illegal */
1112 /* DBG_8723A("marc: clnt auth failed due to illegal seq =%x\n",
1118 DBG_8723A_LEVEL(_drv_always_, "auth success, start assoc\n");
1119 start_clnt_assoc23a(padapter);
1125 /* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
1130 #ifdef CONFIG_8723AU_AP_MODE
1131 static int rtw_validate_vendor_specific_ies(const u8 *pos, int elen)
1135 /* first 3 bytes in vendor specific information element are the IEEE
1136 * OUI of the vendor. The following byte is used a vendor specific
1139 DBG_8723A("short vendor specific information element "
1140 "ignored (len =%i)\n", elen);
1144 oui = RTW_GET_BE24(pos);
1146 case WLAN_OUI_MICROSOFT:
1147 /* Microsoft/Wi-Fi information elements are further typed and
1151 /* Microsoft OUI (00:50:F2) with OUI Type 1:
1152 * real WPA information element */
1154 case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */
1156 DBG_8723A("short WME information element "
1157 "ignored (len =%i)\n", elen);
1161 case WME_OUI_SUBTYPE_INFORMATION_ELEMENT:
1162 case WME_OUI_SUBTYPE_PARAMETER_ELEMENT:
1164 case WME_OUI_SUBTYPE_TSPEC_ELEMENT:
1167 DBG_8723A("unknown WME information element "
1168 "ignored (subtype =%d len =%i)\n",
1174 /* Wi-Fi Protected Setup (WPS) IE */
1177 DBG_8723A("Unknown Microsoft information element "
1178 "ignored (type =%d len =%i)\n",
1186 case VENDOR_HT_CAPAB_OUI_TYPE:
1189 DBG_8723A("Unknown Broadcom information element "
1190 "ignored (type =%d len =%i)\n", pos[3], elen);
1196 DBG_8723A("unknown vendor specific information element "
1197 "ignored (vendor OUI %02x:%02x:%02x len =%i)\n",
1198 pos[0], pos[1], pos[2], elen);
1205 static int rtw_validate_frame_ies(const u8 *start, uint len)
1207 const u8 *pos = start;
1219 DBG_8723A("%s: IEEE 802.11 failed (id =%d elen =%d "
1220 "left =%i)\n", __func__, id, elen, left);
1226 case WLAN_EID_SUPP_RATES:
1227 case WLAN_EID_FH_PARAMS:
1228 case WLAN_EID_DS_PARAMS:
1229 case WLAN_EID_CF_PARAMS:
1231 case WLAN_EID_IBSS_PARAMS:
1232 case WLAN_EID_CHALLENGE:
1233 case WLAN_EID_ERP_INFO:
1234 case WLAN_EID_EXT_SUPP_RATES:
1235 case WLAN_EID_VENDOR_SPECIFIC:
1236 if (rtw_validate_vendor_specific_ies(pos, elen))
1240 case WLAN_EID_PWR_CAPABILITY:
1241 case WLAN_EID_SUPPORTED_CHANNELS:
1242 case WLAN_EID_MOBILITY_DOMAIN:
1243 case WLAN_EID_FAST_BSS_TRANSITION:
1244 case WLAN_EID_TIMEOUT_INTERVAL:
1245 case WLAN_EID_HT_CAPABILITY:
1246 case WLAN_EID_HT_OPERATION:
1249 DBG_8723A("%s IEEE 802.11 ignored unknown element "
1250 "(id =%d elen =%d)\n", __func__, id, elen);
1266 OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1268 #ifdef CONFIG_8723AU_AP_MODE
1269 u16 capab_info, listen_interval;
1270 struct sta_info *pstat;
1271 unsigned char reassoc;
1272 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
1273 int i, wpa_ie_len, left;
1274 unsigned char supportRate[16];
1276 unsigned short status = WLAN_STATUS_SUCCESS;
1277 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1278 struct security_priv *psecuritypriv = &padapter->securitypriv;
1279 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1280 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1281 struct wlan_bssid_ex *cur = &pmlmeinfo->network;
1282 struct sta_priv *pstapriv = &padapter->stapriv;
1283 struct sk_buff *skb = precv_frame->pkt;
1284 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1285 const u8 *pos, *p, *wpa_ie, *wps_ie;
1286 u8 *pframe = skb->data;
1287 uint pkt_len = skb->len;
1290 if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
1293 left = pkt_len - sizeof(struct ieee80211_hdr_3addr);
1294 if (ieee80211_is_assoc_req(mgmt->frame_control)) {
1296 pos = mgmt->u.assoc_req.variable;
1297 left -= offsetof(struct ieee80211_mgmt, u.assoc_req.variable);
1298 } else { /* WIFI_REASSOCREQ */
1300 pos = mgmt->u.reassoc_req.variable;
1301 left -= offsetof(struct ieee80211_mgmt, u.reassoc_req.variable);
1305 DBG_8723A("handle_assoc(reassoc =%d) - too short payload "
1306 "(len =%lu)\n", reassoc, (unsigned long)pkt_len);
1310 pstat = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1312 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
1313 goto asoc_class2_error;
1316 /* These two are located at the same offsets whether it's an
1317 * assoc_req or a reassoc_req */
1318 capab_info = get_unaligned_le16(&mgmt->u.assoc_req.capab_info);
1320 get_unaligned_le16(&mgmt->u.assoc_req.listen_interval);
1322 DBG_8723A("%s\n", __func__);
1324 /* check if this stat has been successfully authenticated/assocated */
1325 if (!(pstat->state & WIFI_FW_AUTH_SUCCESS)) {
1326 if (!(pstat->state & WIFI_FW_ASSOC_SUCCESS)) {
1327 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
1328 goto asoc_class2_error;
1330 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
1331 pstat->state |= WIFI_FW_ASSOC_STATE;
1334 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
1335 pstat->state |= WIFI_FW_ASSOC_STATE;
1338 pstat->capability = capab_info;
1340 /* now parse all ieee802_11 ie to point to elems */
1342 if (rtw_validate_frame_ies(pos, left)) {
1343 DBG_8723A("STA " MAC_FMT " sent invalid association request\n",
1344 MAC_ARG(pstat->hwaddr));
1345 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1346 goto OnAssocReq23aFail;
1349 /* now we should check all the fields... */
1351 p = cfg80211_find_ie(WLAN_EID_SSID, pos, left);
1352 if (!p || p[1] == 0) {
1353 /* broadcast ssid, however it is not allowed in assocreq */
1354 DBG_8723A("STA " MAC_FMT " sent invalid association request "
1355 "lacking an SSID\n", MAC_ARG(pstat->hwaddr));
1356 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1357 goto OnAssocReq23aFail;
1359 /* check if ssid match */
1360 if (memcmp(p + 2, cur->Ssid.ssid, cur->Ssid.ssid_len))
1361 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1363 if (p[1] != cur->Ssid.ssid_len)
1364 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1367 if (status != WLAN_STATUS_SUCCESS)
1368 goto OnAssocReq23aFail;
1370 /* check if the supported rate is ok */
1371 p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, pos, left);
1373 DBG_8723A("Rx a sta assoc-req which supported rate is "
1375 /* use our own rate set as statoin used */
1376 /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
1377 /* supportRateNum = AP_BSSRATE_LEN; */
1379 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1380 goto OnAssocReq23aFail;
1382 memcpy(supportRate, p + 2, p[1]);
1383 supportRateNum = p[1];
1385 p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, pos, left);
1387 if (supportRateNum <= sizeof(supportRate)) {
1388 memcpy(supportRate+supportRateNum, p + 2, p[1]);
1389 supportRateNum += p[1];
1394 /* todo: mask supportRate between AP & STA -> move to update raid */
1395 /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */
1397 /* update station supportRate */
1398 pstat->bssratelen = supportRateNum;
1399 memcpy(pstat->bssrateset, supportRate, supportRateNum);
1400 Update23aTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
1402 /* check RSN/WPA/WPS */
1403 pstat->dot8021xalg = 0;
1405 pstat->wpa_group_cipher = 0;
1406 pstat->wpa2_group_cipher = 0;
1407 pstat->wpa_pairwise_cipher = 0;
1408 pstat->wpa2_pairwise_cipher = 0;
1409 memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
1411 wpa_ie = cfg80211_find_ie(WLAN_EID_RSN, pos, left);
1413 wpa_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1414 WLAN_OUI_TYPE_MICROSOFT_WPA,
1417 int group_cipher = 0, pairwise_cipher = 0;
1419 wpa_ie_len = wpa_ie[1];
1420 if (psecuritypriv->wpa_psk & BIT(1)) {
1421 r = rtw_parse_wpa2_ie23a(wpa_ie, wpa_ie_len + 2,
1423 &pairwise_cipher, NULL);
1424 if (r == _SUCCESS) {
1425 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1426 pstat->wpa_psk |= BIT(1);
1428 pstat->wpa2_group_cipher = group_cipher &
1429 psecuritypriv->wpa2_group_cipher;
1430 pstat->wpa2_pairwise_cipher = pairwise_cipher &
1431 psecuritypriv->wpa2_pairwise_cipher;
1433 status = WLAN_STATUS_INVALID_IE;
1434 } else if (psecuritypriv->wpa_psk & BIT(0)) {
1435 r = rtw_parse_wpa_ie23a(wpa_ie, wpa_ie_len + 2,
1436 &group_cipher, &pairwise_cipher,
1438 if (r == _SUCCESS) {
1439 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1440 pstat->wpa_psk |= BIT(0);
1442 pstat->wpa_group_cipher = group_cipher &
1443 psecuritypriv->wpa_group_cipher;
1444 pstat->wpa_pairwise_cipher = pairwise_cipher &
1445 psecuritypriv->wpa_pairwise_cipher;
1447 status = WLAN_STATUS_INVALID_IE;
1452 if (wpa_ie && status == WLAN_STATUS_SUCCESS) {
1453 if (!pstat->wpa_group_cipher)
1454 status = WLAN_STATUS_INVALID_GROUP_CIPHER;
1456 if (!pstat->wpa_pairwise_cipher)
1457 status = WLAN_STATUS_INVALID_PAIRWISE_CIPHER;
1461 if (status != WLAN_STATUS_SUCCESS)
1462 goto OnAssocReq23aFail;
1464 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
1466 wps_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
1467 WLAN_OUI_TYPE_MICROSOFT_WPS,
1472 DBG_8723A("STA included WPS IE in (Re)Association "
1473 "Request - assume WPS is used\n");
1474 pstat->flags |= WLAN_STA_WPS;
1476 DBG_8723A("STA did not include WPA/RSN IE in (Re)"
1477 "Association Request - possible WPS use\n");
1478 pstat->flags |= WLAN_STA_MAYBE_WPS;
1481 /* AP support WPA/RSN, and sta is going to do WPS, but AP
1483 /* that the selected registrar of AP is _FLASE */
1484 if (psecuritypriv->wpa_psk > 0 &&
1485 pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS)) {
1486 if (pmlmepriv->wps_beacon_ie) {
1487 u8 selected_registrar = 0;
1489 rtw_get_wps_attr_content23a(
1490 pmlmepriv->wps_beacon_ie,
1491 pmlmepriv->wps_beacon_ie_len,
1492 WPS_ATTR_SELECTED_REGISTRAR,
1493 &selected_registrar, NULL);
1495 if (!selected_registrar) {
1496 DBG_8723A("selected_registrar is false,"
1497 "or AP is not ready to do "
1500 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1501 goto OnAssocReq23aFail;
1508 if (psecuritypriv->wpa_psk == 0) {
1509 DBG_8723A("STA " MAC_FMT ": WPA/RSN IE in association "
1510 "request, but AP don't support WPA/RSN\n",
1511 MAC_ARG(pstat->hwaddr));
1513 status = WLAN_STATUS_INVALID_IE;
1515 goto OnAssocReq23aFail;
1519 DBG_8723A("STA included WPS IE in (Re)Association "
1520 "Request - WPS is used\n");
1521 pstat->flags |= WLAN_STA_WPS;
1524 copy_len = ((wpa_ie_len + 2) > sizeof(pstat->wpa_ie)) ?
1525 sizeof(pstat->wpa_ie) : (wpa_ie_len + 2);
1529 memcpy(pstat->wpa_ie, wpa_ie - 2, copy_len);
1532 /* check if there is WMM IE & support WWM-PS */
1533 pstat->flags &= ~WLAN_STA_WME;
1534 pstat->qos_option = 0;
1535 pstat->qos_info = 0;
1536 pstat->has_legacy_ac = true;
1537 pstat->uapsd_vo = 0;
1538 pstat->uapsd_vi = 0;
1539 pstat->uapsd_be = 0;
1540 pstat->uapsd_bk = 0;
1541 if (pmlmepriv->qos_option) {
1542 const u8 *end = pos + left;
1547 p = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, p, left);
1549 if (!memcmp(p + 2, WMM_IE, 6)) {
1550 pstat->flags |= WLAN_STA_WME;
1552 pstat->qos_option = 1;
1553 pstat->qos_info = *(p + 8);
1556 (pstat->qos_info >> 5) & 0x3;
1558 if ((pstat->qos_info & 0xf) != 0xf)
1559 pstat->has_legacy_ac = true;
1561 pstat->has_legacy_ac = false;
1563 if (pstat->qos_info & 0xf) {
1564 if (pstat->qos_info & BIT(0))
1565 pstat->uapsd_vo = BIT(0)|BIT(1);
1567 pstat->uapsd_vo = 0;
1569 if (pstat->qos_info & BIT(1))
1570 pstat->uapsd_vi = BIT(0)|BIT(1);
1572 pstat->uapsd_vi = 0;
1574 if (pstat->qos_info & BIT(2))
1575 pstat->uapsd_bk = BIT(0)|BIT(1);
1577 pstat->uapsd_bk = 0;
1579 if (pstat->qos_info & BIT(3))
1580 pstat->uapsd_be = BIT(0)|BIT(1);
1582 pstat->uapsd_be = 0;
1595 /* save HT capabilities in the sta object */
1596 memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap));
1597 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pos, left);
1599 if (p && p[1] >= sizeof(struct ieee80211_ht_cap)) {
1600 pstat->flags |= WLAN_STA_HT;
1602 pstat->flags |= WLAN_STA_WME;
1604 memcpy(&pstat->htpriv.ht_cap, p + 2,
1605 sizeof(struct ieee80211_ht_cap));
1607 pstat->flags &= ~WLAN_STA_HT;
1609 if (pmlmepriv->htpriv.ht_option == false && pstat->flags & WLAN_STA_HT){
1610 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1611 goto OnAssocReq23aFail;
1614 if (pstat->flags & WLAN_STA_HT &&
1615 (pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP ||
1616 pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP)) {
1617 DBG_8723A("HT: " MAC_FMT " tried to use TKIP with HT "
1618 "association\n", MAC_ARG(pstat->hwaddr));
1620 /* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */
1621 /* goto OnAssocReq23aFail; */
1624 pstat->flags |= WLAN_STA_NONERP;
1625 for (i = 0; i < pstat->bssratelen; i++) {
1626 if ((pstat->bssrateset[i] & 0x7f) > 22) {
1627 pstat->flags &= ~WLAN_STA_NONERP;
1632 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1633 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
1635 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1637 if (status != WLAN_STATUS_SUCCESS)
1638 goto OnAssocReq23aFail;
1640 /* TODO: identify_proprietary_vendor_ie(); */
1641 /* Realtek proprietary IE */
1642 /* identify if this is Broadcom sta */
1643 /* identify if this is ralink sta */
1644 /* Customer proprietary IE */
1646 /* get a unique AID */
1647 if (pstat->aid > 0) {
1648 DBG_8723A(" old AID %d\n", pstat->aid);
1650 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
1651 if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
1654 if (pstat->aid > NUM_STA)
1655 pstat->aid = NUM_STA;
1656 if (pstat->aid > pstapriv->max_num_sta) {
1660 DBG_8723A(" no room for more AIDs\n");
1662 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1664 goto OnAssocReq23aFail;
1666 pstapriv->sta_aid[pstat->aid - 1] = pstat;
1667 DBG_8723A("allocate new AID = (%d)\n", pstat->aid);
1671 pstat->state &= ~WIFI_FW_ASSOC_STATE;
1672 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
1674 spin_lock_bh(&pstapriv->auth_list_lock);
1675 if (!list_empty(&pstat->auth_list)) {
1676 list_del_init(&pstat->auth_list);
1677 pstapriv->auth_list_cnt--;
1679 spin_unlock_bh(&pstapriv->auth_list_lock);
1681 spin_lock_bh(&pstapriv->asoc_list_lock);
1682 if (list_empty(&pstat->asoc_list)) {
1683 pstat->expire_to = pstapriv->expire_to;
1684 list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list);
1685 pstapriv->asoc_list_cnt++;
1687 spin_unlock_bh(&pstapriv->asoc_list_lock);
1689 /* now the station is qualified to join our BSS... */
1690 if (pstat && pstat->state & WIFI_FW_ASSOC_SUCCESS &&
1691 status == WLAN_STATUS_SUCCESS) {
1692 #ifdef CONFIG_8723AU_AP_MODE
1693 /* 1 bss_cap_update & sta_info_update23a */
1694 bss_cap_update_on_sta_join23a(padapter, pstat);
1695 sta_info_update23a(padapter, pstat);
1697 /* issue assoc rsp before notify station join event. */
1698 if (ieee80211_is_assoc_req(mgmt->frame_control))
1699 issue_asocrsp23a(padapter, status, pstat,
1702 issue_asocrsp23a(padapter, status, pstat,
1705 /* 2 - report to upper layer */
1706 DBG_8723A("indicate_sta_join_event to upper layer - hostapd\n");
1707 rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
1709 /* 3-(1) report sta add event */
1710 report_add_sta_event23a(padapter, pstat->hwaddr, pstat->aid);
1718 #ifdef CONFIG_8723AU_AP_MODE
1719 issue_deauth23a(padapter, mgmt->sa, status);
1725 #ifdef CONFIG_8723AU_AP_MODE
1727 if (ieee80211_is_assoc_req(mgmt->frame_control))
1728 issue_asocrsp23a(padapter, status, pstat, WIFI_ASSOCRSP);
1730 issue_asocrsp23a(padapter, status, pstat, WIFI_REASSOCRSP);
1733 #endif /* CONFIG_8723AU_AP_MODE */
1739 OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1741 struct ndis_802_11_var_ies *pIE;
1742 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1743 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1744 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1745 struct sk_buff *skb = precv_frame->pkt;
1746 struct ieee80211_mgmt *pmgmt = (struct ieee80211_mgmt *) skb->data;
1748 unsigned short status;
1749 u8 *pframe = skb->data;
1750 int pkt_len = skb->len;
1752 DBG_8723A("%s\n", __func__);
1754 /* check A1 matches or not */
1755 if (!ether_addr_equal(myid(&padapter->eeprompriv), pmgmt->da))
1758 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
1761 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1764 del_timer_sync(&pmlmeext->link_timer);
1767 status = le16_to_cpu(pmgmt->u.assoc_resp.status_code);
1769 DBG_8723A("assoc reject, status code: %d\n", status);
1770 pmlmeinfo->state = WIFI_FW_NULL_STATE;
1772 goto report_assoc_result;
1775 /* get capabilities */
1776 pmlmeinfo->capability = le16_to_cpu(pmgmt->u.assoc_resp.capab_info);
1779 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
1782 res = pmlmeinfo->aid = le16_to_cpu(pmgmt->u.assoc_resp.aid) & 0x3fff;
1784 /* following are moved to join event callback function */
1785 /* to handle HT, WMM, rate adaptive, update MAC reg */
1786 /* for not to handle the synchronous IO in the tasklet */
1787 for (i = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
1789 pIE = (struct ndis_802_11_var_ies *)(pframe + i);
1791 switch (pIE->ElementID)
1793 case WLAN_EID_VENDOR_SPECIFIC:
1794 if (!memcmp(pIE->data, WMM_PARA_OUI23A, 6))/* WMM */
1795 WMM_param_handler23a(padapter, pIE);
1798 case WLAN_EID_HT_CAPABILITY: /* HT caps */
1799 HT_caps_handler23a(padapter, pIE);
1802 case WLAN_EID_HT_OPERATION: /* HT info */
1803 HT_info_handler23a(padapter, pIE);
1806 case WLAN_EID_ERP_INFO:
1807 ERP_IE_handler23a(padapter, pIE);
1813 i += (pIE->Length + 2);
1816 pmlmeinfo->state &= ~WIFI_FW_ASSOC_STATE;
1817 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
1819 /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
1820 UpdateBrateTbl23a(padapter, pmlmeinfo->network.SupportedRates);
1822 report_assoc_result:
1823 pmlmepriv->assoc_rsp_len = 0;
1825 kfree(pmlmepriv->assoc_rsp);
1826 pmlmepriv->assoc_rsp = kmalloc(pkt_len, GFP_ATOMIC);
1827 if (pmlmepriv->assoc_rsp) {
1828 memcpy(pmlmepriv->assoc_rsp, pframe, pkt_len);
1829 pmlmepriv->assoc_rsp_len = pkt_len;
1832 kfree(pmlmepriv->assoc_rsp);
1834 report_join_res23a(padapter, res);
1840 OnDeAuth23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1842 unsigned short reason;
1843 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1844 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1845 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1846 struct sk_buff *skb = precv_frame->pkt;
1847 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1849 if (!ether_addr_equal(mgmt->bssid,
1850 get_my_bssid23a(&pmlmeinfo->network)))
1853 reason = le16_to_cpu(mgmt->u.deauth.reason_code);
1855 DBG_8723A("%s Reason code(%d)\n", __func__, reason);
1857 #ifdef CONFIG_8723AU_AP_MODE
1858 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
1859 struct sta_info *psta;
1860 struct sta_priv *pstapriv = &padapter->stapriv;
1862 DBG_8723A_LEVEL(_drv_always_, "ap recv deauth reason code(%d) "
1863 "sta:%pM\n", reason, mgmt->sa);
1865 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1869 spin_lock_bh(&pstapriv->asoc_list_lock);
1870 if (!list_empty(&psta->asoc_list)) {
1871 list_del_init(&psta->asoc_list);
1872 pstapriv->asoc_list_cnt--;
1873 updated = ap_free_sta23a(padapter, psta,
1876 spin_unlock_bh(&pstapriv->asoc_list_lock);
1878 associated_clients_update23a(padapter, updated);
1885 DBG_8723A_LEVEL(_drv_always_, "sta recv deauth reason code(%d) "
1886 "sta:%pM\n", reason, mgmt->bssid);
1888 receive_disconnect23a(padapter, mgmt->bssid, reason);
1890 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1896 OnDisassoc23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1898 unsigned short reason;
1899 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1900 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1901 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1902 struct sk_buff *skb = precv_frame->pkt;
1903 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1905 if (!ether_addr_equal(mgmt->bssid,
1906 get_my_bssid23a(&pmlmeinfo->network)))
1909 reason = le16_to_cpu(mgmt->u.disassoc.reason_code);
1911 DBG_8723A("%s Reason code(%d)\n", __func__, reason);
1913 #ifdef CONFIG_8723AU_AP_MODE
1914 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1915 struct sta_info *psta;
1916 struct sta_priv *pstapriv = &padapter->stapriv;
1918 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason code(%d)"
1919 " sta:%pM\n", reason, mgmt->sa);
1921 psta = rtw_get_stainfo23a(pstapriv, mgmt->sa);
1925 spin_lock_bh(&pstapriv->asoc_list_lock);
1926 if (!list_empty(&psta->asoc_list)) {
1927 list_del_init(&psta->asoc_list);
1928 pstapriv->asoc_list_cnt--;
1929 updated = ap_free_sta23a(padapter, psta,
1932 spin_unlock_bh(&pstapriv->asoc_list_lock);
1934 associated_clients_update23a(padapter, updated);
1941 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason "
1942 "code(%d) sta:%pM\n", reason, mgmt->bssid);
1944 receive_disconnect23a(padapter, mgmt->bssid, reason);
1946 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1951 OnAtim23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1953 DBG_8723A("%s\n", __func__);
1958 on_action_spct23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1964 OnAction23a_qos(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1970 OnAction23a_dls(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1975 static int OnAction23a_back23a(struct rtw_adapter *padapter,
1976 struct recv_frame *precv_frame)
1979 struct sta_info *psta = NULL;
1980 struct recv_reorder_ctrl *preorder_ctrl;
1981 unsigned char category, action;
1982 unsigned short tid, status, capab, params, reason_code = 0;
1983 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1984 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1985 struct sk_buff *skb = precv_frame->pkt;
1986 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
1987 struct sta_priv *pstapriv = &padapter->stapriv;
1989 /* check RA matches or not */
1990 if (!ether_addr_equal(myid(&padapter->eeprompriv), mgmt->da))
1993 DBG_8723A("%s\n", __func__);
1995 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1996 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
2000 psta = rtw_get_stainfo23a(pstapriv, addr);
2005 category = mgmt->u.action.category;
2006 if (category == WLAN_CATEGORY_BACK) { /* representing Block Ack */
2007 if (!pmlmeinfo->HT_enable)
2009 /* action_code is located in the same place for all
2010 action events, so pick any */
2011 action = mgmt->u.action.u.wme_action.action_code;
2012 DBG_8723A("%s, action =%d\n", __func__, action);
2014 case WLAN_ACTION_ADDBA_REQ: /* ADDBA request */
2015 memcpy(&pmlmeinfo->ADDBA_req,
2016 &mgmt->u.action.u.addba_req.dialog_token,
2017 sizeof(struct ADDBA_request));
2018 process_addba_req23a(padapter,
2019 (u8 *)&pmlmeinfo->ADDBA_req, addr);
2020 if (pmlmeinfo->bAcceptAddbaReq == true)
2021 issue_action_BA23a(padapter, addr,
2022 WLAN_ACTION_ADDBA_RESP, 0);
2024 /* reject ADDBA Req */
2025 issue_action_BA23a(padapter, addr,
2026 WLAN_ACTION_ADDBA_RESP, 37);
2029 case WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
2030 status = get_unaligned_le16(
2031 &mgmt->u.action.u.addba_resp.status);
2032 capab = get_unaligned_le16(
2033 &mgmt->u.action.u.addba_resp.capab);
2034 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
2035 if (status == 0) { /* successful */
2036 DBG_8723A("agg_enable for TID =%d\n", tid);
2037 psta->htpriv.agg_enable_bitmap |= 1 << tid;
2038 psta->htpriv.candidate_tid_bitmap &=
2041 psta->htpriv.agg_enable_bitmap &= ~CHKBIT(tid);
2044 case WLAN_ACTION_DELBA: /* DELBA */
2045 params = get_unaligned_le16(
2046 &mgmt->u.action.u.delba.params);
2049 if (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) {
2050 preorder_ctrl = &psta->recvreorder_ctrl[tid];
2051 preorder_ctrl->enable = false;
2052 preorder_ctrl->indicate_seq = 0xffff;
2054 psta->htpriv.agg_enable_bitmap &= ~(1 << tid);
2055 psta->htpriv.candidate_tid_bitmap &=
2058 reason_code = get_unaligned_le16(
2059 &mgmt->u.action.u.delba.reason_code);
2060 DBG_8723A("%s(): DELBA: %x(%x)\n", __func__,
2061 pmlmeinfo->agg_enable_bitmap, reason_code);
2062 /* todo: how to notify the host while receiving
2072 static s32 rtw_action_public_decache(struct recv_frame *recv_frame, s32 token)
2074 struct rtw_adapter *adapter = recv_frame->adapter;
2075 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
2076 struct sk_buff *skb = recv_frame->pkt;
2077 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2080 seq_ctrl = ((recv_frame->attrib.seq_num&0xffff) << 4) |
2081 (recv_frame->attrib.frag_num & 0xf);
2083 if (ieee80211_has_retry(hdr->frame_control)) {
2085 if ((seq_ctrl == mlmeext->action_public_rxseq) &&
2086 (token == mlmeext->action_public_dialog_token)) {
2087 DBG_8723A("%s(%s): seq_ctrl = 0x%x, "
2088 "rxseq = 0x%x, token:%d\n", __func__,
2089 adapter->pnetdev->name, seq_ctrl,
2090 mlmeext->action_public_rxseq, token);
2094 if (seq_ctrl == mlmeext->action_public_rxseq) {
2095 DBG_8723A("%s(%s): seq_ctrl = 0x%x, "
2096 "rxseq = 0x%x\n", __func__,
2097 adapter->pnetdev->name, seq_ctrl,
2098 mlmeext->action_public_rxseq);
2104 mlmeext->action_public_rxseq = seq_ctrl;
2107 mlmeext->action_public_dialog_token = token;
2112 static unsigned int on_action_public23a_p2p(struct recv_frame *precv_frame)
2114 struct sk_buff *skb = precv_frame->pkt;
2115 u8 *pframe = skb->data;
2119 frame_body = (unsigned char *)
2120 (pframe + sizeof(struct ieee80211_hdr_3addr));
2122 dialogToken = frame_body[7];
2124 if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
2130 static unsigned int on_action_public23a_vendor(struct recv_frame *precv_frame)
2132 unsigned int ret = _FAIL;
2133 struct sk_buff *skb = precv_frame->pkt;
2134 u8 *pframe = skb->data;
2135 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2137 if (!memcmp(frame_body + 2, P2P_OUI23A, 4)) {
2138 ret = on_action_public23a_p2p(precv_frame);
2145 on_action_public23a_default(struct recv_frame *precv_frame, u8 action)
2147 unsigned int ret = _FAIL;
2148 struct sk_buff *skb = precv_frame->pkt;
2149 u8 *pframe = skb->data;
2150 uint frame_len = skb->len;
2151 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2153 struct rtw_adapter *adapter = precv_frame->adapter;
2157 token = frame_body[2];
2159 if (rtw_action_public_decache(precv_frame, token) == _FAIL)
2162 cnt += sprintf((msg+cnt), "%s(token:%u)",
2163 action_public_str23a(action), token);
2164 rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
2172 static int on_action_public23a(struct rtw_adapter *padapter,
2173 struct recv_frame *precv_frame)
2175 unsigned int ret = _FAIL;
2176 struct sk_buff *skb = precv_frame->pkt;
2177 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2178 u8 *pframe = skb->data;
2179 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2180 u8 category, action;
2182 /* check RA matches or not */
2183 if (!ether_addr_equal(myid(&padapter->eeprompriv), hdr->addr1))
2186 category = frame_body[0];
2187 if (category != WLAN_CATEGORY_PUBLIC)
2190 action = frame_body[1];
2192 case ACT_PUBLIC_VENDOR:
2193 ret = on_action_public23a_vendor(precv_frame);
2196 ret = on_action_public23a_default(precv_frame, action);
2205 OnAction23a_ht(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2211 OnAction23a_wmm(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2217 OnAction23a_p2p(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2223 OnAction23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2227 struct action_handler *ptable;
2228 struct sk_buff *skb = precv_frame->pkt;
2229 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
2231 category = mgmt->u.action.category;
2234 i < sizeof(OnAction23a_tbl) / sizeof(struct action_handler); i++) {
2235 ptable = &OnAction23a_tbl[i];
2237 if (category == ptable->num)
2238 ptable->func(padapter, precv_frame);
2244 static int DoReserved23a(struct rtw_adapter *padapter,
2245 struct recv_frame *precv_frame)
2250 struct xmit_frame *alloc_mgtxmitframe23a(struct xmit_priv *pxmitpriv)
2252 struct xmit_frame *pmgntframe;
2253 struct xmit_buf *pxmitbuf;
2255 pmgntframe = rtw_alloc_xmitframe23a_ext(pxmitpriv);
2258 DBG_8723A("%s(%s): alloc xmitframe fail\n", __func__,
2259 pxmitpriv->adapter->pnetdev->name);
2263 pxmitbuf = rtw_alloc_xmitbuf23a_ext(pxmitpriv);
2265 DBG_8723A("%s(%s): alloc xmitbuf fail\n", __func__,
2266 pxmitpriv->adapter->pnetdev->name);
2267 rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
2272 pmgntframe->frame_tag = MGNT_FRAMETAG;
2273 pmgntframe->pxmitbuf = pxmitbuf;
2274 pmgntframe->buf_addr = pxmitbuf->pbuf;
2275 pxmitbuf->priv_data = pmgntframe;
2281 /****************************************************************************
2283 Following are some TX fuctions for WiFi MLME
2285 *****************************************************************************/
2287 void update_mgnt_tx_rate23a(struct rtw_adapter *padapter, u8 rate)
2289 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2291 pmlmeext->tx_rate = rate;
2292 DBG_8723A("%s(): rate = %x\n", __func__, rate);
2295 void update_mgntframe_attrib23a(struct rtw_adapter *padapter,
2296 struct pkt_attrib *pattrib)
2298 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2300 memset((u8 *)pattrib, 0, sizeof(struct pkt_attrib));
2302 pattrib->hdrlen = 24;
2303 pattrib->nr_frags = 1;
2304 pattrib->priority = 7;
2305 pattrib->mac_id = 0;
2306 pattrib->qsel = 0x12;
2308 pattrib->pktlen = 0;
2310 if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
2311 pattrib->raid = 6;/* b mode */
2313 pattrib->raid = 5;/* a/g mode */
2315 pattrib->encrypt = _NO_PRIVACY_;
2316 pattrib->bswenc = false;
2318 pattrib->qos_en = false;
2319 pattrib->ht_en = false;
2320 pattrib->bwmode = HT_CHANNEL_WIDTH_20;
2321 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2322 pattrib->sgi = false;
2324 pattrib->seqnum = pmlmeext->mgnt_seq;
2326 pattrib->retry_ctrl = true;
2329 void dump_mgntframe23a(struct rtw_adapter *padapter,
2330 struct xmit_frame *pmgntframe)
2332 if (padapter->bSurpriseRemoved == true ||
2333 padapter->bDriverStopped == true)
2336 rtw_hal_mgnt_xmit23a(padapter, pmgntframe);
2339 s32 dump_mgntframe23a_and_wait(struct rtw_adapter *padapter,
2340 struct xmit_frame *pmgntframe, int timeout_ms)
2344 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2345 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
2346 struct submit_ctx sctx;
2348 if (padapter->bSurpriseRemoved == true ||
2349 padapter->bDriverStopped == true)
2352 rtw_sctx_init23a(&sctx, timeout_ms);
2353 pxmitbuf->sctx = &sctx;
2355 ret = rtw_hal_mgnt_xmit23a(padapter, pmgntframe);
2357 if (ret == _SUCCESS)
2358 ret = rtw_sctx_wait23a(&sctx);
2360 spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL);
2361 pxmitbuf->sctx = NULL;
2362 spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL);
2367 s32 dump_mgntframe23a_and_wait_ack23a(struct rtw_adapter *padapter,
2368 struct xmit_frame *pmgntframe)
2371 u32 timeout_ms = 500;/* 500ms */
2372 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2374 if (padapter->bSurpriseRemoved == true ||
2375 padapter->bDriverStopped == true)
2378 mutex_lock(&pxmitpriv->ack_tx_mutex);
2379 pxmitpriv->ack_tx = true;
2381 pmgntframe->ack_report = 1;
2382 if (rtw_hal_mgnt_xmit23a(padapter, pmgntframe) == _SUCCESS) {
2383 ret = rtw_ack_tx_wait23a(pxmitpriv, timeout_ms);
2386 pxmitpriv->ack_tx = false;
2387 mutex_unlock(&pxmitpriv->ack_tx_mutex);
2392 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
2400 ssid_ie = rtw_get_ie23a(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
2402 /* DBG_8723A("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n",
2403 __func__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
2405 if (ssid_ie && ssid_len_ori > 0) {
2406 switch (hidden_ssid_mode)
2409 next_ie = ssid_ie + 2 + ssid_len_ori;
2412 remain_len = ies_len -(next_ie-ies);
2415 memcpy(ssid_ie+2, next_ie, remain_len);
2416 len_diff -= ssid_len_ori;
2420 memset(&ssid_ie[2], 0, ssid_len_ori);
2430 void issue_beacon23a(struct rtw_adapter *padapter, int timeout_ms)
2432 struct xmit_frame *pmgntframe;
2433 struct pkt_attrib *pattrib;
2434 unsigned char *pframe;
2435 struct ieee80211_hdr *pwlanhdr;
2437 unsigned int rate_len;
2438 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2439 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2440 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2441 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2442 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
2443 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2449 /* DBG_8723A("%s\n", __func__); */
2451 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL) {
2452 DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
2455 #ifdef CONFIG_8723AU_AP_MODE
2456 spin_lock_bh(&pmlmepriv->bcn_update_lock);
2459 /* update attribute */
2460 pattrib = &pmgntframe->attrib;
2461 update_mgntframe_attrib23a(padapter, pattrib);
2462 pattrib->qsel = 0x10;
2464 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2466 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2467 pwlanhdr = (struct ieee80211_hdr *)pframe;
2469 fctrl = &pwlanhdr->frame_control;
2472 ether_addr_copy(pwlanhdr->addr1, bc_addr);
2473 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
2474 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(cur_network));
2476 SetSeqNum(pwlanhdr, 0 /*pmlmeext->mgnt_seq*/);
2477 /* pmlmeext->mgnt_seq++; */
2478 SetFrameSubType(pframe, WIFI_BEACON);
2480 pframe += sizeof(struct ieee80211_hdr_3addr);
2481 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
2483 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
2484 /* DBG_8723A("ie len =%d\n", cur_network->IELength); */
2485 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2486 len_diff = update_hidden_ssid(pframe + _BEACON_IE_OFFSET_,
2487 cur_network->IELength -
2489 pmlmeinfo->hidden_ssid_mode);
2490 pframe += (cur_network->IELength+len_diff);
2491 pattrib->pktlen += (cur_network->IELength+len_diff);
2493 wps_ie = rtw_get_wps_ie23a(pmgntframe->buf_addr + TXDESC_OFFSET+
2494 sizeof (struct ieee80211_hdr_3addr) +
2495 _BEACON_IE_OFFSET_, pattrib->pktlen -
2496 sizeof (struct ieee80211_hdr_3addr) -
2497 _BEACON_IE_OFFSET_, NULL,
2499 if (wps_ie && wps_ielen > 0) {
2500 rtw_get_wps_attr_content23a(wps_ie, wps_ielen,
2501 WPS_ATTR_SELECTED_REGISTRAR,
2505 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
2507 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
2512 /* below for ad-hoc mode */
2514 /* timestamp will be inserted by hardware */
2516 pattrib->pktlen += 8;
2518 /* beacon interval: 2 bytes */
2520 memcpy(pframe, (unsigned char *)
2521 rtw_get_beacon_interval23a_from_ie(cur_network->IEs), 2);
2524 pattrib->pktlen += 2;
2526 /* capability info: 2 bytes */
2528 memcpy(pframe, (unsigned char *)
2529 rtw_get_capability23a_from_ie(cur_network->IEs), 2);
2532 pattrib->pktlen += 2;
2535 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
2536 cur_network->Ssid.ssid_len,
2537 cur_network->Ssid.ssid, &pattrib->pktlen);
2539 /* supported rates... */
2540 rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
2541 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2542 ((rate_len > 8)? 8: rate_len),
2543 cur_network->SupportedRates, &pattrib->pktlen);
2545 /* DS parameter set */
2546 pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)
2547 &cur_network->Configuration.DSConfig,
2550 /* if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
2554 /* IBSS Parameter Set... */
2555 /* ATIMWindow = cur->Configuration.ATIMWindow; */
2557 pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
2558 (unsigned char *)&ATIMWindow,
2562 pframe = rtw_set_ie23a(pframe, WLAN_EID_ERP_INFO, 1,
2563 &erpinfo, &pattrib->pktlen);
2566 /* EXTERNDED SUPPORTED RATE */
2568 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2570 cur_network->SupportedRates + 8,
2573 /* todo:HT for adhoc */
2577 #ifdef CONFIG_8723AU_AP_MODE
2578 pmlmepriv->update_bcn = false;
2580 spin_unlock_bh(&pmlmepriv->bcn_update_lock);
2583 if ((pattrib->pktlen + TXDESC_SIZE) > 512) {
2584 DBG_8723A("beacon frame too large\n");
2588 pattrib->last_txcmdsz = pattrib->pktlen;
2590 /* DBG_8723A("issue bcn_sz =%d\n", pattrib->last_txcmdsz); */
2592 dump_mgntframe23a_and_wait(padapter, pmgntframe, timeout_ms);
2594 dump_mgntframe23a(padapter, pmgntframe);
2597 void issue_probersp23a(struct rtw_adapter *padapter, unsigned char *da,
2598 u8 is_valid_p2p_probereq)
2600 struct xmit_frame *pmgntframe;
2601 struct pkt_attrib *pattrib;
2602 unsigned char *pframe;
2603 struct ieee80211_hdr *pwlanhdr;
2605 unsigned char *mac, *bssid;
2606 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2607 #ifdef CONFIG_8723AU_AP_MODE
2612 int ssid_ielen_diff;
2615 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2617 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2618 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2619 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
2620 unsigned int rate_len;
2622 /* DBG_8723A("%s\n", __func__); */
2624 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2626 DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
2630 /* update attribute */
2631 pattrib = &pmgntframe->attrib;
2632 update_mgntframe_attrib23a(padapter, pattrib);
2634 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2636 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
2637 pwlanhdr = (struct ieee80211_hdr *)pframe;
2639 mac = myid(&padapter->eeprompriv);
2640 bssid = cur_network->MacAddress;
2642 fctrl = &pwlanhdr->frame_control;
2644 ether_addr_copy(pwlanhdr->addr1, da);
2645 ether_addr_copy(pwlanhdr->addr2, mac);
2646 ether_addr_copy(pwlanhdr->addr3, bssid);
2648 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2649 pmlmeext->mgnt_seq++;
2650 SetFrameSubType(fctrl, WIFI_PROBERSP);
2652 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
2653 pattrib->pktlen = pattrib->hdrlen;
2654 pframe += pattrib->hdrlen;
2656 if (cur_network->IELength > MAX_IE_SZ)
2659 #ifdef CONFIG_8723AU_AP_MODE
2660 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
2661 pwps_ie = rtw_get_wps_ie23a(cur_network->IEs +
2663 cur_network->IELength -
2664 _FIXED_IE_LENGTH_, NULL,
2667 /* inerset & update wps_probe_resp_ie */
2668 if (pmlmepriv->wps_probe_resp_ie && pwps_ie && wps_ielen > 0) {
2669 uint wps_offset, remainder_ielen;
2672 wps_offset = (uint)(pwps_ie - cur_network->IEs);
2674 premainder_ie = pwps_ie + wps_ielen;
2676 remainder_ielen = cur_network->IELength - wps_offset -
2679 memcpy(pframe, cur_network->IEs, wps_offset);
2680 pframe += wps_offset;
2681 pattrib->pktlen += wps_offset;
2683 /* to get ie data len */
2684 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];
2685 if (wps_offset + wps_ielen + 2 <= MAX_IE_SZ) {
2686 memcpy(pframe, pmlmepriv->wps_probe_resp_ie,
2688 pframe += wps_ielen+2;
2689 pattrib->pktlen += wps_ielen+2;
2692 if (wps_offset + wps_ielen + 2 + remainder_ielen <=
2694 memcpy(pframe, premainder_ie, remainder_ielen);
2695 pframe += remainder_ielen;
2696 pattrib->pktlen += remainder_ielen;
2699 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2700 pframe += cur_network->IELength;
2701 pattrib->pktlen += cur_network->IELength;
2704 /* retrieve SSID IE from cur_network->Ssid */
2705 ies = pmgntframe->buf_addr + TXDESC_OFFSET +
2706 sizeof(struct ieee80211_hdr_3addr);
2708 ssid_ie = rtw_get_ie23a(ies + _FIXED_IE_LENGTH_, WLAN_EID_SSID,
2710 pframe - ies - _FIXED_IE_LENGTH_);
2712 ssid_ielen_diff = cur_network->Ssid.ssid_len - ssid_ielen;
2714 if (ssid_ie && cur_network->Ssid.ssid_len) {
2715 uint remainder_ielen;
2717 remainder_ie = ssid_ie + 2;
2718 remainder_ielen = pframe - remainder_ie;
2720 DBG_8723A_LEVEL(_drv_warning_, "%s(%s): "
2721 "remainder_ielen > MAX_IE_SZ\n",
2722 __func__, padapter->pnetdev->name);
2723 if (remainder_ielen > MAX_IE_SZ)
2724 remainder_ielen = MAX_IE_SZ;
2726 memcpy(buf, remainder_ie, remainder_ielen);
2727 memcpy(remainder_ie + ssid_ielen_diff, buf,
2729 *(ssid_ie + 1) = cur_network->Ssid.ssid_len;
2730 memcpy(ssid_ie + 2, cur_network->Ssid.ssid,
2731 cur_network->Ssid.ssid_len);
2733 pframe += ssid_ielen_diff;
2734 pattrib->pktlen += ssid_ielen_diff;
2740 /* timestamp will be inserted by hardware */
2742 pattrib->pktlen += 8;
2744 /* beacon interval: 2 bytes */
2746 memcpy(pframe, (unsigned char *)
2747 rtw_get_beacon_interval23a_from_ie(cur_network->IEs), 2);
2750 pattrib->pktlen += 2;
2752 /* capability info: 2 bytes */
2754 memcpy(pframe, (unsigned char *)
2755 rtw_get_capability23a_from_ie(cur_network->IEs), 2);
2758 pattrib->pktlen += 2;
2760 /* below for ad-hoc mode */
2763 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
2764 cur_network->Ssid.ssid_len,
2765 cur_network->Ssid.ssid,
2768 /* supported rates... */
2769 rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
2770 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2771 ((rate_len > 8)? 8: rate_len),
2772 cur_network->SupportedRates,
2775 /* DS parameter set */
2776 pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1,
2778 &cur_network->Configuration.DSConfig,
2781 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
2784 /* IBSS Parameter Set... */
2785 /* ATIMWindow = cur->Configuration.ATIMWindow; */
2787 pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
2788 (unsigned char *)&ATIMWindow,
2792 pframe = rtw_set_ie23a(pframe, WLAN_EID_ERP_INFO, 1,
2793 &erpinfo, &pattrib->pktlen);
2796 /* EXTERNDED SUPPORTED RATE */
2798 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2800 cur_network->SupportedRates + 8,
2803 /* todo:HT for adhoc */
2806 pattrib->last_txcmdsz = pattrib->pktlen;
2808 dump_mgntframe23a(padapter, pmgntframe);
2813 static int _issue_probereq23a(struct rtw_adapter *padapter,
2814 struct cfg80211_ssid *pssid, u8 *da, int wait_ack)
2817 struct xmit_frame *pmgntframe;
2818 struct pkt_attrib *pattrib;
2819 unsigned char *pframe;
2820 struct ieee80211_hdr *pwlanhdr;
2823 unsigned char bssrate[NumRates];
2824 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2825 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2826 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2827 int bssrate_len = 0;
2828 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2830 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
2831 ("+issue_probereq23a\n"));
2833 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
2836 /* update attribute */
2837 pattrib = &pmgntframe->attrib;
2838 update_mgntframe_attrib23a(padapter, pattrib);
2840 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2842 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2843 pwlanhdr = (struct ieee80211_hdr *)pframe;
2845 mac = myid(&padapter->eeprompriv);
2847 fctrl = &pwlanhdr->frame_control;
2851 /* unicast probe request frame */
2852 ether_addr_copy(pwlanhdr->addr1, da);
2853 ether_addr_copy(pwlanhdr->addr3, da);
2855 /* broadcast probe request frame */
2856 ether_addr_copy(pwlanhdr->addr1, bc_addr);
2857 ether_addr_copy(pwlanhdr->addr3, bc_addr);
2860 ether_addr_copy(pwlanhdr->addr2, mac);
2862 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2863 pmlmeext->mgnt_seq++;
2864 SetFrameSubType(pframe, WIFI_PROBEREQ);
2866 pframe += sizeof (struct ieee80211_hdr_3addr);
2867 pattrib->pktlen = sizeof (struct ieee80211_hdr_3addr);
2870 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID, pssid->ssid_len,
2871 pssid->ssid, &pattrib->pktlen);
2873 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID, 0, NULL,
2876 get_rate_set23a(padapter, bssrate, &bssrate_len);
2878 if (bssrate_len > 8) {
2879 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
2880 bssrate, &pattrib->pktlen);
2881 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2882 (bssrate_len - 8), (bssrate + 8),
2885 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2886 bssrate_len, bssrate, &pattrib->pktlen);
2889 /* add wps_ie for wps2.0 */
2890 if (pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie) {
2891 memcpy(pframe, pmlmepriv->wps_probe_req_ie,
2892 pmlmepriv->wps_probe_req_ie_len);
2893 pframe += pmlmepriv->wps_probe_req_ie_len;
2894 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
2897 pattrib->last_txcmdsz = pattrib->pktlen;
2899 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
2900 ("issuing probe_req, tx_len =%d\n", pattrib->last_txcmdsz));
2903 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
2905 dump_mgntframe23a(padapter, pmgntframe);
2913 inline void issue_probereq23a(struct rtw_adapter *padapter,
2914 struct cfg80211_ssid *pssid, u8 *da)
2916 _issue_probereq23a(padapter, pssid, da, false);
2919 int issue_probereq23a_ex23a(struct rtw_adapter *padapter,
2920 struct cfg80211_ssid *pssid, u8 *da,
2921 int try_cnt, int wait_ms)
2925 unsigned long start = jiffies;
2928 ret = _issue_probereq23a(padapter, pssid, da,
2929 wait_ms > 0 ? true : false);
2933 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
2936 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
2939 } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
2946 if (try_cnt && wait_ms) {
2948 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
2949 "in %u ms\n", __func__,
2950 padapter->pnetdev->name,
2951 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
2952 ret == _SUCCESS?", acked":"", i, try_cnt,
2953 jiffies_to_msecs(jiffies - start));
2955 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
2956 __func__, padapter->pnetdev->name,
2957 rtw_get_oper_ch23a(padapter),
2958 ret == _SUCCESS?", acked":"", i, try_cnt,
2959 jiffies_to_msecs(jiffies - start));
2965 /* if psta == NULL, indiate we are station(client) now... */
2966 void issue_auth23a(struct rtw_adapter *padapter, struct sta_info *psta,
2967 unsigned short status)
2969 struct xmit_frame *pmgntframe;
2970 struct pkt_attrib *pattrib;
2971 unsigned char *pframe;
2972 struct ieee80211_hdr *pwlanhdr;
2975 unsigned short val16;
2976 int use_shared_key = 0;
2977 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2978 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2979 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2981 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
2984 /* update attribute */
2985 pattrib = &pmgntframe->attrib;
2986 update_mgntframe_attrib23a(padapter, pattrib);
2988 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2990 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2991 pwlanhdr = (struct ieee80211_hdr *)pframe;
2993 fctrl = &pwlanhdr->frame_control;
2996 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2997 pmlmeext->mgnt_seq++;
2998 SetFrameSubType(pframe, WIFI_AUTH);
3000 pframe += sizeof(struct ieee80211_hdr_3addr);
3001 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3003 if (psta) { /* for AP mode */
3004 #ifdef CONFIG_8723AU_AP_MODE
3006 ether_addr_copy(pwlanhdr->addr1, psta->hwaddr);
3007 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3008 ether_addr_copy(pwlanhdr->addr3, myid(&padapter->eeprompriv));
3010 /* setting auth algo number */
3011 val16 = (u16)psta->authalg;
3013 if (status != WLAN_STATUS_SUCCESS)
3017 val16 = cpu_to_le16(val16);
3021 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_ALGM_NUM_,
3022 (unsigned char *)&val16,
3025 /* setting auth seq number */
3026 val16 = (u16)psta->auth_seq;
3027 val16 = cpu_to_le16(val16);
3028 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_SEQ_NUM_,
3029 (unsigned char *)&val16,
3032 /* setting status code... */
3034 val16 = cpu_to_le16(val16);
3035 pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
3036 (unsigned char *)&val16,
3039 /* added challenging text... */
3040 if ((psta->auth_seq == 2) &&
3041 (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
3042 pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
3043 psta->chg_txt, &pattrib->pktlen);
3046 ether_addr_copy(pwlanhdr->addr1,
3047 get_my_bssid23a(&pmlmeinfo->network));
3048 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3049 ether_addr_copy(pwlanhdr->addr3,
3050 get_my_bssid23a(&pmlmeinfo->network));
3052 /* setting auth algo number */
3053 /* 0:OPEN System, 1:Shared key */
3054 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;
3056 val16 = cpu_to_le16(val16);
3059 /* DBG_8723A("%s auth_algo = %s auth_seq =%d\n", __func__,
3060 (pmlmeinfo->auth_algo == 0)?"OPEN":"SHARED",
3061 pmlmeinfo->auth_seq); */
3063 /* setting IV for auth seq #3 */
3064 if ((pmlmeinfo->auth_seq == 3) &&
3065 (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
3066 (use_shared_key == 1)) {
3067 /* DBG_8723A("==> iv(%d), key_index(%d)\n",
3068 pmlmeinfo->iv, pmlmeinfo->key_index); */
3069 val32 = ((pmlmeinfo->iv++) |
3070 (pmlmeinfo->key_index << 30));
3071 val32 = cpu_to_le32(val32);
3072 pframe = rtw_set_fixed_ie23a(pframe, 4,
3073 (unsigned char *)&val32,
3076 pattrib->iv_len = 4;
3079 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_ALGM_NUM_,
3080 (unsigned char *)&val16,
3083 /* setting auth seq number */
3084 val16 = pmlmeinfo->auth_seq;
3085 val16 = cpu_to_le16(val16);
3086 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_SEQ_NUM_,
3087 (unsigned char *)&val16,
3090 /* setting status code... */
3092 val16 = cpu_to_le16(val16);
3093 pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
3094 (unsigned char *)&val16,
3097 /* then checking to see if sending challenging text... */
3098 if ((pmlmeinfo->auth_seq == 3) &&
3099 (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
3100 (use_shared_key == 1)) {
3101 pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
3107 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
3109 pattrib->encrypt = _WEP40_;
3111 pattrib->icv_len = 4;
3113 pattrib->pktlen += pattrib->icv_len;
3117 pattrib->last_txcmdsz = pattrib->pktlen;
3119 rtw_wep_encrypt23a(padapter, pmgntframe);
3120 DBG_8723A("%s\n", __func__);
3121 dump_mgntframe23a(padapter, pmgntframe);
3126 void issue_asocrsp23a(struct rtw_adapter *padapter, unsigned short status,
3127 struct sta_info *pstat, int pkt_type)
3129 #ifdef CONFIG_8723AU_AP_MODE
3130 struct xmit_frame *pmgntframe;
3131 struct ieee80211_hdr *pwlanhdr;
3132 struct pkt_attrib *pattrib;
3133 unsigned char *pframe;
3135 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3136 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3137 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3138 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3139 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
3141 u8 *ie = pnetwork->IEs;
3143 DBG_8723A("%s\n", __func__);
3145 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3149 /* update attribute */
3150 pattrib = &pmgntframe->attrib;
3151 update_mgntframe_attrib23a(padapter, pattrib);
3153 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3155 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3156 pwlanhdr = (struct ieee80211_hdr *)pframe;
3158 pwlanhdr->frame_control = 0;
3160 ether_addr_copy(pwlanhdr->addr1, pstat->hwaddr);
3161 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3162 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3164 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3165 pmlmeext->mgnt_seq++;
3166 if (pkt_type == WIFI_ASSOCRSP || pkt_type == WIFI_REASSOCRSP)
3167 SetFrameSubType(pwlanhdr, pkt_type);
3171 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
3172 pattrib->pktlen += pattrib->hdrlen;
3173 pframe += pattrib->hdrlen;
3176 val = *(unsigned short *)rtw_get_capability23a_from_ie(ie);
3178 pframe = rtw_set_fixed_ie23a(pframe, _CAPABILITY_,
3179 (unsigned char *)&val, &pattrib->pktlen);
3181 status = cpu_to_le16(status);
3182 pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
3183 (unsigned char *)&status,
3186 val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
3187 pframe = rtw_set_fixed_ie23a(pframe, _ASOC_ID_, (unsigned char *)&val,
3190 if (pstat->bssratelen <= 8) {
3191 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
3192 pstat->bssratelen, pstat->bssrateset,
3195 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
3196 pstat->bssrateset, &pattrib->pktlen);
3197 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
3198 pstat->bssratelen - 8,
3199 pstat->bssrateset + 8, &pattrib->pktlen);
3202 if (pstat->flags & WLAN_STA_HT && pmlmepriv->htpriv.ht_option) {
3203 /* FILL HT CAP INFO IE */
3204 /* p = hostapd_eid_ht_capabilities_info(hapd, p); */
3205 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
3206 ie + _BEACON_IE_OFFSET_,
3207 pnetwork->IELength -_BEACON_IE_OFFSET_);
3209 memcpy(pframe, p, p[1] + 2);
3210 pframe += (p[1] + 2);
3211 pattrib->pktlen += (p[1] + 2);
3214 /* FILL HT ADD INFO IE */
3215 /* p = hostapd_eid_ht_operation(hapd, p); */
3216 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
3217 ie + _BEACON_IE_OFFSET_,
3218 pnetwork->IELength - _BEACON_IE_OFFSET_);
3219 if (p && p[1] > 0) {
3220 memcpy(pframe, p, p[1] + 2);
3221 pframe += (p[1] + 2);
3222 pattrib->pktlen += (p[1] + 2);
3227 if (pstat->flags & WLAN_STA_WME && pmlmepriv->qos_option) {
3228 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02,
3232 for (p = ie + _BEACON_IE_OFFSET_; ; p += (ie_len + 2)) {
3233 p = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, p,
3234 pnetwork->IELength -
3235 _BEACON_IE_OFFSET_ - (ie_len + 2));
3240 if (p && !memcmp(p + 2, WMM_PARA_IE, 6)) {
3241 memcpy(pframe, p, ie_len + 2);
3242 pframe += (ie_len + 2);
3243 pattrib->pktlen += (ie_len + 2);
3248 if (!p || ie_len == 0)
3253 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) {
3254 pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
3255 REALTEK_96B_IE, &pattrib->pktlen);
3258 /* add WPS IE ie for wps 2.0 */
3259 if (pmlmepriv->wps_assoc_resp_ie &&
3260 pmlmepriv->wps_assoc_resp_ie_len > 0) {
3261 memcpy(pframe, pmlmepriv->wps_assoc_resp_ie,
3262 pmlmepriv->wps_assoc_resp_ie_len);
3264 pframe += pmlmepriv->wps_assoc_resp_ie_len;
3265 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
3268 pattrib->last_txcmdsz = pattrib->pktlen;
3270 dump_mgntframe23a(padapter, pmgntframe);
3274 void issue_assocreq23a(struct rtw_adapter *padapter)
3277 struct xmit_frame *pmgntframe;
3278 struct pkt_attrib *pattrib;
3279 unsigned char *pframe;
3281 struct ieee80211_hdr *pwlanhdr;
3283 unsigned int i, j, index = 0;
3284 unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
3285 struct ndis_802_11_var_ies *pIE;
3286 struct registry_priv *pregpriv = &padapter->registrypriv;
3287 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3288 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3289 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3290 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3291 int bssrate_len = 0, sta_bssrate_len = 0, pie_len;
3294 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3298 /* update attribute */
3299 pattrib = &pmgntframe->attrib;
3300 update_mgntframe_attrib23a(padapter, pattrib);
3302 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3304 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
3305 pwlanhdr = (struct ieee80211_hdr *)pframe;
3307 fctrl = &pwlanhdr->frame_control;
3309 ether_addr_copy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network));
3310 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3311 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3313 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3314 pmlmeext->mgnt_seq++;
3315 SetFrameSubType(pframe, WIFI_ASSOCREQ);
3317 pframe += sizeof(struct ieee80211_hdr_3addr);
3318 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3322 rtw_get_capability23a_from_ie(pmlmeinfo->network.IEs), 2);
3325 pattrib->pktlen += 2;
3327 /* listen interval */
3328 /* todo: listen interval for power saving */
3329 put_unaligned_le16(3, pframe);
3331 pattrib->pktlen += 2;
3334 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
3335 pmlmeinfo->network.Ssid.ssid_len,
3336 pmlmeinfo->network.Ssid.ssid, &pattrib->pktlen);
3338 /* supported rate & extended supported rate */
3340 get_rate_set23a(padapter, sta_bssrate, &sta_bssrate_len);
3341 /* DBG_8723A("sta_bssrate_len =%d\n", sta_bssrate_len); */
3343 /* for JAPAN, channel 14 can only uses B Mode(CCK) */
3344 if (pmlmeext->cur_channel == 14)
3345 sta_bssrate_len = 4;
3347 /* for (i = 0; i < sta_bssrate_len; i++) { */
3348 /* DBG_8723A("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
3351 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3352 if (pmlmeinfo->network.SupportedRates[i] == 0)
3354 DBG_8723A("network.SupportedRates[%d]=%02X\n", i,
3355 pmlmeinfo->network.SupportedRates[i]);
3358 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3359 if (pmlmeinfo->network.SupportedRates[i] == 0)
3362 /* Check if the AP's supported rates are also
3363 supported by STA. */
3364 for (j = 0; j < sta_bssrate_len; j++) {
3365 /* Avoid the proprietary data rate (22Mbps) of
3366 Handlink WSG-4000 AP */
3367 if ((pmlmeinfo->network.SupportedRates[i] |
3368 IEEE80211_BASIC_RATE_MASK) ==
3369 (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) {
3370 /* DBG_8723A("match i = %d, j =%d\n", i, j); */
3375 if (j == sta_bssrate_len) {
3376 /* the rate is not supported by STA */
3377 DBG_8723A("%s(): the rate[%d]=%02X is not supported by "
3378 "STA!\n", __func__, i,
3379 pmlmeinfo->network.SupportedRates[i]);
3381 /* the rate is supported by STA */
3382 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
3386 bssrate_len = index;
3387 DBG_8723A("bssrate_len = %d\n", bssrate_len);
3389 if (bssrate_len == 0) {
3390 rtw_free_xmitbuf23a(pxmitpriv, pmgntframe->pxmitbuf);
3391 rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
3392 goto exit; /* don't connect to AP if no joint supported rate */
3395 if (bssrate_len > 8) {
3396 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
3397 bssrate, &pattrib->pktlen);
3398 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
3399 (bssrate_len - 8), (bssrate + 8),
3402 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
3403 bssrate_len, bssrate, &pattrib->pktlen);
3406 pie = pmlmeinfo->network.IEs + sizeof(struct ndis_802_11_fixed_ies);
3407 pie_len = pmlmeinfo->network.IELength -
3408 sizeof(struct ndis_802_11_fixed_ies);
3410 p = cfg80211_find_ie(WLAN_EID_RSN, pie, pie_len);
3412 pframe = rtw_set_ie23a(pframe, WLAN_EID_RSN, p[1], p + 2,
3416 if (padapter->mlmepriv.htpriv.ht_option == true) {
3417 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pie, pie_len);
3419 if (p && !is_ap_in_tkip23a(padapter)) {
3420 memcpy(&pmlmeinfo->HT_caps, p + 2,
3421 sizeof(struct HT_caps_element));
3423 /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
3424 if (pregpriv->cbw40_enable == 0) {
3425 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &= (~(BIT(6) | BIT(1)));
3427 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= BIT(1);
3430 /* todo: disable SM power save mode */
3431 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |=
3434 rf_type = rtl8723a_get_rf_type(padapter);
3435 /* switch (pregpriv->rf_config) */
3438 /* RX STBC One spatial stream */
3439 if (pregpriv->rx_stbc)
3440 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);
3442 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R23A, 16);
3448 /* enable for 2.4/5 GHz */
3449 if (pregpriv->rx_stbc == 0x3 ||
3450 (pmlmeext->cur_wireless_mode &
3452 /* enable for 2.4GHz */
3453 pregpriv->rx_stbc == 0x1) ||
3454 (pmlmeext->cur_wireless_mode &
3456 pregpriv->rx_stbc == 0x2) ||
3457 /* enable for 5GHz */
3458 pregpriv->wifi_spec == 1) {
3459 DBG_8723A("declare supporting RX "
3461 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0200);/* RX STBC two spatial stream */
3463 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R23A, 16);
3466 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info =
3467 cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
3469 #ifdef CONFIG_8723AU_BT_COEXIST
3470 if (BT_1Ant(padapter) == true) {
3472 pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para &= (u8)~IEEE80211_HT_AMPDU_PARM_FACTOR;
3473 /* pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para |= MAX_AMPDU_FACTOR_8K */
3477 pframe = rtw_set_ie23a(pframe, WLAN_EID_HT_CAPABILITY,
3478 p[1], (u8 *)&pmlmeinfo->HT_caps,
3483 /* vendor specific IE, such as WPA, WMM, WPS */
3484 for (i = sizeof(struct ndis_802_11_fixed_ies);
3485 i < pmlmeinfo->network.IELength;) {
3486 pIE = (struct ndis_802_11_var_ies *)
3487 (pmlmeinfo->network.IEs + i);
3489 switch (pIE->ElementID)
3491 case WLAN_EID_VENDOR_SPECIFIC:
3492 if (!memcmp(pIE->data, RTW_WPA_OUI23A_TYPE, 4) ||
3493 !memcmp(pIE->data, WMM_OUI23A, 4) ||
3494 !memcmp(pIE->data, WPS_OUI23A, 4)) {
3495 if (!padapter->registrypriv.wifi_spec) {
3496 /* Commented by Kurt 20110629 */
3497 /* In some older APs, WPS handshake */
3498 /* would be fail if we append vender
3499 extensions informations to AP */
3500 if (!memcmp(pIE->data, WPS_OUI23A, 4))
3503 pframe = rtw_set_ie23a(pframe,
3504 WLAN_EID_VENDOR_SPECIFIC,
3505 pIE->Length, pIE->data,
3514 i += pIE->Length + 2;
3517 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
3518 pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
3519 REALTEK_96B_IE, &pattrib->pktlen);
3521 pattrib->last_txcmdsz = pattrib->pktlen;
3522 dump_mgntframe23a(padapter, pmgntframe);
3527 pmlmepriv->assoc_req_len = 0;
3528 if (ret == _SUCCESS) {
3529 kfree(pmlmepriv->assoc_req);
3530 pmlmepriv->assoc_req = kmalloc(pattrib->pktlen, GFP_ATOMIC);
3531 if (pmlmepriv->assoc_req) {
3532 memcpy(pmlmepriv->assoc_req, pwlanhdr, pattrib->pktlen);
3533 pmlmepriv->assoc_req_len = pattrib->pktlen;
3536 kfree(pmlmepriv->assoc_req);
3541 /* when wait_ack is ture, this function shoule be called at process context */
3542 static int _issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3543 unsigned int power_mode, int wait_ack)
3546 struct xmit_frame *pmgntframe;
3547 struct pkt_attrib *pattrib;
3548 unsigned char *pframe;
3549 struct ieee80211_hdr *pwlanhdr;
3551 struct xmit_priv *pxmitpriv;
3552 struct mlme_ext_priv *pmlmeext;
3553 struct mlme_ext_info *pmlmeinfo;
3555 /* DBG_8723A("%s:%d\n", __func__, power_mode); */
3560 pxmitpriv = &padapter->xmitpriv;
3561 pmlmeext = &padapter->mlmeextpriv;
3562 pmlmeinfo = &pmlmeext->mlmext_info;
3564 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3567 /* update attribute */
3568 pattrib = &pmgntframe->attrib;
3569 update_mgntframe_attrib23a(padapter, pattrib);
3570 pattrib->retry_ctrl = false;
3572 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3574 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3575 pwlanhdr = (struct ieee80211_hdr *)pframe;
3577 fctrl = &pwlanhdr->frame_control;
3580 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3582 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
3588 ether_addr_copy(pwlanhdr->addr1, da);
3589 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3590 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3592 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3593 pmlmeext->mgnt_seq++;
3594 SetFrameSubType(pframe, WIFI_DATA_NULL);
3596 pframe += sizeof(struct ieee80211_hdr_3addr);
3597 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3599 pattrib->last_txcmdsz = pattrib->pktlen;
3602 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3604 dump_mgntframe23a(padapter, pmgntframe);
3612 /* when wait_ms >0 , this function shoule be called at process context */
3613 /* da == NULL for station mode */
3614 int issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3615 unsigned int power_mode, int try_cnt, int wait_ms)
3619 unsigned long start = jiffies;
3620 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3621 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3623 /* da == NULL, assum it's null data for sta to ap*/
3625 da = get_my_bssid23a(&pmlmeinfo->network);
3628 ret = _issue_nulldata23a(padapter, da, power_mode,
3629 wait_ms > 0 ? true : false);
3633 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3636 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3639 } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
3646 if (try_cnt && wait_ms) {
3648 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
3649 "in %u ms\n", __func__,
3650 padapter->pnetdev->name,
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("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3656 __func__, padapter->pnetdev->name,
3657 rtw_get_oper_ch23a(padapter),
3658 ret == _SUCCESS?", acked":"", i, try_cnt,
3659 jiffies_to_msecs(jiffies - start));
3665 /* when wait_ack is ture, this function shoule be called at process context */
3666 static int _issue_qos_nulldata23a(struct rtw_adapter *padapter,
3667 unsigned char *da, u16 tid, int wait_ack)
3670 struct xmit_frame *pmgntframe;
3671 struct pkt_attrib *pattrib;
3672 unsigned char *pframe;
3673 struct ieee80211_hdr *pwlanhdr;
3676 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3677 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3678 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3680 DBG_8723A("%s\n", __func__);
3682 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3685 /* update attribute */
3686 pattrib = &pmgntframe->attrib;
3687 update_mgntframe_attrib23a(padapter, pattrib);
3689 pattrib->hdrlen += 2;
3690 pattrib->qos_en = true;
3692 pattrib->ack_policy = 0;
3695 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3697 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3698 pwlanhdr = (struct ieee80211_hdr *)pframe;
3700 fctrl = &pwlanhdr->frame_control;
3703 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3705 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
3711 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
3713 SetPriority(qc, tid);
3715 SetEOSP(qc, pattrib->eosp);
3717 SetAckpolicy(qc, pattrib->ack_policy);
3719 ether_addr_copy(pwlanhdr->addr1, da);
3720 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3721 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3723 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3724 pmlmeext->mgnt_seq++;
3725 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
3727 pframe += sizeof(struct ieee80211_qos_hdr);
3728 pattrib->pktlen = sizeof(struct ieee80211_qos_hdr);
3730 pattrib->last_txcmdsz = pattrib->pktlen;
3733 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3735 dump_mgntframe23a(padapter, pmgntframe);
3743 /* when wait_ms >0 , this function shoule be called at process context */
3744 /* da == NULL for station mode */
3745 int issue_qos_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3746 u16 tid, int try_cnt, int wait_ms)
3750 unsigned long start = jiffies;
3751 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3752 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3754 /* da == NULL, assum it's null data for sta to ap*/
3756 da = get_my_bssid23a(&pmlmeinfo->network);
3759 ret = _issue_qos_nulldata23a(padapter, da, tid,
3760 wait_ms > 0 ? true : false);
3764 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3767 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3769 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
3776 if (try_cnt && wait_ms) {
3778 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
3779 "in %u ms\n", __func__,
3780 padapter->pnetdev->name,
3781 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3782 ret == _SUCCESS?", acked":"", i, try_cnt,
3783 jiffies_to_msecs(jiffies - start));
3785 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3786 __func__, padapter->pnetdev->name,
3787 rtw_get_oper_ch23a(padapter),
3788 ret == _SUCCESS?", acked":"", i, try_cnt,
3789 jiffies_to_msecs(jiffies - start));
3795 static int _issue_deauth23a(struct rtw_adapter *padapter, unsigned char *da,
3796 unsigned short reason, u8 wait_ack)
3798 struct xmit_frame *pmgntframe;
3799 struct pkt_attrib *pattrib;
3800 unsigned char *pframe;
3801 struct ieee80211_hdr *pwlanhdr;
3803 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3804 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3805 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3808 /* DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
3810 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3813 /* update attribute */
3814 pattrib = &pmgntframe->attrib;
3815 update_mgntframe_attrib23a(padapter, pattrib);
3816 pattrib->retry_ctrl = false;
3818 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3820 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3821 pwlanhdr = (struct ieee80211_hdr *)pframe;
3823 fctrl = &pwlanhdr->frame_control;
3826 ether_addr_copy(pwlanhdr->addr1, da);
3827 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3828 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3830 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3831 pmlmeext->mgnt_seq++;
3832 SetFrameSubType(pframe, WIFI_DEAUTH);
3834 pframe += sizeof(struct ieee80211_hdr_3addr);
3835 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3837 reason = cpu_to_le16(reason);
3838 pframe = rtw_set_fixed_ie23a(pframe, WLAN_REASON_PREV_AUTH_NOT_VALID,
3839 (unsigned char *)&reason,
3842 pattrib->last_txcmdsz = pattrib->pktlen;
3845 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3847 dump_mgntframe23a(padapter, pmgntframe);
3855 int issue_deauth23a(struct rtw_adapter *padapter, unsigned char *da,
3856 unsigned short reason)
3858 DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
3859 return _issue_deauth23a(padapter, da, reason, false);
3862 int issue_deauth23a_ex23a(struct rtw_adapter *padapter, u8 *da,
3863 unsigned short reason, int try_cnt, int wait_ms)
3867 unsigned long start = jiffies;
3870 ret = _issue_deauth23a(padapter, da, reason,
3871 wait_ms >0 ? true : false);
3875 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3878 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3881 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
3888 if (try_cnt && wait_ms) {
3890 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
3891 "in %u ms\n", __func__,
3892 padapter->pnetdev->name,
3893 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3894 ret == _SUCCESS?", acked":"", i, try_cnt,
3895 jiffies_to_msecs(jiffies - start));
3897 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3898 __func__, padapter->pnetdev->name,
3899 rtw_get_oper_ch23a(padapter),
3900 ret == _SUCCESS?", acked":"", i, try_cnt,
3901 jiffies_to_msecs(jiffies - start));
3907 void issue_action_spct_ch_switch23a(struct rtw_adapter *padapter,
3908 u8 *ra, u8 new_ch, u8 ch_offset)
3910 struct xmit_frame *pmgntframe;
3911 struct pkt_attrib *pattrib;
3912 unsigned char *pframe;
3913 struct ieee80211_hdr *pwlanhdr;
3915 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3916 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3917 u8 category, action;
3919 DBG_8723A("%s(%s): ra ="MAC_FMT", ch:%u, offset:%u\n", __func__,
3920 padapter->pnetdev->name, MAC_ARG(ra), new_ch, ch_offset);
3922 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3925 /* update attribute */
3926 pattrib = &pmgntframe->attrib;
3927 update_mgntframe_attrib23a(padapter, pattrib);
3929 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3931 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3932 pwlanhdr = (struct ieee80211_hdr *)pframe;
3934 fctrl = &pwlanhdr->frame_control;
3937 ether_addr_copy(pwlanhdr->addr1, ra); /* RA */
3938 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv)); /* TA */
3939 ether_addr_copy(pwlanhdr->addr3, ra); /* DA = RA */
3941 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3942 pmlmeext->mgnt_seq++;
3943 SetFrameSubType(pframe, WIFI_ACTION);
3945 pframe += sizeof(struct ieee80211_hdr_3addr);
3946 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3948 /* category, action */
3949 category = WLAN_CATEGORY_SPECTRUM_MGMT;
3950 action = WLAN_ACTION_SPCT_CHL_SWITCH;
3952 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
3953 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
3955 pframe = rtw_set_ie23a_ch_switch (pframe, &pattrib->pktlen, 0,
3957 pframe = rtw_set_ie23a_secondary_ch_offset(pframe, &pattrib->pktlen,
3958 hal_ch_offset_to_secondary_ch_offset23a(ch_offset));
3960 pattrib->last_txcmdsz = pattrib->pktlen;
3962 dump_mgntframe23a(padapter, pmgntframe);
3965 void issue_action_BA23a(struct rtw_adapter *padapter,
3966 const unsigned char *raddr,
3967 unsigned char action, unsigned short status)
3969 u8 category = WLAN_CATEGORY_BACK;
3973 u16 BA_timeout_value;
3974 u16 BA_starting_seqctrl;
3975 int max_rx_ampdu_factor;
3976 struct xmit_frame *pmgntframe;
3977 struct pkt_attrib *pattrib;
3979 struct ieee80211_hdr *pwlanhdr;
3981 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3982 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3983 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3984 struct sta_info *psta;
3985 struct sta_priv *pstapriv = &padapter->stapriv;
3986 struct registry_priv *pregpriv = &padapter->registrypriv;
3987 #ifdef CONFIG_8723AU_BT_COEXIST
3988 u8 tendaAPMac[] = {0xC8, 0x3A, 0x35};
3991 DBG_8723A("%s, category =%d, action =%d, status =%d\n",
3992 __func__, category, action, status);
3994 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3997 /* update attribute */
3998 pattrib = &pmgntframe->attrib;
3999 update_mgntframe_attrib23a(padapter, pattrib);
4001 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4003 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4004 pwlanhdr = (struct ieee80211_hdr *)pframe;
4006 fctrl = &pwlanhdr->frame_control;
4009 /* memcpy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN); */
4010 ether_addr_copy(pwlanhdr->addr1, raddr);
4011 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
4012 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
4014 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4015 pmlmeext->mgnt_seq++;
4016 SetFrameSubType(pframe, WIFI_ACTION);
4018 pframe += sizeof(struct ieee80211_hdr_3addr);
4019 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
4021 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
4022 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
4024 status = cpu_to_le16(status);
4031 case 0: /* ADDBA req */
4033 pmlmeinfo->dialogToken++;
4034 } while (pmlmeinfo->dialogToken == 0);
4035 pframe = rtw_set_fixed_ie23a(pframe, 1, &pmlmeinfo->dialogToken,
4038 #ifdef CONFIG_8723AU_BT_COEXIST
4039 if ((BT_1Ant(padapter) == true) &&
4040 ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
4041 memcmp(raddr, tendaAPMac, 3))) {
4042 /* A-MSDU NOT Supported */
4044 /* immediate Block Ack */
4045 BA_para_set |= (1 << 1) &
4046 IEEE80211_ADDBA_PARAM_POLICY_MASK;
4048 BA_para_set |= (status << 2) &
4049 IEEE80211_ADDBA_PARAM_TID_MASK;
4050 /* max buffer size is 8 MSDU */
4051 BA_para_set |= (8 << 6) &
4052 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4056 /* immediate ack & 64 buffer size */
4057 BA_para_set = (0x1002 | ((status & 0xf) << 2));
4059 BA_para_set = cpu_to_le16(BA_para_set);
4060 pframe = rtw_set_fixed_ie23a(pframe, 2,
4061 (unsigned char *)&BA_para_set,
4064 BA_timeout_value = 5000;/* 5ms */
4065 BA_timeout_value = cpu_to_le16(BA_timeout_value);
4066 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)
4070 /* if ((psta = rtw_get_stainfo23a(pstapriv,
4071 pmlmeinfo->network.MacAddress)) != NULL) */
4072 if ((psta = rtw_get_stainfo23a(pstapriv, raddr))) {
4073 start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1;
4075 DBG_8723A("BA_starting_seqctrl = %d for TID =%d\n",
4076 start_seq, status & 0x07);
4078 psta->BA_starting_seqctrl[status & 0x07] = start_seq;
4080 BA_starting_seqctrl = start_seq << 4;
4083 BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
4084 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)&BA_starting_seqctrl, &pattrib->pktlen);
4087 case 1: /* ADDBA rsp */
4088 pframe = rtw_set_fixed_ie23a(pframe, 1, &pmlmeinfo->ADDBA_req.dialog_token, &pattrib->pktlen);
4089 pframe = rtw_set_fixed_ie23a(pframe, 2,
4090 (unsigned char *)&status,
4092 rtw_hal_get_def_var23a(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
4093 &max_rx_ampdu_factor);
4094 if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_64K)
4095 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
4096 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_32K)
4097 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800); /* 32 buffer size */
4098 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_16K)
4099 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0400); /* 16 buffer size */
4100 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_8K)
4101 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0200); /* 8 buffer size */
4103 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
4105 #ifdef CONFIG_8723AU_BT_COEXIST
4106 if ((BT_1Ant(padapter) == true) &&
4107 ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
4108 memcmp(raddr, tendaAPMac, 3))) {
4109 /* max buffer size is 8 MSDU */
4110 BA_para_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4111 BA_para_set |= (8 << 6) &
4112 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4116 if (pregpriv->ampdu_amsdu == 0)/* disabled */
4117 BA_para_set = cpu_to_le16(BA_para_set & ~BIT(0));
4118 else if (pregpriv->ampdu_amsdu == 1)/* enabled */
4119 BA_para_set = cpu_to_le16(BA_para_set | BIT(0));
4121 BA_para_set = cpu_to_le16(BA_para_set);
4123 pframe = rtw_set_fixed_ie23a(pframe, 2,
4124 (unsigned char *)&BA_para_set,
4126 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)&pmlmeinfo->ADDBA_req.BA_timeout_value, &pattrib->pktlen);
4129 BA_para_set = (status & 0x1F) << 3;
4130 BA_para_set = cpu_to_le16(BA_para_set);
4131 pframe = rtw_set_fixed_ie23a(pframe, 2,
4132 (unsigned char *)&BA_para_set,
4135 reason_code = 37;/* Requested from peer STA as it does not
4136 want to use the mechanism */
4137 reason_code = cpu_to_le16(reason_code);
4138 pframe = rtw_set_fixed_ie23a(pframe, 2,
4139 (unsigned char *)&reason_code,
4147 pattrib->last_txcmdsz = pattrib->pktlen;
4149 dump_mgntframe23a(padapter, pmgntframe);
4152 static void issue_action_BSSCoexistPacket(struct rtw_adapter *padapter)
4154 struct list_head *plist, *phead, *ptmp;
4155 unsigned char category, action;
4156 struct xmit_frame *pmgntframe;
4157 struct pkt_attrib *pattrib;
4159 struct ieee80211_hdr *pwlanhdr;
4161 struct wlan_network *pnetwork;
4162 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4163 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4164 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4165 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4166 struct rtw_queue *queue = &pmlmepriv->scanned_queue;
4167 u8 InfoContent[16] = {0};
4171 if (pmlmepriv->num_FortyMHzIntolerant == 0 ||
4172 pmlmepriv->num_sta_no_ht == 0)
4175 if (pmlmeinfo->bwmode_updated)
4178 DBG_8723A("%s\n", __func__);
4180 category = WLAN_CATEGORY_PUBLIC;
4181 action = ACT_PUBLIC_BSSCOEXIST;
4183 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
4187 /* update attribute */
4188 pattrib = &pmgntframe->attrib;
4189 update_mgntframe_attrib23a(padapter, pattrib);
4191 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4193 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
4194 pwlanhdr = (struct ieee80211_hdr *)pframe;
4196 fctrl = &pwlanhdr->frame_control;
4199 ether_addr_copy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network));
4200 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
4201 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
4203 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4204 pmlmeext->mgnt_seq++;
4205 SetFrameSubType(pframe, WIFI_ACTION);
4207 pframe += sizeof(struct ieee80211_hdr_3addr);
4208 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
4210 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
4211 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
4213 if (pmlmepriv->num_FortyMHzIntolerant > 0) {
4214 u8 iedata = BIT(2);/* 20 MHz BSS Width Request */
4216 pframe = rtw_set_ie23a(pframe, WLAN_EID_BSS_COEX_2040, 1,
4217 &iedata, &pattrib->pktlen);
4220 if (pmlmepriv->num_sta_no_ht <= 0)
4223 memset(ICS, 0, sizeof(ICS));
4225 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
4227 phead = get_list_head(queue);
4228 plist = phead->next;
4230 list_for_each_safe(plist, ptmp, phead) {
4232 struct wlan_bssid_ex *pbss_network;
4234 pnetwork = container_of(plist, struct wlan_network, list);
4236 pbss_network = &pnetwork->network;
4238 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
4239 pbss_network->IEs + _FIXED_IE_LENGTH_,
4240 pbss_network->IELength -_FIXED_IE_LENGTH_);
4241 if (!p || !p[1]) { /* non-HT */
4242 if (pbss_network->Configuration.DSConfig <= 0 ||
4243 pbss_network->Configuration.DSConfig > 14)
4246 ICS[0][pbss_network->Configuration.DSConfig] = 1;
4254 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
4256 for (i = 0; i < 8;i++) {
4257 if (ICS[i][0] == 1) {
4261 /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */
4264 for (j = 1; j <= 14; j++) {
4265 if (ICS[i][j] == 1) {
4267 /* channel number */
4274 pframe = rtw_set_ie23a(pframe,
4275 EID_BSSIntolerantChlReport, k,
4276 InfoContent, &pattrib->pktlen);
4281 pattrib->last_txcmdsz = pattrib->pktlen;
4283 dump_mgntframe23a(padapter, pmgntframe);
4286 unsigned int send_delba23a(struct rtw_adapter *padapter, u8 initiator, u8 *addr)
4288 struct sta_priv *pstapriv = &padapter->stapriv;
4289 struct sta_info *psta = NULL;
4290 /* struct recv_reorder_ctrl *preorder_ctrl; */
4291 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4292 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4295 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
4296 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
4299 psta = rtw_get_stainfo23a(pstapriv, addr);
4303 if (initiator == 0) { /* recipient */
4304 for (tid = 0; tid < MAXTID; tid++) {
4305 if (psta->recvreorder_ctrl[tid].enable == true) {
4306 DBG_8723A("rx agg disable tid(%d)\n", tid);
4307 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
4308 psta->recvreorder_ctrl[tid].enable = false;
4309 psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
4312 } else if (initiator == 1) { /* originator */
4313 for (tid = 0; tid < MAXTID; tid++) {
4314 if (psta->htpriv.agg_enable_bitmap & BIT(tid)) {
4315 DBG_8723A("tx agg disable tid(%d)\n", tid);
4316 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
4317 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
4318 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
4326 unsigned int send_beacon23a(struct rtw_adapter *padapter)
4331 unsigned long start = jiffies;
4332 unsigned int passing_time;
4334 rtl8723a_bcn_valid(padapter);
4336 issue_beacon23a(padapter, 100);
4340 bxmitok = rtl8723a_get_bcn_valid(padapter);
4342 } while ((poll % 10) != 0 && bxmitok == false &&
4343 !padapter->bSurpriseRemoved &&
4344 !padapter->bDriverStopped);
4346 } while (!bxmitok && issue<100 && !padapter->bSurpriseRemoved &&
4347 !padapter->bDriverStopped);
4349 if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
4352 passing_time = jiffies_to_msecs(jiffies - start);
4355 DBG_8723A("%s fail! %u ms\n", __func__, passing_time);
4359 if (passing_time > 100 || issue > 3)
4360 DBG_8723A("%s success, issue:%d, poll:%d, %u ms\n",
4361 __func__, issue, poll, passing_time);
4366 /****************************************************************************
4368 Following are some utitity fuctions for WiFi MLME
4370 *****************************************************************************/
4372 bool IsLegal5GChannel(struct rtw_adapter *Adapter, u8 channel)
4376 u8 Channel_5G[45] = {36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
4377 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
4378 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
4380 for (i = 0; i < sizeof(Channel_5G); i++)
4381 if (channel == Channel_5G[i])
4386 void site_survey23a(struct rtw_adapter *padapter)
4388 unsigned char survey_channel = 0;
4389 enum rt_scan_type ScanType = SCAN_PASSIVE;
4390 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4391 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4392 struct rtw_ieee80211_channel *ch;
4394 if (pmlmeext->sitesurvey_res.channel_idx <
4395 pmlmeext->sitesurvey_res.ch_num) {
4396 ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
4397 survey_channel = ch->hw_value;
4398 ScanType = (ch->flags & IEEE80211_CHAN_NO_IR) ?
4399 SCAN_PASSIVE : SCAN_ACTIVE;
4402 if (survey_channel != 0) {
4403 /* PAUSE 4-AC Queue when site_survey23a */
4404 if (pmlmeext->sitesurvey_res.channel_idx == 0)
4405 set_channel_bwmode23a(padapter, survey_channel,
4406 HAL_PRIME_CHNL_OFFSET_DONT_CARE,
4407 HT_CHANNEL_WIDTH_20);
4409 SelectChannel23a(padapter, survey_channel);
4411 if (ScanType == SCAN_ACTIVE) /* obey the channel plan setting... */
4414 for (i = 0;i<RTW_SSID_SCAN_AMOUNT;i++) {
4415 if (pmlmeext->sitesurvey_res.ssid[i].ssid_len) {
4416 /* todo: to issue two probe req??? */
4417 issue_probereq23a(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
4418 /* msleep(SURVEY_TO>>1); */
4419 issue_probereq23a(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
4423 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
4424 /* todo: to issue two probe req??? */
4425 issue_probereq23a(padapter, NULL, NULL);
4426 /* msleep(SURVEY_TO>>1); */
4427 issue_probereq23a(padapter, NULL, NULL);
4431 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
4433 /* channel number is 0 or this channel is not valid. */
4434 pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
4436 /* switch back to the original channel */
4438 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
4439 pmlmeext->cur_ch_offset,
4440 pmlmeext->cur_bwmode);
4442 /* flush 4-AC Queue after site_survey23a */
4446 Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
4448 /* restore RX GAIN */
4449 rtl8723a_set_initial_gain(padapter, 0xff);
4450 /* turn on dynamic functions */
4451 rtl8723a_odm_support_ability_restore(padapter);
4453 if (is_client_associated_to_ap23a(padapter) == true)
4454 issue_nulldata23a(padapter, NULL, 0, 3, 500);
4456 rtl8723a_mlme_sitesurvey(padapter, 0);
4458 report_surveydone_event23a(padapter);
4460 pmlmeext->chan_scan_time = SURVEY_TO;
4461 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
4463 issue_action_BSSCoexistPacket(padapter);
4464 issue_action_BSSCoexistPacket(padapter);
4465 issue_action_BSSCoexistPacket(padapter);
4471 /* collect bss info from Beacon and Probe request/response frames. */
4472 u8 collect_bss_info23a(struct rtw_adapter *padapter,
4473 struct recv_frame *precv_frame,
4474 struct wlan_bssid_ex *bssid)
4478 struct sk_buff *skb = precv_frame->pkt;
4479 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
4480 unsigned int length;
4482 struct registry_priv *pregistrypriv = &padapter->registrypriv;
4483 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4484 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4487 length = skb->len - sizeof(struct ieee80211_hdr_3addr);
4489 if (length > MAX_IE_SZ) {
4490 /* DBG_8723A("IE too long for survey event\n"); */
4494 memset(bssid, 0, sizeof(struct wlan_bssid_ex));
4496 if (ieee80211_is_beacon(mgmt->frame_control)) {
4497 bssid->reserved = 1;
4498 ie_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
4499 capab_info = mgmt->u.beacon.capab_info;
4500 } else if (ieee80211_is_probe_req(mgmt->frame_control)) {
4501 ie_offset = offsetof(struct ieee80211_mgmt,
4502 u.probe_req.variable);
4503 bssid->reserved = 2;
4505 } else if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4506 ie_offset = offsetof(struct ieee80211_mgmt,
4507 u.probe_resp.variable);
4508 bssid->reserved = 3;
4509 capab_info = mgmt->u.probe_resp.capab_info;
4511 bssid->reserved = 0;
4512 ie_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
4513 capab_info = mgmt->u.beacon.capab_info;
4515 ie_offset -= offsetof(struct ieee80211_mgmt, u);
4517 bssid->Length = offsetof(struct wlan_bssid_ex, IEs) + length;
4519 /* below is to copy the information element */
4520 bssid->IELength = length;
4521 memcpy(bssid->IEs, &mgmt->u, bssid->IELength);
4523 /* get the signal strength */
4524 /* in dBM.raw data */
4525 bssid->Rssi = precv_frame->attrib.phy_info.RecvSignalPower;
4526 bssid->PhyInfo.SignalQuality =
4527 precv_frame->attrib.phy_info.SignalQuality;/* in percentage */
4528 bssid->PhyInfo.SignalStrength =
4529 precv_frame->attrib.phy_info.SignalStrength;/* in percentage */
4532 p = cfg80211_find_ie(WLAN_EID_SSID, bssid->IEs + ie_offset,
4533 bssid->IELength - ie_offset);
4536 DBG_8723A("marc: cannot find SSID for survey event\n");
4540 if (p[1] > IEEE80211_MAX_SSID_LEN) {
4541 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4542 "event\n", __func__, __LINE__, p[1]);
4545 memcpy(bssid->Ssid.ssid, p + 2, p[1]);
4546 bssid->Ssid.ssid_len = p[1];
4548 memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
4550 /* checking rate info... */
4552 p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, bssid->IEs + ie_offset,
4553 bssid->IELength - ie_offset);
4555 if (p[1] > NDIS_802_11_LENGTH_RATES_EX) {
4556 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4557 "event\n", __func__, __LINE__, p[1]);
4560 memcpy(bssid->SupportedRates, p + 2, p[1]);
4564 p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, bssid->IEs + ie_offset,
4565 bssid->IELength - ie_offset);
4567 if (p[1] > (NDIS_802_11_LENGTH_RATES_EX-i)) {
4568 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4569 "event\n", __func__, __LINE__, p[1]);
4572 memcpy(bssid->SupportedRates + i, p + 2, p[1]);
4575 bssid->NetworkTypeInUse = Ndis802_11OFDM24;
4577 if (bssid->IELength < 12)
4580 /* Checking for DSConfig */
4581 p = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bssid->IEs + ie_offset,
4582 bssid->IELength - ie_offset);
4584 bssid->Configuration.DSConfig = 0;
4585 bssid->Configuration.Length = 0;
4588 bssid->Configuration.DSConfig = p[2];
4589 } else {/* In 5G, some ap do not have DSSET IE */
4590 /* checking HT info for channel */
4591 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
4592 bssid->IEs + ie_offset,
4593 bssid->IELength - ie_offset);
4595 struct HT_info_element *HT_info =
4596 (struct HT_info_element *)(p + 2);
4597 bssid->Configuration.DSConfig =
4598 HT_info->primary_channel;
4599 } else { /* use current channel */
4600 bssid->Configuration.DSConfig =
4601 rtw_get_oper_ch23a(padapter);
4605 if (ieee80211_is_probe_req(mgmt->frame_control)) {
4607 bssid->InfrastructureMode = Ndis802_11Infrastructure;
4608 ether_addr_copy(bssid->MacAddress, mgmt->sa);
4613 memcpy(&bssid->Configuration.BeaconPeriod,
4614 rtw_get_beacon_interval23a_from_ie(bssid->IEs), 2);
4615 bssid->Configuration.BeaconPeriod =
4616 le32_to_cpu(bssid->Configuration.BeaconPeriod);
4618 if (capab_info & BIT(0)) {
4619 bssid->InfrastructureMode = Ndis802_11Infrastructure;
4620 ether_addr_copy(bssid->MacAddress, mgmt->sa);
4622 bssid->InfrastructureMode = Ndis802_11IBSS;
4623 ether_addr_copy(bssid->MacAddress, mgmt->bssid);
4626 if (capab_info & BIT(4))
4631 bssid->Configuration.ATIMWindow = 0;
4633 /* 20/40 BSS Coexistence check */
4634 if (pregistrypriv->wifi_spec == 1 &&
4635 pmlmeinfo->bwmode_updated == false) {
4636 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4638 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
4639 bssid->IEs + ie_offset,
4640 bssid->IELength - ie_offset);
4641 if (p && p[1] > 0) {
4642 struct HT_caps_element *pHT_caps;
4643 pHT_caps = (struct HT_caps_element *)(p + 2);
4645 if (pHT_caps->u.HT_cap_element.HT_caps_info & BIT(14))
4646 pmlmepriv->num_FortyMHzIntolerant++;
4648 pmlmepriv->num_sta_no_ht++;
4652 /* mark bss info receving from nearby channel as SignalQuality 101 */
4653 if (bssid->Configuration.DSConfig != rtw_get_oper_ch23a(padapter))
4654 bssid->PhyInfo.SignalQuality = 101;
4659 void start_create_ibss23a(struct rtw_adapter* padapter)
4661 unsigned short caps;
4662 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4663 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4664 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
4665 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
4666 pmlmeinfo->bcn_interval = get_beacon_interval23a(pnetwork);
4668 /* update wireless mode */
4669 update_wireless_mode23a(padapter);
4671 /* udpate capability */
4672 caps = rtw_get_capability23a(pnetwork);
4673 update_capinfo23a(padapter, caps);
4674 if (caps&cap_IBSS) { /* adhoc master */
4675 rtl8723a_set_sec_cfg(padapter, 0xcf);
4677 /* switch channel */
4678 /* SelectChannel23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
4679 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4681 beacon_timing_control23a(padapter);
4683 /* set msr to WIFI_FW_ADHOC_STATE */
4684 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4685 Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
4688 if (send_beacon23a(padapter) == _FAIL)
4690 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("issuing beacon frame fail....\n"));
4692 report_join_res23a(padapter, -1);
4693 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4697 hw_var_set_bssid(padapter, padapter->registrypriv.dev_network.MacAddress);
4698 hw_var_set_mlme_join(padapter, 0);
4700 report_join_res23a(padapter, 1);
4701 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
4706 DBG_8723A("start_create_ibss23a, invalid cap:%x\n", caps);
4711 void start_clnt_join23a(struct rtw_adapter* padapter)
4713 unsigned short caps;
4715 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4716 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4717 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
4720 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
4721 pmlmeinfo->bcn_interval = get_beacon_interval23a(pnetwork);
4723 /* update wireless mode */
4724 update_wireless_mode23a(padapter);
4726 /* udpate capability */
4727 caps = rtw_get_capability23a(pnetwork);
4728 update_capinfo23a(padapter, caps);
4730 /* switch channel */
4731 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4733 Set_MSR23a(padapter, WIFI_FW_STATION_STATE);
4735 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ?
4738 rtl8723a_set_sec_cfg(padapter, val8);
4740 /* switch channel */
4741 /* set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
4743 /* here wait for receiving the beacon to start auth */
4744 /* and enable a timer */
4745 beacon_timeout = decide_wait_for_beacon_timeout23a(pmlmeinfo->bcn_interval);
4746 set_link_timer(pmlmeext, beacon_timeout);
4747 mod_timer(&padapter->mlmepriv.assoc_timer, jiffies +
4748 msecs_to_jiffies((REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) + beacon_timeout));
4749 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
4751 else if (caps&cap_IBSS) { /* adhoc client */
4752 Set_MSR23a(padapter, WIFI_FW_ADHOC_STATE);
4754 rtl8723a_set_sec_cfg(padapter, 0xcf);
4756 /* switch channel */
4757 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4759 beacon_timing_control23a(padapter);
4761 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4763 report_join_res23a(padapter, 1);
4767 /* DBG_8723A("marc: invalid cap:%x\n", caps); */
4772 void start_clnt_auth23a(struct rtw_adapter* padapter)
4774 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4775 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4777 del_timer_sync(&pmlmeext->link_timer);
4779 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
4780 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
4782 pmlmeinfo->auth_seq = 1;
4783 pmlmeinfo->reauth_count = 0;
4784 pmlmeinfo->reassoc_count = 0;
4785 pmlmeinfo->link_count = 0;
4786 pmlmeext->retry = 0;
4788 /* Because of AP's not receiving deauth before */
4789 /* AP may: 1)not response auth or 2)deauth us after link is complete */
4790 /* issue deauth before issuing auth to deal with the situation */
4791 /* Commented by Albert 2012/07/21 */
4792 /* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
4793 issue_deauth23a(padapter, (&pmlmeinfo->network)->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
4795 DBG_8723A_LEVEL(_drv_always_, "start auth\n");
4796 issue_auth23a(padapter, NULL, 0);
4798 set_link_timer(pmlmeext, REAUTH_TO);
4801 void start_clnt_assoc23a(struct rtw_adapter* padapter)
4803 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4804 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4806 del_timer_sync(&pmlmeext->link_timer);
4808 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
4809 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
4811 issue_assocreq23a(padapter);
4813 set_link_timer(pmlmeext, REASSOC_TO);
4816 unsigned int receive_disconnect23a(struct rtw_adapter *padapter, unsigned char *MacAddr, unsigned short reason)
4818 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4819 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4822 if (!ether_addr_equal(MacAddr, get_my_bssid23a(&pmlmeinfo->network)))
4825 DBG_8723A("%s\n", __func__);
4827 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
4829 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
4831 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4832 report_del_sta_event23a(padapter, MacAddr, reason);
4835 else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
4837 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4838 report_join_res23a(padapter, -2);
4845 static void process_80211d(struct rtw_adapter *padapter,
4846 struct wlan_bssid_ex *bssid)
4848 struct registry_priv *pregistrypriv;
4849 struct mlme_ext_priv *pmlmeext;
4850 struct rt_channel_info *chplan_new;
4854 pregistrypriv = &padapter->registrypriv;
4855 pmlmeext = &padapter->mlmeextpriv;
4857 /* Adjust channel plan by AP Country IE */
4858 if (pregistrypriv->enable80211d &&
4859 !pmlmeext->update_channel_plan_by_ap_done) {
4861 struct rt_channel_plan chplan_ap;
4862 struct rt_channel_info chplan_sta[MAX_CHANNEL_NUM];
4864 u8 fcn; /* first channel number */
4865 u8 noc; /* number of channel */
4868 ie = cfg80211_find_ie(WLAN_EID_COUNTRY,
4869 bssid->IEs + _FIXED_IE_LENGTH_,
4870 bssid->IELength - _FIXED_IE_LENGTH_);
4871 if (!ie || ie[1] < IEEE80211_COUNTRY_IE_MIN_LEN)
4878 memcpy(country, p, 3);
4882 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
4883 ("%s: 802.11d country =%s\n", __func__, country));
4886 while ((ie - p) >= 3) {
4891 for (j = 0; j < noc; j++) {
4893 channel = fcn + j; /* 2.4 GHz */
4895 channel = fcn + j * 4; /* 5 GHz */
4897 chplan_ap.Channel[i++] = channel;
4902 memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
4903 memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
4904 chplan_new = pmlmeext->channel_set;
4907 if (pregistrypriv->wireless_mode & WIRELESS_11G) {
4909 if (i == MAX_CHANNEL_NUM ||
4910 chplan_sta[i].ChannelNum == 0 ||
4911 chplan_sta[i].ChannelNum > 14)
4914 if (j == chplan_ap.Len ||
4915 chplan_ap.Channel[j] > 14)
4918 if (chplan_sta[i].ChannelNum ==
4919 chplan_ap.Channel[j]) {
4920 chplan_new[k].ChannelNum =
4921 chplan_ap.Channel[j];
4922 chplan_new[k].ScanType = SCAN_ACTIVE;
4926 } else if (chplan_sta[i].ChannelNum <
4927 chplan_ap.Channel[j]) {
4928 chplan_new[k].ChannelNum =
4929 chplan_sta[i].ChannelNum;
4930 chplan_new[k].ScanType =
4934 } else if (chplan_sta[i].ChannelNum >
4935 chplan_ap.Channel[j]) {
4936 chplan_new[k].ChannelNum =
4937 chplan_ap.Channel[j];
4938 chplan_new[k].ScanType =
4945 /* change AP not support channel to Passive scan */
4946 while (i < MAX_CHANNEL_NUM &&
4947 chplan_sta[i].ChannelNum != 0 &&
4948 chplan_sta[i].ChannelNum <= 14) {
4949 chplan_new[k].ChannelNum =
4950 chplan_sta[i].ChannelNum;
4951 chplan_new[k].ScanType = SCAN_PASSIVE;
4956 /* add channel AP supported */
4957 while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14){
4958 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4959 chplan_new[k].ScanType = SCAN_ACTIVE;
4964 /* keep original STA 2.4G channel plan */
4965 while (i < MAX_CHANNEL_NUM &&
4966 chplan_sta[i].ChannelNum != 0 &&
4967 chplan_sta[i].ChannelNum <= 14) {
4968 chplan_new[k].ChannelNum =
4969 chplan_sta[i].ChannelNum;
4970 chplan_new[k].ScanType = chplan_sta[i].ScanType;
4975 /* skip AP 2.4G channel plan */
4976 while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14)
4980 if (pregistrypriv->wireless_mode & WIRELESS_11A) {
4982 if (i == MAX_CHANNEL_NUM ||
4983 chplan_sta[i].ChannelNum == 0)
4986 if (j == chplan_ap.Len ||
4987 chplan_ap.Channel[j] == 0)
4990 if (chplan_sta[i].ChannelNum ==
4991 chplan_ap.Channel[j]) {
4992 chplan_new[k].ChannelNum =
4993 chplan_ap.Channel[j];
4994 chplan_new[k].ScanType = SCAN_ACTIVE;
4998 } else if (chplan_sta[i].ChannelNum <
4999 chplan_ap.Channel[j]) {
5000 chplan_new[k].ChannelNum =
5001 chplan_sta[i].ChannelNum;
5002 chplan_new[k].ScanType = SCAN_PASSIVE;
5005 } else if (chplan_sta[i].ChannelNum >
5006 chplan_ap.Channel[j]) {
5007 chplan_new[k].ChannelNum =
5008 chplan_ap.Channel[j];
5009 chplan_new[k].ScanType = SCAN_ACTIVE;
5015 /* change AP not support channel to Passive scan */
5016 while (i < MAX_CHANNEL_NUM &&
5017 chplan_sta[i].ChannelNum != 0) {
5018 chplan_new[k].ChannelNum =
5019 chplan_sta[i].ChannelNum;
5020 chplan_new[k].ScanType = SCAN_PASSIVE;
5025 /* add channel AP supported */
5026 while (j < chplan_ap.Len && chplan_ap.Channel[j] != 0) {
5027 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
5028 chplan_new[k].ScanType = SCAN_ACTIVE;
5033 /* keep original STA 5G channel plan */
5034 while (i < MAX_CHANNEL_NUM &&
5035 chplan_sta[i].ChannelNum != 0) {
5036 chplan_new[k].ChannelNum =
5037 chplan_sta[i].ChannelNum;
5038 chplan_new[k].ScanType = chplan_sta[i].ScanType;
5043 pmlmeext->update_channel_plan_by_ap_done = 1;
5046 /* If channel is used by AP, set channel scan type to active */
5047 channel = bssid->Configuration.DSConfig;
5048 chplan_new = pmlmeext->channel_set;
5050 while (i < MAX_CHANNEL_NUM && chplan_new[i].ChannelNum != 0) {
5051 if (chplan_new[i].ChannelNum == channel) {
5052 if (chplan_new[i].ScanType == SCAN_PASSIVE) {
5053 /* 5G Bnad 2, 3 (DFS) doesn't change
5055 if (channel >= 52 && channel <= 144)
5058 chplan_new[i].ScanType = SCAN_ACTIVE;
5059 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
5060 ("%s: change channel %d scan type "
5061 "from passive to active\n",
5062 __func__, channel));
5070 /****************************************************************************
5072 Following are the functions to report events
5074 *****************************************************************************/
5076 void report_survey_event23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
5078 struct cmd_obj *pcmd_obj;
5081 struct survey_event *psurvey_evt;
5082 struct C2HEvent_Header *pc2h_evt_hdr;
5083 struct mlme_ext_priv *pmlmeext;
5084 struct cmd_priv *pcmdpriv;
5089 pmlmeext = &padapter->mlmeextpriv;
5090 pcmdpriv = &padapter->cmdpriv;
5092 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5097 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
5098 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5104 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5105 pcmd_obj->cmdsz = cmdsz;
5106 pcmd_obj->parmbuf = pevtcmd;
5108 pcmd_obj->rsp = NULL;
5109 pcmd_obj->rspsz = 0;
5111 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5112 pc2h_evt_hdr->len = sizeof(struct survey_event);
5113 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
5114 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5116 psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5118 if (collect_bss_info23a(padapter, precv_frame, &psurvey_evt->bss) == _FAIL) {
5124 process_80211d(padapter, &psurvey_evt->bss);
5126 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5128 pmlmeext->sitesurvey_res.bss_cnt++;
5133 void report_surveydone_event23a(struct rtw_adapter *padapter)
5135 struct cmd_obj *pcmd_obj;
5138 struct surveydone_event *psurveydone_evt;
5139 struct C2HEvent_Header *pc2h_evt_hdr;
5140 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5141 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5143 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5148 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
5149 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5155 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5156 pcmd_obj->cmdsz = cmdsz;
5157 pcmd_obj->parmbuf = pevtcmd;
5159 pcmd_obj->rsp = NULL;
5160 pcmd_obj->rspsz = 0;
5162 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5163 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
5164 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
5165 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5167 psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5168 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
5170 DBG_8723A("survey done event(%x)\n", psurveydone_evt->bss_cnt);
5172 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5177 void report_join_res23a(struct rtw_adapter *padapter, int res)
5179 struct cmd_obj *pcmd_obj;
5182 struct joinbss_event *pjoinbss_evt;
5183 struct C2HEvent_Header *pc2h_evt_hdr;
5184 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5185 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5186 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5188 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5193 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
5194 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5200 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5201 pcmd_obj->cmdsz = cmdsz;
5202 pcmd_obj->parmbuf = pevtcmd;
5204 pcmd_obj->rsp = NULL;
5205 pcmd_obj->rspsz = 0;
5207 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5208 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
5209 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
5210 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5212 pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5213 memcpy((unsigned char *)&pjoinbss_evt->network.network,
5214 &pmlmeinfo->network, sizeof(struct wlan_bssid_ex));
5215 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
5217 DBG_8723A("report_join_res23a(%d)\n", res);
5219 rtw_joinbss_event_prehandle23a(padapter, (u8 *)&pjoinbss_evt->network);
5221 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5226 void report_del_sta_event23a(struct rtw_adapter *padapter, unsigned char* MacAddr, unsigned short reason)
5228 struct cmd_obj *pcmd_obj;
5231 struct sta_info *psta;
5233 struct stadel_event *pdel_sta_evt;
5234 struct C2HEvent_Header *pc2h_evt_hdr;
5235 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5236 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5238 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5243 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
5244 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5250 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5251 pcmd_obj->cmdsz = cmdsz;
5252 pcmd_obj->parmbuf = pevtcmd;
5254 pcmd_obj->rsp = NULL;
5255 pcmd_obj->rspsz = 0;
5257 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5258 pc2h_evt_hdr->len = sizeof(struct stadel_event);
5259 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
5260 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5262 pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5263 ether_addr_copy((unsigned char *)&pdel_sta_evt->macaddr, MacAddr);
5264 memcpy((unsigned char *)pdel_sta_evt->rsvd, (unsigned char *)&reason,
5267 psta = rtw_get_stainfo23a(&padapter->stapriv, MacAddr);
5269 mac_id = (int)psta->mac_id;
5273 pdel_sta_evt->mac_id = mac_id;
5275 DBG_8723A("report_del_sta_event23a: delete STA, mac_id =%d\n", mac_id);
5277 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5282 void report_add_sta_event23a(struct rtw_adapter *padapter, unsigned char* MacAddr, int cam_idx)
5284 struct cmd_obj *pcmd_obj;
5287 struct stassoc_event *padd_sta_evt;
5288 struct C2HEvent_Header *pc2h_evt_hdr;
5289 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5290 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5292 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5297 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
5298 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5304 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5305 pcmd_obj->cmdsz = cmdsz;
5306 pcmd_obj->parmbuf = pevtcmd;
5308 pcmd_obj->rsp = NULL;
5309 pcmd_obj->rspsz = 0;
5311 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5312 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
5313 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
5314 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5316 padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5317 ether_addr_copy((unsigned char *)&padd_sta_evt->macaddr, MacAddr);
5318 padd_sta_evt->cam_id = cam_idx;
5320 DBG_8723A("report_add_sta_event23a: add STA\n");
5322 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5327 /****************************************************************************
5329 Following are the event callback functions
5331 *****************************************************************************/
5333 /* for sta/adhoc mode */
5334 void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta)
5336 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5337 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5338 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5341 VCS_update23a(padapter, psta);
5344 if (pmlmepriv->htpriv.ht_option)
5346 psta->htpriv.ht_option = true;
5348 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
5350 if (support_short_GI23a(padapter, &pmlmeinfo->HT_caps))
5351 psta->htpriv.sgi = true;
5353 psta->qos_option = true;
5358 psta->htpriv.ht_option = false;
5360 psta->htpriv.ampdu_enable = false;
5362 psta->htpriv.sgi = false;
5363 psta->qos_option = false;
5366 psta->htpriv.bwmode = pmlmeext->cur_bwmode;
5367 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
5369 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
5370 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
5373 if (pmlmepriv->qos_option)
5374 psta->qos_option = true;
5376 psta->state = _FW_LINKED;
5379 void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter, int join_res)
5381 struct sta_info *psta, *psta_bmc;
5382 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5383 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5384 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
5385 struct sta_priv *pstapriv = &padapter->stapriv;
5388 hw_var_set_mlme_join(padapter, 1);
5389 hw_var_set_bssid(padapter, null_addr);
5391 /* restore to initial setting. */
5392 update_tx_basic_rate23a(padapter,
5393 padapter->registrypriv.wireless_mode);
5395 goto exit_mlmeext_joinbss_event_callback23a;
5398 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
5401 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
5404 pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc;
5405 update_bmc_sta_support_rate23a(padapter, psta_bmc->mac_id);
5406 Update_RA_Entry23a(padapter, psta_bmc);
5410 /* turn on dynamic functions */
5411 rtl8723a_odm_support_ability_set(padapter, DYNAMIC_ALL_FUNC_ENABLE);
5413 /* update IOT-releated issue */
5414 update_IOT_info23a(padapter);
5416 HalSetBrateCfg23a(padapter, cur_network->SupportedRates);
5419 rtl8723a_set_beacon_interval(padapter, pmlmeinfo->bcn_interval);
5421 /* udpate capability */
5422 update_capinfo23a(padapter, pmlmeinfo->capability);
5424 /* WMM, Update EDCA param */
5425 WMMOnAssocRsp23a(padapter);
5428 HTOnAssocRsp23a(padapter);
5430 /* Set cur_channel&cur_bwmode&cur_ch_offset */
5431 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5433 psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
5434 if (psta) /* only for infra. mode */
5436 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5438 /* DBG_8723A("set_sta_rate23a\n"); */
5440 psta->wireless_mode = pmlmeext->cur_wireless_mode;
5442 /* set per sta rate after updating HT cap. */
5443 set_sta_rate23a(padapter, psta);
5446 hw_var_set_mlme_join(padapter, 2);
5448 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
5449 /* correcting TSF */
5450 rtw_correct_TSF(padapter);
5452 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5455 rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_CONNECT, 0);
5457 exit_mlmeext_joinbss_event_callback23a:
5458 DBG_8723A("=>%s\n", __func__);
5461 void mlmeext_sta_add_event_callback23a(struct rtw_adapter *padapter, struct sta_info *psta)
5463 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5464 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5466 DBG_8723A("%s\n", __func__);
5468 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
5470 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)/* adhoc master or sta_count>1 */
5474 else/* adhoc client */
5476 /* correcting TSF */
5477 rtw_correct_TSF(padapter);
5480 if (send_beacon23a(padapter) == _FAIL)
5482 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
5484 pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
5489 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
5493 hw_var_set_mlme_join(padapter, 2);
5496 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5498 /* rate radaptive */
5499 Update_RA_Entry23a(padapter, psta);
5501 /* update adhoc sta_info */
5502 update_sta_info23a(padapter, psta);
5505 void mlmeext_sta_del_event_callback23a(struct rtw_adapter *padapter)
5507 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5508 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5510 if (is_client_associated_to_ap23a(padapter) || is_IBSS_empty23a(padapter))
5512 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
5514 hw_var_set_mlme_disconnect(padapter);
5515 hw_var_set_bssid(padapter, null_addr);
5517 /* restore to initial setting. */
5518 update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
5520 /* switch to the 20M Hz mode after disconnect */
5521 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5522 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5524 /* SelectChannel23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
5525 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5527 flush_all_cam_entry23a(padapter);
5529 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5531 /* set MSR to no link state -> infra. mode */
5532 Set_MSR23a(padapter, _HW_STATE_STATION_);
5534 del_timer_sync(&pmlmeext->link_timer);
5538 static u8 chk_ap_is_alive(struct rtw_adapter *padapter, struct sta_info *psta)
5542 if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)) &&
5543 sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) &&
5544 sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
5549 sta_update_last_rx_pkts(psta);
5553 void linked_status_chk23a(struct rtw_adapter *padapter)
5556 struct sta_info *psta;
5557 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5558 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5559 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5560 struct sta_priv *pstapriv = &padapter->stapriv;
5562 rtw_hal_sreset_linked_status_check23a(padapter);
5564 if (is_client_associated_to_ap23a(padapter))
5566 /* linked infrastructure client mode */
5568 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
5573 if ((psta = rtw_get_stainfo23a(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
5575 bool is_p2p_enable = false;
5577 if (chk_ap_is_alive(padapter, psta) == false)
5580 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
5583 if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
5584 u8 backup_oper_channel = 0;
5586 /* switch to correct channel of current network before issue keep-alive frames */
5587 if (rtw_get_oper_ch23a(padapter) != pmlmeext->cur_channel) {
5588 backup_oper_channel = rtw_get_oper_ch23a(padapter);
5589 SelectChannel23a(padapter, pmlmeext->cur_channel);
5592 if (rx_chk != _SUCCESS)
5593 issue_probereq23a_ex23a(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1);
5595 if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) {
5596 tx_chk = issue_nulldata23a(padapter, psta->hwaddr, 0, 3, 1);
5597 /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
5598 if (tx_chk == _SUCCESS && !is_p2p_enable)
5602 /* back to the original operation channel */
5603 if (backup_oper_channel>0)
5604 SelectChannel23a(padapter, backup_oper_channel);
5607 if (rx_chk != _SUCCESS) {
5608 if (pmlmeext->retry == 0) {
5609 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5610 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5611 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5615 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf)
5616 tx_chk = issue_nulldata23a(padapter, NULL, 0, 1, 0);
5619 if (rx_chk == _FAIL) {
5621 if (pmlmeext->retry > rx_chk_limit) {
5622 DBG_8723A_LEVEL(_drv_always_,
5623 "%s(%s): disconnect or "
5624 "roaming\n", __func__,
5625 padapter->pnetdev->name);
5626 receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress,
5627 WLAN_REASON_EXPIRATION_CHK);
5631 pmlmeext->retry = 0;
5634 if (tx_chk == _FAIL) {
5635 pmlmeinfo->link_count &= 0xf;
5637 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
5638 pmlmeinfo->link_count = 0;
5641 } /* end of if ((psta = rtw_get_stainfo23a(pstapriv, passoc_res->network.MacAddress)) != NULL) */
5643 else if (is_client_associated_to_ibss23a(padapter))
5645 /* linked IBSS mode */
5646 /* for each assoc list entry to check the rx pkt counter */
5647 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
5649 if (pmlmeinfo->FW_sta_info[i].status == 1)
5651 psta = pmlmeinfo->FW_sta_info[i].psta;
5653 if (NULL == psta) continue;
5655 if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta))
5658 if (pmlmeinfo->FW_sta_info[i].retry<3)
5660 pmlmeinfo->FW_sta_info[i].retry++;
5664 pmlmeinfo->FW_sta_info[i].retry = 0;
5665 pmlmeinfo->FW_sta_info[i].status = 0;
5666 report_del_sta_event23a(padapter, psta->hwaddr,
5667 65535/* indicate disconnect caused by no rx */
5673 pmlmeinfo->FW_sta_info[i].retry = 0;
5674 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
5679 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5684 static void survey_timer_hdl(unsigned long data)
5686 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
5687 struct cmd_obj *ph2c;
5688 struct sitesurvey_parm *psurveyPara;
5689 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5690 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5692 /* issue rtw_sitesurvey_cmd23a */
5693 if (pmlmeext->sitesurvey_res.state > SCAN_START) {
5694 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
5695 pmlmeext->sitesurvey_res.channel_idx++;
5697 if (pmlmeext->scan_abort == true) {
5698 pmlmeext->sitesurvey_res.channel_idx =
5699 pmlmeext->sitesurvey_res.ch_num;
5700 DBG_8723A("%s idx:%d\n", __func__,
5701 pmlmeext->sitesurvey_res.channel_idx);
5703 pmlmeext->scan_abort = false;/* reset */
5706 ph2c = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5709 goto exit_survey_timer_hdl;
5711 psurveyPara = (struct sitesurvey_parm*)
5712 kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC);
5715 goto exit_survey_timer_hdl;
5718 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
5719 rtw_enqueue_cmd23a(pcmdpriv, ph2c);
5722 exit_survey_timer_hdl:
5726 static void link_timer_hdl(unsigned long data)
5728 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
5729 /* static unsigned int rx_pkt = 0; */
5730 /* static u64 tx_cnt = 0; */
5731 /* struct xmit_priv *pxmitpriv = &padapter->xmitpriv; */
5732 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5733 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5734 /* struct sta_priv *pstapriv = &padapter->stapriv; */
5736 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
5738 DBG_8723A("link_timer_hdl:no beacon while connecting\n");
5739 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5740 report_join_res23a(padapter, -3);
5742 else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE)
5745 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT)
5747 /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
5749 pmlmeinfo->state = 0;
5750 report_join_res23a(padapter, -1);
5755 /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
5756 /* pmlmeinfo->reauth_count = 0; */
5760 DBG_8723A("link_timer_hdl: auth timeout and try again\n");
5761 pmlmeinfo->auth_seq = 1;
5762 issue_auth23a(padapter, NULL, 0);
5763 set_link_timer(pmlmeext, REAUTH_TO);
5765 else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)
5767 /* re-assoc timer */
5768 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT)
5770 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5771 report_join_res23a(padapter, -2);
5775 DBG_8723A("link_timer_hdl: assoc timeout and try again\n");
5776 issue_assocreq23a(padapter);
5777 set_link_timer(pmlmeext, REASSOC_TO);
5783 static void addba_timer_hdl(unsigned long data)
5785 struct sta_info *psta = (struct sta_info *)data;
5786 struct ht_priv *phtpriv;
5791 phtpriv = &psta->htpriv;
5793 if ((phtpriv->ht_option == true) && (phtpriv->ampdu_enable == true))
5795 if (phtpriv->candidate_tid_bitmap)
5796 phtpriv->candidate_tid_bitmap = 0x0;
5801 void init_addba_retry_timer23a(struct sta_info *psta)
5803 setup_timer(&psta->addba_retry_timer, addba_timer_hdl,
5804 (unsigned long)psta);
5807 void init_mlme_ext_timer23a(struct rtw_adapter *padapter)
5809 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5811 setup_timer(&pmlmeext->survey_timer, survey_timer_hdl,
5812 (unsigned long)padapter);
5814 setup_timer(&pmlmeext->link_timer, link_timer_hdl,
5815 (unsigned long)padapter);
5818 u8 NULL_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5823 u8 setopmode_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5826 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5827 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5828 const struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
5830 if (psetop->mode == Ndis802_11APMode) {
5831 pmlmeinfo->state = WIFI_FW_AP_STATE;
5832 type = _HW_STATE_AP_;
5833 } else if (psetop->mode == Ndis802_11Infrastructure) {
5834 pmlmeinfo->state &= ~(BIT(0)|BIT(1));/* clear state */
5835 pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */
5836 type = _HW_STATE_STATION_;
5837 } else if (psetop->mode == Ndis802_11IBSS)
5838 type = _HW_STATE_ADHOC_;
5840 type = _HW_STATE_NOLINK_;
5842 hw_var_set_opmode(padapter, type);
5843 /* Set_NETYPE0_MSR(padapter, type); */
5848 u8 createbss_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5850 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5851 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5852 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5853 const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
5854 /* u32 initialgain; */
5856 if (pparm->InfrastructureMode == Ndis802_11APMode) {
5857 #ifdef CONFIG_8723AU_AP_MODE
5859 if (pmlmeinfo->state == WIFI_FW_AP_STATE)
5867 /* below is for ad-hoc master */
5868 if (pparm->InfrastructureMode == Ndis802_11IBSS) {
5869 rtw_joinbss_reset23a(padapter);
5871 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5872 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5873 pmlmeinfo->ERP_enable = 0;
5874 pmlmeinfo->WMM_enable = 0;
5875 pmlmeinfo->HT_enable = 0;
5876 pmlmeinfo->HT_caps_enable = 0;
5877 pmlmeinfo->HT_info_enable = 0;
5878 pmlmeinfo->agg_enable_bitmap = 0;
5879 pmlmeinfo->candidate_tid_bitmap = 0;
5881 /* disable dynamic functions, such as high power, DIG */
5882 rtl8723a_odm_support_ability_backup(padapter);
5884 rtl8723a_odm_support_ability_clr(padapter,
5885 DYNAMIC_FUNC_DISABLE);
5887 /* cancel link timer */
5888 del_timer_sync(&pmlmeext->link_timer);
5891 flush_all_cam_entry23a(padapter);
5893 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
5894 return H2C_PARAMETERS_ERROR;
5896 memcpy(pnetwork, pparm, sizeof(struct wlan_bssid_ex));
5898 start_create_ibss23a(padapter);
5904 u8 join_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5906 struct ndis_802_11_var_ies * pIE;
5907 struct registry_priv *pregpriv = &padapter->registrypriv;
5908 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5909 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5910 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5911 const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
5912 struct HT_info_element *pht_info;
5914 /* u32 initialgain; */
5917 /* check already connecting to AP or not */
5918 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
5920 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
5921 issue_deauth23a_ex23a(padapter, pnetwork->MacAddress,
5922 WLAN_REASON_DEAUTH_LEAVING, 5, 100);
5924 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5927 flush_all_cam_entry23a(padapter);
5929 del_timer_sync(&pmlmeext->link_timer);
5931 /* set MSR to nolink -> infra. mode */
5932 /* Set_MSR23a(padapter, _HW_STATE_NOLINK_); */
5933 Set_MSR23a(padapter, _HW_STATE_STATION_);
5935 hw_var_set_mlme_disconnect(padapter);
5938 rtw_joinbss_reset23a(padapter);
5940 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5941 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5942 pmlmeinfo->ERP_enable = 0;
5943 pmlmeinfo->WMM_enable = 0;
5944 pmlmeinfo->HT_enable = 0;
5945 pmlmeinfo->HT_caps_enable = 0;
5946 pmlmeinfo->HT_info_enable = 0;
5947 pmlmeinfo->agg_enable_bitmap = 0;
5948 pmlmeinfo->candidate_tid_bitmap = 0;
5949 pmlmeinfo->bwmode_updated = false;
5950 /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
5952 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
5953 return H2C_PARAMETERS_ERROR;
5955 memcpy(pnetwork, pbuf, sizeof(struct wlan_bssid_ex));
5957 /* Check AP vendor to move rtw_joinbss_cmd23a() */
5958 /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP23a(pnetwork->IEs,
5959 pnetwork->IELength); */
5961 for (i = sizeof(struct ndis_802_11_fixed_ies); i < pnetwork->IELength;)
5963 pIE = (struct ndis_802_11_var_ies *)(pnetwork->IEs + i);
5965 switch (pIE->ElementID)
5967 case WLAN_EID_VENDOR_SPECIFIC:/* Get WMM IE. */
5968 if (!memcmp(pIE->data, WMM_OUI23A, 4))
5969 pmlmeinfo->WMM_enable = 1;
5972 case WLAN_EID_HT_CAPABILITY: /* Get HT Cap IE. */
5973 pmlmeinfo->HT_caps_enable = 1;
5976 case WLAN_EID_HT_OPERATION: /* Get HT Info IE. */
5977 pmlmeinfo->HT_info_enable = 1;
5979 /* spec case only for cisco's ap because cisco's ap
5980 * issue assoc rsp using mcs rate @40MHz or @20MHz */
5981 pht_info = (struct HT_info_element *)(pIE->data);
5983 if ((pregpriv->cbw40_enable) &&
5984 (pht_info->infos[0] & BIT(2))) {
5985 /* switch to the 40M Hz mode according to AP */
5986 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
5987 switch (pht_info->infos[0] & 0x3)
5990 pmlmeext->cur_ch_offset =
5991 HAL_PRIME_CHNL_OFFSET_LOWER;
5995 pmlmeext->cur_ch_offset =
5996 HAL_PRIME_CHNL_OFFSET_UPPER;
6000 pmlmeext->cur_ch_offset =
6001 HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6005 DBG_8723A("set ch/bw before connected\n");
6013 i += (pIE->Length + 2);
6016 hw_var_set_bssid(padapter, pmlmeinfo->network.MacAddress);
6017 hw_var_set_mlme_join(padapter, 0);
6019 /* cancel link timer */
6020 del_timer_sync(&pmlmeext->link_timer);
6022 start_clnt_join23a(padapter);
6027 u8 disconnect_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6029 const struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
6030 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6031 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6032 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
6034 if (is_client_associated_to_ap23a(padapter))
6036 issue_deauth23a_ex23a(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
6039 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
6041 /* pmlmeinfo->state = WIFI_FW_NULL_STATE; */
6043 hw_var_set_mlme_disconnect(padapter);
6044 hw_var_set_bssid(padapter, null_addr);
6046 /* restore to initial setting. */
6047 update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
6049 if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
6050 ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
6051 rtl8723a_set_bcn_func(padapter, 0); /* Stop BCN */
6053 /* set MSR to no link state -> infra. mode */
6054 Set_MSR23a(padapter, _HW_STATE_STATION_);
6056 pmlmeinfo->state = WIFI_FW_NULL_STATE;
6058 /* switch to the 20M Hz mode after disconnect */
6059 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
6060 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6062 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
6064 flush_all_cam_entry23a(padapter);
6066 del_timer_sync(&pmlmeext->link_timer);
6068 rtw_free_uc_swdec_pending_queue23a(padapter);
6074 rtw_scan_ch_decision(struct rtw_adapter *padapter,
6075 struct rtw_ieee80211_channel *out, u32 out_num,
6076 const struct rtw_ieee80211_channel *in, u32 in_num)
6079 int scan_ch_num = 0;
6081 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6083 /* clear out first */
6084 memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
6086 /* acquire channels from in */
6088 for (i = 0;i<in_num;i++) {
6089 if (in[i].hw_value && !(in[i].flags & IEEE80211_CHAN_DISABLED)
6090 && (set_idx = rtw_ch_set_search_ch23a(pmlmeext->channel_set, in[i].hw_value)) >= 0
6093 memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
6095 if (pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
6096 out[j].flags &= IEEE80211_CHAN_NO_IR;
6104 /* if out is empty, use channel_set as default */
6106 for (i = 0;i<pmlmeext->max_chan_nums;i++) {
6107 out[i].hw_value = pmlmeext->channel_set[i].ChannelNum;
6109 if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
6110 out[i].flags &= IEEE80211_CHAN_NO_IR;
6116 if (padapter->setband == GHZ_24) { /* 2.4G */
6117 for (i = 0; i < j ; i++) {
6118 if (out[i].hw_value > 35)
6120 sizeof(struct rtw_ieee80211_channel));
6125 } else if (padapter->setband == GHZ_50) { /* 5G */
6126 for (i = 0; i < j ; i++) {
6127 if (out[i].hw_value > 35) {
6128 memcpy(&out[scan_ch_num++], &out[i], sizeof(struct rtw_ieee80211_channel));
6138 u8 sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6140 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6141 const struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
6142 u8 bdelayscan = false;
6146 if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
6147 pmlmeext->sitesurvey_res.state = SCAN_START;
6148 pmlmeext->sitesurvey_res.bss_cnt = 0;
6149 pmlmeext->sitesurvey_res.channel_idx = 0;
6151 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
6152 if (pparm->ssid[i].ssid_len) {
6153 memcpy(pmlmeext->sitesurvey_res.ssid[i].ssid,
6154 pparm->ssid[i].ssid, IW_ESSID_MAX_SIZE);
6155 pmlmeext->sitesurvey_res.ssid[i].ssid_len =
6156 pparm->ssid[i].ssid_len;
6158 pmlmeext->sitesurvey_res.ssid[i].ssid_len = 0;
6162 pmlmeext->sitesurvey_res.ch_num =
6163 rtw_scan_ch_decision(padapter,
6164 pmlmeext->sitesurvey_res.ch,
6165 RTW_CHANNEL_SCAN_AMOUNT,
6166 pparm->ch, pparm->ch_num);
6168 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
6170 /* issue null data if associating to the AP */
6171 if (is_client_associated_to_ap23a(padapter)) {
6172 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
6174 /* switch to correct channel of current network
6175 before issue keep-alive frames */
6176 if (rtw_get_oper_ch23a(padapter) != pmlmeext->cur_channel)
6177 SelectChannel23a(padapter, pmlmeext->cur_channel);
6179 issue_nulldata23a(padapter, NULL, 1, 3, 500);
6185 /* delay 50ms to protect nulldata(1). */
6186 set_survey_timer(pmlmeext, 50);
6191 if ((pmlmeext->sitesurvey_res.state == SCAN_START) ||
6192 (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) {
6193 /* disable dynamic functions, such as high power, DIG */
6194 rtl8723a_odm_support_ability_backup(padapter);
6195 rtl8723a_odm_support_ability_clr(padapter,
6196 DYNAMIC_FUNC_DISABLE);
6198 /* config the initial gain under scaning, need to
6199 write the BB registers */
6200 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == true)
6205 rtl8723a_set_initial_gain(padapter, initialgain);
6207 /* set MSR to no link state */
6208 Set_MSR23a(padapter, _HW_STATE_NOLINK_);
6210 rtl8723a_mlme_sitesurvey(padapter, 1);
6212 pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
6215 site_survey23a(padapter);
6220 u8 setauth_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6222 const struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
6223 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6224 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6226 if (pparm->mode < 4)
6228 pmlmeinfo->auth_algo = pparm->mode;
6234 u8 setkey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6236 unsigned short ctrl;
6237 const struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
6238 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6239 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6240 unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
6242 /* main tx key for wep. */
6244 pmlmeinfo->key_index = pparm->keyid;
6247 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
6249 DBG_8723A_LEVEL(_drv_always_, "set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) "
6250 "keyid:%d\n", pparm->algorithm, pparm->keyid);
6251 rtl8723a_cam_write(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
6253 /* allow multicast packets to driver */
6254 rtl8723a_on_rcr_am(padapter);
6259 u8 set_stakey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6262 u8 cam_id;/* cam_entry */
6263 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6264 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6265 const struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
6268 /* 0~3 for default key */
6270 /* for concurrent mode (ap+sta): */
6271 /* default key is disable, using sw encrypt/decrypt */
6272 /* cam_entry = 4 for sta mode (macid = 0) */
6273 /* cam_entry(macid+3) = 5 ~ N for ap mode (aid = 1~N, macid = 2 ~N) */
6275 /* for concurrent mode (sta+sta): */
6276 /* default key is disable, using sw encrypt/decrypt */
6277 /* cam_entry = 4 mapping to macid = 0 */
6278 /* cam_entry = 5 mapping to macid = 2 */
6282 DBG_8723A_LEVEL(_drv_always_, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) camid:%d\n",
6283 pparm->algorithm, cam_id);
6284 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
6287 struct sta_info *psta;
6288 struct sta_priv *pstapriv = &padapter->stapriv;
6290 if (pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */
6292 clear_cam_entry23a(padapter, pparm->id);
6293 return H2C_SUCCESS_RSP;
6296 psta = rtw_get_stainfo23a(pstapriv, pparm->addr);
6299 ctrl = (BIT(15) | ((pparm->algorithm) << 2));
6301 DBG_8723A("r871x_set_stakey_hdl23a(): enc_algorithm =%d\n", pparm->algorithm);
6303 if ((psta->mac_id<1) || (psta->mac_id>(NUM_STA-4)))
6305 DBG_8723A("r871x_set_stakey_hdl23a():set_stakey failed, mac_id(aid) =%d\n", psta->mac_id);
6306 return H2C_REJECTED;
6309 cam_id = (psta->mac_id + 3);/* 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */
6311 DBG_8723A("Write CAM, mac_addr =%x:%x:%x:%x:%x:%x, cam_entry =%d\n", pparm->addr[0],
6312 pparm->addr[1], pparm->addr[2], pparm->addr[3], pparm->addr[4],
6313 pparm->addr[5], cam_id);
6315 rtl8723a_cam_write(padapter, cam_id, ctrl,
6316 pparm->addr, pparm->key);
6318 return H2C_SUCCESS_RSP;
6323 DBG_8723A("r871x_set_stakey_hdl23a(): sta has been free\n");
6324 return H2C_REJECTED;
6329 /* below for sta mode */
6331 if (pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */
6333 clear_cam_entry23a(padapter, pparm->id);
6337 ctrl = BIT(15) | ((pparm->algorithm) << 2);
6339 rtl8723a_cam_write(padapter, cam_id, ctrl, pparm->addr, pparm->key);
6341 pmlmeinfo->enc_algo = pparm->algorithm;
6346 u8 add_ba_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6348 const struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
6349 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6350 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6352 struct sta_info *psta = rtw_get_stainfo23a(&padapter->stapriv, pparm->addr);
6357 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) &&
6358 (pmlmeinfo->HT_enable)) ||
6359 ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
6360 issue_action_BA23a(padapter, pparm->addr,
6361 WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
6362 mod_timer(&psta->addba_retry_timer,
6363 jiffies + msecs_to_jiffies(ADDBA_TO));
6365 psta->htpriv.candidate_tid_bitmap &= ~CHKBIT(pparm->tid);
6370 u8 set_tx_beacon_cmd23a(struct rtw_adapter* padapter)
6372 struct cmd_obj *ph2c;
6373 struct Tx_Beacon_param *ptxBeacon_parm;
6374 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
6375 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6376 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6382 ph2c = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
6388 ptxBeacon_parm = (struct Tx_Beacon_param *)
6389 kzalloc(sizeof(struct Tx_Beacon_param), GFP_ATOMIC);
6390 if (!ptxBeacon_parm) {
6396 memcpy(&ptxBeacon_parm->network, &pmlmeinfo->network,
6397 sizeof(struct wlan_bssid_ex));
6399 len_diff = update_hidden_ssid(
6400 ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_,
6401 ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_,
6402 pmlmeinfo->hidden_ssid_mode);
6403 ptxBeacon_parm->network.IELength += len_diff;
6405 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
6407 res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
6416 u8 mlme_evt_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6418 u8 evt_code, evt_seq;
6420 const struct C2HEvent_Header *c2h;
6421 void (*event_callback)(struct rtw_adapter *dev, const u8 *pbuf);
6423 c2h = (struct C2HEvent_Header *)pbuf;
6428 /* checking if event code is valid */
6429 if (evt_code >= MAX_C2HEVT) {
6430 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nEvent Code(%d) mismatch!\n", evt_code));
6434 /* checking if event size match the event parm size */
6435 if ((wlanevents[evt_code].parmsize != 0) &&
6436 (wlanevents[evt_code].parmsize != evt_sz)) {
6437 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
6438 evt_code, wlanevents[evt_code].parmsize, evt_sz));
6442 event_callback = wlanevents[evt_code].event_callback;
6443 event_callback(padapter, pbuf + sizeof(struct C2HEvent_Header));
6450 u8 h2c_msg_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6453 return H2C_PARAMETERS_ERROR;
6458 u8 tx_beacon_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6460 if (send_beacon23a(padapter) == _FAIL)
6462 DBG_8723A("issue_beacon23a, fail!\n");
6463 return H2C_PARAMETERS_ERROR;
6465 #ifdef CONFIG_8723AU_AP_MODE
6466 else /* tx bc/mc frames after update TIM */
6468 struct sta_info *psta_bmc;
6469 struct list_head *plist, *phead, *ptmp;
6470 struct xmit_frame *pxmitframe;
6471 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6472 struct sta_priv *pstapriv = &padapter->stapriv;
6474 /* for BC/MC Frames */
6475 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
6479 if ((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0))
6481 msleep(10);/* 10ms, ATIM(HIQ) Windows */
6482 /* spin_lock_bh(&psta_bmc->sleep_q.lock); */
6483 spin_lock_bh(&pxmitpriv->lock);
6485 phead = get_list_head(&psta_bmc->sleep_q);
6487 list_for_each_safe(plist, ptmp, phead) {
6488 pxmitframe = container_of(plist,
6492 list_del_init(&pxmitframe->list);
6494 psta_bmc->sleepq_len--;
6495 if (psta_bmc->sleepq_len>0)
6496 pxmitframe->attrib.mdata = 1;
6498 pxmitframe->attrib.mdata = 0;
6500 pxmitframe->attrib.triggered = 1;
6502 pxmitframe->attrib.qsel = 0x11;/* HIQ */
6504 rtw_hal_xmit23aframe_enqueue(padapter, pxmitframe);
6507 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
6508 spin_unlock_bh(&pxmitpriv->lock);
6517 u8 set_ch_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6519 const struct set_ch_parm *set_ch_parm;
6520 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6523 return H2C_PARAMETERS_ERROR;
6525 set_ch_parm = (struct set_ch_parm *)pbuf;
6527 DBG_8723A("%s(%s): ch:%u, bw:%u, ch_offset:%u\n", __func__,
6528 padapter->pnetdev->name, set_ch_parm->ch,
6529 set_ch_parm->bw, set_ch_parm->ch_offset);
6531 pmlmeext->cur_channel = set_ch_parm->ch;
6532 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
6533 pmlmeext->cur_bwmode = set_ch_parm->bw;
6535 set_channel_bwmode23a(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
6540 u8 set_chplan_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6542 const struct SetChannelPlan_param *setChannelPlan_param;
6543 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6546 return H2C_PARAMETERS_ERROR;
6548 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
6550 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
6551 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
6556 u8 led_blink_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6558 struct LedBlink_param *ledBlink_param;
6561 return H2C_PARAMETERS_ERROR;
6563 ledBlink_param = (struct LedBlink_param *)pbuf;
6568 u8 set_csa_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6570 return H2C_REJECTED;
6573 /* TDLS_WRCR : write RCR DATA BIT */
6574 /* TDLS_SD_PTI : issue peer traffic indication */
6575 /* TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure */
6576 /* TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame */
6577 /* TDLS_DONE_CH_SEN: channel sensing and report candidate channel */
6578 /* TDLS_OFF_CH : first time set channel to off channel */
6579 /* TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel */
6580 /* TDLS_P_OFF_CH : periodically go to off channel */
6581 /* TDLS_P_BASE_CH : periodically go back to base channel */
6582 /* TDLS_RS_RCR : restore RCR */
6583 /* TDLS_CKALV_PH1 : check alive timer phase1 */
6584 /* TDLS_CKALV_PH2 : check alive timer phase2 */
6585 /* TDLS_FREE_STA : free tdls sta */
6586 u8 tdls_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6588 return H2C_REJECTED;