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 |= BIT(tid);
2038 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
2040 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
2043 case WLAN_ACTION_DELBA: /* DELBA */
2044 params = get_unaligned_le16(
2045 &mgmt->u.action.u.delba.params);
2048 if (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) {
2049 preorder_ctrl = &psta->recvreorder_ctrl[tid];
2050 preorder_ctrl->enable = false;
2051 preorder_ctrl->indicate_seq = 0xffff;
2053 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
2054 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
2056 reason_code = get_unaligned_le16(
2057 &mgmt->u.action.u.delba.reason_code);
2058 /* todo: how to notify the host while receiving
2068 static s32 rtw_action_public_decache(struct recv_frame *recv_frame, s32 token)
2070 struct rtw_adapter *adapter = recv_frame->adapter;
2071 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
2072 struct sk_buff *skb = recv_frame->pkt;
2073 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2076 seq_ctrl = ((recv_frame->attrib.seq_num&0xffff) << 4) |
2077 (recv_frame->attrib.frag_num & 0xf);
2079 if (ieee80211_has_retry(hdr->frame_control)) {
2081 if ((seq_ctrl == mlmeext->action_public_rxseq) &&
2082 (token == mlmeext->action_public_dialog_token)) {
2083 DBG_8723A("%s(%s): seq_ctrl = 0x%x, "
2084 "rxseq = 0x%x, token:%d\n", __func__,
2085 adapter->pnetdev->name, seq_ctrl,
2086 mlmeext->action_public_rxseq, token);
2090 if (seq_ctrl == mlmeext->action_public_rxseq) {
2091 DBG_8723A("%s(%s): seq_ctrl = 0x%x, "
2092 "rxseq = 0x%x\n", __func__,
2093 adapter->pnetdev->name, seq_ctrl,
2094 mlmeext->action_public_rxseq);
2100 mlmeext->action_public_rxseq = seq_ctrl;
2103 mlmeext->action_public_dialog_token = token;
2108 static unsigned int on_action_public23a_p2p(struct recv_frame *precv_frame)
2110 struct sk_buff *skb = precv_frame->pkt;
2111 u8 *pframe = skb->data;
2115 frame_body = (unsigned char *)
2116 (pframe + sizeof(struct ieee80211_hdr_3addr));
2118 dialogToken = frame_body[7];
2120 if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
2126 static unsigned int on_action_public23a_vendor(struct recv_frame *precv_frame)
2128 unsigned int ret = _FAIL;
2129 struct sk_buff *skb = precv_frame->pkt;
2130 u8 *pframe = skb->data;
2131 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2133 if (!memcmp(frame_body + 2, P2P_OUI23A, 4)) {
2134 ret = on_action_public23a_p2p(precv_frame);
2141 on_action_public23a_default(struct recv_frame *precv_frame, u8 action)
2143 unsigned int ret = _FAIL;
2144 struct sk_buff *skb = precv_frame->pkt;
2145 u8 *pframe = skb->data;
2146 uint frame_len = skb->len;
2147 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2149 struct rtw_adapter *adapter = precv_frame->adapter;
2153 token = frame_body[2];
2155 if (rtw_action_public_decache(precv_frame, token) == _FAIL)
2158 cnt += sprintf((msg+cnt), "%s(token:%u)",
2159 action_public_str23a(action), token);
2160 rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
2168 static int on_action_public23a(struct rtw_adapter *padapter,
2169 struct recv_frame *precv_frame)
2171 unsigned int ret = _FAIL;
2172 struct sk_buff *skb = precv_frame->pkt;
2173 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2174 u8 *pframe = skb->data;
2175 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
2176 u8 category, action;
2178 /* check RA matches or not */
2179 if (!ether_addr_equal(myid(&padapter->eeprompriv), hdr->addr1))
2182 category = frame_body[0];
2183 if (category != WLAN_CATEGORY_PUBLIC)
2186 action = frame_body[1];
2188 case ACT_PUBLIC_VENDOR:
2189 ret = on_action_public23a_vendor(precv_frame);
2192 ret = on_action_public23a_default(precv_frame, action);
2201 OnAction23a_ht(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2207 OnAction23a_wmm(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2213 OnAction23a_p2p(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2219 OnAction23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2223 struct action_handler *ptable;
2224 struct sk_buff *skb = precv_frame->pkt;
2225 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
2227 category = mgmt->u.action.category;
2230 i < sizeof(OnAction23a_tbl) / sizeof(struct action_handler); i++) {
2231 ptable = &OnAction23a_tbl[i];
2233 if (category == ptable->num)
2234 ptable->func(padapter, precv_frame);
2240 static int DoReserved23a(struct rtw_adapter *padapter,
2241 struct recv_frame *precv_frame)
2246 struct xmit_frame *alloc_mgtxmitframe23a(struct xmit_priv *pxmitpriv)
2248 struct xmit_frame *pmgntframe;
2249 struct xmit_buf *pxmitbuf;
2251 pmgntframe = rtw_alloc_xmitframe23a_ext(pxmitpriv);
2254 DBG_8723A("%s(%s): alloc xmitframe fail\n", __func__,
2255 pxmitpriv->adapter->pnetdev->name);
2259 pxmitbuf = rtw_alloc_xmitbuf23a_ext(pxmitpriv);
2261 DBG_8723A("%s(%s): alloc xmitbuf fail\n", __func__,
2262 pxmitpriv->adapter->pnetdev->name);
2263 rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
2268 pmgntframe->frame_tag = MGNT_FRAMETAG;
2269 pmgntframe->pxmitbuf = pxmitbuf;
2270 pmgntframe->buf_addr = pxmitbuf->pbuf;
2271 pxmitbuf->priv_data = pmgntframe;
2277 /****************************************************************************
2279 Following are some TX fuctions for WiFi MLME
2281 *****************************************************************************/
2283 void update_mgnt_tx_rate23a(struct rtw_adapter *padapter, u8 rate)
2285 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2287 pmlmeext->tx_rate = rate;
2288 DBG_8723A("%s(): rate = %x\n", __func__, rate);
2291 void update_mgntframe_attrib23a(struct rtw_adapter *padapter,
2292 struct pkt_attrib *pattrib)
2294 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2296 memset((u8 *)pattrib, 0, sizeof(struct pkt_attrib));
2298 pattrib->hdrlen = 24;
2299 pattrib->nr_frags = 1;
2300 pattrib->priority = 7;
2301 pattrib->mac_id = 0;
2302 pattrib->qsel = 0x12;
2304 pattrib->pktlen = 0;
2306 if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
2307 pattrib->raid = 6;/* b mode */
2309 pattrib->raid = 5;/* a/g mode */
2311 pattrib->encrypt = _NO_PRIVACY_;
2312 pattrib->bswenc = false;
2314 pattrib->qos_en = false;
2315 pattrib->ht_en = false;
2316 pattrib->bwmode = HT_CHANNEL_WIDTH_20;
2317 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
2318 pattrib->sgi = false;
2320 pattrib->seqnum = pmlmeext->mgnt_seq;
2322 pattrib->retry_ctrl = true;
2325 void dump_mgntframe23a(struct rtw_adapter *padapter,
2326 struct xmit_frame *pmgntframe)
2328 if (padapter->bSurpriseRemoved == true ||
2329 padapter->bDriverStopped == true)
2332 rtw_hal_mgnt_xmit23a(padapter, pmgntframe);
2335 s32 dump_mgntframe23a_and_wait(struct rtw_adapter *padapter,
2336 struct xmit_frame *pmgntframe, int timeout_ms)
2340 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2341 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
2342 struct submit_ctx sctx;
2344 if (padapter->bSurpriseRemoved == true ||
2345 padapter->bDriverStopped == true)
2348 rtw_sctx_init23a(&sctx, timeout_ms);
2349 pxmitbuf->sctx = &sctx;
2351 ret = rtw_hal_mgnt_xmit23a(padapter, pmgntframe);
2353 if (ret == _SUCCESS)
2354 ret = rtw_sctx_wait23a(&sctx);
2356 spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL);
2357 pxmitbuf->sctx = NULL;
2358 spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL);
2363 s32 dump_mgntframe23a_and_wait_ack23a(struct rtw_adapter *padapter,
2364 struct xmit_frame *pmgntframe)
2367 u32 timeout_ms = 500;/* 500ms */
2368 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2370 if (padapter->bSurpriseRemoved == true ||
2371 padapter->bDriverStopped == true)
2374 mutex_lock(&pxmitpriv->ack_tx_mutex);
2375 pxmitpriv->ack_tx = true;
2377 pmgntframe->ack_report = 1;
2378 if (rtw_hal_mgnt_xmit23a(padapter, pmgntframe) == _SUCCESS) {
2379 ret = rtw_ack_tx_wait23a(pxmitpriv, timeout_ms);
2382 pxmitpriv->ack_tx = false;
2383 mutex_unlock(&pxmitpriv->ack_tx_mutex);
2388 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
2396 ssid_ie = rtw_get_ie23a(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
2398 /* DBG_8723A("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n",
2399 __func__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
2401 if (ssid_ie && ssid_len_ori > 0) {
2402 switch (hidden_ssid_mode)
2405 next_ie = ssid_ie + 2 + ssid_len_ori;
2408 remain_len = ies_len -(next_ie-ies);
2411 memcpy(ssid_ie+2, next_ie, remain_len);
2412 len_diff -= ssid_len_ori;
2416 memset(&ssid_ie[2], 0, ssid_len_ori);
2426 void issue_beacon23a(struct rtw_adapter *padapter, int timeout_ms)
2428 struct xmit_frame *pmgntframe;
2429 struct pkt_attrib *pattrib;
2430 unsigned char *pframe;
2431 struct ieee80211_hdr *pwlanhdr;
2433 unsigned int rate_len;
2434 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2435 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2436 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2437 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2438 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
2439 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2445 /* DBG_8723A("%s\n", __func__); */
2447 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL) {
2448 DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
2451 #ifdef CONFIG_8723AU_AP_MODE
2452 spin_lock_bh(&pmlmepriv->bcn_update_lock);
2455 /* update attribute */
2456 pattrib = &pmgntframe->attrib;
2457 update_mgntframe_attrib23a(padapter, pattrib);
2458 pattrib->qsel = 0x10;
2460 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2462 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2463 pwlanhdr = (struct ieee80211_hdr *)pframe;
2465 fctrl = &pwlanhdr->frame_control;
2468 ether_addr_copy(pwlanhdr->addr1, bc_addr);
2469 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
2470 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(cur_network));
2472 SetSeqNum(pwlanhdr, 0 /*pmlmeext->mgnt_seq*/);
2473 /* pmlmeext->mgnt_seq++; */
2474 SetFrameSubType(pframe, WIFI_BEACON);
2476 pframe += sizeof(struct ieee80211_hdr_3addr);
2477 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
2479 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
2480 /* DBG_8723A("ie len =%d\n", cur_network->IELength); */
2481 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2482 len_diff = update_hidden_ssid(pframe + _BEACON_IE_OFFSET_,
2483 cur_network->IELength -
2485 pmlmeinfo->hidden_ssid_mode);
2486 pframe += (cur_network->IELength+len_diff);
2487 pattrib->pktlen += (cur_network->IELength+len_diff);
2489 wps_ie = rtw_get_wps_ie23a(pmgntframe->buf_addr + TXDESC_OFFSET+
2490 sizeof (struct ieee80211_hdr_3addr) +
2491 _BEACON_IE_OFFSET_, pattrib->pktlen -
2492 sizeof (struct ieee80211_hdr_3addr) -
2493 _BEACON_IE_OFFSET_, NULL,
2495 if (wps_ie && wps_ielen > 0) {
2496 rtw_get_wps_attr_content23a(wps_ie, wps_ielen,
2497 WPS_ATTR_SELECTED_REGISTRAR,
2501 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
2503 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
2508 /* below for ad-hoc mode */
2510 /* timestamp will be inserted by hardware */
2512 pattrib->pktlen += 8;
2514 /* beacon interval: 2 bytes */
2516 memcpy(pframe, (unsigned char *)
2517 rtw_get_beacon_interval23a_from_ie(cur_network->IEs), 2);
2520 pattrib->pktlen += 2;
2522 /* capability info: 2 bytes */
2524 memcpy(pframe, (unsigned char *)
2525 rtw_get_capability23a_from_ie(cur_network->IEs), 2);
2528 pattrib->pktlen += 2;
2531 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
2532 cur_network->Ssid.ssid_len,
2533 cur_network->Ssid.ssid, &pattrib->pktlen);
2535 /* supported rates... */
2536 rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
2537 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2538 ((rate_len > 8)? 8: rate_len),
2539 cur_network->SupportedRates, &pattrib->pktlen);
2541 /* DS parameter set */
2542 pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)
2543 &cur_network->Configuration.DSConfig,
2546 /* if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
2550 /* IBSS Parameter Set... */
2551 /* ATIMWindow = cur->Configuration.ATIMWindow; */
2553 pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
2554 (unsigned char *)&ATIMWindow,
2558 pframe = rtw_set_ie23a(pframe, WLAN_EID_ERP_INFO, 1,
2559 &erpinfo, &pattrib->pktlen);
2562 /* EXTERNDED SUPPORTED RATE */
2564 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2566 cur_network->SupportedRates + 8,
2569 /* todo:HT for adhoc */
2573 #ifdef CONFIG_8723AU_AP_MODE
2574 pmlmepriv->update_bcn = false;
2576 spin_unlock_bh(&pmlmepriv->bcn_update_lock);
2579 if ((pattrib->pktlen + TXDESC_SIZE) > 512) {
2580 DBG_8723A("beacon frame too large\n");
2584 pattrib->last_txcmdsz = pattrib->pktlen;
2586 /* DBG_8723A("issue bcn_sz =%d\n", pattrib->last_txcmdsz); */
2588 dump_mgntframe23a_and_wait(padapter, pmgntframe, timeout_ms);
2590 dump_mgntframe23a(padapter, pmgntframe);
2593 void issue_probersp23a(struct rtw_adapter *padapter, unsigned char *da,
2594 u8 is_valid_p2p_probereq)
2596 struct xmit_frame *pmgntframe;
2597 struct pkt_attrib *pattrib;
2598 unsigned char *pframe;
2599 struct ieee80211_hdr *pwlanhdr;
2601 unsigned char *mac, *bssid;
2602 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2603 #ifdef CONFIG_8723AU_AP_MODE
2608 int ssid_ielen_diff;
2611 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2613 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2614 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2615 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
2616 unsigned int rate_len;
2618 /* DBG_8723A("%s\n", __func__); */
2620 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
2622 DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
2626 /* update attribute */
2627 pattrib = &pmgntframe->attrib;
2628 update_mgntframe_attrib23a(padapter, pattrib);
2630 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2632 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
2633 pwlanhdr = (struct ieee80211_hdr *)pframe;
2635 mac = myid(&padapter->eeprompriv);
2636 bssid = cur_network->MacAddress;
2638 fctrl = &pwlanhdr->frame_control;
2640 ether_addr_copy(pwlanhdr->addr1, da);
2641 ether_addr_copy(pwlanhdr->addr2, mac);
2642 ether_addr_copy(pwlanhdr->addr3, bssid);
2644 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2645 pmlmeext->mgnt_seq++;
2646 SetFrameSubType(fctrl, WIFI_PROBERSP);
2648 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
2649 pattrib->pktlen = pattrib->hdrlen;
2650 pframe += pattrib->hdrlen;
2652 if (cur_network->IELength > MAX_IE_SZ)
2655 #ifdef CONFIG_8723AU_AP_MODE
2656 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
2657 pwps_ie = rtw_get_wps_ie23a(cur_network->IEs +
2659 cur_network->IELength -
2660 _FIXED_IE_LENGTH_, NULL,
2663 /* inerset & update wps_probe_resp_ie */
2664 if (pmlmepriv->wps_probe_resp_ie && pwps_ie && wps_ielen > 0) {
2665 uint wps_offset, remainder_ielen;
2668 wps_offset = (uint)(pwps_ie - cur_network->IEs);
2670 premainder_ie = pwps_ie + wps_ielen;
2672 remainder_ielen = cur_network->IELength - wps_offset -
2675 memcpy(pframe, cur_network->IEs, wps_offset);
2676 pframe += wps_offset;
2677 pattrib->pktlen += wps_offset;
2679 /* to get ie data len */
2680 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];
2681 if (wps_offset + wps_ielen + 2 <= MAX_IE_SZ) {
2682 memcpy(pframe, pmlmepriv->wps_probe_resp_ie,
2684 pframe += wps_ielen+2;
2685 pattrib->pktlen += wps_ielen+2;
2688 if (wps_offset + wps_ielen + 2 + remainder_ielen <=
2690 memcpy(pframe, premainder_ie, remainder_ielen);
2691 pframe += remainder_ielen;
2692 pattrib->pktlen += remainder_ielen;
2695 memcpy(pframe, cur_network->IEs, cur_network->IELength);
2696 pframe += cur_network->IELength;
2697 pattrib->pktlen += cur_network->IELength;
2700 /* retrieve SSID IE from cur_network->Ssid */
2701 ies = pmgntframe->buf_addr + TXDESC_OFFSET +
2702 sizeof(struct ieee80211_hdr_3addr);
2704 ssid_ie = rtw_get_ie23a(ies + _FIXED_IE_LENGTH_, WLAN_EID_SSID,
2706 pframe - ies - _FIXED_IE_LENGTH_);
2708 ssid_ielen_diff = cur_network->Ssid.ssid_len - ssid_ielen;
2710 if (ssid_ie && cur_network->Ssid.ssid_len) {
2711 uint remainder_ielen;
2713 remainder_ie = ssid_ie + 2;
2714 remainder_ielen = pframe - remainder_ie;
2716 DBG_8723A_LEVEL(_drv_warning_, "%s(%s): "
2717 "remainder_ielen > MAX_IE_SZ\n",
2718 __func__, padapter->pnetdev->name);
2719 if (remainder_ielen > MAX_IE_SZ)
2720 remainder_ielen = MAX_IE_SZ;
2722 memcpy(buf, remainder_ie, remainder_ielen);
2723 memcpy(remainder_ie + ssid_ielen_diff, buf,
2725 *(ssid_ie + 1) = cur_network->Ssid.ssid_len;
2726 memcpy(ssid_ie + 2, cur_network->Ssid.ssid,
2727 cur_network->Ssid.ssid_len);
2729 pframe += ssid_ielen_diff;
2730 pattrib->pktlen += ssid_ielen_diff;
2736 /* timestamp will be inserted by hardware */
2738 pattrib->pktlen += 8;
2740 /* beacon interval: 2 bytes */
2742 memcpy(pframe, (unsigned char *)
2743 rtw_get_beacon_interval23a_from_ie(cur_network->IEs), 2);
2746 pattrib->pktlen += 2;
2748 /* capability info: 2 bytes */
2750 memcpy(pframe, (unsigned char *)
2751 rtw_get_capability23a_from_ie(cur_network->IEs), 2);
2754 pattrib->pktlen += 2;
2756 /* below for ad-hoc mode */
2759 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
2760 cur_network->Ssid.ssid_len,
2761 cur_network->Ssid.ssid,
2764 /* supported rates... */
2765 rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
2766 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2767 ((rate_len > 8)? 8: rate_len),
2768 cur_network->SupportedRates,
2771 /* DS parameter set */
2772 pframe = rtw_set_ie23a(pframe, WLAN_EID_DS_PARAMS, 1,
2774 &cur_network->Configuration.DSConfig,
2777 if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
2780 /* IBSS Parameter Set... */
2781 /* ATIMWindow = cur->Configuration.ATIMWindow; */
2783 pframe = rtw_set_ie23a(pframe, WLAN_EID_IBSS_PARAMS, 2,
2784 (unsigned char *)&ATIMWindow,
2788 pframe = rtw_set_ie23a(pframe, WLAN_EID_ERP_INFO, 1,
2789 &erpinfo, &pattrib->pktlen);
2792 /* EXTERNDED SUPPORTED RATE */
2794 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2796 cur_network->SupportedRates + 8,
2799 /* todo:HT for adhoc */
2802 pattrib->last_txcmdsz = pattrib->pktlen;
2804 dump_mgntframe23a(padapter, pmgntframe);
2809 static int _issue_probereq23a(struct rtw_adapter *padapter,
2810 struct cfg80211_ssid *pssid, u8 *da, int wait_ack)
2813 struct xmit_frame *pmgntframe;
2814 struct pkt_attrib *pattrib;
2815 unsigned char *pframe;
2816 struct ieee80211_hdr *pwlanhdr;
2819 unsigned char bssrate[NumRates];
2820 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2821 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2822 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2823 int bssrate_len = 0;
2824 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2826 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
2827 ("+issue_probereq23a\n"));
2829 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
2832 /* update attribute */
2833 pattrib = &pmgntframe->attrib;
2834 update_mgntframe_attrib23a(padapter, pattrib);
2836 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2838 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2839 pwlanhdr = (struct ieee80211_hdr *)pframe;
2841 mac = myid(&padapter->eeprompriv);
2843 fctrl = &pwlanhdr->frame_control;
2847 /* unicast probe request frame */
2848 ether_addr_copy(pwlanhdr->addr1, da);
2849 ether_addr_copy(pwlanhdr->addr3, da);
2851 /* broadcast probe request frame */
2852 ether_addr_copy(pwlanhdr->addr1, bc_addr);
2853 ether_addr_copy(pwlanhdr->addr3, bc_addr);
2856 ether_addr_copy(pwlanhdr->addr2, mac);
2858 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2859 pmlmeext->mgnt_seq++;
2860 SetFrameSubType(pframe, WIFI_PROBEREQ);
2862 pframe += sizeof (struct ieee80211_hdr_3addr);
2863 pattrib->pktlen = sizeof (struct ieee80211_hdr_3addr);
2866 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID, pssid->ssid_len,
2867 pssid->ssid, &pattrib->pktlen);
2869 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID, 0, NULL,
2872 get_rate_set23a(padapter, bssrate, &bssrate_len);
2874 if (bssrate_len > 8) {
2875 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
2876 bssrate, &pattrib->pktlen);
2877 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
2878 (bssrate_len - 8), (bssrate + 8),
2881 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
2882 bssrate_len, bssrate, &pattrib->pktlen);
2885 /* add wps_ie for wps2.0 */
2886 if (pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie) {
2887 memcpy(pframe, pmlmepriv->wps_probe_req_ie,
2888 pmlmepriv->wps_probe_req_ie_len);
2889 pframe += pmlmepriv->wps_probe_req_ie_len;
2890 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
2893 pattrib->last_txcmdsz = pattrib->pktlen;
2895 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
2896 ("issuing probe_req, tx_len =%d\n", pattrib->last_txcmdsz));
2899 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
2901 dump_mgntframe23a(padapter, pmgntframe);
2909 inline void issue_probereq23a(struct rtw_adapter *padapter,
2910 struct cfg80211_ssid *pssid, u8 *da)
2912 _issue_probereq23a(padapter, pssid, da, false);
2915 int issue_probereq23a_ex23a(struct rtw_adapter *padapter,
2916 struct cfg80211_ssid *pssid, u8 *da,
2917 int try_cnt, int wait_ms)
2921 unsigned long start = jiffies;
2924 ret = _issue_probereq23a(padapter, pssid, da,
2925 wait_ms > 0 ? true : false);
2929 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
2932 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
2935 } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
2942 if (try_cnt && wait_ms) {
2944 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
2945 "in %u ms\n", __func__,
2946 padapter->pnetdev->name,
2947 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
2948 ret == _SUCCESS?", acked":"", i, try_cnt,
2949 jiffies_to_msecs(jiffies - start));
2951 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
2952 __func__, padapter->pnetdev->name,
2953 rtw_get_oper_ch23a(padapter),
2954 ret == _SUCCESS?", acked":"", i, try_cnt,
2955 jiffies_to_msecs(jiffies - start));
2961 /* if psta == NULL, indiate we are station(client) now... */
2962 void issue_auth23a(struct rtw_adapter *padapter, struct sta_info *psta,
2963 unsigned short status)
2965 struct xmit_frame *pmgntframe;
2966 struct pkt_attrib *pattrib;
2967 unsigned char *pframe;
2968 struct ieee80211_hdr *pwlanhdr;
2971 unsigned short val16;
2972 int use_shared_key = 0;
2973 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2974 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2975 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2977 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
2980 /* update attribute */
2981 pattrib = &pmgntframe->attrib;
2982 update_mgntframe_attrib23a(padapter, pattrib);
2984 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2986 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2987 pwlanhdr = (struct ieee80211_hdr *)pframe;
2989 fctrl = &pwlanhdr->frame_control;
2992 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2993 pmlmeext->mgnt_seq++;
2994 SetFrameSubType(pframe, WIFI_AUTH);
2996 pframe += sizeof(struct ieee80211_hdr_3addr);
2997 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
2999 if (psta) { /* for AP mode */
3000 #ifdef CONFIG_8723AU_AP_MODE
3002 ether_addr_copy(pwlanhdr->addr1, psta->hwaddr);
3003 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3004 ether_addr_copy(pwlanhdr->addr3, myid(&padapter->eeprompriv));
3006 /* setting auth algo number */
3007 val16 = (u16)psta->authalg;
3009 if (status != WLAN_STATUS_SUCCESS)
3013 val16 = cpu_to_le16(val16);
3017 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_ALGM_NUM_,
3018 (unsigned char *)&val16,
3021 /* setting auth seq number */
3022 val16 = (u16)psta->auth_seq;
3023 val16 = cpu_to_le16(val16);
3024 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_SEQ_NUM_,
3025 (unsigned char *)&val16,
3028 /* setting status code... */
3030 val16 = cpu_to_le16(val16);
3031 pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
3032 (unsigned char *)&val16,
3035 /* added challenging text... */
3036 if ((psta->auth_seq == 2) &&
3037 (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
3038 pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
3039 psta->chg_txt, &pattrib->pktlen);
3042 ether_addr_copy(pwlanhdr->addr1,
3043 get_my_bssid23a(&pmlmeinfo->network));
3044 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3045 ether_addr_copy(pwlanhdr->addr3,
3046 get_my_bssid23a(&pmlmeinfo->network));
3048 /* setting auth algo number */
3049 /* 0:OPEN System, 1:Shared key */
3050 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;
3052 val16 = cpu_to_le16(val16);
3055 /* DBG_8723A("%s auth_algo = %s auth_seq =%d\n", __func__,
3056 (pmlmeinfo->auth_algo == 0)?"OPEN":"SHARED",
3057 pmlmeinfo->auth_seq); */
3059 /* setting IV for auth seq #3 */
3060 if ((pmlmeinfo->auth_seq == 3) &&
3061 (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
3062 (use_shared_key == 1)) {
3063 /* DBG_8723A("==> iv(%d), key_index(%d)\n",
3064 pmlmeinfo->iv, pmlmeinfo->key_index); */
3065 val32 = ((pmlmeinfo->iv++) |
3066 (pmlmeinfo->key_index << 30));
3067 val32 = cpu_to_le32(val32);
3068 pframe = rtw_set_fixed_ie23a(pframe, 4,
3069 (unsigned char *)&val32,
3072 pattrib->iv_len = 4;
3075 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_ALGM_NUM_,
3076 (unsigned char *)&val16,
3079 /* setting auth seq number */
3080 val16 = pmlmeinfo->auth_seq;
3081 val16 = cpu_to_le16(val16);
3082 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_SEQ_NUM_,
3083 (unsigned char *)&val16,
3086 /* setting status code... */
3088 val16 = cpu_to_le16(val16);
3089 pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
3090 (unsigned char *)&val16,
3093 /* then checking to see if sending challenging text... */
3094 if ((pmlmeinfo->auth_seq == 3) &&
3095 (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
3096 (use_shared_key == 1)) {
3097 pframe = rtw_set_ie23a(pframe, WLAN_EID_CHALLENGE, 128,
3103 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
3105 pattrib->encrypt = _WEP40_;
3107 pattrib->icv_len = 4;
3109 pattrib->pktlen += pattrib->icv_len;
3113 pattrib->last_txcmdsz = pattrib->pktlen;
3115 rtw_wep_encrypt23a(padapter, pmgntframe);
3116 DBG_8723A("%s\n", __func__);
3117 dump_mgntframe23a(padapter, pmgntframe);
3122 void issue_asocrsp23a(struct rtw_adapter *padapter, unsigned short status,
3123 struct sta_info *pstat, int pkt_type)
3125 #ifdef CONFIG_8723AU_AP_MODE
3126 struct xmit_frame *pmgntframe;
3127 struct ieee80211_hdr *pwlanhdr;
3128 struct pkt_attrib *pattrib;
3129 unsigned char *pframe;
3131 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3132 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3133 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3134 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3135 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
3137 u8 *ie = pnetwork->IEs;
3139 DBG_8723A("%s\n", __func__);
3141 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3145 /* update attribute */
3146 pattrib = &pmgntframe->attrib;
3147 update_mgntframe_attrib23a(padapter, pattrib);
3149 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3151 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3152 pwlanhdr = (struct ieee80211_hdr *)pframe;
3154 pwlanhdr->frame_control = 0;
3156 ether_addr_copy(pwlanhdr->addr1, pstat->hwaddr);
3157 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3158 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3160 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3161 pmlmeext->mgnt_seq++;
3162 if (pkt_type == WIFI_ASSOCRSP || pkt_type == WIFI_REASSOCRSP)
3163 SetFrameSubType(pwlanhdr, pkt_type);
3167 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
3168 pattrib->pktlen += pattrib->hdrlen;
3169 pframe += pattrib->hdrlen;
3172 val = *(unsigned short *)rtw_get_capability23a_from_ie(ie);
3174 pframe = rtw_set_fixed_ie23a(pframe, _CAPABILITY_,
3175 (unsigned char *)&val, &pattrib->pktlen);
3177 status = cpu_to_le16(status);
3178 pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
3179 (unsigned char *)&status,
3182 val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
3183 pframe = rtw_set_fixed_ie23a(pframe, _ASOC_ID_, (unsigned char *)&val,
3186 if (pstat->bssratelen <= 8) {
3187 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
3188 pstat->bssratelen, pstat->bssrateset,
3191 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
3192 pstat->bssrateset, &pattrib->pktlen);
3193 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
3194 pstat->bssratelen - 8,
3195 pstat->bssrateset + 8, &pattrib->pktlen);
3198 if (pstat->flags & WLAN_STA_HT && pmlmepriv->htpriv.ht_option) {
3199 /* FILL HT CAP INFO IE */
3200 /* p = hostapd_eid_ht_capabilities_info(hapd, p); */
3201 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
3202 ie + _BEACON_IE_OFFSET_,
3203 pnetwork->IELength -_BEACON_IE_OFFSET_);
3205 memcpy(pframe, p, p[1] + 2);
3206 pframe += (p[1] + 2);
3207 pattrib->pktlen += (p[1] + 2);
3210 /* FILL HT ADD INFO IE */
3211 /* p = hostapd_eid_ht_operation(hapd, p); */
3212 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
3213 ie + _BEACON_IE_OFFSET_,
3214 pnetwork->IELength - _BEACON_IE_OFFSET_);
3215 if (p && p[1] > 0) {
3216 memcpy(pframe, p, p[1] + 2);
3217 pframe += (p[1] + 2);
3218 pattrib->pktlen += (p[1] + 2);
3223 if (pstat->flags & WLAN_STA_WME && pmlmepriv->qos_option) {
3224 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02,
3228 for (p = ie + _BEACON_IE_OFFSET_; ; p += (ie_len + 2)) {
3229 p = cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC, p,
3230 pnetwork->IELength -
3231 _BEACON_IE_OFFSET_ - (ie_len + 2));
3236 if (p && !memcmp(p + 2, WMM_PARA_IE, 6)) {
3237 memcpy(pframe, p, ie_len + 2);
3238 pframe += (ie_len + 2);
3239 pattrib->pktlen += (ie_len + 2);
3244 if (!p || ie_len == 0)
3249 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) {
3250 pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
3251 REALTEK_96B_IE, &pattrib->pktlen);
3254 /* add WPS IE ie for wps 2.0 */
3255 if (pmlmepriv->wps_assoc_resp_ie &&
3256 pmlmepriv->wps_assoc_resp_ie_len > 0) {
3257 memcpy(pframe, pmlmepriv->wps_assoc_resp_ie,
3258 pmlmepriv->wps_assoc_resp_ie_len);
3260 pframe += pmlmepriv->wps_assoc_resp_ie_len;
3261 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
3264 pattrib->last_txcmdsz = pattrib->pktlen;
3266 dump_mgntframe23a(padapter, pmgntframe);
3270 void issue_assocreq23a(struct rtw_adapter *padapter)
3273 struct xmit_frame *pmgntframe;
3274 struct pkt_attrib *pattrib;
3275 unsigned char *pframe;
3277 struct ieee80211_hdr *pwlanhdr;
3279 unsigned int i, j, index = 0;
3280 unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
3281 struct ndis_802_11_var_ies *pIE;
3282 struct registry_priv *pregpriv = &padapter->registrypriv;
3283 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3284 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3285 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3286 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3287 int bssrate_len = 0, sta_bssrate_len = 0, pie_len;
3290 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
3294 /* update attribute */
3295 pattrib = &pmgntframe->attrib;
3296 update_mgntframe_attrib23a(padapter, pattrib);
3298 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3300 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
3301 pwlanhdr = (struct ieee80211_hdr *)pframe;
3303 fctrl = &pwlanhdr->frame_control;
3305 ether_addr_copy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network));
3306 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3307 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3309 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3310 pmlmeext->mgnt_seq++;
3311 SetFrameSubType(pframe, WIFI_ASSOCREQ);
3313 pframe += sizeof(struct ieee80211_hdr_3addr);
3314 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3318 rtw_get_capability23a_from_ie(pmlmeinfo->network.IEs), 2);
3321 pattrib->pktlen += 2;
3323 /* listen interval */
3324 /* todo: listen interval for power saving */
3325 put_unaligned_le16(3, pframe);
3327 pattrib->pktlen += 2;
3330 pframe = rtw_set_ie23a(pframe, WLAN_EID_SSID,
3331 pmlmeinfo->network.Ssid.ssid_len,
3332 pmlmeinfo->network.Ssid.ssid, &pattrib->pktlen);
3334 /* supported rate & extended supported rate */
3336 get_rate_set23a(padapter, sta_bssrate, &sta_bssrate_len);
3337 /* DBG_8723A("sta_bssrate_len =%d\n", sta_bssrate_len); */
3339 /* for JAPAN, channel 14 can only uses B Mode(CCK) */
3340 if (pmlmeext->cur_channel == 14)
3341 sta_bssrate_len = 4;
3343 /* for (i = 0; i < sta_bssrate_len; i++) { */
3344 /* DBG_8723A("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
3347 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3348 if (pmlmeinfo->network.SupportedRates[i] == 0)
3350 DBG_8723A("network.SupportedRates[%d]=%02X\n", i,
3351 pmlmeinfo->network.SupportedRates[i]);
3354 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
3355 if (pmlmeinfo->network.SupportedRates[i] == 0)
3358 /* Check if the AP's supported rates are also
3359 supported by STA. */
3360 for (j = 0; j < sta_bssrate_len; j++) {
3361 /* Avoid the proprietary data rate (22Mbps) of
3362 Handlink WSG-4000 AP */
3363 if ((pmlmeinfo->network.SupportedRates[i] |
3364 IEEE80211_BASIC_RATE_MASK) ==
3365 (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) {
3366 /* DBG_8723A("match i = %d, j =%d\n", i, j); */
3371 if (j == sta_bssrate_len) {
3372 /* the rate is not supported by STA */
3373 DBG_8723A("%s(): the rate[%d]=%02X is not supported by "
3374 "STA!\n", __func__, i,
3375 pmlmeinfo->network.SupportedRates[i]);
3377 /* the rate is supported by STA */
3378 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
3382 bssrate_len = index;
3383 DBG_8723A("bssrate_len = %d\n", bssrate_len);
3385 if (bssrate_len == 0) {
3386 rtw_free_xmitbuf23a(pxmitpriv, pmgntframe->pxmitbuf);
3387 rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
3388 goto exit; /* don't connect to AP if no joint supported rate */
3391 if (bssrate_len > 8) {
3392 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES, 8,
3393 bssrate, &pattrib->pktlen);
3394 pframe = rtw_set_ie23a(pframe, WLAN_EID_EXT_SUPP_RATES,
3395 (bssrate_len - 8), (bssrate + 8),
3398 pframe = rtw_set_ie23a(pframe, WLAN_EID_SUPP_RATES,
3399 bssrate_len, bssrate, &pattrib->pktlen);
3402 pie = pmlmeinfo->network.IEs + sizeof(struct ndis_802_11_fixed_ies);
3403 pie_len = pmlmeinfo->network.IELength -
3404 sizeof(struct ndis_802_11_fixed_ies);
3406 p = cfg80211_find_ie(WLAN_EID_RSN, pie, pie_len);
3408 pframe = rtw_set_ie23a(pframe, WLAN_EID_RSN, p[1], p + 2,
3412 if (padapter->mlmepriv.htpriv.ht_option == true) {
3413 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, pie, pie_len);
3415 if (p && !is_ap_in_tkip23a(padapter)) {
3416 memcpy(&pmlmeinfo->HT_caps, p + 2,
3417 sizeof(struct HT_caps_element));
3419 /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
3420 if (pregpriv->cbw40_enable == 0) {
3421 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &= (~(BIT(6) | BIT(1)));
3423 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= BIT(1);
3426 /* todo: disable SM power save mode */
3427 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |=
3430 rf_type = rtl8723a_get_rf_type(padapter);
3431 /* switch (pregpriv->rf_config) */
3434 /* RX STBC One spatial stream */
3435 if (pregpriv->rx_stbc)
3436 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);
3438 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R23A, 16);
3444 /* enable for 2.4/5 GHz */
3445 if (pregpriv->rx_stbc == 0x3 ||
3446 (pmlmeext->cur_wireless_mode &
3448 /* enable for 2.4GHz */
3449 pregpriv->rx_stbc == 0x1) ||
3450 (pmlmeext->cur_wireless_mode &
3452 pregpriv->rx_stbc == 0x2) ||
3453 /* enable for 5GHz */
3454 pregpriv->wifi_spec == 1) {
3455 DBG_8723A("declare supporting RX "
3457 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0200);/* RX STBC two spatial stream */
3459 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R23A, 16);
3462 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info =
3463 cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
3465 #ifdef CONFIG_8723AU_BT_COEXIST
3466 if (BT_1Ant(padapter) == true) {
3468 pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para &= (u8)~IEEE80211_HT_AMPDU_PARM_FACTOR;
3469 /* pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para |= MAX_AMPDU_FACTOR_8K */
3473 pframe = rtw_set_ie23a(pframe, WLAN_EID_HT_CAPABILITY,
3474 p[1], (u8 *)&pmlmeinfo->HT_caps,
3479 /* vendor specific IE, such as WPA, WMM, WPS */
3480 for (i = sizeof(struct ndis_802_11_fixed_ies);
3481 i < pmlmeinfo->network.IELength;) {
3482 pIE = (struct ndis_802_11_var_ies *)
3483 (pmlmeinfo->network.IEs + i);
3485 switch (pIE->ElementID)
3487 case WLAN_EID_VENDOR_SPECIFIC:
3488 if (!memcmp(pIE->data, RTW_WPA_OUI23A_TYPE, 4) ||
3489 !memcmp(pIE->data, WMM_OUI23A, 4) ||
3490 !memcmp(pIE->data, WPS_OUI23A, 4)) {
3491 if (!padapter->registrypriv.wifi_spec) {
3492 /* Commented by Kurt 20110629 */
3493 /* In some older APs, WPS handshake */
3494 /* would be fail if we append vender
3495 extensions informations to AP */
3496 if (!memcmp(pIE->data, WPS_OUI23A, 4))
3499 pframe = rtw_set_ie23a(pframe,
3500 WLAN_EID_VENDOR_SPECIFIC,
3501 pIE->Length, pIE->data,
3510 i += pIE->Length + 2;
3513 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
3514 pframe = rtw_set_ie23a(pframe, WLAN_EID_VENDOR_SPECIFIC, 6,
3515 REALTEK_96B_IE, &pattrib->pktlen);
3517 pattrib->last_txcmdsz = pattrib->pktlen;
3518 dump_mgntframe23a(padapter, pmgntframe);
3523 pmlmepriv->assoc_req_len = 0;
3524 if (ret == _SUCCESS) {
3525 kfree(pmlmepriv->assoc_req);
3526 pmlmepriv->assoc_req = kmalloc(pattrib->pktlen, GFP_ATOMIC);
3527 if (pmlmepriv->assoc_req) {
3528 memcpy(pmlmepriv->assoc_req, pwlanhdr, pattrib->pktlen);
3529 pmlmepriv->assoc_req_len = pattrib->pktlen;
3532 kfree(pmlmepriv->assoc_req);
3537 /* when wait_ack is ture, this function shoule be called at process context */
3538 static int _issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3539 unsigned int power_mode, int wait_ack)
3542 struct xmit_frame *pmgntframe;
3543 struct pkt_attrib *pattrib;
3544 unsigned char *pframe;
3545 struct ieee80211_hdr *pwlanhdr;
3547 struct xmit_priv *pxmitpriv;
3548 struct mlme_ext_priv *pmlmeext;
3549 struct mlme_ext_info *pmlmeinfo;
3551 /* DBG_8723A("%s:%d\n", __func__, power_mode); */
3556 pxmitpriv = &padapter->xmitpriv;
3557 pmlmeext = &padapter->mlmeextpriv;
3558 pmlmeinfo = &pmlmeext->mlmext_info;
3560 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3563 /* update attribute */
3564 pattrib = &pmgntframe->attrib;
3565 update_mgntframe_attrib23a(padapter, pattrib);
3566 pattrib->retry_ctrl = false;
3568 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3570 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3571 pwlanhdr = (struct ieee80211_hdr *)pframe;
3573 fctrl = &pwlanhdr->frame_control;
3576 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3578 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
3584 ether_addr_copy(pwlanhdr->addr1, da);
3585 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3586 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3588 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3589 pmlmeext->mgnt_seq++;
3590 SetFrameSubType(pframe, WIFI_DATA_NULL);
3592 pframe += sizeof(struct ieee80211_hdr_3addr);
3593 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3595 pattrib->last_txcmdsz = pattrib->pktlen;
3598 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3600 dump_mgntframe23a(padapter, pmgntframe);
3608 /* when wait_ms >0 , this function shoule be called at process context */
3609 /* da == NULL for station mode */
3610 int issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3611 unsigned int power_mode, int try_cnt, int wait_ms)
3615 unsigned long start = jiffies;
3616 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3617 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3619 /* da == NULL, assum it's null data for sta to ap*/
3621 da = get_my_bssid23a(&pmlmeinfo->network);
3624 ret = _issue_nulldata23a(padapter, da, power_mode,
3625 wait_ms > 0 ? true : false);
3629 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3632 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3635 } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
3642 if (try_cnt && wait_ms) {
3644 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
3645 "in %u ms\n", __func__,
3646 padapter->pnetdev->name,
3647 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3648 ret == _SUCCESS?", acked":"", i, try_cnt,
3649 jiffies_to_msecs(jiffies - start));
3651 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3652 __func__, padapter->pnetdev->name,
3653 rtw_get_oper_ch23a(padapter),
3654 ret == _SUCCESS?", acked":"", i, try_cnt,
3655 jiffies_to_msecs(jiffies - start));
3661 /* when wait_ack is ture, this function shoule be called at process context */
3662 static int _issue_qos_nulldata23a(struct rtw_adapter *padapter,
3663 unsigned char *da, u16 tid, int wait_ack)
3666 struct xmit_frame *pmgntframe;
3667 struct pkt_attrib *pattrib;
3668 unsigned char *pframe;
3669 struct ieee80211_hdr *pwlanhdr;
3672 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3673 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3674 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3676 DBG_8723A("%s\n", __func__);
3678 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3681 /* update attribute */
3682 pattrib = &pmgntframe->attrib;
3683 update_mgntframe_attrib23a(padapter, pattrib);
3685 pattrib->hdrlen += 2;
3686 pattrib->qos_en = true;
3688 pattrib->ack_policy = 0;
3691 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3693 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3694 pwlanhdr = (struct ieee80211_hdr *)pframe;
3696 fctrl = &pwlanhdr->frame_control;
3699 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
3701 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
3707 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
3709 SetPriority(qc, tid);
3711 SetEOSP(qc, pattrib->eosp);
3713 SetAckpolicy(qc, pattrib->ack_policy);
3715 ether_addr_copy(pwlanhdr->addr1, da);
3716 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3717 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3719 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3720 pmlmeext->mgnt_seq++;
3721 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
3723 pframe += sizeof(struct ieee80211_qos_hdr);
3724 pattrib->pktlen = sizeof(struct ieee80211_qos_hdr);
3726 pattrib->last_txcmdsz = pattrib->pktlen;
3729 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3731 dump_mgntframe23a(padapter, pmgntframe);
3739 /* when wait_ms >0 , this function shoule be called at process context */
3740 /* da == NULL for station mode */
3741 int issue_qos_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
3742 u16 tid, int try_cnt, int wait_ms)
3746 unsigned long start = jiffies;
3747 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3748 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3750 /* da == NULL, assum it's null data for sta to ap*/
3752 da = get_my_bssid23a(&pmlmeinfo->network);
3755 ret = _issue_qos_nulldata23a(padapter, da, tid,
3756 wait_ms > 0 ? true : false);
3760 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3763 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3765 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
3772 if (try_cnt && wait_ms) {
3774 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
3775 "in %u ms\n", __func__,
3776 padapter->pnetdev->name,
3777 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3778 ret == _SUCCESS?", acked":"", i, try_cnt,
3779 jiffies_to_msecs(jiffies - start));
3781 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3782 __func__, padapter->pnetdev->name,
3783 rtw_get_oper_ch23a(padapter),
3784 ret == _SUCCESS?", acked":"", i, try_cnt,
3785 jiffies_to_msecs(jiffies - start));
3791 static int _issue_deauth23a(struct rtw_adapter *padapter, unsigned char *da,
3792 unsigned short reason, u8 wait_ack)
3794 struct xmit_frame *pmgntframe;
3795 struct pkt_attrib *pattrib;
3796 unsigned char *pframe;
3797 struct ieee80211_hdr *pwlanhdr;
3799 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3800 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3801 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3804 /* DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
3806 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3809 /* update attribute */
3810 pattrib = &pmgntframe->attrib;
3811 update_mgntframe_attrib23a(padapter, pattrib);
3812 pattrib->retry_ctrl = false;
3814 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3816 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3817 pwlanhdr = (struct ieee80211_hdr *)pframe;
3819 fctrl = &pwlanhdr->frame_control;
3822 ether_addr_copy(pwlanhdr->addr1, da);
3823 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3824 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
3826 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3827 pmlmeext->mgnt_seq++;
3828 SetFrameSubType(pframe, WIFI_DEAUTH);
3830 pframe += sizeof(struct ieee80211_hdr_3addr);
3831 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3833 reason = cpu_to_le16(reason);
3834 pframe = rtw_set_fixed_ie23a(pframe, WLAN_REASON_PREV_AUTH_NOT_VALID,
3835 (unsigned char *)&reason,
3838 pattrib->last_txcmdsz = pattrib->pktlen;
3841 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
3843 dump_mgntframe23a(padapter, pmgntframe);
3851 int issue_deauth23a(struct rtw_adapter *padapter, unsigned char *da,
3852 unsigned short reason)
3854 DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
3855 return _issue_deauth23a(padapter, da, reason, false);
3858 int issue_deauth23a_ex23a(struct rtw_adapter *padapter, u8 *da,
3859 unsigned short reason, int try_cnt, int wait_ms)
3863 unsigned long start = jiffies;
3866 ret = _issue_deauth23a(padapter, da, reason,
3867 wait_ms >0 ? true : false);
3871 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
3874 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
3877 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
3884 if (try_cnt && wait_ms) {
3886 DBG_8723A("%s(%s): to "MAC_FMT", ch:%u%s, %d/%d "
3887 "in %u ms\n", __func__,
3888 padapter->pnetdev->name,
3889 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
3890 ret == _SUCCESS?", acked":"", i, try_cnt,
3891 jiffies_to_msecs(jiffies - start));
3893 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3894 __func__, padapter->pnetdev->name,
3895 rtw_get_oper_ch23a(padapter),
3896 ret == _SUCCESS?", acked":"", i, try_cnt,
3897 jiffies_to_msecs(jiffies - start));
3903 void issue_action_spct_ch_switch23a(struct rtw_adapter *padapter,
3904 u8 *ra, u8 new_ch, u8 ch_offset)
3906 struct xmit_frame *pmgntframe;
3907 struct pkt_attrib *pattrib;
3908 unsigned char *pframe;
3909 struct ieee80211_hdr *pwlanhdr;
3911 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3912 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3913 u8 category, action;
3915 DBG_8723A("%s(%s): ra ="MAC_FMT", ch:%u, offset:%u\n", __func__,
3916 padapter->pnetdev->name, MAC_ARG(ra), new_ch, ch_offset);
3918 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3921 /* update attribute */
3922 pattrib = &pmgntframe->attrib;
3923 update_mgntframe_attrib23a(padapter, pattrib);
3925 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3927 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3928 pwlanhdr = (struct ieee80211_hdr *)pframe;
3930 fctrl = &pwlanhdr->frame_control;
3933 ether_addr_copy(pwlanhdr->addr1, ra); /* RA */
3934 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv)); /* TA */
3935 ether_addr_copy(pwlanhdr->addr3, ra); /* DA = RA */
3937 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3938 pmlmeext->mgnt_seq++;
3939 SetFrameSubType(pframe, WIFI_ACTION);
3941 pframe += sizeof(struct ieee80211_hdr_3addr);
3942 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3944 /* category, action */
3945 category = WLAN_CATEGORY_SPECTRUM_MGMT;
3946 action = WLAN_ACTION_SPCT_CHL_SWITCH;
3948 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
3949 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
3951 pframe = rtw_set_ie23a_ch_switch (pframe, &pattrib->pktlen, 0,
3953 pframe = rtw_set_ie23a_secondary_ch_offset(pframe, &pattrib->pktlen,
3954 hal_ch_offset_to_secondary_ch_offset23a(ch_offset));
3956 pattrib->last_txcmdsz = pattrib->pktlen;
3958 dump_mgntframe23a(padapter, pmgntframe);
3961 void issue_action_BA23a(struct rtw_adapter *padapter,
3962 const unsigned char *raddr,
3963 unsigned char action, unsigned short status)
3965 u8 category = WLAN_CATEGORY_BACK;
3969 u16 BA_timeout_value;
3970 u16 BA_starting_seqctrl;
3971 int max_rx_ampdu_factor;
3972 struct xmit_frame *pmgntframe;
3973 struct pkt_attrib *pattrib;
3975 struct ieee80211_hdr *pwlanhdr;
3977 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3978 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3979 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3980 struct sta_info *psta;
3981 struct sta_priv *pstapriv = &padapter->stapriv;
3982 struct registry_priv *pregpriv = &padapter->registrypriv;
3983 #ifdef CONFIG_8723AU_BT_COEXIST
3984 u8 tendaAPMac[] = {0xC8, 0x3A, 0x35};
3987 DBG_8723A("%s, category =%d, action =%d, status =%d\n",
3988 __func__, category, action, status);
3990 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3993 /* update attribute */
3994 pattrib = &pmgntframe->attrib;
3995 update_mgntframe_attrib23a(padapter, pattrib);
3997 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3999 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4000 pwlanhdr = (struct ieee80211_hdr *)pframe;
4002 fctrl = &pwlanhdr->frame_control;
4005 /* memcpy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN); */
4006 ether_addr_copy(pwlanhdr->addr1, raddr);
4007 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
4008 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
4010 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4011 pmlmeext->mgnt_seq++;
4012 SetFrameSubType(pframe, WIFI_ACTION);
4014 pframe += sizeof(struct ieee80211_hdr_3addr);
4015 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
4017 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
4018 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
4020 status = cpu_to_le16(status);
4027 case 0: /* ADDBA req */
4029 pmlmeinfo->dialogToken++;
4030 } while (pmlmeinfo->dialogToken == 0);
4031 pframe = rtw_set_fixed_ie23a(pframe, 1, &pmlmeinfo->dialogToken,
4034 #ifdef CONFIG_8723AU_BT_COEXIST
4035 if ((BT_1Ant(padapter) == true) &&
4036 ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
4037 memcmp(raddr, tendaAPMac, 3))) {
4038 /* A-MSDU NOT Supported */
4040 /* immediate Block Ack */
4041 BA_para_set |= (1 << 1) &
4042 IEEE80211_ADDBA_PARAM_POLICY_MASK;
4044 BA_para_set |= (status << 2) &
4045 IEEE80211_ADDBA_PARAM_TID_MASK;
4046 /* max buffer size is 8 MSDU */
4047 BA_para_set |= (8 << 6) &
4048 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4052 /* immediate ack & 64 buffer size */
4053 BA_para_set = (0x1002 | ((status & 0xf) << 2));
4055 BA_para_set = cpu_to_le16(BA_para_set);
4056 pframe = rtw_set_fixed_ie23a(pframe, 2,
4057 (unsigned char *)&BA_para_set,
4060 BA_timeout_value = 5000;/* 5ms */
4061 BA_timeout_value = cpu_to_le16(BA_timeout_value);
4062 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)
4066 /* if ((psta = rtw_get_stainfo23a(pstapriv,
4067 pmlmeinfo->network.MacAddress)) != NULL) */
4068 if ((psta = rtw_get_stainfo23a(pstapriv, raddr))) {
4069 start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1;
4071 DBG_8723A("BA_starting_seqctrl = %d for TID =%d\n",
4072 start_seq, status & 0x07);
4074 psta->BA_starting_seqctrl[status & 0x07] = start_seq;
4076 BA_starting_seqctrl = start_seq << 4;
4079 BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
4080 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)&BA_starting_seqctrl, &pattrib->pktlen);
4083 case 1: /* ADDBA rsp */
4084 pframe = rtw_set_fixed_ie23a(pframe, 1, &pmlmeinfo->ADDBA_req.dialog_token, &pattrib->pktlen);
4085 pframe = rtw_set_fixed_ie23a(pframe, 2,
4086 (unsigned char *)&status,
4088 rtw_hal_get_def_var23a(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
4089 &max_rx_ampdu_factor);
4090 if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_64K)
4091 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
4092 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_32K)
4093 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800); /* 32 buffer size */
4094 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_16K)
4095 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0400); /* 16 buffer size */
4096 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_8K)
4097 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0200); /* 8 buffer size */
4099 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
4101 #ifdef CONFIG_8723AU_BT_COEXIST
4102 if ((BT_1Ant(padapter) == true) &&
4103 ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
4104 memcmp(raddr, tendaAPMac, 3))) {
4105 /* max buffer size is 8 MSDU */
4106 BA_para_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4107 BA_para_set |= (8 << 6) &
4108 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
4112 if (pregpriv->ampdu_amsdu == 0)/* disabled */
4113 BA_para_set = cpu_to_le16(BA_para_set & ~BIT(0));
4114 else if (pregpriv->ampdu_amsdu == 1)/* enabled */
4115 BA_para_set = cpu_to_le16(BA_para_set | BIT(0));
4117 BA_para_set = cpu_to_le16(BA_para_set);
4119 pframe = rtw_set_fixed_ie23a(pframe, 2,
4120 (unsigned char *)&BA_para_set,
4122 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)&pmlmeinfo->ADDBA_req.BA_timeout_value, &pattrib->pktlen);
4125 BA_para_set = (status & 0x1F) << 3;
4126 BA_para_set = cpu_to_le16(BA_para_set);
4127 pframe = rtw_set_fixed_ie23a(pframe, 2,
4128 (unsigned char *)&BA_para_set,
4131 reason_code = 37;/* Requested from peer STA as it does not
4132 want to use the mechanism */
4133 reason_code = cpu_to_le16(reason_code);
4134 pframe = rtw_set_fixed_ie23a(pframe, 2,
4135 (unsigned char *)&reason_code,
4143 pattrib->last_txcmdsz = pattrib->pktlen;
4145 dump_mgntframe23a(padapter, pmgntframe);
4148 static void issue_action_BSSCoexistPacket(struct rtw_adapter *padapter)
4150 struct list_head *plist, *phead, *ptmp;
4151 unsigned char category, action;
4152 struct xmit_frame *pmgntframe;
4153 struct pkt_attrib *pattrib;
4155 struct ieee80211_hdr *pwlanhdr;
4157 struct wlan_network *pnetwork;
4158 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4159 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4160 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4161 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4162 struct rtw_queue *queue = &pmlmepriv->scanned_queue;
4163 u8 InfoContent[16] = {0};
4167 if (pmlmepriv->num_FortyMHzIntolerant == 0 ||
4168 pmlmepriv->num_sta_no_ht == 0)
4171 if (pmlmeinfo->bwmode_updated)
4174 DBG_8723A("%s\n", __func__);
4176 category = WLAN_CATEGORY_PUBLIC;
4177 action = ACT_PUBLIC_BSSCOEXIST;
4179 pmgntframe = alloc_mgtxmitframe23a(pxmitpriv);
4183 /* update attribute */
4184 pattrib = &pmgntframe->attrib;
4185 update_mgntframe_attrib23a(padapter, pattrib);
4187 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4189 pframe = (u8 *)pmgntframe->buf_addr + TXDESC_OFFSET;
4190 pwlanhdr = (struct ieee80211_hdr *)pframe;
4192 fctrl = &pwlanhdr->frame_control;
4195 ether_addr_copy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network));
4196 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
4197 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
4199 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4200 pmlmeext->mgnt_seq++;
4201 SetFrameSubType(pframe, WIFI_ACTION);
4203 pframe += sizeof(struct ieee80211_hdr_3addr);
4204 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
4206 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
4207 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
4209 if (pmlmepriv->num_FortyMHzIntolerant > 0) {
4210 u8 iedata = BIT(2);/* 20 MHz BSS Width Request */
4212 pframe = rtw_set_ie23a(pframe, WLAN_EID_BSS_COEX_2040, 1,
4213 &iedata, &pattrib->pktlen);
4216 if (pmlmepriv->num_sta_no_ht <= 0)
4219 memset(ICS, 0, sizeof(ICS));
4221 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
4223 phead = get_list_head(queue);
4224 plist = phead->next;
4226 list_for_each_safe(plist, ptmp, phead) {
4228 struct wlan_bssid_ex *pbss_network;
4230 pnetwork = container_of(plist, struct wlan_network, list);
4232 pbss_network = &pnetwork->network;
4234 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
4235 pbss_network->IEs + _FIXED_IE_LENGTH_,
4236 pbss_network->IELength -_FIXED_IE_LENGTH_);
4237 if (!p || !p[1]) { /* non-HT */
4238 if (pbss_network->Configuration.DSConfig <= 0 ||
4239 pbss_network->Configuration.DSConfig > 14)
4242 ICS[0][pbss_network->Configuration.DSConfig] = 1;
4250 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
4252 for (i = 0; i < 8;i++) {
4253 if (ICS[i][0] == 1) {
4257 /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */
4260 for (j = 1; j <= 14; j++) {
4261 if (ICS[i][j] == 1) {
4263 /* channel number */
4270 pframe = rtw_set_ie23a(pframe,
4271 EID_BSSIntolerantChlReport, k,
4272 InfoContent, &pattrib->pktlen);
4277 pattrib->last_txcmdsz = pattrib->pktlen;
4279 dump_mgntframe23a(padapter, pmgntframe);
4282 unsigned int send_delba23a(struct rtw_adapter *padapter, u8 initiator, u8 *addr)
4284 struct sta_priv *pstapriv = &padapter->stapriv;
4285 struct sta_info *psta = NULL;
4286 /* struct recv_reorder_ctrl *preorder_ctrl; */
4287 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4288 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4291 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
4292 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
4295 psta = rtw_get_stainfo23a(pstapriv, addr);
4299 if (initiator == 0) { /* recipient */
4300 for (tid = 0; tid < MAXTID; tid++) {
4301 if (psta->recvreorder_ctrl[tid].enable == true) {
4302 DBG_8723A("rx agg disable tid(%d)\n", tid);
4303 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
4304 psta->recvreorder_ctrl[tid].enable = false;
4305 psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
4308 } else if (initiator == 1) { /* originator */
4309 for (tid = 0; tid < MAXTID; tid++) {
4310 if (psta->htpriv.agg_enable_bitmap & BIT(tid)) {
4311 DBG_8723A("tx agg disable tid(%d)\n", tid);
4312 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
4313 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
4314 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
4322 unsigned int send_beacon23a(struct rtw_adapter *padapter)
4327 unsigned long start = jiffies;
4328 unsigned int passing_time;
4330 rtl8723a_bcn_valid(padapter);
4332 issue_beacon23a(padapter, 100);
4336 bxmitok = rtl8723a_get_bcn_valid(padapter);
4338 } while ((poll % 10) != 0 && bxmitok == false &&
4339 !padapter->bSurpriseRemoved &&
4340 !padapter->bDriverStopped);
4342 } while (!bxmitok && issue<100 && !padapter->bSurpriseRemoved &&
4343 !padapter->bDriverStopped);
4345 if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
4348 passing_time = jiffies_to_msecs(jiffies - start);
4351 DBG_8723A("%s fail! %u ms\n", __func__, passing_time);
4355 if (passing_time > 100 || issue > 3)
4356 DBG_8723A("%s success, issue:%d, poll:%d, %u ms\n",
4357 __func__, issue, poll, passing_time);
4362 /****************************************************************************
4364 Following are some utitity fuctions for WiFi MLME
4366 *****************************************************************************/
4368 bool IsLegal5GChannel(struct rtw_adapter *Adapter, u8 channel)
4372 u8 Channel_5G[45] = {36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
4373 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
4374 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
4376 for (i = 0; i < sizeof(Channel_5G); i++)
4377 if (channel == Channel_5G[i])
4382 void site_survey23a(struct rtw_adapter *padapter)
4384 unsigned char survey_channel = 0;
4385 enum rt_scan_type ScanType = SCAN_PASSIVE;
4386 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4387 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4388 struct rtw_ieee80211_channel *ch;
4390 if (pmlmeext->sitesurvey_res.channel_idx <
4391 pmlmeext->sitesurvey_res.ch_num) {
4392 ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
4393 survey_channel = ch->hw_value;
4394 ScanType = (ch->flags & IEEE80211_CHAN_NO_IR) ?
4395 SCAN_PASSIVE : SCAN_ACTIVE;
4398 if (survey_channel != 0) {
4399 /* PAUSE 4-AC Queue when site_survey23a */
4400 if (pmlmeext->sitesurvey_res.channel_idx == 0)
4401 set_channel_bwmode23a(padapter, survey_channel,
4402 HAL_PRIME_CHNL_OFFSET_DONT_CARE,
4403 HT_CHANNEL_WIDTH_20);
4405 SelectChannel23a(padapter, survey_channel);
4407 if (ScanType == SCAN_ACTIVE) /* obey the channel plan setting... */
4410 for (i = 0;i<RTW_SSID_SCAN_AMOUNT;i++) {
4411 if (pmlmeext->sitesurvey_res.ssid[i].ssid_len) {
4412 /* todo: to issue two probe req??? */
4413 issue_probereq23a(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
4414 /* msleep(SURVEY_TO>>1); */
4415 issue_probereq23a(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
4419 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
4420 /* todo: to issue two probe req??? */
4421 issue_probereq23a(padapter, NULL, NULL);
4422 /* msleep(SURVEY_TO>>1); */
4423 issue_probereq23a(padapter, NULL, NULL);
4427 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
4429 /* channel number is 0 or this channel is not valid. */
4430 pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
4432 /* switch back to the original channel */
4434 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
4435 pmlmeext->cur_ch_offset,
4436 pmlmeext->cur_bwmode);
4438 /* flush 4-AC Queue after site_survey23a */
4442 Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
4444 /* restore RX GAIN */
4445 rtl8723a_set_initial_gain(padapter, 0xff);
4446 /* turn on dynamic functions */
4447 rtl8723a_odm_support_ability_restore(padapter);
4449 if (is_client_associated_to_ap23a(padapter) == true)
4450 issue_nulldata23a(padapter, NULL, 0, 3, 500);
4452 rtl8723a_mlme_sitesurvey(padapter, 0);
4454 report_surveydone_event23a(padapter);
4456 pmlmeext->chan_scan_time = SURVEY_TO;
4457 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
4459 issue_action_BSSCoexistPacket(padapter);
4460 issue_action_BSSCoexistPacket(padapter);
4461 issue_action_BSSCoexistPacket(padapter);
4467 /* collect bss info from Beacon and Probe request/response frames. */
4468 u8 collect_bss_info23a(struct rtw_adapter *padapter,
4469 struct recv_frame *precv_frame,
4470 struct wlan_bssid_ex *bssid)
4474 struct sk_buff *skb = precv_frame->pkt;
4475 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) skb->data;
4476 unsigned int length;
4478 struct registry_priv *pregistrypriv = &padapter->registrypriv;
4479 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4480 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4483 length = skb->len - sizeof(struct ieee80211_hdr_3addr);
4485 if (length > MAX_IE_SZ) {
4486 /* DBG_8723A("IE too long for survey event\n"); */
4490 memset(bssid, 0, sizeof(struct wlan_bssid_ex));
4492 if (ieee80211_is_beacon(mgmt->frame_control)) {
4493 bssid->reserved = 1;
4494 ie_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
4495 capab_info = mgmt->u.beacon.capab_info;
4496 } else if (ieee80211_is_probe_req(mgmt->frame_control)) {
4497 ie_offset = offsetof(struct ieee80211_mgmt,
4498 u.probe_req.variable);
4499 bssid->reserved = 2;
4501 } else if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4502 ie_offset = offsetof(struct ieee80211_mgmt,
4503 u.probe_resp.variable);
4504 bssid->reserved = 3;
4505 capab_info = mgmt->u.probe_resp.capab_info;
4507 bssid->reserved = 0;
4508 ie_offset = offsetof(struct ieee80211_mgmt, u.beacon.variable);
4509 capab_info = mgmt->u.beacon.capab_info;
4511 ie_offset -= offsetof(struct ieee80211_mgmt, u);
4513 bssid->Length = offsetof(struct wlan_bssid_ex, IEs) + length;
4515 /* below is to copy the information element */
4516 bssid->IELength = length;
4517 memcpy(bssid->IEs, &mgmt->u, bssid->IELength);
4519 /* get the signal strength */
4520 /* in dBM.raw data */
4521 bssid->Rssi = precv_frame->attrib.phy_info.RecvSignalPower;
4522 bssid->PhyInfo.SignalQuality =
4523 precv_frame->attrib.phy_info.SignalQuality;/* in percentage */
4524 bssid->PhyInfo.SignalStrength =
4525 precv_frame->attrib.phy_info.SignalStrength;/* in percentage */
4528 p = cfg80211_find_ie(WLAN_EID_SSID, bssid->IEs + ie_offset,
4529 bssid->IELength - ie_offset);
4532 DBG_8723A("marc: cannot find SSID for survey event\n");
4536 if (p[1] > IEEE80211_MAX_SSID_LEN) {
4537 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4538 "event\n", __func__, __LINE__, p[1]);
4541 memcpy(bssid->Ssid.ssid, p + 2, p[1]);
4542 bssid->Ssid.ssid_len = p[1];
4544 memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
4546 /* checking rate info... */
4548 p = cfg80211_find_ie(WLAN_EID_SUPP_RATES, bssid->IEs + ie_offset,
4549 bssid->IELength - ie_offset);
4551 if (p[1] > NDIS_802_11_LENGTH_RATES_EX) {
4552 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4553 "event\n", __func__, __LINE__, p[1]);
4556 memcpy(bssid->SupportedRates, p + 2, p[1]);
4560 p = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, bssid->IEs + ie_offset,
4561 bssid->IELength - ie_offset);
4563 if (p[1] > (NDIS_802_11_LENGTH_RATES_EX-i)) {
4564 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4565 "event\n", __func__, __LINE__, p[1]);
4568 memcpy(bssid->SupportedRates + i, p + 2, p[1]);
4571 bssid->NetworkTypeInUse = Ndis802_11OFDM24;
4573 if (bssid->IELength < 12)
4576 /* Checking for DSConfig */
4577 p = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bssid->IEs + ie_offset,
4578 bssid->IELength - ie_offset);
4580 bssid->Configuration.DSConfig = 0;
4581 bssid->Configuration.Length = 0;
4584 bssid->Configuration.DSConfig = p[2];
4585 } else {/* In 5G, some ap do not have DSSET IE */
4586 /* checking HT info for channel */
4587 p = cfg80211_find_ie(WLAN_EID_HT_OPERATION,
4588 bssid->IEs + ie_offset,
4589 bssid->IELength - ie_offset);
4591 struct HT_info_element *HT_info =
4592 (struct HT_info_element *)(p + 2);
4593 bssid->Configuration.DSConfig =
4594 HT_info->primary_channel;
4595 } else { /* use current channel */
4596 bssid->Configuration.DSConfig =
4597 rtw_get_oper_ch23a(padapter);
4601 if (ieee80211_is_probe_req(mgmt->frame_control)) {
4603 bssid->InfrastructureMode = Ndis802_11Infrastructure;
4604 ether_addr_copy(bssid->MacAddress, mgmt->sa);
4609 memcpy(&bssid->Configuration.BeaconPeriod,
4610 rtw_get_beacon_interval23a_from_ie(bssid->IEs), 2);
4611 bssid->Configuration.BeaconPeriod =
4612 le32_to_cpu(bssid->Configuration.BeaconPeriod);
4614 if (capab_info & BIT(0)) {
4615 bssid->InfrastructureMode = Ndis802_11Infrastructure;
4616 ether_addr_copy(bssid->MacAddress, mgmt->sa);
4618 bssid->InfrastructureMode = Ndis802_11IBSS;
4619 ether_addr_copy(bssid->MacAddress, mgmt->bssid);
4622 if (capab_info & BIT(4))
4627 bssid->Configuration.ATIMWindow = 0;
4629 /* 20/40 BSS Coexistence check */
4630 if (pregistrypriv->wifi_spec == 1 &&
4631 pmlmeinfo->bwmode_updated == false) {
4632 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4634 p = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY,
4635 bssid->IEs + ie_offset,
4636 bssid->IELength - ie_offset);
4637 if (p && p[1] > 0) {
4638 struct HT_caps_element *pHT_caps;
4639 pHT_caps = (struct HT_caps_element *)(p + 2);
4641 if (pHT_caps->u.HT_cap_element.HT_caps_info & BIT(14))
4642 pmlmepriv->num_FortyMHzIntolerant++;
4644 pmlmepriv->num_sta_no_ht++;
4648 /* mark bss info receving from nearby channel as SignalQuality 101 */
4649 if (bssid->Configuration.DSConfig != rtw_get_oper_ch23a(padapter))
4650 bssid->PhyInfo.SignalQuality = 101;
4655 void start_create_ibss23a(struct rtw_adapter* padapter)
4657 unsigned short caps;
4658 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4659 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4660 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
4661 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
4662 pmlmeinfo->bcn_interval = get_beacon_interval23a(pnetwork);
4664 /* update wireless mode */
4665 update_wireless_mode23a(padapter);
4667 /* udpate capability */
4668 caps = rtw_get_capability23a(pnetwork);
4669 update_capinfo23a(padapter, caps);
4670 if (caps&cap_IBSS) { /* adhoc master */
4671 rtl8723a_set_sec_cfg(padapter, 0xcf);
4673 /* switch channel */
4674 /* SelectChannel23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
4675 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
4677 beacon_timing_control23a(padapter);
4679 /* set msr to WIFI_FW_ADHOC_STATE */
4680 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4681 Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
4684 if (send_beacon23a(padapter) == _FAIL)
4686 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("issuing beacon frame fail....\n"));
4688 report_join_res23a(padapter, -1);
4689 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4693 hw_var_set_bssid(padapter, padapter->registrypriv.dev_network.MacAddress);
4694 hw_var_set_mlme_join(padapter, 0);
4696 report_join_res23a(padapter, 1);
4697 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
4702 DBG_8723A("start_create_ibss23a, invalid cap:%x\n", caps);
4707 void start_clnt_join23a(struct rtw_adapter* padapter)
4709 unsigned short caps;
4711 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4712 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4713 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
4716 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
4717 pmlmeinfo->bcn_interval = get_beacon_interval23a(pnetwork);
4719 /* update wireless mode */
4720 update_wireless_mode23a(padapter);
4722 /* udpate capability */
4723 caps = rtw_get_capability23a(pnetwork);
4724 update_capinfo23a(padapter, caps);
4726 /* switch channel */
4727 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4729 Set_MSR23a(padapter, WIFI_FW_STATION_STATE);
4731 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ?
4734 rtl8723a_set_sec_cfg(padapter, val8);
4736 /* switch channel */
4737 /* set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
4739 /* here wait for receiving the beacon to start auth */
4740 /* and enable a timer */
4741 beacon_timeout = decide_wait_for_beacon_timeout23a(pmlmeinfo->bcn_interval);
4742 set_link_timer(pmlmeext, beacon_timeout);
4743 mod_timer(&padapter->mlmepriv.assoc_timer, jiffies +
4744 msecs_to_jiffies((REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) + beacon_timeout));
4745 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
4747 else if (caps&cap_IBSS) { /* adhoc client */
4748 Set_MSR23a(padapter, WIFI_FW_ADHOC_STATE);
4750 rtl8723a_set_sec_cfg(padapter, 0xcf);
4752 /* switch channel */
4753 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
4755 beacon_timing_control23a(padapter);
4757 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
4759 report_join_res23a(padapter, 1);
4763 /* DBG_8723A("marc: invalid cap:%x\n", caps); */
4768 void start_clnt_auth23a(struct rtw_adapter* padapter)
4770 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4771 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4773 del_timer_sync(&pmlmeext->link_timer);
4775 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
4776 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
4778 pmlmeinfo->auth_seq = 1;
4779 pmlmeinfo->reauth_count = 0;
4780 pmlmeinfo->reassoc_count = 0;
4781 pmlmeinfo->link_count = 0;
4782 pmlmeext->retry = 0;
4784 /* Because of AP's not receiving deauth before */
4785 /* AP may: 1)not response auth or 2)deauth us after link is complete */
4786 /* issue deauth before issuing auth to deal with the situation */
4787 /* Commented by Albert 2012/07/21 */
4788 /* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
4789 issue_deauth23a(padapter, (&pmlmeinfo->network)->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
4791 DBG_8723A_LEVEL(_drv_always_, "start auth\n");
4792 issue_auth23a(padapter, NULL, 0);
4794 set_link_timer(pmlmeext, REAUTH_TO);
4797 void start_clnt_assoc23a(struct rtw_adapter* padapter)
4799 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4800 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4802 del_timer_sync(&pmlmeext->link_timer);
4804 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
4805 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
4807 issue_assocreq23a(padapter);
4809 set_link_timer(pmlmeext, REASSOC_TO);
4812 unsigned int receive_disconnect23a(struct rtw_adapter *padapter, unsigned char *MacAddr, unsigned short reason)
4814 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4815 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4818 if (!ether_addr_equal(MacAddr, get_my_bssid23a(&pmlmeinfo->network)))
4821 DBG_8723A("%s\n", __func__);
4823 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
4825 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
4827 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4828 report_del_sta_event23a(padapter, MacAddr, reason);
4831 else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
4833 pmlmeinfo->state = WIFI_FW_NULL_STATE;
4834 report_join_res23a(padapter, -2);
4841 static void process_80211d(struct rtw_adapter *padapter,
4842 struct wlan_bssid_ex *bssid)
4844 struct registry_priv *pregistrypriv;
4845 struct mlme_ext_priv *pmlmeext;
4846 struct rt_channel_info *chplan_new;
4850 pregistrypriv = &padapter->registrypriv;
4851 pmlmeext = &padapter->mlmeextpriv;
4853 /* Adjust channel plan by AP Country IE */
4854 if (pregistrypriv->enable80211d &&
4855 !pmlmeext->update_channel_plan_by_ap_done) {
4857 struct rt_channel_plan chplan_ap;
4858 struct rt_channel_info chplan_sta[MAX_CHANNEL_NUM];
4860 u8 fcn; /* first channel number */
4861 u8 noc; /* number of channel */
4864 ie = cfg80211_find_ie(WLAN_EID_COUNTRY,
4865 bssid->IEs + _FIXED_IE_LENGTH_,
4866 bssid->IELength - _FIXED_IE_LENGTH_);
4867 if (!ie || ie[1] < IEEE80211_COUNTRY_IE_MIN_LEN)
4874 memcpy(country, p, 3);
4878 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
4879 ("%s: 802.11d country =%s\n", __func__, country));
4882 while ((ie - p) >= 3) {
4887 for (j = 0; j < noc; j++) {
4889 channel = fcn + j; /* 2.4 GHz */
4891 channel = fcn + j * 4; /* 5 GHz */
4893 chplan_ap.Channel[i++] = channel;
4898 memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
4899 memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
4900 chplan_new = pmlmeext->channel_set;
4903 if (pregistrypriv->wireless_mode & WIRELESS_11G) {
4905 if (i == MAX_CHANNEL_NUM ||
4906 chplan_sta[i].ChannelNum == 0 ||
4907 chplan_sta[i].ChannelNum > 14)
4910 if (j == chplan_ap.Len ||
4911 chplan_ap.Channel[j] > 14)
4914 if (chplan_sta[i].ChannelNum ==
4915 chplan_ap.Channel[j]) {
4916 chplan_new[k].ChannelNum =
4917 chplan_ap.Channel[j];
4918 chplan_new[k].ScanType = SCAN_ACTIVE;
4922 } else if (chplan_sta[i].ChannelNum <
4923 chplan_ap.Channel[j]) {
4924 chplan_new[k].ChannelNum =
4925 chplan_sta[i].ChannelNum;
4926 chplan_new[k].ScanType =
4930 } else if (chplan_sta[i].ChannelNum >
4931 chplan_ap.Channel[j]) {
4932 chplan_new[k].ChannelNum =
4933 chplan_ap.Channel[j];
4934 chplan_new[k].ScanType =
4941 /* change AP not support channel to Passive scan */
4942 while (i < MAX_CHANNEL_NUM &&
4943 chplan_sta[i].ChannelNum != 0 &&
4944 chplan_sta[i].ChannelNum <= 14) {
4945 chplan_new[k].ChannelNum =
4946 chplan_sta[i].ChannelNum;
4947 chplan_new[k].ScanType = SCAN_PASSIVE;
4952 /* add channel AP supported */
4953 while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14){
4954 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
4955 chplan_new[k].ScanType = SCAN_ACTIVE;
4960 /* keep original STA 2.4G channel plan */
4961 while (i < MAX_CHANNEL_NUM &&
4962 chplan_sta[i].ChannelNum != 0 &&
4963 chplan_sta[i].ChannelNum <= 14) {
4964 chplan_new[k].ChannelNum =
4965 chplan_sta[i].ChannelNum;
4966 chplan_new[k].ScanType = chplan_sta[i].ScanType;
4971 /* skip AP 2.4G channel plan */
4972 while (j < chplan_ap.Len && chplan_ap.Channel[j] <= 14)
4976 if (pregistrypriv->wireless_mode & WIRELESS_11A) {
4978 if (i == MAX_CHANNEL_NUM ||
4979 chplan_sta[i].ChannelNum == 0)
4982 if (j == chplan_ap.Len ||
4983 chplan_ap.Channel[j] == 0)
4986 if (chplan_sta[i].ChannelNum ==
4987 chplan_ap.Channel[j]) {
4988 chplan_new[k].ChannelNum =
4989 chplan_ap.Channel[j];
4990 chplan_new[k].ScanType = SCAN_ACTIVE;
4994 } else if (chplan_sta[i].ChannelNum <
4995 chplan_ap.Channel[j]) {
4996 chplan_new[k].ChannelNum =
4997 chplan_sta[i].ChannelNum;
4998 chplan_new[k].ScanType = SCAN_PASSIVE;
5001 } else if (chplan_sta[i].ChannelNum >
5002 chplan_ap.Channel[j]) {
5003 chplan_new[k].ChannelNum =
5004 chplan_ap.Channel[j];
5005 chplan_new[k].ScanType = SCAN_ACTIVE;
5011 /* change AP not support channel to Passive scan */
5012 while (i < MAX_CHANNEL_NUM &&
5013 chplan_sta[i].ChannelNum != 0) {
5014 chplan_new[k].ChannelNum =
5015 chplan_sta[i].ChannelNum;
5016 chplan_new[k].ScanType = SCAN_PASSIVE;
5021 /* add channel AP supported */
5022 while (j < chplan_ap.Len && chplan_ap.Channel[j] != 0) {
5023 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
5024 chplan_new[k].ScanType = SCAN_ACTIVE;
5029 /* keep original STA 5G channel plan */
5030 while (i < MAX_CHANNEL_NUM &&
5031 chplan_sta[i].ChannelNum != 0) {
5032 chplan_new[k].ChannelNum =
5033 chplan_sta[i].ChannelNum;
5034 chplan_new[k].ScanType = chplan_sta[i].ScanType;
5039 pmlmeext->update_channel_plan_by_ap_done = 1;
5042 /* If channel is used by AP, set channel scan type to active */
5043 channel = bssid->Configuration.DSConfig;
5044 chplan_new = pmlmeext->channel_set;
5046 while (i < MAX_CHANNEL_NUM && chplan_new[i].ChannelNum != 0) {
5047 if (chplan_new[i].ChannelNum == channel) {
5048 if (chplan_new[i].ScanType == SCAN_PASSIVE) {
5049 /* 5G Bnad 2, 3 (DFS) doesn't change
5051 if (channel >= 52 && channel <= 144)
5054 chplan_new[i].ScanType = SCAN_ACTIVE;
5055 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
5056 ("%s: change channel %d scan type "
5057 "from passive to active\n",
5058 __func__, channel));
5066 /****************************************************************************
5068 Following are the functions to report events
5070 *****************************************************************************/
5072 void report_survey_event23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
5074 struct cmd_obj *pcmd_obj;
5077 struct survey_event *psurvey_evt;
5078 struct C2HEvent_Header *pc2h_evt_hdr;
5079 struct mlme_ext_priv *pmlmeext;
5080 struct cmd_priv *pcmdpriv;
5085 pmlmeext = &padapter->mlmeextpriv;
5086 pcmdpriv = &padapter->cmdpriv;
5088 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5093 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
5094 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5100 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5101 pcmd_obj->cmdsz = cmdsz;
5102 pcmd_obj->parmbuf = pevtcmd;
5104 pcmd_obj->rsp = NULL;
5105 pcmd_obj->rspsz = 0;
5107 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5108 pc2h_evt_hdr->len = sizeof(struct survey_event);
5109 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
5110 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5112 psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5114 if (collect_bss_info23a(padapter, precv_frame, &psurvey_evt->bss) == _FAIL) {
5120 process_80211d(padapter, &psurvey_evt->bss);
5122 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5124 pmlmeext->sitesurvey_res.bss_cnt++;
5129 void report_surveydone_event23a(struct rtw_adapter *padapter)
5131 struct cmd_obj *pcmd_obj;
5134 struct surveydone_event *psurveydone_evt;
5135 struct C2HEvent_Header *pc2h_evt_hdr;
5136 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5137 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5139 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5144 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
5145 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5151 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5152 pcmd_obj->cmdsz = cmdsz;
5153 pcmd_obj->parmbuf = pevtcmd;
5155 pcmd_obj->rsp = NULL;
5156 pcmd_obj->rspsz = 0;
5158 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5159 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
5160 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
5161 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5163 psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5164 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
5166 DBG_8723A("survey done event(%x)\n", psurveydone_evt->bss_cnt);
5168 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5173 void report_join_res23a(struct rtw_adapter *padapter, int res)
5175 struct cmd_obj *pcmd_obj;
5178 struct joinbss_event *pjoinbss_evt;
5179 struct C2HEvent_Header *pc2h_evt_hdr;
5180 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5181 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5182 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5184 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5189 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
5190 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5196 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5197 pcmd_obj->cmdsz = cmdsz;
5198 pcmd_obj->parmbuf = pevtcmd;
5200 pcmd_obj->rsp = NULL;
5201 pcmd_obj->rspsz = 0;
5203 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5204 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
5205 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
5206 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5208 pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5209 memcpy((unsigned char *)&pjoinbss_evt->network.network,
5210 &pmlmeinfo->network, sizeof(struct wlan_bssid_ex));
5211 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
5213 DBG_8723A("report_join_res23a(%d)\n", res);
5215 rtw_joinbss_event_prehandle23a(padapter, (u8 *)&pjoinbss_evt->network);
5217 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5222 void report_del_sta_event23a(struct rtw_adapter *padapter, unsigned char* MacAddr, unsigned short reason)
5224 struct cmd_obj *pcmd_obj;
5227 struct sta_info *psta;
5229 struct stadel_event *pdel_sta_evt;
5230 struct C2HEvent_Header *pc2h_evt_hdr;
5231 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5232 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5234 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5239 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
5240 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5246 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5247 pcmd_obj->cmdsz = cmdsz;
5248 pcmd_obj->parmbuf = pevtcmd;
5250 pcmd_obj->rsp = NULL;
5251 pcmd_obj->rspsz = 0;
5253 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5254 pc2h_evt_hdr->len = sizeof(struct stadel_event);
5255 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
5256 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5258 pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5259 ether_addr_copy((unsigned char *)&pdel_sta_evt->macaddr, MacAddr);
5260 memcpy((unsigned char *)pdel_sta_evt->rsvd, (unsigned char *)&reason,
5263 psta = rtw_get_stainfo23a(&padapter->stapriv, MacAddr);
5265 mac_id = (int)psta->mac_id;
5269 pdel_sta_evt->mac_id = mac_id;
5271 DBG_8723A("report_del_sta_event23a: delete STA, mac_id =%d\n", mac_id);
5273 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5278 void report_add_sta_event23a(struct rtw_adapter *padapter, unsigned char* MacAddr, int cam_idx)
5280 struct cmd_obj *pcmd_obj;
5283 struct stassoc_event *padd_sta_evt;
5284 struct C2HEvent_Header *pc2h_evt_hdr;
5285 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5286 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5288 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5293 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
5294 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
5300 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
5301 pcmd_obj->cmdsz = cmdsz;
5302 pcmd_obj->parmbuf = pevtcmd;
5304 pcmd_obj->rsp = NULL;
5305 pcmd_obj->rspsz = 0;
5307 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
5308 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
5309 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
5310 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
5312 padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
5313 ether_addr_copy((unsigned char *)&padd_sta_evt->macaddr, MacAddr);
5314 padd_sta_evt->cam_id = cam_idx;
5316 DBG_8723A("report_add_sta_event23a: add STA\n");
5318 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
5323 /****************************************************************************
5325 Following are the event callback functions
5327 *****************************************************************************/
5329 /* for sta/adhoc mode */
5330 void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta)
5332 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5333 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5334 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5337 VCS_update23a(padapter, psta);
5340 if (pmlmepriv->htpriv.ht_option)
5342 psta->htpriv.ht_option = true;
5344 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
5346 if (support_short_GI23a(padapter, &pmlmeinfo->HT_caps))
5347 psta->htpriv.sgi = true;
5349 psta->qos_option = true;
5354 psta->htpriv.ht_option = false;
5356 psta->htpriv.ampdu_enable = false;
5358 psta->htpriv.sgi = false;
5359 psta->qos_option = false;
5362 psta->htpriv.bwmode = pmlmeext->cur_bwmode;
5363 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
5365 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
5366 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
5369 if (pmlmepriv->qos_option)
5370 psta->qos_option = true;
5372 psta->state = _FW_LINKED;
5375 void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter, int join_res)
5377 struct sta_info *psta, *psta_bmc;
5378 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5379 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5380 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
5381 struct sta_priv *pstapriv = &padapter->stapriv;
5384 hw_var_set_mlme_join(padapter, 1);
5385 hw_var_set_bssid(padapter, null_addr);
5387 /* restore to initial setting. */
5388 update_tx_basic_rate23a(padapter,
5389 padapter->registrypriv.wireless_mode);
5391 goto exit_mlmeext_joinbss_event_callback23a;
5394 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
5397 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
5400 pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc;
5401 update_bmc_sta_support_rate23a(padapter, psta_bmc->mac_id);
5402 Update_RA_Entry23a(padapter, psta_bmc);
5406 /* turn on dynamic functions */
5407 rtl8723a_odm_support_ability_set(padapter, DYNAMIC_ALL_FUNC_ENABLE);
5409 /* update IOT-releated issue */
5410 update_IOT_info23a(padapter);
5412 HalSetBrateCfg23a(padapter, cur_network->SupportedRates);
5415 rtl8723a_set_beacon_interval(padapter, pmlmeinfo->bcn_interval);
5417 /* udpate capability */
5418 update_capinfo23a(padapter, pmlmeinfo->capability);
5420 /* WMM, Update EDCA param */
5421 WMMOnAssocRsp23a(padapter);
5424 HTOnAssocRsp23a(padapter);
5426 /* Set cur_channel&cur_bwmode&cur_ch_offset */
5427 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5429 psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
5430 if (psta) /* only for infra. mode */
5432 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5434 /* DBG_8723A("set_sta_rate23a\n"); */
5436 psta->wireless_mode = pmlmeext->cur_wireless_mode;
5438 /* set per sta rate after updating HT cap. */
5439 set_sta_rate23a(padapter, psta);
5442 hw_var_set_mlme_join(padapter, 2);
5444 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) {
5445 /* correcting TSF */
5446 rtw_correct_TSF(padapter);
5448 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5451 rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_CONNECT, 0);
5453 exit_mlmeext_joinbss_event_callback23a:
5454 DBG_8723A("=>%s\n", __func__);
5457 void mlmeext_sta_add_event_callback23a(struct rtw_adapter *padapter, struct sta_info *psta)
5459 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5460 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5462 DBG_8723A("%s\n", __func__);
5464 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
5466 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)/* adhoc master or sta_count>1 */
5470 else/* adhoc client */
5472 /* correcting TSF */
5473 rtw_correct_TSF(padapter);
5476 if (send_beacon23a(padapter) == _FAIL)
5478 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
5480 pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
5485 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
5489 hw_var_set_mlme_join(padapter, 2);
5492 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
5494 /* rate radaptive */
5495 Update_RA_Entry23a(padapter, psta);
5497 /* update adhoc sta_info */
5498 update_sta_info23a(padapter, psta);
5501 void mlmeext_sta_del_event_callback23a(struct rtw_adapter *padapter)
5503 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5504 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5506 if (is_client_associated_to_ap23a(padapter) || is_IBSS_empty23a(padapter))
5508 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
5510 hw_var_set_mlme_disconnect(padapter);
5511 hw_var_set_bssid(padapter, null_addr);
5513 /* restore to initial setting. */
5514 update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
5516 /* switch to the 20M Hz mode after disconnect */
5517 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5518 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5520 /* SelectChannel23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
5521 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
5523 flush_all_cam_entry23a(padapter);
5525 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5527 /* set MSR to no link state -> infra. mode */
5528 Set_MSR23a(padapter, _HW_STATE_STATION_);
5530 del_timer_sync(&pmlmeext->link_timer);
5534 static u8 chk_ap_is_alive(struct rtw_adapter *padapter, struct sta_info *psta)
5538 if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)) &&
5539 sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) &&
5540 sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
5545 sta_update_last_rx_pkts(psta);
5549 void linked_status_chk23a(struct rtw_adapter *padapter)
5552 struct sta_info *psta;
5553 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5554 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5555 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5556 struct sta_priv *pstapriv = &padapter->stapriv;
5558 rtw_hal_sreset_linked_status_check23a(padapter);
5560 if (is_client_associated_to_ap23a(padapter))
5562 /* linked infrastructure client mode */
5564 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
5569 if ((psta = rtw_get_stainfo23a(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
5571 bool is_p2p_enable = false;
5573 if (chk_ap_is_alive(padapter, psta) == false)
5576 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
5579 if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
5580 u8 backup_oper_channel = 0;
5582 /* switch to correct channel of current network before issue keep-alive frames */
5583 if (rtw_get_oper_ch23a(padapter) != pmlmeext->cur_channel) {
5584 backup_oper_channel = rtw_get_oper_ch23a(padapter);
5585 SelectChannel23a(padapter, pmlmeext->cur_channel);
5588 if (rx_chk != _SUCCESS)
5589 issue_probereq23a_ex23a(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1);
5591 if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) {
5592 tx_chk = issue_nulldata23a(padapter, psta->hwaddr, 0, 3, 1);
5593 /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
5594 if (tx_chk == _SUCCESS && !is_p2p_enable)
5598 /* back to the original operation channel */
5599 if (backup_oper_channel>0)
5600 SelectChannel23a(padapter, backup_oper_channel);
5603 if (rx_chk != _SUCCESS) {
5604 if (pmlmeext->retry == 0) {
5605 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5606 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5607 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
5611 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf)
5612 tx_chk = issue_nulldata23a(padapter, NULL, 0, 1, 0);
5615 if (rx_chk == _FAIL) {
5617 if (pmlmeext->retry > rx_chk_limit) {
5618 DBG_8723A_LEVEL(_drv_always_,
5619 "%s(%s): disconnect or "
5620 "roaming\n", __func__,
5621 padapter->pnetdev->name);
5622 receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress,
5623 WLAN_REASON_EXPIRATION_CHK);
5627 pmlmeext->retry = 0;
5630 if (tx_chk == _FAIL) {
5631 pmlmeinfo->link_count &= 0xf;
5633 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
5634 pmlmeinfo->link_count = 0;
5637 } /* end of if ((psta = rtw_get_stainfo23a(pstapriv, passoc_res->network.MacAddress)) != NULL) */
5639 else if (is_client_associated_to_ibss23a(padapter))
5641 /* linked IBSS mode */
5642 /* for each assoc list entry to check the rx pkt counter */
5643 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
5645 if (pmlmeinfo->FW_sta_info[i].status == 1)
5647 psta = pmlmeinfo->FW_sta_info[i].psta;
5649 if (NULL == psta) continue;
5651 if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta))
5654 if (pmlmeinfo->FW_sta_info[i].retry<3)
5656 pmlmeinfo->FW_sta_info[i].retry++;
5660 pmlmeinfo->FW_sta_info[i].retry = 0;
5661 pmlmeinfo->FW_sta_info[i].status = 0;
5662 report_del_sta_event23a(padapter, psta->hwaddr,
5663 65535/* indicate disconnect caused by no rx */
5669 pmlmeinfo->FW_sta_info[i].retry = 0;
5670 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
5675 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5680 static void survey_timer_hdl(unsigned long data)
5682 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
5683 struct cmd_obj *ph2c;
5684 struct sitesurvey_parm *psurveyPara;
5685 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
5686 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5688 /* issue rtw_sitesurvey_cmd23a */
5689 if (pmlmeext->sitesurvey_res.state > SCAN_START) {
5690 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
5691 pmlmeext->sitesurvey_res.channel_idx++;
5693 if (pmlmeext->scan_abort == true) {
5694 pmlmeext->sitesurvey_res.channel_idx =
5695 pmlmeext->sitesurvey_res.ch_num;
5696 DBG_8723A("%s idx:%d\n", __func__,
5697 pmlmeext->sitesurvey_res.channel_idx);
5699 pmlmeext->scan_abort = false;/* reset */
5702 ph2c = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
5705 goto exit_survey_timer_hdl;
5707 psurveyPara = (struct sitesurvey_parm*)
5708 kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC);
5711 goto exit_survey_timer_hdl;
5714 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
5715 rtw_enqueue_cmd23a(pcmdpriv, ph2c);
5718 exit_survey_timer_hdl:
5722 static void link_timer_hdl(unsigned long data)
5724 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
5725 /* static unsigned int rx_pkt = 0; */
5726 /* static u64 tx_cnt = 0; */
5727 /* struct xmit_priv *pxmitpriv = &padapter->xmitpriv; */
5728 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5729 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5730 /* struct sta_priv *pstapriv = &padapter->stapriv; */
5732 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
5734 DBG_8723A("link_timer_hdl:no beacon while connecting\n");
5735 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5736 report_join_res23a(padapter, -3);
5738 else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE)
5741 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT)
5743 /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
5745 pmlmeinfo->state = 0;
5746 report_join_res23a(padapter, -1);
5751 /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
5752 /* pmlmeinfo->reauth_count = 0; */
5756 DBG_8723A("link_timer_hdl: auth timeout and try again\n");
5757 pmlmeinfo->auth_seq = 1;
5758 issue_auth23a(padapter, NULL, 0);
5759 set_link_timer(pmlmeext, REAUTH_TO);
5761 else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)
5763 /* re-assoc timer */
5764 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT)
5766 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5767 report_join_res23a(padapter, -2);
5771 DBG_8723A("link_timer_hdl: assoc timeout and try again\n");
5772 issue_assocreq23a(padapter);
5773 set_link_timer(pmlmeext, REASSOC_TO);
5779 static void addba_timer_hdl(unsigned long data)
5781 struct sta_info *psta = (struct sta_info *)data;
5782 struct ht_priv *phtpriv;
5787 phtpriv = &psta->htpriv;
5789 if ((phtpriv->ht_option == true) && (phtpriv->ampdu_enable == true))
5791 if (phtpriv->candidate_tid_bitmap)
5792 phtpriv->candidate_tid_bitmap = 0x0;
5797 void init_addba_retry_timer23a(struct sta_info *psta)
5799 setup_timer(&psta->addba_retry_timer, addba_timer_hdl,
5800 (unsigned long)psta);
5803 void init_mlme_ext_timer23a(struct rtw_adapter *padapter)
5805 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5807 setup_timer(&pmlmeext->survey_timer, survey_timer_hdl,
5808 (unsigned long)padapter);
5810 setup_timer(&pmlmeext->link_timer, link_timer_hdl,
5811 (unsigned long)padapter);
5814 u8 NULL_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5819 u8 setopmode_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5822 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5823 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5824 const struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
5826 if (psetop->mode == Ndis802_11APMode) {
5827 pmlmeinfo->state = WIFI_FW_AP_STATE;
5828 type = _HW_STATE_AP_;
5829 } else if (psetop->mode == Ndis802_11Infrastructure) {
5830 pmlmeinfo->state &= ~(BIT(0)|BIT(1));/* clear state */
5831 pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */
5832 type = _HW_STATE_STATION_;
5833 } else if (psetop->mode == Ndis802_11IBSS)
5834 type = _HW_STATE_ADHOC_;
5836 type = _HW_STATE_NOLINK_;
5838 hw_var_set_opmode(padapter, type);
5839 /* Set_NETYPE0_MSR(padapter, type); */
5844 u8 createbss_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5846 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5847 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5848 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5849 const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
5850 /* u32 initialgain; */
5852 if (pparm->InfrastructureMode == Ndis802_11APMode) {
5853 #ifdef CONFIG_8723AU_AP_MODE
5855 if (pmlmeinfo->state == WIFI_FW_AP_STATE)
5863 /* below is for ad-hoc master */
5864 if (pparm->InfrastructureMode == Ndis802_11IBSS) {
5865 rtw_joinbss_reset23a(padapter);
5867 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5868 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5869 pmlmeinfo->ERP_enable = 0;
5870 pmlmeinfo->WMM_enable = 0;
5871 pmlmeinfo->HT_enable = 0;
5872 pmlmeinfo->HT_caps_enable = 0;
5873 pmlmeinfo->HT_info_enable = 0;
5875 /* disable dynamic functions, such as high power, DIG */
5876 rtl8723a_odm_support_ability_backup(padapter);
5878 rtl8723a_odm_support_ability_clr(padapter,
5879 DYNAMIC_FUNC_DISABLE);
5881 /* cancel link timer */
5882 del_timer_sync(&pmlmeext->link_timer);
5885 flush_all_cam_entry23a(padapter);
5887 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
5888 return H2C_PARAMETERS_ERROR;
5890 memcpy(pnetwork, pparm, sizeof(struct wlan_bssid_ex));
5892 start_create_ibss23a(padapter);
5898 u8 join_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
5900 struct ndis_802_11_var_ies * pIE;
5901 struct registry_priv *pregpriv = &padapter->registrypriv;
5902 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5903 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5904 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
5905 const struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
5906 struct HT_info_element *pht_info;
5908 /* u32 initialgain; */
5911 /* check already connecting to AP or not */
5912 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
5914 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
5915 issue_deauth23a_ex23a(padapter, pnetwork->MacAddress,
5916 WLAN_REASON_DEAUTH_LEAVING, 5, 100);
5918 pmlmeinfo->state = WIFI_FW_NULL_STATE;
5921 flush_all_cam_entry23a(padapter);
5923 del_timer_sync(&pmlmeext->link_timer);
5925 /* set MSR to nolink -> infra. mode */
5926 /* Set_MSR23a(padapter, _HW_STATE_NOLINK_); */
5927 Set_MSR23a(padapter, _HW_STATE_STATION_);
5929 hw_var_set_mlme_disconnect(padapter);
5932 rtw_joinbss_reset23a(padapter);
5934 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
5935 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5936 pmlmeinfo->ERP_enable = 0;
5937 pmlmeinfo->WMM_enable = 0;
5938 pmlmeinfo->HT_enable = 0;
5939 pmlmeinfo->HT_caps_enable = 0;
5940 pmlmeinfo->HT_info_enable = 0;
5941 pmlmeinfo->bwmode_updated = false;
5942 /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
5944 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
5945 return H2C_PARAMETERS_ERROR;
5947 memcpy(pnetwork, pbuf, sizeof(struct wlan_bssid_ex));
5949 /* Check AP vendor to move rtw_joinbss_cmd23a() */
5950 /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP23a(pnetwork->IEs,
5951 pnetwork->IELength); */
5953 for (i = sizeof(struct ndis_802_11_fixed_ies); i < pnetwork->IELength;)
5955 pIE = (struct ndis_802_11_var_ies *)(pnetwork->IEs + i);
5957 switch (pIE->ElementID)
5959 case WLAN_EID_VENDOR_SPECIFIC:/* Get WMM IE. */
5960 if (!memcmp(pIE->data, WMM_OUI23A, 4))
5961 pmlmeinfo->WMM_enable = 1;
5964 case WLAN_EID_HT_CAPABILITY: /* Get HT Cap IE. */
5965 pmlmeinfo->HT_caps_enable = 1;
5968 case WLAN_EID_HT_OPERATION: /* Get HT Info IE. */
5969 pmlmeinfo->HT_info_enable = 1;
5971 /* spec case only for cisco's ap because cisco's ap
5972 * issue assoc rsp using mcs rate @40MHz or @20MHz */
5973 pht_info = (struct HT_info_element *)(pIE->data);
5975 if ((pregpriv->cbw40_enable) &&
5976 (pht_info->infos[0] & BIT(2))) {
5977 /* switch to the 40M Hz mode according to AP */
5978 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
5979 switch (pht_info->infos[0] & 0x3)
5982 pmlmeext->cur_ch_offset =
5983 HAL_PRIME_CHNL_OFFSET_LOWER;
5987 pmlmeext->cur_ch_offset =
5988 HAL_PRIME_CHNL_OFFSET_UPPER;
5992 pmlmeext->cur_ch_offset =
5993 HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5997 DBG_8723A("set ch/bw before connected\n");
6005 i += (pIE->Length + 2);
6008 hw_var_set_bssid(padapter, pmlmeinfo->network.MacAddress);
6009 hw_var_set_mlme_join(padapter, 0);
6011 /* cancel link timer */
6012 del_timer_sync(&pmlmeext->link_timer);
6014 start_clnt_join23a(padapter);
6019 u8 disconnect_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6021 const struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
6022 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6023 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6024 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
6026 if (is_client_associated_to_ap23a(padapter))
6028 issue_deauth23a_ex23a(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
6031 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
6033 /* pmlmeinfo->state = WIFI_FW_NULL_STATE; */
6035 hw_var_set_mlme_disconnect(padapter);
6036 hw_var_set_bssid(padapter, null_addr);
6038 /* restore to initial setting. */
6039 update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
6041 if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
6042 ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
6043 rtl8723a_set_bcn_func(padapter, 0); /* Stop BCN */
6045 /* set MSR to no link state -> infra. mode */
6046 Set_MSR23a(padapter, _HW_STATE_STATION_);
6048 pmlmeinfo->state = WIFI_FW_NULL_STATE;
6050 /* switch to the 20M Hz mode after disconnect */
6051 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
6052 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6054 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
6056 flush_all_cam_entry23a(padapter);
6058 del_timer_sync(&pmlmeext->link_timer);
6060 rtw_free_uc_swdec_pending_queue23a(padapter);
6066 rtw_scan_ch_decision(struct rtw_adapter *padapter,
6067 struct rtw_ieee80211_channel *out, u32 out_num,
6068 const struct rtw_ieee80211_channel *in, u32 in_num)
6071 int scan_ch_num = 0;
6073 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6075 /* clear out first */
6076 memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
6078 /* acquire channels from in */
6080 for (i = 0;i<in_num;i++) {
6081 if (in[i].hw_value && !(in[i].flags & IEEE80211_CHAN_DISABLED)
6082 && (set_idx = rtw_ch_set_search_ch23a(pmlmeext->channel_set, in[i].hw_value)) >= 0
6085 memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
6087 if (pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
6088 out[j].flags &= IEEE80211_CHAN_NO_IR;
6096 /* if out is empty, use channel_set as default */
6098 for (i = 0;i<pmlmeext->max_chan_nums;i++) {
6099 out[i].hw_value = pmlmeext->channel_set[i].ChannelNum;
6101 if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
6102 out[i].flags &= IEEE80211_CHAN_NO_IR;
6108 if (padapter->setband == GHZ_24) { /* 2.4G */
6109 for (i = 0; i < j ; i++) {
6110 if (out[i].hw_value > 35)
6112 sizeof(struct rtw_ieee80211_channel));
6117 } else if (padapter->setband == GHZ_50) { /* 5G */
6118 for (i = 0; i < j ; i++) {
6119 if (out[i].hw_value > 35) {
6120 memcpy(&out[scan_ch_num++], &out[i], sizeof(struct rtw_ieee80211_channel));
6130 u8 sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6132 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6133 const struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
6134 u8 bdelayscan = false;
6138 if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
6139 pmlmeext->sitesurvey_res.state = SCAN_START;
6140 pmlmeext->sitesurvey_res.bss_cnt = 0;
6141 pmlmeext->sitesurvey_res.channel_idx = 0;
6143 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
6144 if (pparm->ssid[i].ssid_len) {
6145 memcpy(pmlmeext->sitesurvey_res.ssid[i].ssid,
6146 pparm->ssid[i].ssid, IW_ESSID_MAX_SIZE);
6147 pmlmeext->sitesurvey_res.ssid[i].ssid_len =
6148 pparm->ssid[i].ssid_len;
6150 pmlmeext->sitesurvey_res.ssid[i].ssid_len = 0;
6154 pmlmeext->sitesurvey_res.ch_num =
6155 rtw_scan_ch_decision(padapter,
6156 pmlmeext->sitesurvey_res.ch,
6157 RTW_CHANNEL_SCAN_AMOUNT,
6158 pparm->ch, pparm->ch_num);
6160 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
6162 /* issue null data if associating to the AP */
6163 if (is_client_associated_to_ap23a(padapter)) {
6164 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
6166 /* switch to correct channel of current network
6167 before issue keep-alive frames */
6168 if (rtw_get_oper_ch23a(padapter) != pmlmeext->cur_channel)
6169 SelectChannel23a(padapter, pmlmeext->cur_channel);
6171 issue_nulldata23a(padapter, NULL, 1, 3, 500);
6177 /* delay 50ms to protect nulldata(1). */
6178 set_survey_timer(pmlmeext, 50);
6183 if ((pmlmeext->sitesurvey_res.state == SCAN_START) ||
6184 (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) {
6185 /* disable dynamic functions, such as high power, DIG */
6186 rtl8723a_odm_support_ability_backup(padapter);
6187 rtl8723a_odm_support_ability_clr(padapter,
6188 DYNAMIC_FUNC_DISABLE);
6190 /* config the initial gain under scaning, need to
6191 write the BB registers */
6192 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == true)
6197 rtl8723a_set_initial_gain(padapter, initialgain);
6199 /* set MSR to no link state */
6200 Set_MSR23a(padapter, _HW_STATE_NOLINK_);
6202 rtl8723a_mlme_sitesurvey(padapter, 1);
6204 pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
6207 site_survey23a(padapter);
6212 u8 setauth_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6214 const struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
6215 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6216 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6218 if (pparm->mode < 4)
6220 pmlmeinfo->auth_algo = pparm->mode;
6226 u8 setkey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6228 unsigned short ctrl;
6229 const struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
6230 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6231 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6232 unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
6234 /* main tx key for wep. */
6236 pmlmeinfo->key_index = pparm->keyid;
6239 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
6241 DBG_8723A_LEVEL(_drv_always_, "set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) "
6242 "keyid:%d\n", pparm->algorithm, pparm->keyid);
6243 rtl8723a_cam_write(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
6245 /* allow multicast packets to driver */
6246 rtl8723a_on_rcr_am(padapter);
6251 u8 set_stakey_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6254 u8 cam_id;/* cam_entry */
6255 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6256 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6257 const struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
6260 /* 0~3 for default key */
6262 /* for concurrent mode (ap+sta): */
6263 /* default key is disable, using sw encrypt/decrypt */
6264 /* cam_entry = 4 for sta mode (macid = 0) */
6265 /* cam_entry(macid+3) = 5 ~ N for ap mode (aid = 1~N, macid = 2 ~N) */
6267 /* for concurrent mode (sta+sta): */
6268 /* default key is disable, using sw encrypt/decrypt */
6269 /* cam_entry = 4 mapping to macid = 0 */
6270 /* cam_entry = 5 mapping to macid = 2 */
6274 DBG_8723A_LEVEL(_drv_always_, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) camid:%d\n",
6275 pparm->algorithm, cam_id);
6276 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
6279 struct sta_info *psta;
6280 struct sta_priv *pstapriv = &padapter->stapriv;
6282 if (pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */
6284 clear_cam_entry23a(padapter, pparm->id);
6285 return H2C_SUCCESS_RSP;
6288 psta = rtw_get_stainfo23a(pstapriv, pparm->addr);
6291 ctrl = (BIT(15) | ((pparm->algorithm) << 2));
6293 DBG_8723A("r871x_set_stakey_hdl23a(): enc_algorithm =%d\n", pparm->algorithm);
6295 if ((psta->mac_id<1) || (psta->mac_id>(NUM_STA-4)))
6297 DBG_8723A("r871x_set_stakey_hdl23a():set_stakey failed, mac_id(aid) =%d\n", psta->mac_id);
6298 return H2C_REJECTED;
6301 cam_id = (psta->mac_id + 3);/* 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */
6303 DBG_8723A("Write CAM, mac_addr =%x:%x:%x:%x:%x:%x, cam_entry =%d\n", pparm->addr[0],
6304 pparm->addr[1], pparm->addr[2], pparm->addr[3], pparm->addr[4],
6305 pparm->addr[5], cam_id);
6307 rtl8723a_cam_write(padapter, cam_id, ctrl,
6308 pparm->addr, pparm->key);
6310 return H2C_SUCCESS_RSP;
6315 DBG_8723A("r871x_set_stakey_hdl23a(): sta has been free\n");
6316 return H2C_REJECTED;
6321 /* below for sta mode */
6323 if (pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */
6325 clear_cam_entry23a(padapter, pparm->id);
6329 ctrl = BIT(15) | ((pparm->algorithm) << 2);
6331 rtl8723a_cam_write(padapter, cam_id, ctrl, pparm->addr, pparm->key);
6333 pmlmeinfo->enc_algo = pparm->algorithm;
6338 u8 add_ba_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6340 const struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
6341 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6342 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6344 struct sta_info *psta = rtw_get_stainfo23a(&padapter->stapriv, pparm->addr);
6349 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) &&
6350 (pmlmeinfo->HT_enable)) ||
6351 ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
6352 issue_action_BA23a(padapter, pparm->addr,
6353 WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
6354 mod_timer(&psta->addba_retry_timer,
6355 jiffies + msecs_to_jiffies(ADDBA_TO));
6357 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
6362 u8 set_tx_beacon_cmd23a(struct rtw_adapter* padapter)
6364 struct cmd_obj *ph2c;
6365 struct Tx_Beacon_param *ptxBeacon_parm;
6366 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
6367 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6368 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6374 ph2c = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
6380 ptxBeacon_parm = (struct Tx_Beacon_param *)
6381 kzalloc(sizeof(struct Tx_Beacon_param), GFP_ATOMIC);
6382 if (!ptxBeacon_parm) {
6388 memcpy(&ptxBeacon_parm->network, &pmlmeinfo->network,
6389 sizeof(struct wlan_bssid_ex));
6391 len_diff = update_hidden_ssid(
6392 ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_,
6393 ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_,
6394 pmlmeinfo->hidden_ssid_mode);
6395 ptxBeacon_parm->network.IELength += len_diff;
6397 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
6399 res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
6408 u8 mlme_evt_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6410 u8 evt_code, evt_seq;
6412 const struct C2HEvent_Header *c2h;
6413 void (*event_callback)(struct rtw_adapter *dev, const u8 *pbuf);
6415 c2h = (struct C2HEvent_Header *)pbuf;
6420 /* checking if event code is valid */
6421 if (evt_code >= MAX_C2HEVT) {
6422 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nEvent Code(%d) mismatch!\n", evt_code));
6426 /* checking if event size match the event parm size */
6427 if ((wlanevents[evt_code].parmsize != 0) &&
6428 (wlanevents[evt_code].parmsize != evt_sz)) {
6429 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
6430 evt_code, wlanevents[evt_code].parmsize, evt_sz));
6434 event_callback = wlanevents[evt_code].event_callback;
6435 event_callback(padapter, pbuf + sizeof(struct C2HEvent_Header));
6442 u8 h2c_msg_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6445 return H2C_PARAMETERS_ERROR;
6450 u8 tx_beacon_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6452 if (send_beacon23a(padapter) == _FAIL)
6454 DBG_8723A("issue_beacon23a, fail!\n");
6455 return H2C_PARAMETERS_ERROR;
6457 #ifdef CONFIG_8723AU_AP_MODE
6458 else /* tx bc/mc frames after update TIM */
6460 struct sta_info *psta_bmc;
6461 struct list_head *plist, *phead, *ptmp;
6462 struct xmit_frame *pxmitframe;
6463 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6464 struct sta_priv *pstapriv = &padapter->stapriv;
6466 /* for BC/MC Frames */
6467 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
6471 if ((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0))
6473 msleep(10);/* 10ms, ATIM(HIQ) Windows */
6474 /* spin_lock_bh(&psta_bmc->sleep_q.lock); */
6475 spin_lock_bh(&pxmitpriv->lock);
6477 phead = get_list_head(&psta_bmc->sleep_q);
6479 list_for_each_safe(plist, ptmp, phead) {
6480 pxmitframe = container_of(plist,
6484 list_del_init(&pxmitframe->list);
6486 psta_bmc->sleepq_len--;
6487 if (psta_bmc->sleepq_len>0)
6488 pxmitframe->attrib.mdata = 1;
6490 pxmitframe->attrib.mdata = 0;
6492 pxmitframe->attrib.triggered = 1;
6494 pxmitframe->attrib.qsel = 0x11;/* HIQ */
6496 rtw_hal_xmit23aframe_enqueue(padapter, pxmitframe);
6499 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
6500 spin_unlock_bh(&pxmitpriv->lock);
6509 u8 set_ch_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6511 const struct set_ch_parm *set_ch_parm;
6512 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6515 return H2C_PARAMETERS_ERROR;
6517 set_ch_parm = (struct set_ch_parm *)pbuf;
6519 DBG_8723A("%s(%s): ch:%u, bw:%u, ch_offset:%u\n", __func__,
6520 padapter->pnetdev->name, set_ch_parm->ch,
6521 set_ch_parm->bw, set_ch_parm->ch_offset);
6523 pmlmeext->cur_channel = set_ch_parm->ch;
6524 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
6525 pmlmeext->cur_bwmode = set_ch_parm->bw;
6527 set_channel_bwmode23a(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
6532 u8 set_chplan_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6534 const struct SetChannelPlan_param *setChannelPlan_param;
6535 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6538 return H2C_PARAMETERS_ERROR;
6540 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
6542 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
6543 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
6548 u8 led_blink_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6550 struct LedBlink_param *ledBlink_param;
6553 return H2C_PARAMETERS_ERROR;
6555 ledBlink_param = (struct LedBlink_param *)pbuf;
6560 u8 set_csa_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6562 return H2C_REJECTED;
6565 /* TDLS_WRCR : write RCR DATA BIT */
6566 /* TDLS_SD_PTI : issue peer traffic indication */
6567 /* TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure */
6568 /* TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame */
6569 /* TDLS_DONE_CH_SEN: channel sensing and report candidate channel */
6570 /* TDLS_OFF_CH : first time set channel to off channel */
6571 /* TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel */
6572 /* TDLS_P_OFF_CH : periodically go to off channel */
6573 /* TDLS_P_BASE_CH : periodically go back to base channel */
6574 /* TDLS_RS_RCR : restore RCR */
6575 /* TDLS_CKALV_PH1 : check alive timer phase1 */
6576 /* TDLS_CKALV_PH2 : check alive timer phase2 */
6577 /* TDLS_FREE_STA : free tdls sta */
6578 u8 tdls_hdl23a(struct rtw_adapter *padapter, const u8 *pbuf)
6580 return H2C_REJECTED;