1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 ******************************************************************************/
15 #define _RTW_MLME_EXT_C_
17 #include <osdep_service.h>
18 #include <drv_types.h>
20 #include <rtw_mlme_ext.h>
21 #include <wlan_bssdef.h>
22 #include <mlme_osdep.h>
23 #include <recv_osdep.h>
24 #include <linux/ieee80211.h>
26 #ifdef CONFIG_8723AU_BT_COEXIST
27 #include <rtl8723a_hal.h>
30 static int OnAssocReq23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
31 static int OnAssocRsp23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
32 static int OnProbeReq23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
33 static int OnProbeRsp23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
34 static int DoReserved23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
35 static int OnBeacon23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
36 static int OnAtim23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
37 static int OnDisassoc23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
38 static int OnAuth23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
39 static int OnAuth23aClient23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
40 static int OnDeAuth23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
41 static int OnAction23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
43 static int on_action_spct23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
44 static int OnAction23a_qos(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
45 static int OnAction23a_dls(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
46 static int OnAction23a_back23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
47 static int on_action_public23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
48 static int OnAction23a_ht(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
49 static int OnAction23a_wmm(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
50 static int OnAction23a_p2p(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
52 static struct mlme_handler mlme_sta_tbl
[]={
53 {"OnAssocReq23a", &OnAssocReq23a
},
54 {"OnAssocRsp23a", &OnAssocRsp23a
},
55 {"OnReAssocReq", &OnAssocReq23a
},
56 {"OnReAssocRsp", &OnAssocRsp23a
},
57 {"OnProbeReq23a", &OnProbeReq23a
},
58 {"OnProbeRsp23a", &OnProbeRsp23a
},
60 /*----------------------------------------------------------
62 -----------------------------------------------------------*/
63 {"DoReserved23a", &DoReserved23a
},
64 {"DoReserved23a", &DoReserved23a
},
65 {"OnBeacon23a", &OnBeacon23a
},
66 {"OnATIM", &OnAtim23a
},
67 {"OnDisassoc23a", &OnDisassoc23a
},
68 {"OnAuth23a", &OnAuth23aClient23a
},
69 {"OnDeAuth23a", &OnDeAuth23a
},
70 {"OnAction23a", &OnAction23a
},
73 static struct action_handler OnAction23a_tbl
[]={
74 {WLAN_CATEGORY_SPECTRUM_MGMT
, "ACTION_SPECTRUM_MGMT", on_action_spct23a
},
75 {WLAN_CATEGORY_QOS
, "ACTION_QOS", &OnAction23a_qos
},
76 {WLAN_CATEGORY_DLS
, "ACTION_DLS", &OnAction23a_dls
},
77 {WLAN_CATEGORY_BACK
, "ACTION_BACK", &OnAction23a_back23a
},
78 {WLAN_CATEGORY_PUBLIC
, "ACTION_PUBLIC", on_action_public23a
},
79 {WLAN_CATEGORY_HT
, "ACTION_HT", &OnAction23a_ht
},
80 {WLAN_CATEGORY_SA_QUERY
, "ACTION_SA_QUERY", &DoReserved23a
},
81 {WLAN_CATEGORY_WMM
, "ACTION_WMM", &OnAction23a_wmm
},
82 {WLAN_CATEGORY_VENDOR_SPECIFIC
, "ACTION_P2P", &OnAction23a_p2p
},
85 static u8 null_addr
[ETH_ALEN
]= {0, 0, 0, 0, 0, 0};
87 /**************************************************
88 OUI definitions for the vendor specific IE
89 ***************************************************/
90 unsigned char WMM_OUI23A
[] = {0x00, 0x50, 0xf2, 0x02};
91 unsigned char WPS_OUI23A
[] = {0x00, 0x50, 0xf2, 0x04};
92 unsigned char P2P_OUI23A
[] = {0x50, 0x6F, 0x9A, 0x09};
93 unsigned char WFD_OUI23A
[] = {0x50, 0x6F, 0x9A, 0x0A};
95 unsigned char WMM_INFO_OUI23A
[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
96 unsigned char WMM_PARA_OUI23A
[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
98 unsigned char WPA_TKIP_CIPHER23A
[4] = {0x00, 0x50, 0xf2, 0x02};
99 unsigned char RSN_TKIP_CIPHER23A
[4] = {0x00, 0x0f, 0xac, 0x02};
102 /********************************************************
104 *********************************************************/
105 unsigned char MCS_rate_2R23A
[16] = {
106 0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
107 unsigned char MCS_rate_1R23A
[16] = {
108 0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
110 /********************************************************
111 ChannelPlan definitions
112 *********************************************************/
114 static struct rt_channel_plan_2g RTW_ChannelPlan2G
[RT_CHANNEL_DOMAIN_2G_MAX
] = {
115 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */
116 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
117 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
118 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
119 {{10, 11, 12, 13}, 4}, /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
120 {{}, 0}, /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */
123 static struct rt_channel_plan_5g RTW_ChannelPlan5G
[RT_CHANNEL_DOMAIN_5G_MAX
] = {
124 {{}, 0}, /* 0x00, RT_CHANNEL_DOMAIN_5G_NULL */
125 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19}, /* 0x01, RT_CHANNEL_DOMAIN_5G_ETSI1 */
126 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24}, /* 0x02, RT_CHANNEL_DOMAIN_5G_ETSI2 */
127 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22}, /* 0x03, RT_CHANNEL_DOMAIN_5G_ETSI3 */
128 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24}, /* 0x04, RT_CHANNEL_DOMAIN_5G_FCC1 */
129 {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9}, /* 0x05, RT_CHANNEL_DOMAIN_5G_FCC2 */
130 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13}, /* 0x06, RT_CHANNEL_DOMAIN_5G_FCC3 */
131 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12}, /* 0x07, RT_CHANNEL_DOMAIN_5G_FCC4 */
132 {{149, 153, 157, 161, 165}, 5}, /* 0x08, RT_CHANNEL_DOMAIN_5G_FCC5 */
133 {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, /* 0x09, RT_CHANNEL_DOMAIN_5G_FCC6 */
134 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 20}, /* 0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1 */
135 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165}, 20}, /* 0x0B, RT_CHANNEL_DOMAIN_5G_KCC1 */
136 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19}, /* 0x0C, RT_CHANNEL_DOMAIN_5G_MKK1 */
137 {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, /* 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 */
138 {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11}, /* 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 */
139 {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 15}, /* 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 */
140 {{56, 60, 64, 149, 153, 157, 161, 165}, 8}, /* 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 */
142 /* Driver self defined for old channel plan Compatible , Remember to modify if have new channel plan definition ===== */
143 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21}, /* 0x11, RT_CHANNEL_DOMAIN_5G_FCC */
144 {{36, 40, 44, 48}, 4}, /* 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS */
145 {{36, 40, 44, 48, 149, 153, 157, 161}, 8}, /* 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS */
148 static struct rt_channel_plan_map RTW_ChannelPlanMap
[RT_CHANNEL_DOMAIN_MAX
] = {
149 /* 0x00 ~ 0x1F , Old Define ===== */
150 {0x02, 0x11}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
151 {0x02, 0x0A}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
152 {0x01, 0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
153 {0x01, 0x00}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
154 {0x01, 0x00}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
155 {0x03, 0x00}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */
156 {0x03, 0x00}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
157 {0x01, 0x09}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
158 {0x03, 0x09}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
159 {0x03, 0x00}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
160 {0x00, 0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
161 {0x02, 0x0F}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
162 {0x01, 0x08}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
163 {0x02, 0x06}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
164 {0x02, 0x0B}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
165 {0x02, 0x09}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
166 {0x01, 0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
167 {0x02, 0x05}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
168 {0x01, 0x12}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
169 {0x00, 0x04}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
170 {0x02, 0x10}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
171 {0x00, 0x12}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
172 {0x00, 0x13}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
173 {0x03, 0x12}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
174 {0x05, 0x08}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
175 {0x02, 0x08}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
176 {0x00, 0x00}, /* 0x1A, */
177 {0x00, 0x00}, /* 0x1B, */
178 {0x00, 0x00}, /* 0x1C, */
179 {0x00, 0x00}, /* 0x1D, */
180 {0x00, 0x00}, /* 0x1E, */
181 {0x05, 0x04}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
182 /* 0x20 ~ 0x7F , New Define ===== */
183 {0x00, 0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
184 {0x01, 0x00}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
185 {0x02, 0x00}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
186 {0x03, 0x00}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
187 {0x04, 0x00}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
188 {0x02, 0x04}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
189 {0x00, 0x01}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
190 {0x03, 0x0C}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
191 {0x00, 0x0B}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
192 {0x00, 0x05}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
193 {0x00, 0x00}, /* 0x2A, */
194 {0x00, 0x00}, /* 0x2B, */
195 {0x00, 0x00}, /* 0x2C, */
196 {0x00, 0x00}, /* 0x2D, */
197 {0x00, 0x00}, /* 0x2E, */
198 {0x00, 0x00}, /* 0x2F, */
199 {0x00, 0x06}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
200 {0x00, 0x07}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
201 {0x00, 0x08}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
202 {0x00, 0x09}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
203 {0x02, 0x0A}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
204 {0x00, 0x02}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
205 {0x00, 0x03}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
206 {0x03, 0x0D}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
207 {0x03, 0x0E}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
208 {0x02, 0x0F}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
209 {0x00, 0x00}, /* 0x3A, */
210 {0x00, 0x00}, /* 0x3B, */
211 {0x00, 0x00}, /* 0x3C, */
212 {0x00, 0x00}, /* 0x3D, */
213 {0x00, 0x00}, /* 0x3E, */
214 {0x00, 0x00}, /* 0x3F, */
215 {0x02, 0x10}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
216 {0x03, 0x00}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */
219 static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE
= {0x03, 0x02}; /* use the conbination for max channel numbers */
221 static struct fwevent wlanevents
[] =
223 {0, rtw_dummy_event_callback23a
}, /*0*/
231 {0, &rtw_survey_event_cb23a
}, /*8*/
232 {sizeof (struct surveydone_event
), &rtw_surveydone_event_callback23a
}, /*9*/
234 {0, &rtw23a_joinbss_event_cb
}, /*10*/
235 {sizeof(struct stassoc_event
), &rtw_stassoc_event_callback23a
},
236 {sizeof(struct stadel_event
), &rtw_stadel_event_callback23a
},
237 {0, &rtw_atimdone_event_callback23a
},
238 {0, rtw_dummy_event_callback23a
},
243 {0, rtw23a_fwdbg_event_callback
},
247 {0, &rtw_cpwm_event_callback23a
},
252 static void rtw_correct_TSF(struct rtw_adapter
*padapter
)
254 hw_var_set_correct_tsf(padapter
);
258 rtw_update_TSF(struct mlme_ext_priv
*pmlmeext
, struct ieee80211_mgmt
*mgmt
)
260 pmlmeext
->TSFValue
= get_unaligned_le64(&mgmt
->u
.beacon
.timestamp
);
264 * Search the @param channel_num in given @param channel_set
265 * @ch_set: the given channel set
266 * @ch: the given channel number
268 * return the index of channel_num in channel_set, -1 if not found
270 int rtw_ch_set_search_ch23a(struct rt_channel_info
*ch_set
, const u32 ch
)
273 for (i
= 0; ch_set
[i
]. ChannelNum
!= 0; i
++) {
274 if (ch
== ch_set
[i
].ChannelNum
)
278 if (i
>= ch_set
[i
].ChannelNum
)
283 /****************************************************************************
285 Following are the initialization functions for WiFi MLME
287 *****************************************************************************/
289 int init_hw_mlme_ext23a(struct rtw_adapter
*padapter
)
291 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
293 set_channel_bwmode23a(padapter
, pmlmeext
->cur_channel
,
294 pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
298 static void init_mlme_ext_priv23a_value(struct rtw_adapter
* padapter
)
300 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
301 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
302 unsigned char mixed_datarate
[NumRates
] = {
303 _1M_RATE_
, _2M_RATE_
, _5M_RATE_
, _11M_RATE_
, _6M_RATE_
,
304 _9M_RATE_
, _12M_RATE_
, _18M_RATE_
, _24M_RATE_
, _36M_RATE_
,
305 _48M_RATE_
, _54M_RATE_
, 0xff};
306 unsigned char mixed_basicrate
[NumRates
] = {
307 _1M_RATE_
, _2M_RATE_
, _5M_RATE_
, _11M_RATE_
, _6M_RATE_
,
308 _12M_RATE_
, _24M_RATE_
, 0xff,};
310 atomic_set(&pmlmeext
->event_seq
, 0);
311 /* reset to zero when disconnect at client mode */
312 pmlmeext
->mgnt_seq
= 0;
314 pmlmeext
->cur_channel
= padapter
->registrypriv
.channel
;
315 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_20
;
316 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
320 pmlmeext
->cur_wireless_mode
= padapter
->registrypriv
.wireless_mode
;
322 memcpy(pmlmeext
->datarate
, mixed_datarate
, NumRates
);
323 memcpy(pmlmeext
->basicrate
, mixed_basicrate
, NumRates
);
325 if (pmlmeext
->cur_channel
> 14)
326 pmlmeext
->tx_rate
= IEEE80211_OFDM_RATE_6MB
;
328 pmlmeext
->tx_rate
= IEEE80211_CCK_RATE_1MB
;
330 pmlmeext
->sitesurvey_res
.state
= SCAN_DISABLE
;
331 pmlmeext
->sitesurvey_res
.channel_idx
= 0;
332 pmlmeext
->sitesurvey_res
.bss_cnt
= 0;
333 pmlmeext
->scan_abort
= false;
335 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
336 pmlmeinfo
->reauth_count
= 0;
337 pmlmeinfo
->reassoc_count
= 0;
338 pmlmeinfo
->link_count
= 0;
339 pmlmeinfo
->auth_seq
= 0;
340 pmlmeinfo
->auth_algo
= dot11AuthAlgrthm_Open
;
341 pmlmeinfo
->key_index
= 0;
344 pmlmeinfo
->enc_algo
= _NO_PRIVACY_
;
345 pmlmeinfo
->authModeToggle
= 0;
347 memset(pmlmeinfo
->chg_txt
, 0, 128);
349 pmlmeinfo
->slotTime
= SHORT_SLOT_TIME
;
350 pmlmeinfo
->preamble_mode
= PREAMBLE_AUTO
;
352 pmlmeinfo
->dialogToken
= 0;
354 pmlmeext
->action_public_rxseq
= 0xffff;
355 pmlmeext
->action_public_dialog_token
= 0xff;
358 static int has_channel(struct rt_channel_info
*channel_set
,
359 u8 chanset_size
, u8 chan
) {
362 for (i
= 0; i
< chanset_size
; i
++) {
363 if (channel_set
[i
].ChannelNum
== chan
)
370 static void init_channel_list(struct rtw_adapter
*padapter
,
371 struct rt_channel_info
*channel_set
,
373 struct p2p_channels
*channel_list
) {
375 struct p2p_oper_class_map op_class
[] = {
376 { IEEE80211G
, 81, 1, 13, 1, BW20
},
377 { IEEE80211G
, 82, 14, 14, 1, BW20
},
378 { IEEE80211A
, 115, 36, 48, 4, BW20
},
379 { IEEE80211A
, 116, 36, 44, 8, BW40PLUS
},
380 { IEEE80211A
, 117, 40, 48, 8, BW40MINUS
},
381 { IEEE80211A
, 124, 149, 161, 4, BW20
},
382 { IEEE80211A
, 125, 149, 169, 4, BW20
},
383 { IEEE80211A
, 126, 149, 157, 8, BW40PLUS
},
384 { IEEE80211A
, 127, 153, 161, 8, BW40MINUS
},
385 { -1, 0, 0, 0, 0, BW20
}
392 for (op
= 0; op_class
[op
].op_class
; op
++) {
394 struct p2p_oper_class_map
*o
= &op_class
[op
];
395 struct p2p_reg_class
*reg
= NULL
;
397 for (ch
= o
->min_chan
; ch
<= o
->max_chan
; ch
+= o
->inc
) {
398 if (!has_channel(channel_set
, chanset_size
, ch
))
401 if ((0 == padapter
->registrypriv
.ht_enable
) &&
405 if ((0 == (padapter
->registrypriv
.cbw40_enable
& BIT(1))) &&
406 ((BW40MINUS
== o
->bw
) || (BW40PLUS
== o
->bw
)))
410 reg
= &channel_list
->reg_class
[cla
];
412 reg
->reg_class
= o
->op_class
;
415 reg
->channel
[reg
->channels
] = ch
;
419 channel_list
->reg_classes
= cla
;
422 static u8
init_channel_set(struct rtw_adapter
* padapter
, u8 cplan
,
423 struct rt_channel_info
*c_set
)
426 u8 b5GBand
= false, b2_4GBand
= false;
427 u8 Index2G
= 0, Index5G
= 0;
429 memset(c_set
, 0, sizeof(struct rt_channel_info
) * MAX_CHANNEL_NUM
);
431 if (cplan
>= RT_CHANNEL_DOMAIN_MAX
&&
432 cplan
!= RT_CHANNEL_DOMAIN_REALTEK_DEFINE
) {
433 DBG_8723A("ChannelPlan ID %x error !!!!!\n", cplan
);
437 if (padapter
->registrypriv
.wireless_mode
& WIRELESS_11G
) {
439 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE
== cplan
)
440 Index2G
= RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE
.Index2G
;
442 Index2G
= RTW_ChannelPlanMap
[cplan
].Index2G
;
445 if (padapter
->registrypriv
.wireless_mode
& WIRELESS_11A
) {
447 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE
== cplan
)
448 Index5G
= RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE
.Index5G
;
450 Index5G
= RTW_ChannelPlanMap
[cplan
].Index5G
;
454 for (i
= 0; i
< RTW_ChannelPlan2G
[Index2G
].Len
; i
++) {
455 c_set
[ch_size
].ChannelNum
=
456 RTW_ChannelPlan2G
[Index2G
].Channel
[i
];
458 if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN
== cplan
) ||
459 /* Channel 1~11 is active, and 12~14 is passive */
460 RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G
== cplan
) {
461 if (c_set
[ch_size
].ChannelNum
>= 1 &&
462 c_set
[ch_size
].ChannelNum
<= 11)
463 c_set
[ch_size
].ScanType
= SCAN_ACTIVE
;
464 else if (c_set
[ch_size
].ChannelNum
>= 12 &&
465 c_set
[ch_size
].ChannelNum
<= 14)
466 c_set
[ch_size
].ScanType
= SCAN_PASSIVE
;
467 } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13
== cplan
||
468 RT_CHANNEL_DOMAIN_WORLD_WIDE_5G
== cplan
||
469 RT_CHANNEL_DOMAIN_2G_WORLD
== Index2G
) {
470 /* channel 12~13, passive scan */
471 if (c_set
[ch_size
].ChannelNum
<= 11)
472 c_set
[ch_size
].ScanType
= SCAN_ACTIVE
;
474 c_set
[ch_size
].ScanType
= SCAN_PASSIVE
;
476 c_set
[ch_size
].ScanType
= SCAN_ACTIVE
;
483 for (i
= 0; i
< RTW_ChannelPlan5G
[Index5G
].Len
; i
++) {
484 if (RTW_ChannelPlan5G
[Index5G
].Channel
[i
] <= 48 ||
485 RTW_ChannelPlan5G
[Index5G
].Channel
[i
] >= 149) {
486 c_set
[ch_size
].ChannelNum
=
487 RTW_ChannelPlan5G
[Index5G
].Channel
[i
];
488 if (RT_CHANNEL_DOMAIN_WORLD_WIDE_5G
== cplan
) {
489 /* passive scan for all 5G channels */
490 c_set
[ch_size
].ScanType
=
493 c_set
[ch_size
].ScanType
=
495 DBG_8723A("%s(): channel_set[%d].ChannelNum = "
496 "%d\n", __func__
, ch_size
,
497 c_set
[ch_size
].ChannelNum
);
506 int init_mlme_ext_priv23a(struct rtw_adapter
* padapter
)
509 struct registry_priv
* pregistrypriv
= &padapter
->registrypriv
;
510 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
511 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
512 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
514 pmlmeext
->padapter
= padapter
;
516 init_mlme_ext_priv23a_value(padapter
);
517 pmlmeinfo
->bAcceptAddbaReq
= pregistrypriv
->bAcceptAddbaReq
;
519 init_mlme_ext_timer23a(padapter
);
521 #ifdef CONFIG_8723AU_AP_MODE
522 init_mlme_ap_info23a(padapter
);
525 pmlmeext
->max_chan_nums
= init_channel_set(padapter
,
526 pmlmepriv
->ChannelPlan
,
527 pmlmeext
->channel_set
);
528 init_channel_list(padapter
, pmlmeext
->channel_set
,
529 pmlmeext
->max_chan_nums
, &pmlmeext
->channel_list
);
531 pmlmeext
->chan_scan_time
= SURVEY_TO
;
532 pmlmeext
->mlmeext_init
= true;
534 pmlmeext
->active_keep_alive_check
= true;
538 void free_mlme_ext_priv23a (struct mlme_ext_priv
*pmlmeext
)
540 struct rtw_adapter
*padapter
= pmlmeext
->padapter
;
545 if (padapter
->bDriverStopped
== true) {
546 del_timer_sync(&pmlmeext
->survey_timer
);
547 del_timer_sync(&pmlmeext
->link_timer
);
548 /* del_timer_sync(&pmlmeext->ADDBA_timer); */
553 _mgt_dispatcher23a(struct rtw_adapter
*padapter
, struct mlme_handler
*ptable
,
554 struct recv_frame
*precv_frame
)
556 struct sk_buff
*skb
= precv_frame
->pkt
;
557 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*) skb
->data
;
560 /* receive the frames that ra(a1) is my address
561 or ra(a1) is bc address. */
562 if (!ether_addr_equal(hdr
->addr1
, myid(&padapter
->eeprompriv
))&&
563 !is_broadcast_ether_addr(hdr
->addr1
))
566 ptable
->func(padapter
, precv_frame
);
570 void mgt_dispatcher23a(struct rtw_adapter
*padapter
,
571 struct recv_frame
*precv_frame
)
573 struct mlme_handler
*ptable
;
574 #ifdef CONFIG_8723AU_AP_MODE
575 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
576 #endif /* CONFIG_8723AU_AP_MODE */
577 struct sk_buff
*skb
= precv_frame
->pkt
;
578 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
579 struct sta_info
*psta
;
583 if (!ieee80211_is_mgmt(mgmt
->frame_control
))
586 /* receive the frames that ra(a1) is my address or ra(a1) is
588 if (!ether_addr_equal(mgmt
->da
, myid(&padapter
->eeprompriv
)) &&
589 !is_broadcast_ether_addr(mgmt
->da
))
592 ptable
= mlme_sta_tbl
;
594 stype
= le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
;
598 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
599 ("Currently we do not support reserved sub-fr-type ="
605 psta
= rtw_get_stainfo23a(&padapter
->stapriv
, mgmt
->sa
);
608 if (ieee80211_has_retry(mgmt
->frame_control
)) {
609 if (precv_frame
->attrib
.seq_num
==
610 psta
->RxMgmtFrameSeqNum
) {
611 /* drop the duplicate management frame */
612 DBG_8723A("Drop duplicate management frame "
613 "with seq_num = %d.\n",
614 precv_frame
->attrib
.seq_num
);
618 psta
->RxMgmtFrameSeqNum
= precv_frame
->attrib
.seq_num
;
621 #ifdef CONFIG_8723AU_AP_MODE
624 case IEEE80211_STYPE_AUTH
:
625 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) == true)
626 ptable
->func
= &OnAuth23a
;
628 ptable
->func
= &OnAuth23aClient23a
;
630 case IEEE80211_STYPE_ASSOC_REQ
:
631 case IEEE80211_STYPE_REASSOC_REQ
:
632 _mgt_dispatcher23a(padapter
, ptable
, precv_frame
);
634 case IEEE80211_STYPE_PROBE_REQ
:
635 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) == true)
636 _mgt_dispatcher23a(padapter
, ptable
, precv_frame
);
638 _mgt_dispatcher23a(padapter
, ptable
, precv_frame
);
640 case IEEE80211_STYPE_BEACON
:
641 _mgt_dispatcher23a(padapter
, ptable
, precv_frame
);
643 case IEEE80211_STYPE_ACTION
:
644 /* if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) */
645 _mgt_dispatcher23a(padapter
, ptable
, precv_frame
);
648 _mgt_dispatcher23a(padapter
, ptable
, precv_frame
);
652 _mgt_dispatcher23a(padapter
, ptable
, precv_frame
);
656 /****************************************************************************
658 Following are the callback functions for each subtype of the management frames
660 *****************************************************************************/
663 OnProbeReq23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
666 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
667 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
668 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
669 struct wlan_bssid_ex
*cur
= &pmlmeinfo
->network
;
670 struct sk_buff
*skb
= precv_frame
->pkt
;
671 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
674 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
))
677 if (!check_fwstate(pmlmepriv
, _FW_LINKED
) &&
678 !check_fwstate(pmlmepriv
,
679 WIFI_ADHOC_MASTER_STATE
| WIFI_AP_STATE
))
682 if (unlikely(!ieee80211_is_probe_req(mgmt
->frame_control
))) {
683 printk(KERN_WARNING
"%s: Received non probe request frame\n",
688 len
-= offsetof(struct ieee80211_mgmt
, u
.probe_req
.variable
);
690 ie
= cfg80211_find_ie(WLAN_EID_SSID
, mgmt
->u
.probe_req
.variable
, len
);
692 /* check (wildcard) SSID */
696 if ((ie
[1] && memcmp(ie
+ 2, cur
->Ssid
.ssid
, cur
->Ssid
.ssid_len
)) ||
697 (ie
[1] == 0 && pmlmeinfo
->hidden_ssid_mode
)) {
701 if (check_fwstate(pmlmepriv
, _FW_LINKED
) &&
702 pmlmepriv
->cur_network
.join_res
)
703 issue_probersp23a(padapter
, mgmt
->sa
, false);
710 OnProbeRsp23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
712 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
714 if (pmlmeext
->sitesurvey_res
.state
== SCAN_PROCESS
) {
715 report_survey_event23a(padapter
, precv_frame
);
723 OnBeacon23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
726 struct sta_info
*psta
;
727 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
728 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
729 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
730 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
731 struct sk_buff
*skb
= precv_frame
->pkt
;
732 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
733 u8
*pframe
= skb
->data
;
734 int pkt_len
= skb
->len
;
735 struct wlan_bssid_ex
*pbss
;
741 pie
= mgmt
->u
.beacon
.variable
;
742 pie_len
= pkt_len
- offsetof(struct ieee80211_mgmt
, u
.beacon
.variable
);
743 p
= rtw_get_ie23a(pie
, WLAN_EID_EXT_SUPP_RATES
, &ielen
, pie_len
);
744 if (p
&& ielen
> 0) {
745 if (p
[1 + ielen
] == 0x2D && p
[2 + ielen
] != 0x2D) {
746 /* Invalid value 0x2D is detected in Extended Supported
747 * Rates (ESR) IE. Try to fix the IE length to avoid
748 * failed Beacon parsing.
750 DBG_8723A("[WIFIDBG] Error in ESR IE is detected in "
751 "Beacon of BSSID: %pM. Fix the length of "
752 "ESR IE to avoid failed Beacon parsing.\n",
758 if (pmlmeext
->sitesurvey_res
.state
== SCAN_PROCESS
) {
759 report_survey_event23a(padapter
, precv_frame
);
763 if (!ether_addr_equal(mgmt
->bssid
,
764 get_my_bssid23a(&pmlmeinfo
->network
)))
767 if (pmlmeinfo
->state
& WIFI_FW_AUTH_NULL
) {
768 /* we should update current network before auth,
769 or some IE is wrong */
770 pbss
= (struct wlan_bssid_ex
*)
771 kmalloc(sizeof(struct wlan_bssid_ex
), GFP_ATOMIC
);
773 if (collect_bss_info23a(padapter
, precv_frame
, pbss
) ==
776 &pmlmepriv
->cur_network
.network
, pbss
,
778 rtw_get_bcn_info23a(&pmlmepriv
->cur_network
);
783 /* check the vendor of the assoc AP */
784 pmlmeinfo
->assoc_AP_vendor
=
785 check_assoc_AP23a((u8
*)&mgmt
->u
.beacon
, pkt_len
-
786 offsetof(struct ieee80211_mgmt
, u
));
788 /* update TSF Value */
789 rtw_update_TSF(pmlmeext
, mgmt
);
792 start_clnt_auth23a(padapter
);
797 if (((pmlmeinfo
->state
& 0x03) == WIFI_FW_STATION_STATE
) &&
798 (pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
)) {
799 psta
= rtw_get_stainfo23a(pstapriv
, mgmt
->sa
);
801 ret
= rtw_check_bcn_info23a(padapter
, mgmt
, pkt_len
);
803 DBG_8723A_LEVEL(_drv_always_
, "ap has changed, "
805 receive_disconnect23a(padapter
, pmlmeinfo
->network
.MacAddress
, 65535);
808 /* update WMM, ERP in the beacon */
809 /* todo: the timer is used instead of
810 the number of the beacon received */
811 if ((sta_rx_pkts(psta
) & 0xf) == 0) {
812 /* DBG_8723A("update_bcn_info\n"); */
813 update_beacon23a_info(padapter
, pframe
,
817 } else if ((pmlmeinfo
->state
&0x03) == WIFI_FW_ADHOC_STATE
) {
818 psta
= rtw_get_stainfo23a(pstapriv
, mgmt
->sa
);
820 /* update WMM, ERP in the beacon */
821 /* todo: the timer is used instead of the
822 number of the beacon received */
823 if ((sta_rx_pkts(psta
) & 0xf) == 0) {
824 /* DBG_8723A("update_bcn_info\n"); */
825 update_beacon23a_info(padapter
, pframe
,
829 /* allocate a new CAM entry for IBSS station */
830 cam_idx
= allocate_fw_sta_entry23a(padapter
);
831 if (cam_idx
== NUM_STA
)
834 /* get supported rate */
835 if (update_sta_support_rate23a(padapter
, pie
, pie_len
,
837 pmlmeinfo
->FW_sta_info
[cam_idx
].status
= 0;
841 /* update TSF Value */
842 rtw_update_TSF(pmlmeext
, mgmt
);
844 /* report sta add event */
845 report_add_sta_event23a(padapter
, mgmt
->sa
,
856 OnAuth23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
858 #ifdef CONFIG_8723AU_AP_MODE
859 static struct sta_info stat
;
860 struct sta_info
*pstat
= NULL
;
861 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
862 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
863 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
864 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
865 struct sk_buff
*skb
= precv_frame
->pkt
;
866 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
870 u16 auth_mode
, seq
, algorithm
;
871 int status
, len
= skb
->len
;
873 if ((pmlmeinfo
->state
& 0x03) != WIFI_FW_AP_STATE
)
876 DBG_8723A("+OnAuth23a\n");
880 auth_mode
= psecuritypriv
->dot11AuthAlgrthm
;
882 pframe
= mgmt
->u
.auth
.variable
;
883 len
= skb
->len
- offsetof(struct ieee80211_mgmt
, u
.auth
.variable
);
885 seq
= le16_to_cpu(mgmt
->u
.auth
.auth_transaction
);
886 algorithm
= le16_to_cpu(mgmt
->u
.auth
.auth_alg
);
888 DBG_8723A("auth alg =%x, seq =%X\n", algorithm
, seq
);
890 if (auth_mode
== 2 &&
891 psecuritypriv
->dot11PrivacyAlgrthm
!= _WEP40_
&&
892 psecuritypriv
->dot11PrivacyAlgrthm
!= _WEP104_
)
895 /* rx a shared-key auth but shared not enabled, or */
896 /* rx a open-system auth but shared-key is enabled */
897 if ((algorithm
!= WLAN_AUTH_OPEN
&& auth_mode
== 0) ||
898 (algorithm
== WLAN_AUTH_OPEN
&& auth_mode
== 1)) {
899 DBG_8723A("auth rejected due to bad alg [alg =%d, auth_mib "
900 "=%d] %02X%02X%02X%02X%02X%02X\n",
901 algorithm
, auth_mode
,
902 sa
[0], sa
[1], sa
[2], sa
[3], sa
[4], sa
[5]);
904 status
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
909 if (rtw_access_ctrl23a(padapter
, sa
) == false) {
910 status
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
914 pstat
= rtw_get_stainfo23a(pstapriv
, sa
);
916 /* allocate a new one */
917 DBG_8723A("going to alloc stainfo for sa ="MAC_FMT
"\n",
919 pstat
= rtw_alloc_stainfo23a(pstapriv
, sa
, GFP_ATOMIC
);
921 DBG_8723A(" Exceed the upper limit of supported "
923 status
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
927 pstat
->state
= WIFI_FW_AUTH_NULL
;
930 /* pstat->flags = 0; */
931 /* pstat->capability = 0; */
933 spin_lock_bh(&pstapriv
->asoc_list_lock
);
934 if (!list_empty(&pstat
->asoc_list
)) {
935 list_del_init(&pstat
->asoc_list
);
936 pstapriv
->asoc_list_cnt
--;
937 if (pstat
->expire_to
> 0) {
938 /* TODO: STA re_auth within expire_to */
941 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
944 /* TODO: STA re_auth and auth timeout */
948 spin_lock_bh(&pstapriv
->auth_list_lock
);
949 if (list_empty(&pstat
->auth_list
)) {
950 list_add_tail(&pstat
->auth_list
, &pstapriv
->auth_list
);
951 pstapriv
->auth_list_cnt
++;
953 spin_unlock_bh(&pstapriv
->auth_list_lock
);
955 if (pstat
->auth_seq
== 0)
956 pstat
->expire_to
= pstapriv
->auth_to
;
958 if ((pstat
->auth_seq
+ 1) != seq
) {
959 DBG_8723A("(1)auth rejected because out of seq [rx_seq =%d, "
960 "exp_seq =%d]!\n", seq
, pstat
->auth_seq
+1);
961 status
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
965 if (algorithm
== WLAN_AUTH_OPEN
&& (auth_mode
== 0 || auth_mode
== 2)) {
967 pstat
->state
&= ~WIFI_FW_AUTH_NULL
;
968 pstat
->state
|= WIFI_FW_AUTH_SUCCESS
;
969 pstat
->expire_to
= pstapriv
->assoc_to
;
970 pstat
->authalg
= algorithm
;
972 DBG_8723A("(2)auth rejected because out of seq "
973 "[rx_seq =%d, exp_seq =%d]!\n",
974 seq
, pstat
->auth_seq
+1);
975 status
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
978 } else { /* shared system or auto authentication */
980 /* prepare for the challenging txt... */
981 pstat
->state
&= ~WIFI_FW_AUTH_NULL
;
982 pstat
->state
|= WIFI_FW_AUTH_STATE
;
983 pstat
->authalg
= algorithm
;
985 } else if (seq
== 3) {
986 /* checking for challenging txt... */
987 DBG_8723A("checking for challenging txt...\n");
989 p
= cfg80211_find_ie(WLAN_EID_CHALLENGE
, pframe
, len
);
990 if (!p
|| p
[1] <= 0) {
991 DBG_8723A("auth rejected because challenge "
993 status
= WLAN_STATUS_CHALLENGE_FAIL
;
997 if (!memcmp(p
+ 2, pstat
->chg_txt
, 128)) {
998 pstat
->state
&= ~WIFI_FW_AUTH_STATE
;
999 pstat
->state
|= WIFI_FW_AUTH_SUCCESS
;
1000 /* challenging txt is correct... */
1001 pstat
->expire_to
= pstapriv
->assoc_to
;
1003 DBG_8723A("auth rejected because challenge "
1005 status
= WLAN_STATUS_CHALLENGE_FAIL
;
1009 DBG_8723A("(3)auth rejected because out of seq "
1010 "[rx_seq =%d, exp_seq =%d]!\n",
1011 seq
, pstat
->auth_seq
+1);
1012 status
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
1017 /* Now, we are going to issue_auth23a... */
1018 pstat
->auth_seq
= seq
+ 1;
1020 issue_auth23a(padapter
, pstat
, WLAN_STATUS_SUCCESS
);
1022 if (pstat
->state
& WIFI_FW_AUTH_SUCCESS
)
1023 pstat
->auth_seq
= 0;
1030 rtw_free_stainfo23a(padapter
, pstat
);
1033 memset((char *)pstat
, '\0', sizeof(stat
));
1034 pstat
->auth_seq
= 2;
1035 memcpy(pstat
->hwaddr
, sa
, 6);
1037 issue_auth23a(padapter
, pstat
, (unsigned short)status
);
1044 OnAuth23aClient23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
1046 unsigned int seq
, status
, algthm
;
1047 unsigned int go2asoc
= 0;
1048 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1049 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
1050 struct sk_buff
*skb
= precv_frame
->pkt
;
1051 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
1054 int plen
= skb
->len
;
1056 DBG_8723A("%s\n", __func__
);
1058 /* check A1 matches or not */
1059 if (!ether_addr_equal(myid(&padapter
->eeprompriv
), mgmt
->da
))
1062 if (!(pmlmeinfo
->state
& WIFI_FW_AUTH_STATE
))
1065 pie
= mgmt
->u
.auth
.variable
;
1066 plen
-= offsetof(struct ieee80211_mgmt
, u
.auth
.variable
);
1068 algthm
= le16_to_cpu(mgmt
->u
.auth
.auth_alg
);
1069 seq
= le16_to_cpu(mgmt
->u
.auth
.auth_transaction
);
1070 status
= le16_to_cpu(mgmt
->u
.auth
.status_code
);
1073 DBG_8723A("clnt auth fail, status: %d\n", status
);
1074 /* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
1075 if (status
== WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
) {
1076 if (pmlmeinfo
->auth_algo
== dot11AuthAlgrthm_Shared
)
1077 pmlmeinfo
->auth_algo
= dot11AuthAlgrthm_Open
;
1079 pmlmeinfo
->auth_algo
= dot11AuthAlgrthm_Shared
;
1080 /* pmlmeinfo->reauth_count = 0; */
1083 set_link_timer(pmlmeext
, 1);
1088 if (pmlmeinfo
->auth_algo
== dot11AuthAlgrthm_Shared
) {
1089 /* legendary shared system */
1090 p
= cfg80211_find_ie(WLAN_EID_CHALLENGE
, pie
, plen
);
1093 /* DBG_8723A("marc: no challenge text?\n"); */
1097 memcpy((void *)(pmlmeinfo
->chg_txt
), p
+ 2, p
[1]);
1098 pmlmeinfo
->auth_seq
= 3;
1099 issue_auth23a(padapter
, NULL
, 0);
1100 set_link_timer(pmlmeext
, REAUTH_TO
);
1107 } else if (seq
== 4) {
1108 if (pmlmeinfo
->auth_algo
== dot11AuthAlgrthm_Shared
)
1113 /* this is also illegal */
1114 /* DBG_8723A("marc: clnt auth failed due to illegal seq =%x\n",
1120 DBG_8723A_LEVEL(_drv_always_
, "auth success, start assoc\n");
1121 start_clnt_assoc23a(padapter
);
1127 /* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
1132 #ifdef CONFIG_8723AU_AP_MODE
1133 static int rtw_validate_vendor_specific_ies(const u8
*pos
, int elen
)
1137 /* first 3 bytes in vendor specific information element are the IEEE
1138 * OUI of the vendor. The following byte is used a vendor specific
1141 DBG_8723A("short vendor specific information element "
1142 "ignored (len =%i)\n", elen
);
1146 oui
= RTW_GET_BE24(pos
);
1148 case WLAN_OUI_MICROSOFT
:
1149 /* Microsoft/Wi-Fi information elements are further typed and
1153 /* Microsoft OUI (00:50:F2) with OUI Type 1:
1154 * real WPA information element */
1156 case WME_OUI_TYPE
: /* this is a Wi-Fi WME info. element */
1158 DBG_8723A("short WME information element "
1159 "ignored (len =%i)\n", elen
);
1163 case WME_OUI_SUBTYPE_INFORMATION_ELEMENT
:
1164 case WME_OUI_SUBTYPE_PARAMETER_ELEMENT
:
1166 case WME_OUI_SUBTYPE_TSPEC_ELEMENT
:
1169 DBG_8723A("unknown WME information element "
1170 "ignored (subtype =%d len =%i)\n",
1176 /* Wi-Fi Protected Setup (WPS) IE */
1179 DBG_8723A("Unknown Microsoft information element "
1180 "ignored (type =%d len =%i)\n",
1188 case VENDOR_HT_CAPAB_OUI_TYPE
:
1191 DBG_8723A("Unknown Broadcom information element "
1192 "ignored (type =%d len =%i)\n", pos
[3], elen
);
1198 DBG_8723A("unknown vendor specific information element "
1199 "ignored (vendor OUI %02x:%02x:%02x len =%i)\n",
1200 pos
[0], pos
[1], pos
[2], elen
);
1207 static int rtw_validate_frame_ies(const u8
*start
, uint len
)
1209 const u8
*pos
= start
;
1221 DBG_8723A("%s: IEEE 802.11 failed (id =%d elen =%d "
1222 "left =%i)\n", __func__
, id
, elen
, left
);
1228 case WLAN_EID_SUPP_RATES
:
1229 case WLAN_EID_FH_PARAMS
:
1230 case WLAN_EID_DS_PARAMS
:
1231 case WLAN_EID_CF_PARAMS
:
1233 case WLAN_EID_IBSS_PARAMS
:
1234 case WLAN_EID_CHALLENGE
:
1235 case WLAN_EID_ERP_INFO
:
1236 case WLAN_EID_EXT_SUPP_RATES
:
1237 case WLAN_EID_VENDOR_SPECIFIC
:
1238 if (rtw_validate_vendor_specific_ies(pos
, elen
))
1242 case WLAN_EID_PWR_CAPABILITY
:
1243 case WLAN_EID_SUPPORTED_CHANNELS
:
1244 case WLAN_EID_MOBILITY_DOMAIN
:
1245 case WLAN_EID_FAST_BSS_TRANSITION
:
1246 case WLAN_EID_TIMEOUT_INTERVAL
:
1247 case WLAN_EID_HT_CAPABILITY
:
1248 case WLAN_EID_HT_OPERATION
:
1251 DBG_8723A("%s IEEE 802.11 ignored unknown element "
1252 "(id =%d elen =%d)\n", __func__
, id
, elen
);
1268 OnAssocReq23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
1270 #ifdef CONFIG_8723AU_AP_MODE
1271 u16 capab_info
, listen_interval
;
1272 struct sta_info
*pstat
;
1273 unsigned char reassoc
;
1274 unsigned char WMM_IE
[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
1275 int i
, wpa_ie_len
, left
;
1276 unsigned char supportRate
[16];
1278 unsigned short status
= WLAN_STATUS_SUCCESS
;
1279 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1280 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
1281 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1282 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
1283 struct wlan_bssid_ex
*cur
= &pmlmeinfo
->network
;
1284 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1285 struct sk_buff
*skb
= precv_frame
->pkt
;
1286 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
1287 const u8
*pos
, *p
, *wpa_ie
, *wps_ie
;
1288 u8
*pframe
= skb
->data
;
1289 uint pkt_len
= skb
->len
;
1292 if ((pmlmeinfo
->state
& 0x03) != WIFI_FW_AP_STATE
)
1295 left
= pkt_len
- sizeof(struct ieee80211_hdr_3addr
);
1296 if (ieee80211_is_assoc_req(mgmt
->frame_control
)) {
1298 pos
= mgmt
->u
.assoc_req
.variable
;
1299 left
-= offsetof(struct ieee80211_mgmt
, u
.assoc_req
.variable
);
1300 } else { /* WIFI_REASSOCREQ */
1302 pos
= mgmt
->u
.reassoc_req
.variable
;
1303 left
-= offsetof(struct ieee80211_mgmt
, u
.reassoc_req
.variable
);
1307 DBG_8723A("handle_assoc(reassoc =%d) - too short payload "
1308 "(len =%lu)\n", reassoc
, (unsigned long)pkt_len
);
1312 pstat
= rtw_get_stainfo23a(pstapriv
, mgmt
->sa
);
1314 status
= WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
;
1315 goto asoc_class2_error
;
1318 /* These two are located at the same offsets whether it's an
1319 * assoc_req or a reassoc_req */
1320 capab_info
= get_unaligned_le16(&mgmt
->u
.assoc_req
.capab_info
);
1322 get_unaligned_le16(&mgmt
->u
.assoc_req
.listen_interval
);
1324 DBG_8723A("%s\n", __func__
);
1326 /* check if this stat has been successfully authenticated/assocated */
1327 if (!(pstat
->state
& WIFI_FW_AUTH_SUCCESS
)) {
1328 if (!(pstat
->state
& WIFI_FW_ASSOC_SUCCESS
)) {
1329 status
= WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
;
1330 goto asoc_class2_error
;
1332 pstat
->state
&= (~WIFI_FW_ASSOC_SUCCESS
);
1333 pstat
->state
|= WIFI_FW_ASSOC_STATE
;
1336 pstat
->state
&= (~WIFI_FW_AUTH_SUCCESS
);
1337 pstat
->state
|= WIFI_FW_ASSOC_STATE
;
1340 pstat
->capability
= capab_info
;
1342 /* now parse all ieee802_11 ie to point to elems */
1344 if (rtw_validate_frame_ies(pos
, left
)) {
1345 DBG_8723A("STA " MAC_FMT
" sent invalid association request\n",
1346 MAC_ARG(pstat
->hwaddr
));
1347 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1348 goto OnAssocReq23aFail
;
1351 /* now we should check all the fields... */
1353 p
= cfg80211_find_ie(WLAN_EID_SSID
, pos
, left
);
1354 if (!p
|| p
[1] == 0) {
1355 /* broadcast ssid, however it is not allowed in assocreq */
1356 DBG_8723A("STA " MAC_FMT
" sent invalid association request "
1357 "lacking an SSID\n", MAC_ARG(pstat
->hwaddr
));
1358 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1359 goto OnAssocReq23aFail
;
1361 /* check if ssid match */
1362 if (memcmp(p
+ 2, cur
->Ssid
.ssid
, cur
->Ssid
.ssid_len
))
1363 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1365 if (p
[1] != cur
->Ssid
.ssid_len
)
1366 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1369 if (status
!= WLAN_STATUS_SUCCESS
)
1370 goto OnAssocReq23aFail
;
1372 /* check if the supported rate is ok */
1373 p
= cfg80211_find_ie(WLAN_EID_SUPP_RATES
, pos
, left
);
1375 DBG_8723A("Rx a sta assoc-req which supported rate is "
1377 /* use our own rate set as statoin used */
1378 /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
1379 /* supportRateNum = AP_BSSRATE_LEN; */
1381 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1382 goto OnAssocReq23aFail
;
1384 memcpy(supportRate
, p
+ 2, p
[1]);
1385 supportRateNum
= p
[1];
1387 p
= cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES
, pos
, left
);
1389 if (supportRateNum
<= sizeof(supportRate
)) {
1390 memcpy(supportRate
+supportRateNum
, p
+ 2, p
[1]);
1391 supportRateNum
+= p
[1];
1396 /* todo: mask supportRate between AP & STA -> move to update raid */
1397 /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */
1399 /* update station supportRate */
1400 pstat
->bssratelen
= supportRateNum
;
1401 memcpy(pstat
->bssrateset
, supportRate
, supportRateNum
);
1402 Update23aTblForSoftAP(pstat
->bssrateset
, pstat
->bssratelen
);
1404 /* check RSN/WPA/WPS */
1405 pstat
->dot8021xalg
= 0;
1407 pstat
->wpa_group_cipher
= 0;
1408 pstat
->wpa2_group_cipher
= 0;
1409 pstat
->wpa_pairwise_cipher
= 0;
1410 pstat
->wpa2_pairwise_cipher
= 0;
1411 memset(pstat
->wpa_ie
, 0, sizeof(pstat
->wpa_ie
));
1413 wpa_ie
= cfg80211_find_ie(WLAN_EID_RSN
, pos
, left
);
1415 wpa_ie
= cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT
,
1416 WLAN_OUI_TYPE_MICROSOFT_WPA
,
1419 int group_cipher
= 0, pairwise_cipher
= 0;
1421 wpa_ie_len
= wpa_ie
[1];
1422 if (psecuritypriv
->wpa_psk
& BIT(1)) {
1423 r
= rtw_parse_wpa2_ie23a(wpa_ie
, wpa_ie_len
+ 2,
1425 &pairwise_cipher
, NULL
);
1426 if (r
== _SUCCESS
) {
1427 pstat
->dot8021xalg
= 1;/* psk, todo:802.1x */
1428 pstat
->wpa_psk
|= BIT(1);
1430 pstat
->wpa2_group_cipher
= group_cipher
&
1431 psecuritypriv
->wpa2_group_cipher
;
1432 pstat
->wpa2_pairwise_cipher
= pairwise_cipher
&
1433 psecuritypriv
->wpa2_pairwise_cipher
;
1435 status
= WLAN_STATUS_INVALID_IE
;
1436 } else if (psecuritypriv
->wpa_psk
& BIT(0)) {
1437 r
= rtw_parse_wpa_ie23a(wpa_ie
, wpa_ie_len
+ 2,
1438 &group_cipher
, &pairwise_cipher
,
1440 if (r
== _SUCCESS
) {
1441 pstat
->dot8021xalg
= 1;/* psk, todo:802.1x */
1442 pstat
->wpa_psk
|= BIT(0);
1444 pstat
->wpa_group_cipher
= group_cipher
&
1445 psecuritypriv
->wpa_group_cipher
;
1446 pstat
->wpa_pairwise_cipher
= pairwise_cipher
&
1447 psecuritypriv
->wpa_pairwise_cipher
;
1449 status
= WLAN_STATUS_INVALID_IE
;
1454 if (wpa_ie
&& status
== WLAN_STATUS_SUCCESS
) {
1455 if (!pstat
->wpa_group_cipher
)
1456 status
= WLAN_STATUS_INVALID_GROUP_CIPHER
;
1458 if (!pstat
->wpa_pairwise_cipher
)
1459 status
= WLAN_STATUS_INVALID_PAIRWISE_CIPHER
;
1463 if (status
!= WLAN_STATUS_SUCCESS
)
1464 goto OnAssocReq23aFail
;
1466 pstat
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
);
1468 wps_ie
= cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT
,
1469 WLAN_OUI_TYPE_MICROSOFT_WPS
,
1474 DBG_8723A("STA included WPS IE in (Re)Association "
1475 "Request - assume WPS is used\n");
1476 pstat
->flags
|= WLAN_STA_WPS
;
1478 DBG_8723A("STA did not include WPA/RSN IE in (Re)"
1479 "Association Request - possible WPS use\n");
1480 pstat
->flags
|= WLAN_STA_MAYBE_WPS
;
1483 /* AP support WPA/RSN, and sta is going to do WPS, but AP
1485 /* that the selected registrar of AP is _FLASE */
1486 if (psecuritypriv
->wpa_psk
> 0 &&
1487 pstat
->flags
& (WLAN_STA_WPS
|WLAN_STA_MAYBE_WPS
)) {
1488 if (pmlmepriv
->wps_beacon_ie
) {
1489 u8 selected_registrar
= 0;
1491 rtw_get_wps_attr_content23a(
1492 pmlmepriv
->wps_beacon_ie
,
1493 pmlmepriv
->wps_beacon_ie_len
,
1494 WPS_ATTR_SELECTED_REGISTRAR
,
1495 &selected_registrar
, NULL
);
1497 if (!selected_registrar
) {
1498 DBG_8723A("selected_registrar is false,"
1499 "or AP is not ready to do "
1502 status
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
1503 goto OnAssocReq23aFail
;
1510 if (psecuritypriv
->wpa_psk
== 0) {
1511 DBG_8723A("STA " MAC_FMT
": WPA/RSN IE in association "
1512 "request, but AP don't support WPA/RSN\n",
1513 MAC_ARG(pstat
->hwaddr
));
1515 status
= WLAN_STATUS_INVALID_IE
;
1517 goto OnAssocReq23aFail
;
1521 DBG_8723A("STA included WPS IE in (Re)Association "
1522 "Request - WPS is used\n");
1523 pstat
->flags
|= WLAN_STA_WPS
;
1526 copy_len
= ((wpa_ie_len
+ 2) > sizeof(pstat
->wpa_ie
)) ?
1527 sizeof(pstat
->wpa_ie
) : (wpa_ie_len
+ 2);
1531 memcpy(pstat
->wpa_ie
, wpa_ie
- 2, copy_len
);
1534 /* check if there is WMM IE & support WWM-PS */
1535 pstat
->flags
&= ~WLAN_STA_WME
;
1536 pstat
->qos_option
= 0;
1537 pstat
->qos_info
= 0;
1538 pstat
->has_legacy_ac
= true;
1539 pstat
->uapsd_vo
= 0;
1540 pstat
->uapsd_vi
= 0;
1541 pstat
->uapsd_be
= 0;
1542 pstat
->uapsd_bk
= 0;
1543 if (pmlmepriv
->qos_option
) {
1544 const u8
*end
= pos
+ left
;
1549 p
= cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC
, p
, left
);
1551 if (!memcmp(p
+ 2, WMM_IE
, 6)) {
1552 pstat
->flags
|= WLAN_STA_WME
;
1554 pstat
->qos_option
= 1;
1555 pstat
->qos_info
= *(p
+ 8);
1558 (pstat
->qos_info
>> 5) & 0x3;
1560 if ((pstat
->qos_info
& 0xf) != 0xf)
1561 pstat
->has_legacy_ac
= true;
1563 pstat
->has_legacy_ac
= false;
1565 if (pstat
->qos_info
& 0xf) {
1566 if (pstat
->qos_info
& BIT(0))
1567 pstat
->uapsd_vo
= BIT(0)|BIT(1);
1569 pstat
->uapsd_vo
= 0;
1571 if (pstat
->qos_info
& BIT(1))
1572 pstat
->uapsd_vi
= BIT(0)|BIT(1);
1574 pstat
->uapsd_vi
= 0;
1576 if (pstat
->qos_info
& BIT(2))
1577 pstat
->uapsd_bk
= BIT(0)|BIT(1);
1579 pstat
->uapsd_bk
= 0;
1581 if (pstat
->qos_info
& BIT(3))
1582 pstat
->uapsd_be
= BIT(0)|BIT(1);
1584 pstat
->uapsd_be
= 0;
1597 /* save HT capabilities in the sta object */
1598 memset(&pstat
->htpriv
.ht_cap
, 0, sizeof(struct ieee80211_ht_cap
));
1599 p
= cfg80211_find_ie(WLAN_EID_HT_CAPABILITY
, pos
, left
);
1601 if (p
&& p
[1] >= sizeof(struct ieee80211_ht_cap
)) {
1602 pstat
->flags
|= WLAN_STA_HT
;
1604 pstat
->flags
|= WLAN_STA_WME
;
1606 memcpy(&pstat
->htpriv
.ht_cap
, p
+ 2,
1607 sizeof(struct ieee80211_ht_cap
));
1609 pstat
->flags
&= ~WLAN_STA_HT
;
1611 if (pmlmepriv
->htpriv
.ht_option
== false && pstat
->flags
& WLAN_STA_HT
){
1612 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1613 goto OnAssocReq23aFail
;
1616 if (pstat
->flags
& WLAN_STA_HT
&&
1617 (pstat
->wpa2_pairwise_cipher
& WPA_CIPHER_TKIP
||
1618 pstat
->wpa_pairwise_cipher
& WPA_CIPHER_TKIP
)) {
1619 DBG_8723A("HT: " MAC_FMT
" tried to use TKIP with HT "
1620 "association\n", MAC_ARG(pstat
->hwaddr
));
1622 /* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */
1623 /* goto OnAssocReq23aFail; */
1626 pstat
->flags
|= WLAN_STA_NONERP
;
1627 for (i
= 0; i
< pstat
->bssratelen
; i
++) {
1628 if ((pstat
->bssrateset
[i
] & 0x7f) > 22) {
1629 pstat
->flags
&= ~WLAN_STA_NONERP
;
1634 if (pstat
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
1635 pstat
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
1637 pstat
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
1639 if (status
!= WLAN_STATUS_SUCCESS
)
1640 goto OnAssocReq23aFail
;
1642 /* TODO: identify_proprietary_vendor_ie(); */
1643 /* Realtek proprietary IE */
1644 /* identify if this is Broadcom sta */
1645 /* identify if this is ralink sta */
1646 /* Customer proprietary IE */
1648 /* get a unique AID */
1649 if (pstat
->aid
> 0) {
1650 DBG_8723A(" old AID %d\n", pstat
->aid
);
1652 for (pstat
->aid
= 1; pstat
->aid
<= NUM_STA
; pstat
->aid
++)
1653 if (pstapriv
->sta_aid
[pstat
->aid
- 1] == NULL
)
1656 if (pstat
->aid
> NUM_STA
)
1657 pstat
->aid
= NUM_STA
;
1658 if (pstat
->aid
> pstapriv
->max_num_sta
) {
1662 DBG_8723A(" no room for more AIDs\n");
1664 status
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
1666 goto OnAssocReq23aFail
;
1668 pstapriv
->sta_aid
[pstat
->aid
- 1] = pstat
;
1669 DBG_8723A("allocate new AID = (%d)\n", pstat
->aid
);
1673 pstat
->state
&= ~WIFI_FW_ASSOC_STATE
;
1674 pstat
->state
|= WIFI_FW_ASSOC_SUCCESS
;
1676 spin_lock_bh(&pstapriv
->auth_list_lock
);
1677 if (!list_empty(&pstat
->auth_list
)) {
1678 list_del_init(&pstat
->auth_list
);
1679 pstapriv
->auth_list_cnt
--;
1681 spin_unlock_bh(&pstapriv
->auth_list_lock
);
1683 spin_lock_bh(&pstapriv
->asoc_list_lock
);
1684 if (list_empty(&pstat
->asoc_list
)) {
1685 pstat
->expire_to
= pstapriv
->expire_to
;
1686 list_add_tail(&pstat
->asoc_list
, &pstapriv
->asoc_list
);
1687 pstapriv
->asoc_list_cnt
++;
1689 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
1691 /* now the station is qualified to join our BSS... */
1692 if (pstat
&& pstat
->state
& WIFI_FW_ASSOC_SUCCESS
&&
1693 status
== WLAN_STATUS_SUCCESS
) {
1694 #ifdef CONFIG_8723AU_AP_MODE
1695 /* 1 bss_cap_update & sta_info_update23a */
1696 bss_cap_update_on_sta_join23a(padapter
, pstat
);
1697 sta_info_update23a(padapter
, pstat
);
1699 /* issue assoc rsp before notify station join event. */
1700 if (ieee80211_is_assoc_req(mgmt
->frame_control
))
1701 issue_asocrsp23a(padapter
, status
, pstat
,
1704 issue_asocrsp23a(padapter
, status
, pstat
,
1707 /* 2 - report to upper layer */
1708 DBG_8723A("indicate_sta_join_event to upper layer - hostapd\n");
1709 rtw_cfg80211_indicate_sta_assoc(padapter
, pframe
, pkt_len
);
1711 /* 3-(1) report sta add event */
1712 report_add_sta_event23a(padapter
, pstat
->hwaddr
, pstat
->aid
);
1720 #ifdef CONFIG_8723AU_AP_MODE
1721 issue_deauth23a(padapter
, mgmt
->sa
, status
);
1727 #ifdef CONFIG_8723AU_AP_MODE
1729 if (ieee80211_is_assoc_req(mgmt
->frame_control
))
1730 issue_asocrsp23a(padapter
, status
, pstat
, WIFI_ASSOCRSP
);
1732 issue_asocrsp23a(padapter
, status
, pstat
, WIFI_REASSOCRSP
);
1735 #endif /* CONFIG_8723AU_AP_MODE */
1741 OnAssocRsp23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
1743 struct ndis_802_11_var_ies
*pIE
;
1744 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1745 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1746 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
1747 struct sk_buff
*skb
= precv_frame
->pkt
;
1748 struct ieee80211_mgmt
*pmgmt
= (struct ieee80211_mgmt
*) skb
->data
;
1750 unsigned short status
;
1751 u8
*pframe
= skb
->data
;
1752 int pkt_len
= skb
->len
;
1754 DBG_8723A("%s\n", __func__
);
1756 /* check A1 matches or not */
1757 if (!ether_addr_equal(myid(&padapter
->eeprompriv
), pmgmt
->da
))
1760 if (!(pmlmeinfo
->state
& (WIFI_FW_AUTH_SUCCESS
| WIFI_FW_ASSOC_STATE
)))
1763 if (pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
)
1766 del_timer_sync(&pmlmeext
->link_timer
);
1769 status
= le16_to_cpu(pmgmt
->u
.assoc_resp
.status_code
);
1771 DBG_8723A("assoc reject, status code: %d\n", status
);
1772 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
1774 goto report_assoc_result
;
1777 /* get capabilities */
1778 pmlmeinfo
->capability
= le16_to_cpu(pmgmt
->u
.assoc_resp
.capab_info
);
1781 pmlmeinfo
->slotTime
= (pmlmeinfo
->capability
& BIT(10))? 9: 20;
1784 res
= pmlmeinfo
->aid
= le16_to_cpu(pmgmt
->u
.assoc_resp
.aid
) & 0x3fff;
1786 /* following are moved to join event callback function */
1787 /* to handle HT, WMM, rate adaptive, update MAC reg */
1788 /* for not to handle the synchronous IO in the tasklet */
1789 for (i
= offsetof(struct ieee80211_mgmt
, u
.assoc_resp
.variable
);
1791 pIE
= (struct ndis_802_11_var_ies
*)(pframe
+ i
);
1793 switch (pIE
->ElementID
)
1795 case WLAN_EID_VENDOR_SPECIFIC
:
1796 if (!memcmp(pIE
->data
, WMM_PARA_OUI23A
, 6))/* WMM */
1797 WMM_param_handler23a(padapter
, pIE
);
1800 case WLAN_EID_HT_CAPABILITY
: /* HT caps */
1801 HT_caps_handler23a(padapter
, pIE
);
1804 case WLAN_EID_HT_OPERATION
: /* HT info */
1805 HT_info_handler23a(padapter
, pIE
);
1808 case WLAN_EID_ERP_INFO
:
1809 ERP_IE_handler23a(padapter
, pIE
);
1815 i
+= (pIE
->Length
+ 2);
1818 pmlmeinfo
->state
&= ~WIFI_FW_ASSOC_STATE
;
1819 pmlmeinfo
->state
|= WIFI_FW_ASSOC_SUCCESS
;
1821 /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
1822 UpdateBrateTbl23a(padapter
, pmlmeinfo
->network
.SupportedRates
);
1824 report_assoc_result
:
1825 pmlmepriv
->assoc_rsp_len
= 0;
1827 kfree(pmlmepriv
->assoc_rsp
);
1828 pmlmepriv
->assoc_rsp
= kmalloc(pkt_len
, GFP_ATOMIC
);
1829 if (pmlmepriv
->assoc_rsp
) {
1830 memcpy(pmlmepriv
->assoc_rsp
, pframe
, pkt_len
);
1831 pmlmepriv
->assoc_rsp_len
= pkt_len
;
1834 kfree(pmlmepriv
->assoc_rsp
);
1836 report_join_res23a(padapter
, res
);
1842 OnDeAuth23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
1844 unsigned short reason
;
1845 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1846 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1847 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
1848 struct sk_buff
*skb
= precv_frame
->pkt
;
1849 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
1851 if (!ether_addr_equal(mgmt
->bssid
,
1852 get_my_bssid23a(&pmlmeinfo
->network
)))
1855 reason
= le16_to_cpu(mgmt
->u
.deauth
.reason_code
);
1857 DBG_8723A("%s Reason code(%d)\n", __func__
, reason
);
1859 #ifdef CONFIG_8723AU_AP_MODE
1860 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) == true) {
1861 struct sta_info
*psta
;
1862 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1864 DBG_8723A_LEVEL(_drv_always_
, "ap recv deauth reason code(%d) "
1865 "sta:%pM\n", reason
, mgmt
->sa
);
1867 psta
= rtw_get_stainfo23a(pstapriv
, mgmt
->sa
);
1871 spin_lock_bh(&pstapriv
->asoc_list_lock
);
1872 if (!list_empty(&psta
->asoc_list
)) {
1873 list_del_init(&psta
->asoc_list
);
1874 pstapriv
->asoc_list_cnt
--;
1875 updated
= ap_free_sta23a(padapter
, psta
,
1878 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
1880 associated_clients_update23a(padapter
, updated
);
1887 DBG_8723A_LEVEL(_drv_always_
, "sta recv deauth reason code(%d) "
1888 "sta:%pM\n", reason
, mgmt
->bssid
);
1890 receive_disconnect23a(padapter
, mgmt
->bssid
, reason
);
1892 pmlmepriv
->LinkDetectInfo
.bBusyTraffic
= false;
1898 OnDisassoc23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
1900 unsigned short reason
;
1901 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1902 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1903 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
1904 struct sk_buff
*skb
= precv_frame
->pkt
;
1905 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
1907 if (!ether_addr_equal(mgmt
->bssid
,
1908 get_my_bssid23a(&pmlmeinfo
->network
)))
1911 reason
= le16_to_cpu(mgmt
->u
.disassoc
.reason_code
);
1913 DBG_8723A("%s Reason code(%d)\n", __func__
, reason
);
1915 #ifdef CONFIG_8723AU_AP_MODE
1916 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
1917 struct sta_info
*psta
;
1918 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1920 DBG_8723A_LEVEL(_drv_always_
, "ap recv disassoc reason code(%d)"
1921 " sta:%pM\n", reason
, mgmt
->sa
);
1923 psta
= rtw_get_stainfo23a(pstapriv
, mgmt
->sa
);
1927 spin_lock_bh(&pstapriv
->asoc_list_lock
);
1928 if (!list_empty(&psta
->asoc_list
)) {
1929 list_del_init(&psta
->asoc_list
);
1930 pstapriv
->asoc_list_cnt
--;
1931 updated
= ap_free_sta23a(padapter
, psta
,
1934 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
1936 associated_clients_update23a(padapter
, updated
);
1943 DBG_8723A_LEVEL(_drv_always_
, "ap recv disassoc reason "
1944 "code(%d) sta:%pM\n", reason
, mgmt
->bssid
);
1946 receive_disconnect23a(padapter
, mgmt
->bssid
, reason
);
1948 pmlmepriv
->LinkDetectInfo
.bBusyTraffic
= false;
1953 OnAtim23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
1955 DBG_8723A("%s\n", __func__
);
1960 on_action_spct23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
1966 OnAction23a_qos(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
1972 OnAction23a_dls(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
1977 static int OnAction23a_back23a(struct rtw_adapter
*padapter
,
1978 struct recv_frame
*precv_frame
)
1981 struct sta_info
*psta
= NULL
;
1982 struct recv_reorder_ctrl
*preorder_ctrl
;
1983 unsigned char category
, action
;
1984 unsigned short tid
, status
, capab
, params
, reason_code
= 0;
1985 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1986 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
1987 struct sk_buff
*skb
= precv_frame
->pkt
;
1988 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
1989 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1991 /* check RA matches or not */
1992 if (!ether_addr_equal(myid(&padapter
->eeprompriv
), mgmt
->da
))
1995 DBG_8723A("%s\n", __func__
);
1997 if ((pmlmeinfo
->state
&0x03) != WIFI_FW_AP_STATE
)
1998 if (!(pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
))
2002 psta
= rtw_get_stainfo23a(pstapriv
, addr
);
2007 category
= mgmt
->u
.action
.category
;
2008 if (category
== WLAN_CATEGORY_BACK
) { /* representing Block Ack */
2009 if (!pmlmeinfo
->HT_enable
)
2011 /* action_code is located in the same place for all
2012 action events, so pick any */
2013 action
= mgmt
->u
.action
.u
.wme_action
.action_code
;
2014 DBG_8723A("%s, action =%d\n", __func__
, action
);
2016 case WLAN_ACTION_ADDBA_REQ
: /* ADDBA request */
2017 memcpy(&pmlmeinfo
->ADDBA_req
,
2018 &mgmt
->u
.action
.u
.addba_req
.dialog_token
,
2019 sizeof(struct ADDBA_request
));
2020 process_addba_req23a(padapter
,
2021 (u8
*)&pmlmeinfo
->ADDBA_req
, addr
);
2022 if (pmlmeinfo
->bAcceptAddbaReq
== true)
2023 issue_action_BA23a(padapter
, addr
,
2024 WLAN_ACTION_ADDBA_RESP
, 0);
2026 /* reject ADDBA Req */
2027 issue_action_BA23a(padapter
, addr
,
2028 WLAN_ACTION_ADDBA_RESP
, 37);
2031 case WLAN_ACTION_ADDBA_RESP
: /* ADDBA response */
2032 status
= get_unaligned_le16(
2033 &mgmt
->u
.action
.u
.addba_resp
.status
);
2034 capab
= get_unaligned_le16(
2035 &mgmt
->u
.action
.u
.addba_resp
.capab
);
2036 tid
= (capab
& IEEE80211_ADDBA_PARAM_TID_MASK
) >> 2;
2037 if (status
== 0) { /* successful */
2038 DBG_8723A("agg_enable for TID =%d\n", tid
);
2039 psta
->htpriv
.agg_enable_bitmap
|= 1 << tid
;
2040 psta
->htpriv
.candidate_tid_bitmap
&=
2043 psta
->htpriv
.agg_enable_bitmap
&= ~CHKBIT(tid
);
2046 case WLAN_ACTION_DELBA
: /* DELBA */
2047 params
= get_unaligned_le16(
2048 &mgmt
->u
.action
.u
.delba
.params
);
2051 if (params
& IEEE80211_DELBA_PARAM_INITIATOR_MASK
) {
2052 preorder_ctrl
= &psta
->recvreorder_ctrl
[tid
];
2053 preorder_ctrl
->enable
= false;
2054 preorder_ctrl
->indicate_seq
= 0xffff;
2056 psta
->htpriv
.agg_enable_bitmap
&= ~(1 << tid
);
2057 psta
->htpriv
.candidate_tid_bitmap
&=
2060 reason_code
= get_unaligned_le16(
2061 &mgmt
->u
.action
.u
.delba
.reason_code
);
2062 DBG_8723A("%s(): DELBA: %x(%x)\n", __func__
,
2063 pmlmeinfo
->agg_enable_bitmap
, reason_code
);
2064 /* todo: how to notify the host while receiving
2074 static s32
rtw_action_public_decache(struct recv_frame
*recv_frame
, s32 token
)
2076 struct rtw_adapter
*adapter
= recv_frame
->adapter
;
2077 struct mlme_ext_priv
*mlmeext
= &adapter
->mlmeextpriv
;
2078 struct sk_buff
*skb
= recv_frame
->pkt
;
2079 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*) skb
->data
;
2082 seq_ctrl
= ((recv_frame
->attrib
.seq_num
&0xffff) << 4) |
2083 (recv_frame
->attrib
.frag_num
& 0xf);
2085 if (ieee80211_has_retry(hdr
->frame_control
)) {
2087 if ((seq_ctrl
== mlmeext
->action_public_rxseq
) &&
2088 (token
== mlmeext
->action_public_dialog_token
)) {
2089 DBG_8723A("%s(%s): seq_ctrl = 0x%x, "
2090 "rxseq = 0x%x, token:%d\n", __func__
,
2091 adapter
->pnetdev
->name
, seq_ctrl
,
2092 mlmeext
->action_public_rxseq
, token
);
2096 if (seq_ctrl
== mlmeext
->action_public_rxseq
) {
2097 DBG_8723A("%s(%s): seq_ctrl = 0x%x, "
2098 "rxseq = 0x%x\n", __func__
,
2099 adapter
->pnetdev
->name
, seq_ctrl
,
2100 mlmeext
->action_public_rxseq
);
2106 mlmeext
->action_public_rxseq
= seq_ctrl
;
2109 mlmeext
->action_public_dialog_token
= token
;
2114 static unsigned int on_action_public23a_p2p(struct recv_frame
*precv_frame
)
2116 struct sk_buff
*skb
= precv_frame
->pkt
;
2117 u8
*pframe
= skb
->data
;
2121 frame_body
= (unsigned char *)
2122 (pframe
+ sizeof(struct ieee80211_hdr_3addr
));
2124 dialogToken
= frame_body
[7];
2126 if (rtw_action_public_decache(precv_frame
, dialogToken
) == _FAIL
)
2132 static unsigned int on_action_public23a_vendor(struct recv_frame
*precv_frame
)
2134 unsigned int ret
= _FAIL
;
2135 struct sk_buff
*skb
= precv_frame
->pkt
;
2136 u8
*pframe
= skb
->data
;
2137 u8
*frame_body
= pframe
+ sizeof(struct ieee80211_hdr_3addr
);
2139 if (!memcmp(frame_body
+ 2, P2P_OUI23A
, 4)) {
2140 ret
= on_action_public23a_p2p(precv_frame
);
2147 on_action_public23a_default(struct recv_frame
*precv_frame
, u8 action
)
2149 unsigned int ret
= _FAIL
;
2150 struct sk_buff
*skb
= precv_frame
->pkt
;
2151 u8
*pframe
= skb
->data
;
2152 uint frame_len
= skb
->len
;
2153 u8
*frame_body
= pframe
+ sizeof(struct ieee80211_hdr_3addr
);
2155 struct rtw_adapter
*adapter
= precv_frame
->adapter
;
2159 token
= frame_body
[2];
2161 if (rtw_action_public_decache(precv_frame
, token
) == _FAIL
)
2164 cnt
+= sprintf((msg
+cnt
), "%s(token:%u)",
2165 action_public_str23a(action
), token
);
2166 rtw_cfg80211_rx_action(adapter
, pframe
, frame_len
, msg
);
2174 static int on_action_public23a(struct rtw_adapter
*padapter
,
2175 struct recv_frame
*precv_frame
)
2177 unsigned int ret
= _FAIL
;
2178 struct sk_buff
*skb
= precv_frame
->pkt
;
2179 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*) skb
->data
;
2180 u8
*pframe
= skb
->data
;
2181 u8
*frame_body
= pframe
+ sizeof(struct ieee80211_hdr_3addr
);
2182 u8 category
, action
;
2184 /* check RA matches or not */
2185 if (!ether_addr_equal(myid(&padapter
->eeprompriv
), hdr
->addr1
))
2188 category
= frame_body
[0];
2189 if (category
!= WLAN_CATEGORY_PUBLIC
)
2192 action
= frame_body
[1];
2194 case ACT_PUBLIC_VENDOR
:
2195 ret
= on_action_public23a_vendor(precv_frame
);
2198 ret
= on_action_public23a_default(precv_frame
, action
);
2207 OnAction23a_ht(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
2213 OnAction23a_wmm(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
2219 OnAction23a_p2p(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
2225 OnAction23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
2229 struct action_handler
*ptable
;
2230 struct sk_buff
*skb
= precv_frame
->pkt
;
2231 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
2233 category
= mgmt
->u
.action
.category
;
2236 i
< sizeof(OnAction23a_tbl
) / sizeof(struct action_handler
); i
++) {
2237 ptable
= &OnAction23a_tbl
[i
];
2239 if (category
== ptable
->num
)
2240 ptable
->func(padapter
, precv_frame
);
2246 static int DoReserved23a(struct rtw_adapter
*padapter
,
2247 struct recv_frame
*precv_frame
)
2252 struct xmit_frame
*alloc_mgtxmitframe23a(struct xmit_priv
*pxmitpriv
)
2254 struct xmit_frame
*pmgntframe
;
2255 struct xmit_buf
*pxmitbuf
;
2257 pmgntframe
= rtw_alloc_xmitframe23a_ext(pxmitpriv
);
2260 DBG_8723A("%s(%s): alloc xmitframe fail\n", __func__
,
2261 pxmitpriv
->adapter
->pnetdev
->name
);
2265 pxmitbuf
= rtw_alloc_xmitbuf23a_ext(pxmitpriv
);
2267 DBG_8723A("%s(%s): alloc xmitbuf fail\n", __func__
,
2268 pxmitpriv
->adapter
->pnetdev
->name
);
2269 rtw_free_xmitframe23a(pxmitpriv
, pmgntframe
);
2274 pmgntframe
->frame_tag
= MGNT_FRAMETAG
;
2275 pmgntframe
->pxmitbuf
= pxmitbuf
;
2276 pmgntframe
->buf_addr
= pxmitbuf
->pbuf
;
2277 pxmitbuf
->priv_data
= pmgntframe
;
2283 /****************************************************************************
2285 Following are some TX fuctions for WiFi MLME
2287 *****************************************************************************/
2289 void update_mgnt_tx_rate23a(struct rtw_adapter
*padapter
, u8 rate
)
2291 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2293 pmlmeext
->tx_rate
= rate
;
2294 DBG_8723A("%s(): rate = %x\n", __func__
, rate
);
2297 void update_mgntframe_attrib23a(struct rtw_adapter
*padapter
,
2298 struct pkt_attrib
*pattrib
)
2300 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2302 memset((u8
*)pattrib
, 0, sizeof(struct pkt_attrib
));
2304 pattrib
->hdrlen
= 24;
2305 pattrib
->nr_frags
= 1;
2306 pattrib
->priority
= 7;
2307 pattrib
->mac_id
= 0;
2308 pattrib
->qsel
= 0x12;
2310 pattrib
->pktlen
= 0;
2312 if (pmlmeext
->cur_wireless_mode
& WIRELESS_11B
)
2313 pattrib
->raid
= 6;/* b mode */
2315 pattrib
->raid
= 5;/* a/g mode */
2317 pattrib
->encrypt
= _NO_PRIVACY_
;
2318 pattrib
->bswenc
= false;
2320 pattrib
->qos_en
= false;
2321 pattrib
->ht_en
= false;
2322 pattrib
->bwmode
= HT_CHANNEL_WIDTH_20
;
2323 pattrib
->ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
2324 pattrib
->sgi
= false;
2326 pattrib
->seqnum
= pmlmeext
->mgnt_seq
;
2328 pattrib
->retry_ctrl
= true;
2331 void dump_mgntframe23a(struct rtw_adapter
*padapter
,
2332 struct xmit_frame
*pmgntframe
)
2334 if (padapter
->bSurpriseRemoved
== true ||
2335 padapter
->bDriverStopped
== true)
2338 rtw_hal_mgnt_xmit23a(padapter
, pmgntframe
);
2341 s32
dump_mgntframe23a_and_wait(struct rtw_adapter
*padapter
,
2342 struct xmit_frame
*pmgntframe
, int timeout_ms
)
2346 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
2347 struct xmit_buf
*pxmitbuf
= pmgntframe
->pxmitbuf
;
2348 struct submit_ctx sctx
;
2350 if (padapter
->bSurpriseRemoved
== true ||
2351 padapter
->bDriverStopped
== true)
2354 rtw_sctx_init23a(&sctx
, timeout_ms
);
2355 pxmitbuf
->sctx
= &sctx
;
2357 ret
= rtw_hal_mgnt_xmit23a(padapter
, pmgntframe
);
2359 if (ret
== _SUCCESS
)
2360 ret
= rtw_sctx_wait23a(&sctx
);
2362 spin_lock_irqsave(&pxmitpriv
->lock_sctx
, irqL
);
2363 pxmitbuf
->sctx
= NULL
;
2364 spin_unlock_irqrestore(&pxmitpriv
->lock_sctx
, irqL
);
2369 s32
dump_mgntframe23a_and_wait_ack23a(struct rtw_adapter
*padapter
,
2370 struct xmit_frame
*pmgntframe
)
2373 u32 timeout_ms
= 500;/* 500ms */
2374 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
2376 if (padapter
->bSurpriseRemoved
== true ||
2377 padapter
->bDriverStopped
== true)
2380 mutex_lock(&pxmitpriv
->ack_tx_mutex
);
2381 pxmitpriv
->ack_tx
= true;
2383 pmgntframe
->ack_report
= 1;
2384 if (rtw_hal_mgnt_xmit23a(padapter
, pmgntframe
) == _SUCCESS
) {
2385 ret
= rtw_ack_tx_wait23a(pxmitpriv
, timeout_ms
);
2388 pxmitpriv
->ack_tx
= false;
2389 mutex_unlock(&pxmitpriv
->ack_tx_mutex
);
2394 static int update_hidden_ssid(u8
*ies
, u32 ies_len
, u8 hidden_ssid_mode
)
2402 ssid_ie
= rtw_get_ie23a(ies
, WLAN_EID_SSID
, &ssid_len_ori
, ies_len
);
2404 /* DBG_8723A("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n",
2405 __func__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
2407 if (ssid_ie
&& ssid_len_ori
> 0) {
2408 switch (hidden_ssid_mode
)
2411 next_ie
= ssid_ie
+ 2 + ssid_len_ori
;
2414 remain_len
= ies_len
-(next_ie
-ies
);
2417 memcpy(ssid_ie
+2, next_ie
, remain_len
);
2418 len_diff
-= ssid_len_ori
;
2422 memset(&ssid_ie
[2], 0, ssid_len_ori
);
2432 void issue_beacon23a(struct rtw_adapter
*padapter
, int timeout_ms
)
2434 struct xmit_frame
*pmgntframe
;
2435 struct pkt_attrib
*pattrib
;
2436 unsigned char *pframe
;
2437 struct ieee80211_hdr
*pwlanhdr
;
2439 unsigned int rate_len
;
2440 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
2441 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2442 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2443 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
2444 struct wlan_bssid_ex
*cur_network
= &pmlmeinfo
->network
;
2445 u8 bc_addr
[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2451 /* DBG_8723A("%s\n", __func__); */
2453 if ((pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
)) == NULL
) {
2454 DBG_8723A("%s, alloc mgnt frame fail\n", __func__
);
2457 #ifdef CONFIG_8723AU_AP_MODE
2458 spin_lock_bh(&pmlmepriv
->bcn_update_lock
);
2461 /* update attribute */
2462 pattrib
= &pmgntframe
->attrib
;
2463 update_mgntframe_attrib23a(padapter
, pattrib
);
2464 pattrib
->qsel
= 0x10;
2466 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
2468 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
2469 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
2471 fctrl
= &pwlanhdr
->frame_control
;
2474 ether_addr_copy(pwlanhdr
->addr1
, bc_addr
);
2475 ether_addr_copy(pwlanhdr
->addr2
, myid(&padapter
->eeprompriv
));
2476 ether_addr_copy(pwlanhdr
->addr3
, get_my_bssid23a(cur_network
));
2478 SetSeqNum(pwlanhdr
, 0 /*pmlmeext->mgnt_seq*/);
2479 /* pmlmeext->mgnt_seq++; */
2480 SetFrameSubType(pframe
, WIFI_BEACON
);
2482 pframe
+= sizeof(struct ieee80211_hdr_3addr
);
2483 pattrib
->pktlen
= sizeof(struct ieee80211_hdr_3addr
);
2485 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_AP_STATE
) {
2486 /* DBG_8723A("ie len =%d\n", cur_network->IELength); */
2487 memcpy(pframe
, cur_network
->IEs
, cur_network
->IELength
);
2488 len_diff
= update_hidden_ssid(pframe
+ _BEACON_IE_OFFSET_
,
2489 cur_network
->IELength
-
2491 pmlmeinfo
->hidden_ssid_mode
);
2492 pframe
+= (cur_network
->IELength
+len_diff
);
2493 pattrib
->pktlen
+= (cur_network
->IELength
+len_diff
);
2495 wps_ie
= rtw_get_wps_ie23a(pmgntframe
->buf_addr
+ TXDESC_OFFSET
+
2496 sizeof (struct ieee80211_hdr_3addr
) +
2497 _BEACON_IE_OFFSET_
, pattrib
->pktlen
-
2498 sizeof (struct ieee80211_hdr_3addr
) -
2499 _BEACON_IE_OFFSET_
, NULL
,
2501 if (wps_ie
&& wps_ielen
> 0) {
2502 rtw_get_wps_attr_content23a(wps_ie
, wps_ielen
,
2503 WPS_ATTR_SELECTED_REGISTRAR
,
2507 set_fwstate(pmlmepriv
, WIFI_UNDER_WPS
);
2509 _clr_fwstate_(pmlmepriv
, WIFI_UNDER_WPS
);
2514 /* below for ad-hoc mode */
2516 /* timestamp will be inserted by hardware */
2518 pattrib
->pktlen
+= 8;
2520 /* beacon interval: 2 bytes */
2522 memcpy(pframe
, (unsigned char *)
2523 rtw_get_beacon_interval23a_from_ie(cur_network
->IEs
), 2);
2526 pattrib
->pktlen
+= 2;
2528 /* capability info: 2 bytes */
2530 memcpy(pframe
, (unsigned char *)
2531 rtw_get_capability23a_from_ie(cur_network
->IEs
), 2);
2534 pattrib
->pktlen
+= 2;
2537 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SSID
,
2538 cur_network
->Ssid
.ssid_len
,
2539 cur_network
->Ssid
.ssid
, &pattrib
->pktlen
);
2541 /* supported rates... */
2542 rate_len
= rtw_get_rateset_len23a(cur_network
->SupportedRates
);
2543 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SUPP_RATES
,
2544 ((rate_len
> 8)? 8: rate_len
),
2545 cur_network
->SupportedRates
, &pattrib
->pktlen
);
2547 /* DS parameter set */
2548 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_DS_PARAMS
, 1, (unsigned char *)
2549 &cur_network
->Configuration
.DSConfig
,
2552 /* if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
2556 /* IBSS Parameter Set... */
2557 /* ATIMWindow = cur->Configuration.ATIMWindow; */
2559 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_IBSS_PARAMS
, 2,
2560 (unsigned char *)&ATIMWindow
,
2564 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_ERP_INFO
, 1,
2565 &erpinfo
, &pattrib
->pktlen
);
2568 /* EXTERNDED SUPPORTED RATE */
2570 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_EXT_SUPP_RATES
,
2572 cur_network
->SupportedRates
+ 8,
2575 /* todo:HT for adhoc */
2579 #ifdef CONFIG_8723AU_AP_MODE
2580 pmlmepriv
->update_bcn
= false;
2582 spin_unlock_bh(&pmlmepriv
->bcn_update_lock
);
2585 if ((pattrib
->pktlen
+ TXDESC_SIZE
) > 512) {
2586 DBG_8723A("beacon frame too large\n");
2590 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
2592 /* DBG_8723A("issue bcn_sz =%d\n", pattrib->last_txcmdsz); */
2594 dump_mgntframe23a_and_wait(padapter
, pmgntframe
, timeout_ms
);
2596 dump_mgntframe23a(padapter
, pmgntframe
);
2599 void issue_probersp23a(struct rtw_adapter
*padapter
, unsigned char *da
,
2600 u8 is_valid_p2p_probereq
)
2602 struct xmit_frame
*pmgntframe
;
2603 struct pkt_attrib
*pattrib
;
2604 unsigned char *pframe
;
2605 struct ieee80211_hdr
*pwlanhdr
;
2607 unsigned char *mac
, *bssid
;
2608 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
2609 #ifdef CONFIG_8723AU_AP_MODE
2614 int ssid_ielen_diff
;
2617 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2619 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2620 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
2621 struct wlan_bssid_ex
*cur_network
= &pmlmeinfo
->network
;
2622 unsigned int rate_len
;
2624 /* DBG_8723A("%s\n", __func__); */
2626 pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
);
2628 DBG_8723A("%s, alloc mgnt frame fail\n", __func__
);
2632 /* update attribute */
2633 pattrib
= &pmgntframe
->attrib
;
2634 update_mgntframe_attrib23a(padapter
, pattrib
);
2636 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
2638 pframe
= (u8
*)pmgntframe
->buf_addr
+ TXDESC_OFFSET
;
2639 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
2641 mac
= myid(&padapter
->eeprompriv
);
2642 bssid
= cur_network
->MacAddress
;
2644 fctrl
= &pwlanhdr
->frame_control
;
2646 ether_addr_copy(pwlanhdr
->addr1
, da
);
2647 ether_addr_copy(pwlanhdr
->addr2
, mac
);
2648 ether_addr_copy(pwlanhdr
->addr3
, bssid
);
2650 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
2651 pmlmeext
->mgnt_seq
++;
2652 SetFrameSubType(fctrl
, WIFI_PROBERSP
);
2654 pattrib
->hdrlen
= sizeof(struct ieee80211_hdr_3addr
);
2655 pattrib
->pktlen
= pattrib
->hdrlen
;
2656 pframe
+= pattrib
->hdrlen
;
2658 if (cur_network
->IELength
> MAX_IE_SZ
)
2661 #ifdef CONFIG_8723AU_AP_MODE
2662 if ((pmlmeinfo
->state
& 0x03) == WIFI_FW_AP_STATE
) {
2663 pwps_ie
= rtw_get_wps_ie23a(cur_network
->IEs
+
2665 cur_network
->IELength
-
2666 _FIXED_IE_LENGTH_
, NULL
,
2669 /* inerset & update wps_probe_resp_ie */
2670 if (pmlmepriv
->wps_probe_resp_ie
&& pwps_ie
&& wps_ielen
> 0) {
2671 uint wps_offset
, remainder_ielen
;
2674 wps_offset
= (uint
)(pwps_ie
- cur_network
->IEs
);
2676 premainder_ie
= pwps_ie
+ wps_ielen
;
2678 remainder_ielen
= cur_network
->IELength
- wps_offset
-
2681 memcpy(pframe
, cur_network
->IEs
, wps_offset
);
2682 pframe
+= wps_offset
;
2683 pattrib
->pktlen
+= wps_offset
;
2685 /* to get ie data len */
2686 wps_ielen
= (uint
)pmlmepriv
->wps_probe_resp_ie
[1];
2687 if (wps_offset
+ wps_ielen
+ 2 <= MAX_IE_SZ
) {
2688 memcpy(pframe
, pmlmepriv
->wps_probe_resp_ie
,
2690 pframe
+= wps_ielen
+2;
2691 pattrib
->pktlen
+= wps_ielen
+2;
2694 if (wps_offset
+ wps_ielen
+ 2 + remainder_ielen
<=
2696 memcpy(pframe
, premainder_ie
, remainder_ielen
);
2697 pframe
+= remainder_ielen
;
2698 pattrib
->pktlen
+= remainder_ielen
;
2701 memcpy(pframe
, cur_network
->IEs
, cur_network
->IELength
);
2702 pframe
+= cur_network
->IELength
;
2703 pattrib
->pktlen
+= cur_network
->IELength
;
2706 /* retrieve SSID IE from cur_network->Ssid */
2707 ies
= pmgntframe
->buf_addr
+ TXDESC_OFFSET
+
2708 sizeof(struct ieee80211_hdr_3addr
);
2710 ssid_ie
= rtw_get_ie23a(ies
+ _FIXED_IE_LENGTH_
, WLAN_EID_SSID
,
2712 pframe
- ies
- _FIXED_IE_LENGTH_
);
2714 ssid_ielen_diff
= cur_network
->Ssid
.ssid_len
- ssid_ielen
;
2716 if (ssid_ie
&& cur_network
->Ssid
.ssid_len
) {
2717 uint remainder_ielen
;
2719 remainder_ie
= ssid_ie
+ 2;
2720 remainder_ielen
= pframe
- remainder_ie
;
2722 DBG_8723A_LEVEL(_drv_warning_
, "%s(%s): "
2723 "remainder_ielen > MAX_IE_SZ\n",
2724 __func__
, padapter
->pnetdev
->name
);
2725 if (remainder_ielen
> MAX_IE_SZ
)
2726 remainder_ielen
= MAX_IE_SZ
;
2728 memcpy(buf
, remainder_ie
, remainder_ielen
);
2729 memcpy(remainder_ie
+ ssid_ielen_diff
, buf
,
2731 *(ssid_ie
+ 1) = cur_network
->Ssid
.ssid_len
;
2732 memcpy(ssid_ie
+ 2, cur_network
->Ssid
.ssid
,
2733 cur_network
->Ssid
.ssid_len
);
2735 pframe
+= ssid_ielen_diff
;
2736 pattrib
->pktlen
+= ssid_ielen_diff
;
2742 /* timestamp will be inserted by hardware */
2744 pattrib
->pktlen
+= 8;
2746 /* beacon interval: 2 bytes */
2748 memcpy(pframe
, (unsigned char *)
2749 rtw_get_beacon_interval23a_from_ie(cur_network
->IEs
), 2);
2752 pattrib
->pktlen
+= 2;
2754 /* capability info: 2 bytes */
2756 memcpy(pframe
, (unsigned char *)
2757 rtw_get_capability23a_from_ie(cur_network
->IEs
), 2);
2760 pattrib
->pktlen
+= 2;
2762 /* below for ad-hoc mode */
2765 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SSID
,
2766 cur_network
->Ssid
.ssid_len
,
2767 cur_network
->Ssid
.ssid
,
2770 /* supported rates... */
2771 rate_len
= rtw_get_rateset_len23a(cur_network
->SupportedRates
);
2772 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SUPP_RATES
,
2773 ((rate_len
> 8)? 8: rate_len
),
2774 cur_network
->SupportedRates
,
2777 /* DS parameter set */
2778 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_DS_PARAMS
, 1,
2780 &cur_network
->Configuration
.DSConfig
,
2783 if ((pmlmeinfo
->state
& 0x03) == WIFI_FW_ADHOC_STATE
) {
2786 /* IBSS Parameter Set... */
2787 /* ATIMWindow = cur->Configuration.ATIMWindow; */
2789 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_IBSS_PARAMS
, 2,
2790 (unsigned char *)&ATIMWindow
,
2794 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_ERP_INFO
, 1,
2795 &erpinfo
, &pattrib
->pktlen
);
2798 /* EXTERNDED SUPPORTED RATE */
2800 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_EXT_SUPP_RATES
,
2802 cur_network
->SupportedRates
+ 8,
2805 /* todo:HT for adhoc */
2808 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
2810 dump_mgntframe23a(padapter
, pmgntframe
);
2815 static int _issue_probereq23a(struct rtw_adapter
*padapter
,
2816 struct cfg80211_ssid
*pssid
, u8
*da
, int wait_ack
)
2819 struct xmit_frame
*pmgntframe
;
2820 struct pkt_attrib
*pattrib
;
2821 unsigned char *pframe
;
2822 struct ieee80211_hdr
*pwlanhdr
;
2825 unsigned char bssrate
[NumRates
];
2826 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
2827 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2828 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2829 int bssrate_len
= 0;
2830 u8 bc_addr
[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2832 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
,
2833 ("+issue_probereq23a\n"));
2835 if ((pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
)) == NULL
)
2838 /* update attribute */
2839 pattrib
= &pmgntframe
->attrib
;
2840 update_mgntframe_attrib23a(padapter
, pattrib
);
2842 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
2844 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
2845 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
2847 mac
= myid(&padapter
->eeprompriv
);
2849 fctrl
= &pwlanhdr
->frame_control
;
2853 /* unicast probe request frame */
2854 ether_addr_copy(pwlanhdr
->addr1
, da
);
2855 ether_addr_copy(pwlanhdr
->addr3
, da
);
2857 /* broadcast probe request frame */
2858 ether_addr_copy(pwlanhdr
->addr1
, bc_addr
);
2859 ether_addr_copy(pwlanhdr
->addr3
, bc_addr
);
2862 ether_addr_copy(pwlanhdr
->addr2
, mac
);
2864 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
2865 pmlmeext
->mgnt_seq
++;
2866 SetFrameSubType(pframe
, WIFI_PROBEREQ
);
2868 pframe
+= sizeof (struct ieee80211_hdr_3addr
);
2869 pattrib
->pktlen
= sizeof (struct ieee80211_hdr_3addr
);
2872 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SSID
, pssid
->ssid_len
,
2873 pssid
->ssid
, &pattrib
->pktlen
);
2875 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SSID
, 0, NULL
,
2878 get_rate_set23a(padapter
, bssrate
, &bssrate_len
);
2880 if (bssrate_len
> 8) {
2881 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SUPP_RATES
, 8,
2882 bssrate
, &pattrib
->pktlen
);
2883 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_EXT_SUPP_RATES
,
2884 (bssrate_len
- 8), (bssrate
+ 8),
2887 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SUPP_RATES
,
2888 bssrate_len
, bssrate
, &pattrib
->pktlen
);
2891 /* add wps_ie for wps2.0 */
2892 if (pmlmepriv
->wps_probe_req_ie_len
>0 && pmlmepriv
->wps_probe_req_ie
) {
2893 memcpy(pframe
, pmlmepriv
->wps_probe_req_ie
,
2894 pmlmepriv
->wps_probe_req_ie_len
);
2895 pframe
+= pmlmepriv
->wps_probe_req_ie_len
;
2896 pattrib
->pktlen
+= pmlmepriv
->wps_probe_req_ie_len
;
2899 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
2901 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
,
2902 ("issuing probe_req, tx_len =%d\n", pattrib
->last_txcmdsz
));
2905 ret
= dump_mgntframe23a_and_wait_ack23a(padapter
, pmgntframe
);
2907 dump_mgntframe23a(padapter
, pmgntframe
);
2915 inline void issue_probereq23a(struct rtw_adapter
*padapter
,
2916 struct cfg80211_ssid
*pssid
, u8
*da
)
2918 _issue_probereq23a(padapter
, pssid
, da
, false);
2921 int issue_probereq23a_ex23a(struct rtw_adapter
*padapter
,
2922 struct cfg80211_ssid
*pssid
, u8
*da
,
2923 int try_cnt
, int wait_ms
)
2927 unsigned long start
= jiffies
;
2930 ret
= _issue_probereq23a(padapter
, pssid
, da
,
2931 wait_ms
> 0 ? true : false);
2935 if (padapter
->bDriverStopped
|| padapter
->bSurpriseRemoved
)
2938 if (i
< try_cnt
&& wait_ms
> 0 && ret
== _FAIL
)
2941 } while((i
< try_cnt
) && ((ret
== _FAIL
) || (wait_ms
== 0)));
2948 if (try_cnt
&& wait_ms
) {
2950 DBG_8723A("%s(%s): to "MAC_FMT
", ch:%u%s, %d/%d "
2951 "in %u ms\n", __func__
,
2952 padapter
->pnetdev
->name
,
2953 MAC_ARG(da
), rtw_get_oper_ch23a(padapter
),
2954 ret
== _SUCCESS
?", acked":"", i
, try_cnt
,
2955 jiffies_to_msecs(jiffies
- start
));
2957 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
2958 __func__
, padapter
->pnetdev
->name
,
2959 rtw_get_oper_ch23a(padapter
),
2960 ret
== _SUCCESS
?", acked":"", i
, try_cnt
,
2961 jiffies_to_msecs(jiffies
- start
));
2967 /* if psta == NULL, indiate we are station(client) now... */
2968 void issue_auth23a(struct rtw_adapter
*padapter
, struct sta_info
*psta
,
2969 unsigned short status
)
2971 struct xmit_frame
*pmgntframe
;
2972 struct pkt_attrib
*pattrib
;
2973 unsigned char *pframe
;
2974 struct ieee80211_hdr
*pwlanhdr
;
2977 unsigned short val16
;
2978 int use_shared_key
= 0;
2979 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
2980 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2981 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
2983 if ((pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
)) == NULL
)
2986 /* update attribute */
2987 pattrib
= &pmgntframe
->attrib
;
2988 update_mgntframe_attrib23a(padapter
, pattrib
);
2990 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
2992 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
2993 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
2995 fctrl
= &pwlanhdr
->frame_control
;
2998 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
2999 pmlmeext
->mgnt_seq
++;
3000 SetFrameSubType(pframe
, WIFI_AUTH
);
3002 pframe
+= sizeof(struct ieee80211_hdr_3addr
);
3003 pattrib
->pktlen
= sizeof(struct ieee80211_hdr_3addr
);
3005 if (psta
) { /* for AP mode */
3006 #ifdef CONFIG_8723AU_AP_MODE
3008 ether_addr_copy(pwlanhdr
->addr1
, psta
->hwaddr
);
3009 ether_addr_copy(pwlanhdr
->addr2
, myid(&padapter
->eeprompriv
));
3010 ether_addr_copy(pwlanhdr
->addr3
, myid(&padapter
->eeprompriv
));
3012 /* setting auth algo number */
3013 val16
= (u16
)psta
->authalg
;
3015 if (status
!= WLAN_STATUS_SUCCESS
)
3019 val16
= cpu_to_le16(val16
);
3023 pframe
= rtw_set_fixed_ie23a(pframe
, _AUTH_ALGM_NUM_
,
3024 (unsigned char *)&val16
,
3027 /* setting auth seq number */
3028 val16
= (u16
)psta
->auth_seq
;
3029 val16
= cpu_to_le16(val16
);
3030 pframe
= rtw_set_fixed_ie23a(pframe
, _AUTH_SEQ_NUM_
,
3031 (unsigned char *)&val16
,
3034 /* setting status code... */
3036 val16
= cpu_to_le16(val16
);
3037 pframe
= rtw_set_fixed_ie23a(pframe
, _STATUS_CODE_
,
3038 (unsigned char *)&val16
,
3041 /* added challenging text... */
3042 if ((psta
->auth_seq
== 2) &&
3043 (psta
->state
& WIFI_FW_AUTH_STATE
) && (use_shared_key
== 1))
3044 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_CHALLENGE
, 128,
3045 psta
->chg_txt
, &pattrib
->pktlen
);
3048 ether_addr_copy(pwlanhdr
->addr1
,
3049 get_my_bssid23a(&pmlmeinfo
->network
));
3050 ether_addr_copy(pwlanhdr
->addr2
, myid(&padapter
->eeprompriv
));
3051 ether_addr_copy(pwlanhdr
->addr3
,
3052 get_my_bssid23a(&pmlmeinfo
->network
));
3054 /* setting auth algo number */
3055 /* 0:OPEN System, 1:Shared key */
3056 val16
= (pmlmeinfo
->auth_algo
== dot11AuthAlgrthm_Shared
)? 1: 0;
3058 val16
= cpu_to_le16(val16
);
3061 /* DBG_8723A("%s auth_algo = %s auth_seq =%d\n", __func__,
3062 (pmlmeinfo->auth_algo == 0)?"OPEN":"SHARED",
3063 pmlmeinfo->auth_seq); */
3065 /* setting IV for auth seq #3 */
3066 if ((pmlmeinfo
->auth_seq
== 3) &&
3067 (pmlmeinfo
->state
& WIFI_FW_AUTH_STATE
) &&
3068 (use_shared_key
== 1)) {
3069 /* DBG_8723A("==> iv(%d), key_index(%d)\n",
3070 pmlmeinfo->iv, pmlmeinfo->key_index); */
3071 val32
= ((pmlmeinfo
->iv
++) |
3072 (pmlmeinfo
->key_index
<< 30));
3073 val32
= cpu_to_le32(val32
);
3074 pframe
= rtw_set_fixed_ie23a(pframe
, 4,
3075 (unsigned char *)&val32
,
3078 pattrib
->iv_len
= 4;
3081 pframe
= rtw_set_fixed_ie23a(pframe
, _AUTH_ALGM_NUM_
,
3082 (unsigned char *)&val16
,
3085 /* setting auth seq number */
3086 val16
= pmlmeinfo
->auth_seq
;
3087 val16
= cpu_to_le16(val16
);
3088 pframe
= rtw_set_fixed_ie23a(pframe
, _AUTH_SEQ_NUM_
,
3089 (unsigned char *)&val16
,
3092 /* setting status code... */
3094 val16
= cpu_to_le16(val16
);
3095 pframe
= rtw_set_fixed_ie23a(pframe
, _STATUS_CODE_
,
3096 (unsigned char *)&val16
,
3099 /* then checking to see if sending challenging text... */
3100 if ((pmlmeinfo
->auth_seq
== 3) &&
3101 (pmlmeinfo
->state
& WIFI_FW_AUTH_STATE
) &&
3102 (use_shared_key
== 1)) {
3103 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_CHALLENGE
, 128,
3109 pattrib
->hdrlen
= sizeof(struct ieee80211_hdr_3addr
);
3111 pattrib
->encrypt
= _WEP40_
;
3113 pattrib
->icv_len
= 4;
3115 pattrib
->pktlen
+= pattrib
->icv_len
;
3119 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
3121 rtw_wep_encrypt23a(padapter
, pmgntframe
);
3122 DBG_8723A("%s\n", __func__
);
3123 dump_mgntframe23a(padapter
, pmgntframe
);
3128 void issue_asocrsp23a(struct rtw_adapter
*padapter
, unsigned short status
,
3129 struct sta_info
*pstat
, int pkt_type
)
3131 #ifdef CONFIG_8723AU_AP_MODE
3132 struct xmit_frame
*pmgntframe
;
3133 struct ieee80211_hdr
*pwlanhdr
;
3134 struct pkt_attrib
*pattrib
;
3135 unsigned char *pframe
;
3137 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
3138 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
3139 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3140 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
3141 struct wlan_bssid_ex
*pnetwork
= &pmlmeinfo
->network
;
3143 u8
*ie
= pnetwork
->IEs
;
3145 DBG_8723A("%s\n", __func__
);
3147 pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
);
3151 /* update attribute */
3152 pattrib
= &pmgntframe
->attrib
;
3153 update_mgntframe_attrib23a(padapter
, pattrib
);
3155 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
3157 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
3158 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
3160 pwlanhdr
->frame_control
= 0;
3162 ether_addr_copy(pwlanhdr
->addr1
, pstat
->hwaddr
);
3163 ether_addr_copy(pwlanhdr
->addr2
, myid(&padapter
->eeprompriv
));
3164 ether_addr_copy(pwlanhdr
->addr3
, get_my_bssid23a(&pmlmeinfo
->network
));
3166 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
3167 pmlmeext
->mgnt_seq
++;
3168 if (pkt_type
== WIFI_ASSOCRSP
|| pkt_type
== WIFI_REASSOCRSP
)
3169 SetFrameSubType(pwlanhdr
, pkt_type
);
3173 pattrib
->hdrlen
= sizeof(struct ieee80211_hdr_3addr
);
3174 pattrib
->pktlen
+= pattrib
->hdrlen
;
3175 pframe
+= pattrib
->hdrlen
;
3178 val
= *(unsigned short *)rtw_get_capability23a_from_ie(ie
);
3180 pframe
= rtw_set_fixed_ie23a(pframe
, _CAPABILITY_
,
3181 (unsigned char *)&val
, &pattrib
->pktlen
);
3183 status
= cpu_to_le16(status
);
3184 pframe
= rtw_set_fixed_ie23a(pframe
, _STATUS_CODE_
,
3185 (unsigned char *)&status
,
3188 val
= cpu_to_le16(pstat
->aid
| BIT(14) | BIT(15));
3189 pframe
= rtw_set_fixed_ie23a(pframe
, _ASOC_ID_
, (unsigned char *)&val
,
3192 if (pstat
->bssratelen
<= 8) {
3193 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SUPP_RATES
,
3194 pstat
->bssratelen
, pstat
->bssrateset
,
3197 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SUPP_RATES
, 8,
3198 pstat
->bssrateset
, &pattrib
->pktlen
);
3199 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_EXT_SUPP_RATES
,
3200 pstat
->bssratelen
- 8,
3201 pstat
->bssrateset
+ 8, &pattrib
->pktlen
);
3204 if (pstat
->flags
& WLAN_STA_HT
&& pmlmepriv
->htpriv
.ht_option
) {
3205 /* FILL HT CAP INFO IE */
3206 /* p = hostapd_eid_ht_capabilities_info(hapd, p); */
3207 p
= cfg80211_find_ie(WLAN_EID_HT_CAPABILITY
,
3208 ie
+ _BEACON_IE_OFFSET_
,
3209 pnetwork
->IELength
-_BEACON_IE_OFFSET_
);
3211 memcpy(pframe
, p
, p
[1] + 2);
3212 pframe
+= (p
[1] + 2);
3213 pattrib
->pktlen
+= (p
[1] + 2);
3216 /* FILL HT ADD INFO IE */
3217 /* p = hostapd_eid_ht_operation(hapd, p); */
3218 p
= cfg80211_find_ie(WLAN_EID_HT_OPERATION
,
3219 ie
+ _BEACON_IE_OFFSET_
,
3220 pnetwork
->IELength
- _BEACON_IE_OFFSET_
);
3221 if (p
&& p
[1] > 0) {
3222 memcpy(pframe
, p
, p
[1] + 2);
3223 pframe
+= (p
[1] + 2);
3224 pattrib
->pktlen
+= (p
[1] + 2);
3229 if (pstat
->flags
& WLAN_STA_WME
&& pmlmepriv
->qos_option
) {
3230 unsigned char WMM_PARA_IE
[] = {0x00, 0x50, 0xf2, 0x02,
3234 for (p
= ie
+ _BEACON_IE_OFFSET_
; ; p
+= (ie_len
+ 2)) {
3235 p
= cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC
, p
,
3236 pnetwork
->IELength
-
3237 _BEACON_IE_OFFSET_
- (ie_len
+ 2));
3242 if (p
&& !memcmp(p
+ 2, WMM_PARA_IE
, 6)) {
3243 memcpy(pframe
, p
, ie_len
+ 2);
3244 pframe
+= (ie_len
+ 2);
3245 pattrib
->pktlen
+= (ie_len
+ 2);
3250 if (!p
|| ie_len
== 0)
3255 if (pmlmeinfo
->assoc_AP_vendor
== HT_IOT_PEER_REALTEK
) {
3256 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_VENDOR_SPECIFIC
, 6,
3257 REALTEK_96B_IE23A
, &pattrib
->pktlen
);
3260 /* add WPS IE ie for wps 2.0 */
3261 if (pmlmepriv
->wps_assoc_resp_ie
&&
3262 pmlmepriv
->wps_assoc_resp_ie_len
> 0) {
3263 memcpy(pframe
, pmlmepriv
->wps_assoc_resp_ie
,
3264 pmlmepriv
->wps_assoc_resp_ie_len
);
3266 pframe
+= pmlmepriv
->wps_assoc_resp_ie_len
;
3267 pattrib
->pktlen
+= pmlmepriv
->wps_assoc_resp_ie_len
;
3270 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
3272 dump_mgntframe23a(padapter
, pmgntframe
);
3276 void issue_assocreq23a(struct rtw_adapter
*padapter
)
3279 struct xmit_frame
*pmgntframe
;
3280 struct pkt_attrib
*pattrib
;
3281 unsigned char *pframe
;
3283 struct ieee80211_hdr
*pwlanhdr
;
3285 unsigned int i
, j
, index
= 0;
3286 unsigned char rf_type
, bssrate
[NumRates
], sta_bssrate
[NumRates
];
3287 struct ndis_802_11_var_ies
*pIE
;
3288 struct registry_priv
*pregpriv
= &padapter
->registrypriv
;
3289 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
3290 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
3291 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3292 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
3293 int bssrate_len
= 0, sta_bssrate_len
= 0, pie_len
;
3296 pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
);
3300 /* update attribute */
3301 pattrib
= &pmgntframe
->attrib
;
3302 update_mgntframe_attrib23a(padapter
, pattrib
);
3304 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
3306 pframe
= (u8
*)pmgntframe
->buf_addr
+ TXDESC_OFFSET
;
3307 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
3309 fctrl
= &pwlanhdr
->frame_control
;
3311 ether_addr_copy(pwlanhdr
->addr1
, get_my_bssid23a(&pmlmeinfo
->network
));
3312 ether_addr_copy(pwlanhdr
->addr2
, myid(&padapter
->eeprompriv
));
3313 ether_addr_copy(pwlanhdr
->addr3
, get_my_bssid23a(&pmlmeinfo
->network
));
3315 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
3316 pmlmeext
->mgnt_seq
++;
3317 SetFrameSubType(pframe
, WIFI_ASSOCREQ
);
3319 pframe
+= sizeof(struct ieee80211_hdr_3addr
);
3320 pattrib
->pktlen
= sizeof(struct ieee80211_hdr_3addr
);
3324 rtw_get_capability23a_from_ie(pmlmeinfo
->network
.IEs
), 2);
3327 pattrib
->pktlen
+= 2;
3329 /* listen interval */
3330 /* todo: listen interval for power saving */
3331 put_unaligned_le16(3, pframe
);
3333 pattrib
->pktlen
+= 2;
3336 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SSID
,
3337 pmlmeinfo
->network
.Ssid
.ssid_len
,
3338 pmlmeinfo
->network
.Ssid
.ssid
, &pattrib
->pktlen
);
3340 /* supported rate & extended supported rate */
3342 get_rate_set23a(padapter
, sta_bssrate
, &sta_bssrate_len
);
3343 /* DBG_8723A("sta_bssrate_len =%d\n", sta_bssrate_len); */
3345 /* for JAPAN, channel 14 can only uses B Mode(CCK) */
3346 if (pmlmeext
->cur_channel
== 14)
3347 sta_bssrate_len
= 4;
3349 /* for (i = 0; i < sta_bssrate_len; i++) { */
3350 /* DBG_8723A("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
3353 for (i
= 0; i
< NDIS_802_11_LENGTH_RATES_EX
; i
++) {
3354 if (pmlmeinfo
->network
.SupportedRates
[i
] == 0)
3356 DBG_8723A("network.SupportedRates[%d]=%02X\n", i
,
3357 pmlmeinfo
->network
.SupportedRates
[i
]);
3360 for (i
= 0; i
< NDIS_802_11_LENGTH_RATES_EX
; i
++) {
3361 if (pmlmeinfo
->network
.SupportedRates
[i
] == 0)
3364 /* Check if the AP's supported rates are also
3365 supported by STA. */
3366 for (j
= 0; j
< sta_bssrate_len
; j
++) {
3367 /* Avoid the proprietary data rate (22Mbps) of
3368 Handlink WSG-4000 AP */
3369 if ((pmlmeinfo
->network
.SupportedRates
[i
] |
3370 IEEE80211_BASIC_RATE_MASK
) ==
3371 (sta_bssrate
[j
] | IEEE80211_BASIC_RATE_MASK
)) {
3372 /* DBG_8723A("match i = %d, j =%d\n", i, j); */
3377 if (j
== sta_bssrate_len
) {
3378 /* the rate is not supported by STA */
3379 DBG_8723A("%s(): the rate[%d]=%02X is not supported by "
3380 "STA!\n", __func__
, i
,
3381 pmlmeinfo
->network
.SupportedRates
[i
]);
3383 /* the rate is supported by STA */
3384 bssrate
[index
++] = pmlmeinfo
->network
.SupportedRates
[i
];
3388 bssrate_len
= index
;
3389 DBG_8723A("bssrate_len = %d\n", bssrate_len
);
3391 if (bssrate_len
== 0) {
3392 rtw_free_xmitbuf23a(pxmitpriv
, pmgntframe
->pxmitbuf
);
3393 rtw_free_xmitframe23a(pxmitpriv
, pmgntframe
);
3394 goto exit
; /* don't connect to AP if no joint supported rate */
3397 if (bssrate_len
> 8) {
3398 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SUPP_RATES
, 8,
3399 bssrate
, &pattrib
->pktlen
);
3400 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_EXT_SUPP_RATES
,
3401 (bssrate_len
- 8), (bssrate
+ 8),
3404 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SUPP_RATES
,
3405 bssrate_len
, bssrate
, &pattrib
->pktlen
);
3408 pie
= pmlmeinfo
->network
.IEs
+ sizeof(struct ndis_802_11_fixed_ies
);
3409 pie_len
= pmlmeinfo
->network
.IELength
-
3410 sizeof(struct ndis_802_11_fixed_ies
);
3412 p
= cfg80211_find_ie(WLAN_EID_RSN
, pie
, pie_len
);
3414 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_RSN
, p
[1], p
+ 2,
3418 if (padapter
->mlmepriv
.htpriv
.ht_option
== true) {
3419 p
= cfg80211_find_ie(WLAN_EID_HT_CAPABILITY
, pie
, pie_len
);
3421 if (p
&& !is_ap_in_tkip23a(padapter
)) {
3422 memcpy(&pmlmeinfo
->HT_caps
, p
+ 2,
3423 sizeof(struct HT_caps_element
));
3425 /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
3426 if (pregpriv
->cbw40_enable
== 0) {
3427 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
&= (~(BIT(6) | BIT(1)));
3429 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
|= BIT(1);
3432 /* todo: disable SM power save mode */
3433 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
|=
3436 rf_type
= rtl8723a_get_rf_type(padapter
);
3437 /* switch (pregpriv->rf_config) */
3440 /* RX STBC One spatial stream */
3441 if (pregpriv
->rx_stbc
)
3442 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
|= cpu_to_le16(0x0100);
3444 memcpy(pmlmeinfo
->HT_caps
.u
.HT_cap_element
.MCS_rate
, MCS_rate_1R23A
, 16);
3450 /* enable for 2.4/5 GHz */
3451 if (pregpriv
->rx_stbc
== 0x3 ||
3452 (pmlmeext
->cur_wireless_mode
&
3454 /* enable for 2.4GHz */
3455 pregpriv
->rx_stbc
== 0x1) ||
3456 (pmlmeext
->cur_wireless_mode
&
3458 pregpriv
->rx_stbc
== 0x2) ||
3459 /* enable for 5GHz */
3460 pregpriv
->wifi_spec
== 1) {
3461 DBG_8723A("declare supporting RX "
3463 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
|= cpu_to_le16(0x0200);/* RX STBC two spatial stream */
3465 memcpy(pmlmeinfo
->HT_caps
.u
.HT_cap_element
.MCS_rate
, MCS_rate_2R23A
, 16);
3468 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
=
3469 cpu_to_le16(pmlmeinfo
->HT_caps
.u
.HT_cap_element
.HT_caps_info
);
3471 #ifdef CONFIG_8723AU_BT_COEXIST
3472 if (BT_1Ant(padapter
) == true) {
3474 pmlmeinfo
->HT_caps
.u
.HT_cap_element
.AMPDU_para
&= (u8
)~IEEE80211_HT_AMPDU_PARM_FACTOR
;
3475 /* pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para |= MAX_AMPDU_FACTOR_8K */
3479 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_HT_CAPABILITY
,
3480 p
[1], (u8
*)&pmlmeinfo
->HT_caps
,
3485 /* vendor specific IE, such as WPA, WMM, WPS */
3486 for (i
= sizeof(struct ndis_802_11_fixed_ies
);
3487 i
< pmlmeinfo
->network
.IELength
;) {
3488 pIE
= (struct ndis_802_11_var_ies
*)
3489 (pmlmeinfo
->network
.IEs
+ i
);
3491 switch (pIE
->ElementID
)
3493 case WLAN_EID_VENDOR_SPECIFIC
:
3494 if (!memcmp(pIE
->data
, RTW_WPA_OUI23A_TYPE
, 4) ||
3495 !memcmp(pIE
->data
, WMM_OUI23A
, 4) ||
3496 !memcmp(pIE
->data
, WPS_OUI23A
, 4)) {
3497 if (!padapter
->registrypriv
.wifi_spec
) {
3498 /* Commented by Kurt 20110629 */
3499 /* In some older APs, WPS handshake */
3500 /* would be fail if we append vender
3501 extensions informations to AP */
3502 if (!memcmp(pIE
->data
, WPS_OUI23A
, 4))
3505 pframe
= rtw_set_ie23a(pframe
,
3506 WLAN_EID_VENDOR_SPECIFIC
,
3507 pIE
->Length
, pIE
->data
,
3516 i
+= pIE
->Length
+ 2;
3519 if (pmlmeinfo
->assoc_AP_vendor
== HT_IOT_PEER_REALTEK
)
3520 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_VENDOR_SPECIFIC
, 6,
3521 REALTEK_96B_IE23A
, &pattrib
->pktlen
);
3523 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
3524 dump_mgntframe23a(padapter
, pmgntframe
);
3529 pmlmepriv
->assoc_req_len
= 0;
3530 if (ret
== _SUCCESS
) {
3531 kfree(pmlmepriv
->assoc_req
);
3532 pmlmepriv
->assoc_req
= kmalloc(pattrib
->pktlen
, GFP_ATOMIC
);
3533 if (pmlmepriv
->assoc_req
) {
3534 memcpy(pmlmepriv
->assoc_req
, pwlanhdr
, pattrib
->pktlen
);
3535 pmlmepriv
->assoc_req_len
= pattrib
->pktlen
;
3538 kfree(pmlmepriv
->assoc_req
);
3543 /* when wait_ack is ture, this function shoule be called at process context */
3544 static int _issue_nulldata23a(struct rtw_adapter
*padapter
, unsigned char *da
,
3545 unsigned int power_mode
, int wait_ack
)
3548 struct xmit_frame
*pmgntframe
;
3549 struct pkt_attrib
*pattrib
;
3550 unsigned char *pframe
;
3551 struct ieee80211_hdr
*pwlanhdr
;
3553 struct xmit_priv
*pxmitpriv
;
3554 struct mlme_ext_priv
*pmlmeext
;
3555 struct mlme_ext_info
*pmlmeinfo
;
3557 /* DBG_8723A("%s:%d\n", __func__, power_mode); */
3562 pxmitpriv
= &padapter
->xmitpriv
;
3563 pmlmeext
= &padapter
->mlmeextpriv
;
3564 pmlmeinfo
= &pmlmeext
->mlmext_info
;
3566 if ((pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
)) == NULL
)
3569 /* update attribute */
3570 pattrib
= &pmgntframe
->attrib
;
3571 update_mgntframe_attrib23a(padapter
, pattrib
);
3572 pattrib
->retry_ctrl
= false;
3574 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
3576 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
3577 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
3579 fctrl
= &pwlanhdr
->frame_control
;
3582 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_AP_STATE
)
3584 else if ((pmlmeinfo
->state
&0x03) == WIFI_FW_STATION_STATE
)
3590 ether_addr_copy(pwlanhdr
->addr1
, da
);
3591 ether_addr_copy(pwlanhdr
->addr2
, myid(&padapter
->eeprompriv
));
3592 ether_addr_copy(pwlanhdr
->addr3
, get_my_bssid23a(&pmlmeinfo
->network
));
3594 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
3595 pmlmeext
->mgnt_seq
++;
3596 SetFrameSubType(pframe
, WIFI_DATA_NULL
);
3598 pframe
+= sizeof(struct ieee80211_hdr_3addr
);
3599 pattrib
->pktlen
= sizeof(struct ieee80211_hdr_3addr
);
3601 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
3604 ret
= dump_mgntframe23a_and_wait_ack23a(padapter
, pmgntframe
);
3606 dump_mgntframe23a(padapter
, pmgntframe
);
3614 /* when wait_ms >0 , this function shoule be called at process context */
3615 /* da == NULL for station mode */
3616 int issue_nulldata23a(struct rtw_adapter
*padapter
, unsigned char *da
,
3617 unsigned int power_mode
, int try_cnt
, int wait_ms
)
3621 unsigned long start
= jiffies
;
3622 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3623 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
3625 /* da == NULL, assum it's null data for sta to ap*/
3627 da
= get_my_bssid23a(&pmlmeinfo
->network
);
3630 ret
= _issue_nulldata23a(padapter
, da
, power_mode
,
3631 wait_ms
> 0 ? true : false);
3635 if (padapter
->bDriverStopped
|| padapter
->bSurpriseRemoved
)
3638 if (i
< try_cnt
&& wait_ms
> 0 && ret
== _FAIL
)
3641 } while((i
< try_cnt
) && ((ret
== _FAIL
) || (wait_ms
== 0)));
3648 if (try_cnt
&& wait_ms
) {
3650 DBG_8723A("%s(%s): to "MAC_FMT
", ch:%u%s, %d/%d "
3651 "in %u ms\n", __func__
,
3652 padapter
->pnetdev
->name
,
3653 MAC_ARG(da
), rtw_get_oper_ch23a(padapter
),
3654 ret
== _SUCCESS
?", acked":"", i
, try_cnt
,
3655 jiffies_to_msecs(jiffies
- start
));
3657 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3658 __func__
, padapter
->pnetdev
->name
,
3659 rtw_get_oper_ch23a(padapter
),
3660 ret
== _SUCCESS
?", acked":"", i
, try_cnt
,
3661 jiffies_to_msecs(jiffies
- start
));
3667 /* when wait_ack is ture, this function shoule be called at process context */
3668 static int _issue_qos_nulldata23a(struct rtw_adapter
*padapter
,
3669 unsigned char *da
, u16 tid
, int wait_ack
)
3672 struct xmit_frame
*pmgntframe
;
3673 struct pkt_attrib
*pattrib
;
3674 unsigned char *pframe
;
3675 struct ieee80211_hdr
*pwlanhdr
;
3678 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
3679 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3680 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
3682 DBG_8723A("%s\n", __func__
);
3684 if ((pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
)) == NULL
)
3687 /* update attribute */
3688 pattrib
= &pmgntframe
->attrib
;
3689 update_mgntframe_attrib23a(padapter
, pattrib
);
3691 pattrib
->hdrlen
+= 2;
3692 pattrib
->qos_en
= true;
3694 pattrib
->ack_policy
= 0;
3697 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
3699 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
3700 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
3702 fctrl
= &pwlanhdr
->frame_control
;
3705 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_AP_STATE
)
3707 else if ((pmlmeinfo
->state
&0x03) == WIFI_FW_STATION_STATE
)
3713 qc
= (unsigned short *)(pframe
+ pattrib
->hdrlen
- 2);
3715 SetPriority(qc
, tid
);
3717 SetEOSP(qc
, pattrib
->eosp
);
3719 SetAckpolicy(qc
, pattrib
->ack_policy
);
3721 ether_addr_copy(pwlanhdr
->addr1
, da
);
3722 ether_addr_copy(pwlanhdr
->addr2
, myid(&padapter
->eeprompriv
));
3723 ether_addr_copy(pwlanhdr
->addr3
, get_my_bssid23a(&pmlmeinfo
->network
));
3725 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
3726 pmlmeext
->mgnt_seq
++;
3727 SetFrameSubType(pframe
, WIFI_QOS_DATA_NULL
);
3729 pframe
+= sizeof(struct ieee80211_qos_hdr
);
3730 pattrib
->pktlen
= sizeof(struct ieee80211_qos_hdr
);
3732 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
3735 ret
= dump_mgntframe23a_and_wait_ack23a(padapter
, pmgntframe
);
3737 dump_mgntframe23a(padapter
, pmgntframe
);
3745 /* when wait_ms >0 , this function shoule be called at process context */
3746 /* da == NULL for station mode */
3747 int issue_qos_nulldata23a(struct rtw_adapter
*padapter
, unsigned char *da
,
3748 u16 tid
, int try_cnt
, int wait_ms
)
3752 unsigned long start
= jiffies
;
3753 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3754 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
3756 /* da == NULL, assum it's null data for sta to ap*/
3758 da
= get_my_bssid23a(&pmlmeinfo
->network
);
3761 ret
= _issue_qos_nulldata23a(padapter
, da
, tid
,
3762 wait_ms
> 0 ? true : false);
3766 if (padapter
->bDriverStopped
|| padapter
->bSurpriseRemoved
)
3769 if (i
< try_cnt
&& wait_ms
> 0 && ret
== _FAIL
)
3771 } while((i
< try_cnt
) && ((ret
== _FAIL
)||(wait_ms
== 0)));
3778 if (try_cnt
&& wait_ms
) {
3780 DBG_8723A("%s(%s): to "MAC_FMT
", ch:%u%s, %d/%d "
3781 "in %u ms\n", __func__
,
3782 padapter
->pnetdev
->name
,
3783 MAC_ARG(da
), rtw_get_oper_ch23a(padapter
),
3784 ret
== _SUCCESS
?", acked":"", i
, try_cnt
,
3785 jiffies_to_msecs(jiffies
- start
));
3787 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3788 __func__
, padapter
->pnetdev
->name
,
3789 rtw_get_oper_ch23a(padapter
),
3790 ret
== _SUCCESS
?", acked":"", i
, try_cnt
,
3791 jiffies_to_msecs(jiffies
- start
));
3797 static int _issue_deauth23a(struct rtw_adapter
*padapter
, unsigned char *da
,
3798 unsigned short reason
, u8 wait_ack
)
3800 struct xmit_frame
*pmgntframe
;
3801 struct pkt_attrib
*pattrib
;
3802 unsigned char *pframe
;
3803 struct ieee80211_hdr
*pwlanhdr
;
3805 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
3806 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3807 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
3810 /* DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
3812 if ((pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
)) == NULL
)
3815 /* update attribute */
3816 pattrib
= &pmgntframe
->attrib
;
3817 update_mgntframe_attrib23a(padapter
, pattrib
);
3818 pattrib
->retry_ctrl
= false;
3820 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
3822 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
3823 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
3825 fctrl
= &pwlanhdr
->frame_control
;
3828 ether_addr_copy(pwlanhdr
->addr1
, da
);
3829 ether_addr_copy(pwlanhdr
->addr2
, myid(&padapter
->eeprompriv
));
3830 ether_addr_copy(pwlanhdr
->addr3
, get_my_bssid23a(&pmlmeinfo
->network
));
3832 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
3833 pmlmeext
->mgnt_seq
++;
3834 SetFrameSubType(pframe
, WIFI_DEAUTH
);
3836 pframe
+= sizeof(struct ieee80211_hdr_3addr
);
3837 pattrib
->pktlen
= sizeof(struct ieee80211_hdr_3addr
);
3839 reason
= cpu_to_le16(reason
);
3840 pframe
= rtw_set_fixed_ie23a(pframe
, WLAN_REASON_PREV_AUTH_NOT_VALID
,
3841 (unsigned char *)&reason
,
3844 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
3847 ret
= dump_mgntframe23a_and_wait_ack23a(padapter
, pmgntframe
);
3849 dump_mgntframe23a(padapter
, pmgntframe
);
3857 int issue_deauth23a(struct rtw_adapter
*padapter
, unsigned char *da
,
3858 unsigned short reason
)
3860 DBG_8723A("%s to "MAC_FMT
"\n", __func__
, MAC_ARG(da
));
3861 return _issue_deauth23a(padapter
, da
, reason
, false);
3864 int issue_deauth23a_ex23a(struct rtw_adapter
*padapter
, u8
*da
,
3865 unsigned short reason
, int try_cnt
, int wait_ms
)
3869 unsigned long start
= jiffies
;
3872 ret
= _issue_deauth23a(padapter
, da
, reason
,
3873 wait_ms
>0 ? true : false);
3877 if (padapter
->bDriverStopped
|| padapter
->bSurpriseRemoved
)
3880 if (i
< try_cnt
&& wait_ms
> 0 && ret
== _FAIL
)
3883 } while((i
< try_cnt
) && ((ret
== _FAIL
)||(wait_ms
== 0)));
3890 if (try_cnt
&& wait_ms
) {
3892 DBG_8723A("%s(%s): to "MAC_FMT
", ch:%u%s, %d/%d "
3893 "in %u ms\n", __func__
,
3894 padapter
->pnetdev
->name
,
3895 MAC_ARG(da
), rtw_get_oper_ch23a(padapter
),
3896 ret
== _SUCCESS
?", acked":"", i
, try_cnt
,
3897 jiffies_to_msecs(jiffies
- start
));
3899 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3900 __func__
, padapter
->pnetdev
->name
,
3901 rtw_get_oper_ch23a(padapter
),
3902 ret
== _SUCCESS
?", acked":"", i
, try_cnt
,
3903 jiffies_to_msecs(jiffies
- start
));
3909 void issue_action_spct_ch_switch23a(struct rtw_adapter
*padapter
,
3910 u8
*ra
, u8 new_ch
, u8 ch_offset
)
3912 struct xmit_frame
*pmgntframe
;
3913 struct pkt_attrib
*pattrib
;
3914 unsigned char *pframe
;
3915 struct ieee80211_hdr
*pwlanhdr
;
3917 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
3918 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3919 u8 category
, action
;
3921 DBG_8723A(FUNC_NDEV_FMT
" ra ="MAC_FMT
", ch:%u, offset:%u\n",
3922 FUNC_NDEV_ARG(padapter
->pnetdev
), MAC_ARG(ra
),
3925 if ((pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
)) == NULL
)
3928 /* update attribute */
3929 pattrib
= &pmgntframe
->attrib
;
3930 update_mgntframe_attrib23a(padapter
, pattrib
);
3932 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
3934 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
3935 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
3937 fctrl
= &pwlanhdr
->frame_control
;
3940 ether_addr_copy(pwlanhdr
->addr1
, ra
); /* RA */
3941 ether_addr_copy(pwlanhdr
->addr2
, myid(&padapter
->eeprompriv
)); /* TA */
3942 ether_addr_copy(pwlanhdr
->addr3
, ra
); /* DA = RA */
3944 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
3945 pmlmeext
->mgnt_seq
++;
3946 SetFrameSubType(pframe
, WIFI_ACTION
);
3948 pframe
+= sizeof(struct ieee80211_hdr_3addr
);
3949 pattrib
->pktlen
= sizeof(struct ieee80211_hdr_3addr
);
3951 /* category, action */
3952 category
= WLAN_CATEGORY_SPECTRUM_MGMT
;
3953 action
= WLAN_ACTION_SPCT_CHL_SWITCH
;
3955 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &category
, &pattrib
->pktlen
);
3956 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &action
, &pattrib
->pktlen
);
3958 pframe
= rtw_set_ie23a_ch_switch (pframe
, &pattrib
->pktlen
, 0,
3960 pframe
= rtw_set_ie23a_secondary_ch_offset(pframe
, &pattrib
->pktlen
,
3961 hal_ch_offset_to_secondary_ch_offset23a(ch_offset
));
3963 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
3965 dump_mgntframe23a(padapter
, pmgntframe
);
3968 void issue_action_BA23a(struct rtw_adapter
*padapter
,
3969 const unsigned char *raddr
,
3970 unsigned char action
, unsigned short status
)
3972 u8 category
= WLAN_CATEGORY_BACK
;
3976 u16 BA_timeout_value
;
3977 u16 BA_starting_seqctrl
;
3978 int max_rx_ampdu_factor
;
3979 struct xmit_frame
*pmgntframe
;
3980 struct pkt_attrib
*pattrib
;
3982 struct ieee80211_hdr
*pwlanhdr
;
3984 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
3985 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3986 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
3987 struct sta_info
*psta
;
3988 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
3989 struct registry_priv
*pregpriv
= &padapter
->registrypriv
;
3990 #ifdef CONFIG_8723AU_BT_COEXIST
3991 u8 tendaAPMac
[] = {0xC8, 0x3A, 0x35};
3994 DBG_8723A("%s, category =%d, action =%d, status =%d\n",
3995 __func__
, category
, action
, status
);
3997 if ((pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
)) == NULL
)
4000 /* update attribute */
4001 pattrib
= &pmgntframe
->attrib
;
4002 update_mgntframe_attrib23a(padapter
, pattrib
);
4004 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
4006 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
4007 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
4009 fctrl
= &pwlanhdr
->frame_control
;
4012 /* memcpy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN); */
4013 ether_addr_copy(pwlanhdr
->addr1
, raddr
);
4014 ether_addr_copy(pwlanhdr
->addr2
, myid(&padapter
->eeprompriv
));
4015 ether_addr_copy(pwlanhdr
->addr3
, get_my_bssid23a(&pmlmeinfo
->network
));
4017 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
4018 pmlmeext
->mgnt_seq
++;
4019 SetFrameSubType(pframe
, WIFI_ACTION
);
4021 pframe
+= sizeof(struct ieee80211_hdr_3addr
);
4022 pattrib
->pktlen
= sizeof(struct ieee80211_hdr_3addr
);
4024 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &category
, &pattrib
->pktlen
);
4025 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &action
, &pattrib
->pktlen
);
4027 status
= cpu_to_le16(status
);
4034 case 0: /* ADDBA req */
4036 pmlmeinfo
->dialogToken
++;
4037 } while (pmlmeinfo
->dialogToken
== 0);
4038 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &pmlmeinfo
->dialogToken
,
4041 #ifdef CONFIG_8723AU_BT_COEXIST
4042 if ((BT_1Ant(padapter
) == true) &&
4043 ((pmlmeinfo
->assoc_AP_vendor
!= broadcomAP
) ||
4044 memcmp(raddr
, tendaAPMac
, 3))) {
4045 /* A-MSDU NOT Supported */
4047 /* immediate Block Ack */
4048 BA_para_set
|= (1 << 1) &
4049 IEEE80211_ADDBA_PARAM_POLICY_MASK
;
4051 BA_para_set
|= (status
<< 2) &
4052 IEEE80211_ADDBA_PARAM_TID_MASK
;
4053 /* max buffer size is 8 MSDU */
4054 BA_para_set
|= (8 << 6) &
4055 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK
;
4059 /* immediate ack & 64 buffer size */
4060 BA_para_set
= (0x1002 | ((status
& 0xf) << 2));
4062 BA_para_set
= cpu_to_le16(BA_para_set
);
4063 pframe
= rtw_set_fixed_ie23a(pframe
, 2,
4064 (unsigned char *)&BA_para_set
,
4067 BA_timeout_value
= 5000;/* 5ms */
4068 BA_timeout_value
= cpu_to_le16(BA_timeout_value
);
4069 pframe
= rtw_set_fixed_ie23a(pframe
, 2, (unsigned char *)
4073 /* if ((psta = rtw_get_stainfo23a(pstapriv,
4074 pmlmeinfo->network.MacAddress)) != NULL) */
4075 if ((psta
= rtw_get_stainfo23a(pstapriv
, raddr
))) {
4076 start_seq
= (psta
->sta_xmitpriv
.txseq_tid
[status
& 0x07]&0xfff) + 1;
4078 DBG_8723A("BA_starting_seqctrl = %d for TID =%d\n",
4079 start_seq
, status
& 0x07);
4081 psta
->BA_starting_seqctrl
[status
& 0x07] = start_seq
;
4083 BA_starting_seqctrl
= start_seq
<< 4;
4086 BA_starting_seqctrl
= cpu_to_le16(BA_starting_seqctrl
);
4087 pframe
= rtw_set_fixed_ie23a(pframe
, 2, (unsigned char *)&BA_starting_seqctrl
, &pattrib
->pktlen
);
4090 case 1: /* ADDBA rsp */
4091 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &pmlmeinfo
->ADDBA_req
.dialog_token
, &pattrib
->pktlen
);
4092 pframe
= rtw_set_fixed_ie23a(pframe
, 2,
4093 (unsigned char *)&status
,
4095 rtw_hal_get_def_var23a(padapter
, HW_VAR_MAX_RX_AMPDU_FACTOR
,
4096 &max_rx_ampdu_factor
);
4097 if (max_rx_ampdu_factor
== IEEE80211_HT_MAX_AMPDU_64K
)
4098 BA_para_set
= ((le16_to_cpu(pmlmeinfo
->ADDBA_req
.BA_para_set
) & 0x3f) | 0x1000); /* 64 buffer size */
4099 else if (max_rx_ampdu_factor
== IEEE80211_HT_MAX_AMPDU_32K
)
4100 BA_para_set
= ((le16_to_cpu(pmlmeinfo
->ADDBA_req
.BA_para_set
) & 0x3f) | 0x0800); /* 32 buffer size */
4101 else if (max_rx_ampdu_factor
== IEEE80211_HT_MAX_AMPDU_16K
)
4102 BA_para_set
= ((le16_to_cpu(pmlmeinfo
->ADDBA_req
.BA_para_set
) & 0x3f) | 0x0400); /* 16 buffer size */
4103 else if (max_rx_ampdu_factor
== IEEE80211_HT_MAX_AMPDU_8K
)
4104 BA_para_set
= ((le16_to_cpu(pmlmeinfo
->ADDBA_req
.BA_para_set
) & 0x3f) | 0x0200); /* 8 buffer size */
4106 BA_para_set
= ((le16_to_cpu(pmlmeinfo
->ADDBA_req
.BA_para_set
) & 0x3f) | 0x1000); /* 64 buffer size */
4108 #ifdef CONFIG_8723AU_BT_COEXIST
4109 if ((BT_1Ant(padapter
) == true) &&
4110 ((pmlmeinfo
->assoc_AP_vendor
!= broadcomAP
) ||
4111 memcmp(raddr
, tendaAPMac
, 3))) {
4112 /* max buffer size is 8 MSDU */
4113 BA_para_set
&= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK
;
4114 BA_para_set
|= (8 << 6) &
4115 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK
;
4119 if (pregpriv
->ampdu_amsdu
== 0)/* disabled */
4120 BA_para_set
= cpu_to_le16(BA_para_set
& ~BIT(0));
4121 else if (pregpriv
->ampdu_amsdu
== 1)/* enabled */
4122 BA_para_set
= cpu_to_le16(BA_para_set
| BIT(0));
4124 BA_para_set
= cpu_to_le16(BA_para_set
);
4126 pframe
= rtw_set_fixed_ie23a(pframe
, 2,
4127 (unsigned char *)&BA_para_set
,
4129 pframe
= rtw_set_fixed_ie23a(pframe
, 2, (unsigned char *)&pmlmeinfo
->ADDBA_req
.BA_timeout_value
, &pattrib
->pktlen
);
4132 BA_para_set
= (status
& 0x1F) << 3;
4133 BA_para_set
= cpu_to_le16(BA_para_set
);
4134 pframe
= rtw_set_fixed_ie23a(pframe
, 2,
4135 (unsigned char *)&BA_para_set
,
4138 reason_code
= 37;/* Requested from peer STA as it does not
4139 want to use the mechanism */
4140 reason_code
= cpu_to_le16(reason_code
);
4141 pframe
= rtw_set_fixed_ie23a(pframe
, 2,
4142 (unsigned char *)&reason_code
,
4150 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
4152 dump_mgntframe23a(padapter
, pmgntframe
);
4155 static void issue_action_BSSCoexistPacket(struct rtw_adapter
*padapter
)
4157 struct list_head
*plist
, *phead
, *ptmp
;
4158 unsigned char category
, action
;
4159 struct xmit_frame
*pmgntframe
;
4160 struct pkt_attrib
*pattrib
;
4162 struct ieee80211_hdr
*pwlanhdr
;
4164 struct wlan_network
*pnetwork
;
4165 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
4166 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
4167 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4168 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4169 struct rtw_queue
*queue
= &pmlmepriv
->scanned_queue
;
4170 u8 InfoContent
[16] = {0};
4174 if (pmlmepriv
->num_FortyMHzIntolerant
== 0 ||
4175 pmlmepriv
->num_sta_no_ht
== 0)
4178 if (pmlmeinfo
->bwmode_updated
)
4181 DBG_8723A("%s\n", __func__
);
4183 category
= WLAN_CATEGORY_PUBLIC
;
4184 action
= ACT_PUBLIC_BSSCOEXIST
;
4186 pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
);
4190 /* update attribute */
4191 pattrib
= &pmgntframe
->attrib
;
4192 update_mgntframe_attrib23a(padapter
, pattrib
);
4194 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
4196 pframe
= (u8
*)pmgntframe
->buf_addr
+ TXDESC_OFFSET
;
4197 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
4199 fctrl
= &pwlanhdr
->frame_control
;
4202 ether_addr_copy(pwlanhdr
->addr1
, get_my_bssid23a(&pmlmeinfo
->network
));
4203 ether_addr_copy(pwlanhdr
->addr2
, myid(&padapter
->eeprompriv
));
4204 ether_addr_copy(pwlanhdr
->addr3
, get_my_bssid23a(&pmlmeinfo
->network
));
4206 SetSeqNum(pwlanhdr
, pmlmeext
->mgnt_seq
);
4207 pmlmeext
->mgnt_seq
++;
4208 SetFrameSubType(pframe
, WIFI_ACTION
);
4210 pframe
+= sizeof(struct ieee80211_hdr_3addr
);
4211 pattrib
->pktlen
= sizeof(struct ieee80211_hdr_3addr
);
4213 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &category
, &pattrib
->pktlen
);
4214 pframe
= rtw_set_fixed_ie23a(pframe
, 1, &action
, &pattrib
->pktlen
);
4216 if (pmlmepriv
->num_FortyMHzIntolerant
> 0) {
4217 u8 iedata
= BIT(2);/* 20 MHz BSS Width Request */
4219 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_BSS_COEX_2040
, 1,
4220 &iedata
, &pattrib
->pktlen
);
4223 if (pmlmepriv
->num_sta_no_ht
<= 0)
4226 memset(ICS
, 0, sizeof(ICS
));
4228 spin_lock_bh(&pmlmepriv
->scanned_queue
.lock
);
4230 phead
= get_list_head(queue
);
4231 plist
= phead
->next
;
4233 list_for_each_safe(plist
, ptmp
, phead
) {
4235 struct wlan_bssid_ex
*pbss_network
;
4237 pnetwork
= container_of(plist
, struct wlan_network
, list
);
4239 pbss_network
= &pnetwork
->network
;
4241 p
= cfg80211_find_ie(WLAN_EID_HT_CAPABILITY
,
4242 pbss_network
->IEs
+ _FIXED_IE_LENGTH_
,
4243 pbss_network
->IELength
-_FIXED_IE_LENGTH_
);
4244 if (!p
|| !p
[1]) { /* non-HT */
4245 if (pbss_network
->Configuration
.DSConfig
<= 0 ||
4246 pbss_network
->Configuration
.DSConfig
> 14)
4249 ICS
[0][pbss_network
->Configuration
.DSConfig
] = 1;
4257 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
4259 for (i
= 0; i
< 8;i
++) {
4260 if (ICS
[i
][0] == 1) {
4264 /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */
4267 for (j
= 1; j
<= 14; j
++) {
4268 if (ICS
[i
][j
] == 1) {
4270 /* channel number */
4277 pframe
= rtw_set_ie23a(pframe
,
4278 EID_BSSIntolerantChlReport
, k
,
4279 InfoContent
, &pattrib
->pktlen
);
4284 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
4286 dump_mgntframe23a(padapter
, pmgntframe
);
4289 unsigned int send_delba23a(struct rtw_adapter
*padapter
, u8 initiator
, u8
*addr
)
4291 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
4292 struct sta_info
*psta
= NULL
;
4293 /* struct recv_reorder_ctrl *preorder_ctrl; */
4294 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4295 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4298 if ((pmlmeinfo
->state
&0x03) != WIFI_FW_AP_STATE
)
4299 if (!(pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
))
4302 psta
= rtw_get_stainfo23a(pstapriv
, addr
);
4306 if (initiator
== 0) { /* recipient */
4307 for (tid
= 0; tid
< MAXTID
; tid
++) {
4308 if (psta
->recvreorder_ctrl
[tid
].enable
== true) {
4309 DBG_8723A("rx agg disable tid(%d)\n", tid
);
4310 issue_action_BA23a(padapter
, addr
, WLAN_ACTION_DELBA
, (((tid
<<1) |initiator
)&0x1F));
4311 psta
->recvreorder_ctrl
[tid
].enable
= false;
4312 psta
->recvreorder_ctrl
[tid
].indicate_seq
= 0xffff;
4315 } else if (initiator
== 1) { /* originator */
4316 for (tid
= 0; tid
< MAXTID
; tid
++) {
4317 if (psta
->htpriv
.agg_enable_bitmap
& BIT(tid
)) {
4318 DBG_8723A("tx agg disable tid(%d)\n", tid
);
4319 issue_action_BA23a(padapter
, addr
, WLAN_ACTION_DELBA
, (((tid
<<1) |initiator
)&0x1F));
4320 psta
->htpriv
.agg_enable_bitmap
&= ~BIT(tid
);
4321 psta
->htpriv
.candidate_tid_bitmap
&= ~BIT(tid
);
4329 unsigned int send_beacon23a(struct rtw_adapter
*padapter
)
4334 unsigned long start
= jiffies
;
4335 unsigned int passing_time
;
4337 rtl8723a_bcn_valid(padapter
);
4339 issue_beacon23a(padapter
, 100);
4343 bxmitok
= rtl8723a_get_bcn_valid(padapter
);
4345 } while ((poll
% 10) != 0 && bxmitok
== false &&
4346 !padapter
->bSurpriseRemoved
&&
4347 !padapter
->bDriverStopped
);
4349 } while (!bxmitok
&& issue
<100 && !padapter
->bSurpriseRemoved
&&
4350 !padapter
->bDriverStopped
);
4352 if (padapter
->bSurpriseRemoved
|| padapter
->bDriverStopped
)
4355 passing_time
= jiffies_to_msecs(jiffies
- start
);
4358 DBG_8723A("%s fail! %u ms\n", __func__
, passing_time
);
4362 if (passing_time
> 100 || issue
> 3)
4363 DBG_8723A("%s success, issue:%d, poll:%d, %u ms\n",
4364 __func__
, issue
, poll
, passing_time
);
4369 /****************************************************************************
4371 Following are some utitity fuctions for WiFi MLME
4373 *****************************************************************************/
4375 bool IsLegal5GChannel(struct rtw_adapter
*Adapter
, u8 channel
)
4379 u8 Channel_5G
[45] = {36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
4380 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
4381 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
4383 for (i
= 0; i
< sizeof(Channel_5G
); i
++)
4384 if (channel
== Channel_5G
[i
])
4389 void site_survey23a(struct rtw_adapter
*padapter
)
4391 unsigned char survey_channel
= 0;
4392 enum rt_scan_type ScanType
= SCAN_PASSIVE
;
4393 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4394 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4395 struct rtw_ieee80211_channel
*ch
;
4397 if (pmlmeext
->sitesurvey_res
.channel_idx
<
4398 pmlmeext
->sitesurvey_res
.ch_num
) {
4399 ch
= &pmlmeext
->sitesurvey_res
.ch
[pmlmeext
->sitesurvey_res
.channel_idx
];
4400 survey_channel
= ch
->hw_value
;
4401 ScanType
= (ch
->flags
& IEEE80211_CHAN_NO_IR
) ?
4402 SCAN_PASSIVE
: SCAN_ACTIVE
;
4405 if (survey_channel
!= 0) {
4406 /* PAUSE 4-AC Queue when site_survey23a */
4407 if (pmlmeext
->sitesurvey_res
.channel_idx
== 0)
4408 set_channel_bwmode23a(padapter
, survey_channel
,
4409 HAL_PRIME_CHNL_OFFSET_DONT_CARE
,
4410 HT_CHANNEL_WIDTH_20
);
4412 SelectChannel23a(padapter
, survey_channel
);
4414 if (ScanType
== SCAN_ACTIVE
) /* obey the channel plan setting... */
4417 for (i
= 0;i
<RTW_SSID_SCAN_AMOUNT
;i
++) {
4418 if (pmlmeext
->sitesurvey_res
.ssid
[i
].ssid_len
) {
4419 /* todo: to issue two probe req??? */
4420 issue_probereq23a(padapter
, &pmlmeext
->sitesurvey_res
.ssid
[i
], NULL
);
4421 /* msleep(SURVEY_TO>>1); */
4422 issue_probereq23a(padapter
, &pmlmeext
->sitesurvey_res
.ssid
[i
], NULL
);
4426 if (pmlmeext
->sitesurvey_res
.scan_mode
== SCAN_ACTIVE
) {
4427 /* todo: to issue two probe req??? */
4428 issue_probereq23a(padapter
, NULL
, NULL
);
4429 /* msleep(SURVEY_TO>>1); */
4430 issue_probereq23a(padapter
, NULL
, NULL
);
4434 set_survey_timer(pmlmeext
, pmlmeext
->chan_scan_time
);
4436 /* channel number is 0 or this channel is not valid. */
4437 pmlmeext
->sitesurvey_res
.state
= SCAN_COMPLETE
;
4439 /* switch back to the original channel */
4441 set_channel_bwmode23a(padapter
, pmlmeext
->cur_channel
,
4442 pmlmeext
->cur_ch_offset
,
4443 pmlmeext
->cur_bwmode
);
4445 /* flush 4-AC Queue after site_survey23a */
4449 Set_MSR23a(padapter
, (pmlmeinfo
->state
& 0x3));
4451 /* restore RX GAIN */
4452 rtl8723a_set_initial_gain(padapter
, 0xff);
4453 /* turn on dynamic functions */
4454 rtl8723a_odm_support_ability_restore(padapter
);
4456 if (is_client_associated_to_ap23a(padapter
) == true)
4457 issue_nulldata23a(padapter
, NULL
, 0, 3, 500);
4459 rtl8723a_mlme_sitesurvey(padapter
, 0);
4461 report_surveydone_event23a(padapter
);
4463 pmlmeext
->chan_scan_time
= SURVEY_TO
;
4464 pmlmeext
->sitesurvey_res
.state
= SCAN_DISABLE
;
4466 issue_action_BSSCoexistPacket(padapter
);
4467 issue_action_BSSCoexistPacket(padapter
);
4468 issue_action_BSSCoexistPacket(padapter
);
4474 /* collect bss info from Beacon and Probe request/response frames. */
4475 u8
collect_bss_info23a(struct rtw_adapter
*padapter
,
4476 struct recv_frame
*precv_frame
,
4477 struct wlan_bssid_ex
*bssid
)
4481 struct sk_buff
*skb
= precv_frame
->pkt
;
4482 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
4483 unsigned int length
;
4485 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
4486 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4487 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4490 length
= skb
->len
- sizeof(struct ieee80211_hdr_3addr
);
4492 if (length
> MAX_IE_SZ
) {
4493 /* DBG_8723A("IE too long for survey event\n"); */
4497 memset(bssid
, 0, sizeof(struct wlan_bssid_ex
));
4499 if (ieee80211_is_beacon(mgmt
->frame_control
)) {
4500 bssid
->reserved
= 1;
4501 ie_offset
= offsetof(struct ieee80211_mgmt
, u
.beacon
.variable
);
4502 capab_info
= mgmt
->u
.beacon
.capab_info
;
4503 } else if (ieee80211_is_probe_req(mgmt
->frame_control
)) {
4504 ie_offset
= offsetof(struct ieee80211_mgmt
,
4505 u
.probe_req
.variable
);
4506 bssid
->reserved
= 2;
4508 } else if (ieee80211_is_probe_resp(mgmt
->frame_control
)) {
4509 ie_offset
= offsetof(struct ieee80211_mgmt
,
4510 u
.probe_resp
.variable
);
4511 bssid
->reserved
= 3;
4512 capab_info
= mgmt
->u
.probe_resp
.capab_info
;
4514 bssid
->reserved
= 0;
4515 ie_offset
= offsetof(struct ieee80211_mgmt
, u
.beacon
.variable
);
4516 capab_info
= mgmt
->u
.beacon
.capab_info
;
4518 ie_offset
-= offsetof(struct ieee80211_mgmt
, u
);
4520 bssid
->Length
= offsetof(struct wlan_bssid_ex
, IEs
) + length
;
4522 /* below is to copy the information element */
4523 bssid
->IELength
= length
;
4524 memcpy(bssid
->IEs
, &mgmt
->u
, bssid
->IELength
);
4526 /* get the signal strength */
4527 /* in dBM.raw data */
4528 bssid
->Rssi
= precv_frame
->attrib
.phy_info
.RecvSignalPower
;
4529 bssid
->PhyInfo
.SignalQuality
=
4530 precv_frame
->attrib
.phy_info
.SignalQuality
;/* in percentage */
4531 bssid
->PhyInfo
.SignalStrength
=
4532 precv_frame
->attrib
.phy_info
.SignalStrength
;/* in percentage */
4535 p
= cfg80211_find_ie(WLAN_EID_SSID
, bssid
->IEs
+ ie_offset
,
4536 bssid
->IELength
- ie_offset
);
4539 DBG_8723A("marc: cannot find SSID for survey event\n");
4543 if (p
[1] > IEEE80211_MAX_SSID_LEN
) {
4544 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4545 "event\n", __func__
, __LINE__
, p
[1]);
4548 memcpy(bssid
->Ssid
.ssid
, p
+ 2, p
[1]);
4549 bssid
->Ssid
.ssid_len
= p
[1];
4551 memset(bssid
->SupportedRates
, 0, NDIS_802_11_LENGTH_RATES_EX
);
4553 /* checking rate info... */
4555 p
= cfg80211_find_ie(WLAN_EID_SUPP_RATES
, bssid
->IEs
+ ie_offset
,
4556 bssid
->IELength
- ie_offset
);
4558 if (p
[1] > NDIS_802_11_LENGTH_RATES_EX
) {
4559 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4560 "event\n", __func__
, __LINE__
, p
[1]);
4563 memcpy(bssid
->SupportedRates
, p
+ 2, p
[1]);
4567 p
= cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES
, bssid
->IEs
+ ie_offset
,
4568 bssid
->IELength
- ie_offset
);
4570 if (p
[1] > (NDIS_802_11_LENGTH_RATES_EX
-i
)) {
4571 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4572 "event\n", __func__
, __LINE__
, p
[1]);
4575 memcpy(bssid
->SupportedRates
+ i
, p
+ 2, p
[1]);
4578 bssid
->NetworkTypeInUse
= Ndis802_11OFDM24
;
4580 if (bssid
->IELength
< 12)
4583 /* Checking for DSConfig */
4584 p
= cfg80211_find_ie(WLAN_EID_DS_PARAMS
, bssid
->IEs
+ ie_offset
,
4585 bssid
->IELength
- ie_offset
);
4587 bssid
->Configuration
.DSConfig
= 0;
4588 bssid
->Configuration
.Length
= 0;
4591 bssid
->Configuration
.DSConfig
= p
[2];
4592 } else {/* In 5G, some ap do not have DSSET IE */
4593 /* checking HT info for channel */
4594 p
= cfg80211_find_ie(WLAN_EID_HT_OPERATION
,
4595 bssid
->IEs
+ ie_offset
,
4596 bssid
->IELength
- ie_offset
);
4598 struct HT_info_element
*HT_info
=
4599 (struct HT_info_element
*)(p
+ 2);
4600 bssid
->Configuration
.DSConfig
=
4601 HT_info
->primary_channel
;
4602 } else { /* use current channel */
4603 bssid
->Configuration
.DSConfig
=
4604 rtw_get_oper_ch23a(padapter
);
4608 if (ieee80211_is_probe_req(mgmt
->frame_control
)) {
4610 bssid
->InfrastructureMode
= Ndis802_11Infrastructure
;
4611 ether_addr_copy(bssid
->MacAddress
, mgmt
->sa
);
4616 memcpy(&bssid
->Configuration
.BeaconPeriod
,
4617 rtw_get_beacon_interval23a_from_ie(bssid
->IEs
), 2);
4618 bssid
->Configuration
.BeaconPeriod
=
4619 le32_to_cpu(bssid
->Configuration
.BeaconPeriod
);
4621 if (capab_info
& BIT(0)) {
4622 bssid
->InfrastructureMode
= Ndis802_11Infrastructure
;
4623 ether_addr_copy(bssid
->MacAddress
, mgmt
->sa
);
4625 bssid
->InfrastructureMode
= Ndis802_11IBSS
;
4626 ether_addr_copy(bssid
->MacAddress
, mgmt
->bssid
);
4629 if (capab_info
& BIT(4))
4634 bssid
->Configuration
.ATIMWindow
= 0;
4636 /* 20/40 BSS Coexistence check */
4637 if (pregistrypriv
->wifi_spec
== 1 &&
4638 pmlmeinfo
->bwmode_updated
== false) {
4639 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
4641 p
= cfg80211_find_ie(WLAN_EID_HT_CAPABILITY
,
4642 bssid
->IEs
+ ie_offset
,
4643 bssid
->IELength
- ie_offset
);
4644 if (p
&& p
[1] > 0) {
4645 struct HT_caps_element
*pHT_caps
;
4646 pHT_caps
= (struct HT_caps_element
*)(p
+ 2);
4648 if (pHT_caps
->u
.HT_cap_element
.HT_caps_info
& BIT(14))
4649 pmlmepriv
->num_FortyMHzIntolerant
++;
4651 pmlmepriv
->num_sta_no_ht
++;
4655 /* mark bss info receving from nearby channel as SignalQuality 101 */
4656 if (bssid
->Configuration
.DSConfig
!= rtw_get_oper_ch23a(padapter
))
4657 bssid
->PhyInfo
.SignalQuality
= 101;
4662 void start_create_ibss23a(struct rtw_adapter
* padapter
)
4664 unsigned short caps
;
4665 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4666 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4667 struct wlan_bssid_ex
*pnetwork
= &pmlmeinfo
->network
;
4668 pmlmeext
->cur_channel
= (u8
)pnetwork
->Configuration
.DSConfig
;
4669 pmlmeinfo
->bcn_interval
= get_beacon_interval23a(pnetwork
);
4671 /* update wireless mode */
4672 update_wireless_mode23a(padapter
);
4674 /* udpate capability */
4675 caps
= rtw_get_capability23a(pnetwork
);
4676 update_capinfo23a(padapter
, caps
);
4677 if (caps
&cap_IBSS
) { /* adhoc master */
4678 rtl8723a_set_sec_cfg(padapter
, 0xcf);
4680 /* switch channel */
4681 /* SelectChannel23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
4682 set_channel_bwmode23a(padapter
, pmlmeext
->cur_channel
, HAL_PRIME_CHNL_OFFSET_DONT_CARE
, HT_CHANNEL_WIDTH_20
);
4684 beacon_timing_control23a(padapter
);
4686 /* set msr to WIFI_FW_ADHOC_STATE */
4687 pmlmeinfo
->state
= WIFI_FW_ADHOC_STATE
;
4688 Set_MSR23a(padapter
, (pmlmeinfo
->state
& 0x3));
4691 if (send_beacon23a(padapter
) == _FAIL
)
4693 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
, ("issuing beacon frame fail....\n"));
4695 report_join_res23a(padapter
, -1);
4696 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
4700 hw_var_set_bssid(padapter
, padapter
->registrypriv
.dev_network
.MacAddress
);
4701 hw_var_set_mlme_join(padapter
, 0);
4703 report_join_res23a(padapter
, 1);
4704 pmlmeinfo
->state
|= WIFI_FW_ASSOC_SUCCESS
;
4709 DBG_8723A("start_create_ibss23a, invalid cap:%x\n", caps
);
4714 void start_clnt_join23a(struct rtw_adapter
* padapter
)
4716 unsigned short caps
;
4718 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4719 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4720 struct wlan_bssid_ex
*pnetwork
= &pmlmeinfo
->network
;
4723 pmlmeext
->cur_channel
= (u8
)pnetwork
->Configuration
.DSConfig
;
4724 pmlmeinfo
->bcn_interval
= get_beacon_interval23a(pnetwork
);
4726 /* update wireless mode */
4727 update_wireless_mode23a(padapter
);
4729 /* udpate capability */
4730 caps
= rtw_get_capability23a(pnetwork
);
4731 update_capinfo23a(padapter
, caps
);
4733 /* switch channel */
4734 set_channel_bwmode23a(padapter
, pmlmeext
->cur_channel
, pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
4736 Set_MSR23a(padapter
, WIFI_FW_STATION_STATE
);
4738 val8
= (pmlmeinfo
->auth_algo
== dot11AuthAlgrthm_8021X
) ?
4741 rtl8723a_set_sec_cfg(padapter
, val8
);
4743 /* switch channel */
4744 /* set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
4746 /* here wait for receiving the beacon to start auth */
4747 /* and enable a timer */
4748 beacon_timeout
= decide_wait_for_beacon_timeout23a(pmlmeinfo
->bcn_interval
);
4749 set_link_timer(pmlmeext
, beacon_timeout
);
4750 mod_timer(&padapter
->mlmepriv
.assoc_timer
, jiffies
+
4751 msecs_to_jiffies((REAUTH_TO
* REAUTH_LIMIT
) + (REASSOC_TO
*REASSOC_LIMIT
) + beacon_timeout
));
4752 pmlmeinfo
->state
= WIFI_FW_AUTH_NULL
| WIFI_FW_STATION_STATE
;
4754 else if (caps
&cap_IBSS
) { /* adhoc client */
4755 Set_MSR23a(padapter
, WIFI_FW_ADHOC_STATE
);
4757 rtl8723a_set_sec_cfg(padapter
, 0xcf);
4759 /* switch channel */
4760 set_channel_bwmode23a(padapter
, pmlmeext
->cur_channel
, pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
4762 beacon_timing_control23a(padapter
);
4764 pmlmeinfo
->state
= WIFI_FW_ADHOC_STATE
;
4766 report_join_res23a(padapter
, 1);
4770 /* DBG_8723A("marc: invalid cap:%x\n", caps); */
4775 void start_clnt_auth23a(struct rtw_adapter
* padapter
)
4777 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4778 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4780 del_timer_sync(&pmlmeext
->link_timer
);
4782 pmlmeinfo
->state
&= (~WIFI_FW_AUTH_NULL
);
4783 pmlmeinfo
->state
|= WIFI_FW_AUTH_STATE
;
4785 pmlmeinfo
->auth_seq
= 1;
4786 pmlmeinfo
->reauth_count
= 0;
4787 pmlmeinfo
->reassoc_count
= 0;
4788 pmlmeinfo
->link_count
= 0;
4789 pmlmeext
->retry
= 0;
4791 /* Because of AP's not receiving deauth before */
4792 /* AP may: 1)not response auth or 2)deauth us after link is complete */
4793 /* issue deauth before issuing auth to deal with the situation */
4794 /* Commented by Albert 2012/07/21 */
4795 /* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
4796 issue_deauth23a(padapter
, (&pmlmeinfo
->network
)->MacAddress
, WLAN_REASON_DEAUTH_LEAVING
);
4798 DBG_8723A_LEVEL(_drv_always_
, "start auth\n");
4799 issue_auth23a(padapter
, NULL
, 0);
4801 set_link_timer(pmlmeext
, REAUTH_TO
);
4804 void start_clnt_assoc23a(struct rtw_adapter
* padapter
)
4806 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4807 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4809 del_timer_sync(&pmlmeext
->link_timer
);
4811 pmlmeinfo
->state
&= (~(WIFI_FW_AUTH_NULL
| WIFI_FW_AUTH_STATE
));
4812 pmlmeinfo
->state
|= (WIFI_FW_AUTH_SUCCESS
| WIFI_FW_ASSOC_STATE
);
4814 issue_assocreq23a(padapter
);
4816 set_link_timer(pmlmeext
, REASSOC_TO
);
4819 unsigned int receive_disconnect23a(struct rtw_adapter
*padapter
, unsigned char *MacAddr
, unsigned short reason
)
4821 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4822 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4825 if (!ether_addr_equal(MacAddr
, get_my_bssid23a(&pmlmeinfo
->network
)))
4828 DBG_8723A("%s\n", __func__
);
4830 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_STATION_STATE
)
4832 if (pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
)
4834 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
4835 report_del_sta_event23a(padapter
, MacAddr
, reason
);
4838 else if (pmlmeinfo
->state
& WIFI_FW_LINKING_STATE
)
4840 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
4841 report_join_res23a(padapter
, -2);
4848 static void process_80211d(struct rtw_adapter
*padapter
,
4849 struct wlan_bssid_ex
*bssid
)
4851 struct registry_priv
*pregistrypriv
;
4852 struct mlme_ext_priv
*pmlmeext
;
4853 struct rt_channel_info
*chplan_new
;
4857 pregistrypriv
= &padapter
->registrypriv
;
4858 pmlmeext
= &padapter
->mlmeextpriv
;
4860 /* Adjust channel plan by AP Country IE */
4861 if (pregistrypriv
->enable80211d
&&
4862 !pmlmeext
->update_channel_plan_by_ap_done
) {
4864 struct rt_channel_plan chplan_ap
;
4865 struct rt_channel_info chplan_sta
[MAX_CHANNEL_NUM
];
4867 u8 fcn
; /* first channel number */
4868 u8 noc
; /* number of channel */
4871 ie
= cfg80211_find_ie(WLAN_EID_COUNTRY
,
4872 bssid
->IEs
+ _FIXED_IE_LENGTH_
,
4873 bssid
->IELength
- _FIXED_IE_LENGTH_
);
4874 if (!ie
|| ie
[1] < IEEE80211_COUNTRY_IE_MIN_LEN
)
4881 memcpy(country
, p
, 3);
4885 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
,
4886 ("%s: 802.11d country =%s\n", __func__
, country
));
4889 while ((ie
- p
) >= 3) {
4894 for (j
= 0; j
< noc
; j
++) {
4896 channel
= fcn
+ j
; /* 2.4 GHz */
4898 channel
= fcn
+ j
* 4; /* 5 GHz */
4900 chplan_ap
.Channel
[i
++] = channel
;
4905 memcpy(chplan_sta
, pmlmeext
->channel_set
, sizeof(chplan_sta
));
4906 memset(pmlmeext
->channel_set
, 0, sizeof(pmlmeext
->channel_set
));
4907 chplan_new
= pmlmeext
->channel_set
;
4910 if (pregistrypriv
->wireless_mode
& WIRELESS_11G
) {
4912 if (i
== MAX_CHANNEL_NUM
||
4913 chplan_sta
[i
].ChannelNum
== 0 ||
4914 chplan_sta
[i
].ChannelNum
> 14)
4917 if (j
== chplan_ap
.Len
||
4918 chplan_ap
.Channel
[j
] > 14)
4921 if (chplan_sta
[i
].ChannelNum
==
4922 chplan_ap
.Channel
[j
]) {
4923 chplan_new
[k
].ChannelNum
=
4924 chplan_ap
.Channel
[j
];
4925 chplan_new
[k
].ScanType
= SCAN_ACTIVE
;
4929 } else if (chplan_sta
[i
].ChannelNum
<
4930 chplan_ap
.Channel
[j
]) {
4931 chplan_new
[k
].ChannelNum
=
4932 chplan_sta
[i
].ChannelNum
;
4933 chplan_new
[k
].ScanType
=
4937 } else if (chplan_sta
[i
].ChannelNum
>
4938 chplan_ap
.Channel
[j
]) {
4939 chplan_new
[k
].ChannelNum
=
4940 chplan_ap
.Channel
[j
];
4941 chplan_new
[k
].ScanType
=
4948 /* change AP not support channel to Passive scan */
4949 while (i
< MAX_CHANNEL_NUM
&&
4950 chplan_sta
[i
].ChannelNum
!= 0 &&
4951 chplan_sta
[i
].ChannelNum
<= 14) {
4952 chplan_new
[k
].ChannelNum
=
4953 chplan_sta
[i
].ChannelNum
;
4954 chplan_new
[k
].ScanType
= SCAN_PASSIVE
;
4959 /* add channel AP supported */
4960 while (j
< chplan_ap
.Len
&& chplan_ap
.Channel
[j
] <= 14){
4961 chplan_new
[k
].ChannelNum
= chplan_ap
.Channel
[j
];
4962 chplan_new
[k
].ScanType
= SCAN_ACTIVE
;
4967 /* keep original STA 2.4G channel plan */
4968 while (i
< MAX_CHANNEL_NUM
&&
4969 chplan_sta
[i
].ChannelNum
!= 0 &&
4970 chplan_sta
[i
].ChannelNum
<= 14) {
4971 chplan_new
[k
].ChannelNum
=
4972 chplan_sta
[i
].ChannelNum
;
4973 chplan_new
[k
].ScanType
= chplan_sta
[i
].ScanType
;
4978 /* skip AP 2.4G channel plan */
4979 while (j
< chplan_ap
.Len
&& chplan_ap
.Channel
[j
] <= 14)
4983 if (pregistrypriv
->wireless_mode
& WIRELESS_11A
) {
4985 if (i
== MAX_CHANNEL_NUM
||
4986 chplan_sta
[i
].ChannelNum
== 0)
4989 if (j
== chplan_ap
.Len
||
4990 chplan_ap
.Channel
[j
] == 0)
4993 if (chplan_sta
[i
].ChannelNum
==
4994 chplan_ap
.Channel
[j
]) {
4995 chplan_new
[k
].ChannelNum
=
4996 chplan_ap
.Channel
[j
];
4997 chplan_new
[k
].ScanType
= SCAN_ACTIVE
;
5001 } else if (chplan_sta
[i
].ChannelNum
<
5002 chplan_ap
.Channel
[j
]) {
5003 chplan_new
[k
].ChannelNum
=
5004 chplan_sta
[i
].ChannelNum
;
5005 chplan_new
[k
].ScanType
= SCAN_PASSIVE
;
5008 } else if (chplan_sta
[i
].ChannelNum
>
5009 chplan_ap
.Channel
[j
]) {
5010 chplan_new
[k
].ChannelNum
=
5011 chplan_ap
.Channel
[j
];
5012 chplan_new
[k
].ScanType
= SCAN_ACTIVE
;
5018 /* change AP not support channel to Passive scan */
5019 while (i
< MAX_CHANNEL_NUM
&&
5020 chplan_sta
[i
].ChannelNum
!= 0) {
5021 chplan_new
[k
].ChannelNum
=
5022 chplan_sta
[i
].ChannelNum
;
5023 chplan_new
[k
].ScanType
= SCAN_PASSIVE
;
5028 /* add channel AP supported */
5029 while (j
< chplan_ap
.Len
&& chplan_ap
.Channel
[j
] != 0) {
5030 chplan_new
[k
].ChannelNum
= chplan_ap
.Channel
[j
];
5031 chplan_new
[k
].ScanType
= SCAN_ACTIVE
;
5036 /* keep original STA 5G channel plan */
5037 while (i
< MAX_CHANNEL_NUM
&&
5038 chplan_sta
[i
].ChannelNum
!= 0) {
5039 chplan_new
[k
].ChannelNum
=
5040 chplan_sta
[i
].ChannelNum
;
5041 chplan_new
[k
].ScanType
= chplan_sta
[i
].ScanType
;
5046 pmlmeext
->update_channel_plan_by_ap_done
= 1;
5049 /* If channel is used by AP, set channel scan type to active */
5050 channel
= bssid
->Configuration
.DSConfig
;
5051 chplan_new
= pmlmeext
->channel_set
;
5053 while (i
< MAX_CHANNEL_NUM
&& chplan_new
[i
].ChannelNum
!= 0) {
5054 if (chplan_new
[i
].ChannelNum
== channel
) {
5055 if (chplan_new
[i
].ScanType
== SCAN_PASSIVE
) {
5056 /* 5G Bnad 2, 3 (DFS) doesn't change
5058 if (channel
>= 52 && channel
<= 144)
5061 chplan_new
[i
].ScanType
= SCAN_ACTIVE
;
5062 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
,
5063 ("%s: change channel %d scan type "
5064 "from passive to active\n",
5065 __func__
, channel
));
5073 /****************************************************************************
5075 Following are the functions to report events
5077 *****************************************************************************/
5079 void report_survey_event23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
5081 struct cmd_obj
*pcmd_obj
;
5084 struct survey_event
*psurvey_evt
;
5085 struct C2HEvent_Header
*pc2h_evt_hdr
;
5086 struct mlme_ext_priv
*pmlmeext
;
5087 struct cmd_priv
*pcmdpriv
;
5092 pmlmeext
= &padapter
->mlmeextpriv
;
5093 pcmdpriv
= &padapter
->cmdpriv
;
5095 pcmd_obj
= (struct cmd_obj
*)kzalloc(sizeof(struct cmd_obj
),
5100 cmdsz
= (sizeof(struct survey_event
) + sizeof(struct C2HEvent_Header
));
5101 pevtcmd
= kzalloc(cmdsz
, GFP_ATOMIC
);
5107 pcmd_obj
->cmdcode
= GEN_CMD_CODE(_Set_MLME_EVT
);
5108 pcmd_obj
->cmdsz
= cmdsz
;
5109 pcmd_obj
->parmbuf
= pevtcmd
;
5111 pcmd_obj
->rsp
= NULL
;
5112 pcmd_obj
->rspsz
= 0;
5114 pc2h_evt_hdr
= (struct C2HEvent_Header
*)(pevtcmd
);
5115 pc2h_evt_hdr
->len
= sizeof(struct survey_event
);
5116 pc2h_evt_hdr
->ID
= GEN_EVT_CODE(_Survey
);
5117 pc2h_evt_hdr
->seq
= atomic_inc_return(&pmlmeext
->event_seq
);
5119 psurvey_evt
= (struct survey_event
*)(pevtcmd
+ sizeof(struct C2HEvent_Header
));
5121 if (collect_bss_info23a(padapter
, precv_frame
, &psurvey_evt
->bss
) == _FAIL
) {
5127 process_80211d(padapter
, &psurvey_evt
->bss
);
5129 rtw_enqueue_cmd23a(pcmdpriv
, pcmd_obj
);
5131 pmlmeext
->sitesurvey_res
.bss_cnt
++;
5136 void report_surveydone_event23a(struct rtw_adapter
*padapter
)
5138 struct cmd_obj
*pcmd_obj
;
5141 struct surveydone_event
*psurveydone_evt
;
5142 struct C2HEvent_Header
*pc2h_evt_hdr
;
5143 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5144 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
5146 pcmd_obj
= (struct cmd_obj
*)kzalloc(sizeof(struct cmd_obj
),
5151 cmdsz
= (sizeof(struct surveydone_event
) + sizeof(struct C2HEvent_Header
));
5152 pevtcmd
= kzalloc(cmdsz
, GFP_ATOMIC
);
5158 pcmd_obj
->cmdcode
= GEN_CMD_CODE(_Set_MLME_EVT
);
5159 pcmd_obj
->cmdsz
= cmdsz
;
5160 pcmd_obj
->parmbuf
= pevtcmd
;
5162 pcmd_obj
->rsp
= NULL
;
5163 pcmd_obj
->rspsz
= 0;
5165 pc2h_evt_hdr
= (struct C2HEvent_Header
*)(pevtcmd
);
5166 pc2h_evt_hdr
->len
= sizeof(struct surveydone_event
);
5167 pc2h_evt_hdr
->ID
= GEN_EVT_CODE(_SurveyDone
);
5168 pc2h_evt_hdr
->seq
= atomic_inc_return(&pmlmeext
->event_seq
);
5170 psurveydone_evt
= (struct surveydone_event
*)(pevtcmd
+ sizeof(struct C2HEvent_Header
));
5171 psurveydone_evt
->bss_cnt
= pmlmeext
->sitesurvey_res
.bss_cnt
;
5173 DBG_8723A("survey done event(%x)\n", psurveydone_evt
->bss_cnt
);
5175 rtw_enqueue_cmd23a(pcmdpriv
, pcmd_obj
);
5180 void report_join_res23a(struct rtw_adapter
*padapter
, int res
)
5182 struct cmd_obj
*pcmd_obj
;
5185 struct joinbss_event
*pjoinbss_evt
;
5186 struct C2HEvent_Header
*pc2h_evt_hdr
;
5187 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5188 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5189 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
5191 pcmd_obj
= (struct cmd_obj
*)kzalloc(sizeof(struct cmd_obj
),
5196 cmdsz
= (sizeof(struct joinbss_event
) + sizeof(struct C2HEvent_Header
));
5197 pevtcmd
= kzalloc(cmdsz
, GFP_ATOMIC
);
5203 pcmd_obj
->cmdcode
= GEN_CMD_CODE(_Set_MLME_EVT
);
5204 pcmd_obj
->cmdsz
= cmdsz
;
5205 pcmd_obj
->parmbuf
= pevtcmd
;
5207 pcmd_obj
->rsp
= NULL
;
5208 pcmd_obj
->rspsz
= 0;
5210 pc2h_evt_hdr
= (struct C2HEvent_Header
*)(pevtcmd
);
5211 pc2h_evt_hdr
->len
= sizeof(struct joinbss_event
);
5212 pc2h_evt_hdr
->ID
= GEN_EVT_CODE(_JoinBss
);
5213 pc2h_evt_hdr
->seq
= atomic_inc_return(&pmlmeext
->event_seq
);
5215 pjoinbss_evt
= (struct joinbss_event
*)(pevtcmd
+ sizeof(struct C2HEvent_Header
));
5216 memcpy((unsigned char *)&pjoinbss_evt
->network
.network
,
5217 &pmlmeinfo
->network
, sizeof(struct wlan_bssid_ex
));
5218 pjoinbss_evt
->network
.join_res
= pjoinbss_evt
->network
.aid
= res
;
5220 DBG_8723A("report_join_res23a(%d)\n", res
);
5222 rtw_joinbss_event_prehandle23a(padapter
, (u8
*)&pjoinbss_evt
->network
);
5224 rtw_enqueue_cmd23a(pcmdpriv
, pcmd_obj
);
5229 void report_del_sta_event23a(struct rtw_adapter
*padapter
, unsigned char* MacAddr
, unsigned short reason
)
5231 struct cmd_obj
*pcmd_obj
;
5234 struct sta_info
*psta
;
5236 struct stadel_event
*pdel_sta_evt
;
5237 struct C2HEvent_Header
*pc2h_evt_hdr
;
5238 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5239 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
5241 pcmd_obj
= (struct cmd_obj
*)kzalloc(sizeof(struct cmd_obj
),
5246 cmdsz
= (sizeof(struct stadel_event
) + sizeof(struct C2HEvent_Header
));
5247 pevtcmd
= kzalloc(cmdsz
, GFP_ATOMIC
);
5253 pcmd_obj
->cmdcode
= GEN_CMD_CODE(_Set_MLME_EVT
);
5254 pcmd_obj
->cmdsz
= cmdsz
;
5255 pcmd_obj
->parmbuf
= pevtcmd
;
5257 pcmd_obj
->rsp
= NULL
;
5258 pcmd_obj
->rspsz
= 0;
5260 pc2h_evt_hdr
= (struct C2HEvent_Header
*)(pevtcmd
);
5261 pc2h_evt_hdr
->len
= sizeof(struct stadel_event
);
5262 pc2h_evt_hdr
->ID
= GEN_EVT_CODE(_DelSTA
);
5263 pc2h_evt_hdr
->seq
= atomic_inc_return(&pmlmeext
->event_seq
);
5265 pdel_sta_evt
= (struct stadel_event
*)(pevtcmd
+ sizeof(struct C2HEvent_Header
));
5266 ether_addr_copy((unsigned char *)&pdel_sta_evt
->macaddr
, MacAddr
);
5267 memcpy((unsigned char *)pdel_sta_evt
->rsvd
, (unsigned char *)&reason
,
5270 psta
= rtw_get_stainfo23a(&padapter
->stapriv
, MacAddr
);
5272 mac_id
= (int)psta
->mac_id
;
5276 pdel_sta_evt
->mac_id
= mac_id
;
5278 DBG_8723A("report_del_sta_event23a: delete STA, mac_id =%d\n", mac_id
);
5280 rtw_enqueue_cmd23a(pcmdpriv
, pcmd_obj
);
5285 void report_add_sta_event23a(struct rtw_adapter
*padapter
, unsigned char* MacAddr
, int cam_idx
)
5287 struct cmd_obj
*pcmd_obj
;
5290 struct stassoc_event
*padd_sta_evt
;
5291 struct C2HEvent_Header
*pc2h_evt_hdr
;
5292 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5293 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
5295 pcmd_obj
= (struct cmd_obj
*)kzalloc(sizeof(struct cmd_obj
),
5300 cmdsz
= (sizeof(struct stassoc_event
) + sizeof(struct C2HEvent_Header
));
5301 pevtcmd
= kzalloc(cmdsz
, GFP_ATOMIC
);
5307 pcmd_obj
->cmdcode
= GEN_CMD_CODE(_Set_MLME_EVT
);
5308 pcmd_obj
->cmdsz
= cmdsz
;
5309 pcmd_obj
->parmbuf
= pevtcmd
;
5311 pcmd_obj
->rsp
= NULL
;
5312 pcmd_obj
->rspsz
= 0;
5314 pc2h_evt_hdr
= (struct C2HEvent_Header
*)(pevtcmd
);
5315 pc2h_evt_hdr
->len
= sizeof(struct stassoc_event
);
5316 pc2h_evt_hdr
->ID
= GEN_EVT_CODE(_AddSTA
);
5317 pc2h_evt_hdr
->seq
= atomic_inc_return(&pmlmeext
->event_seq
);
5319 padd_sta_evt
= (struct stassoc_event
*)(pevtcmd
+ sizeof(struct C2HEvent_Header
));
5320 ether_addr_copy((unsigned char *)&padd_sta_evt
->macaddr
, MacAddr
);
5321 padd_sta_evt
->cam_id
= cam_idx
;
5323 DBG_8723A("report_add_sta_event23a: add STA\n");
5325 rtw_enqueue_cmd23a(pcmdpriv
, pcmd_obj
);
5330 /****************************************************************************
5332 Following are the event callback functions
5334 *****************************************************************************/
5336 /* for sta/adhoc mode */
5337 void update_sta_info23a(struct rtw_adapter
*padapter
, struct sta_info
*psta
)
5339 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
5340 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5341 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5344 VCS_update23a(padapter
, psta
);
5347 if (pmlmepriv
->htpriv
.ht_option
)
5349 psta
->htpriv
.ht_option
= true;
5351 psta
->htpriv
.ampdu_enable
= pmlmepriv
->htpriv
.ampdu_enable
;
5353 if (support_short_GI23a(padapter
, &pmlmeinfo
->HT_caps
))
5354 psta
->htpriv
.sgi
= true;
5356 psta
->qos_option
= true;
5361 psta
->htpriv
.ht_option
= false;
5363 psta
->htpriv
.ampdu_enable
= false;
5365 psta
->htpriv
.sgi
= false;
5366 psta
->qos_option
= false;
5369 psta
->htpriv
.bwmode
= pmlmeext
->cur_bwmode
;
5370 psta
->htpriv
.ch_offset
= pmlmeext
->cur_ch_offset
;
5372 psta
->htpriv
.agg_enable_bitmap
= 0x0;/* reset */
5373 psta
->htpriv
.candidate_tid_bitmap
= 0x0;/* reset */
5376 if (pmlmepriv
->qos_option
)
5377 psta
->qos_option
= true;
5379 psta
->state
= _FW_LINKED
;
5382 void mlmeext_joinbss_event_callback23a(struct rtw_adapter
*padapter
, int join_res
)
5384 struct sta_info
*psta
, *psta_bmc
;
5385 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5386 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5387 struct wlan_bssid_ex
*cur_network
= &pmlmeinfo
->network
;
5388 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
5391 hw_var_set_mlme_join(padapter
, 1);
5392 hw_var_set_bssid(padapter
, null_addr
);
5394 /* restore to initial setting. */
5395 update_tx_basic_rate23a(padapter
,
5396 padapter
->registrypriv
.wireless_mode
);
5398 goto exit_mlmeext_joinbss_event_callback23a
;
5401 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_ADHOC_STATE
)
5404 psta_bmc
= rtw_get_bcmc_stainfo23a(padapter
);
5407 pmlmeinfo
->FW_sta_info
[psta_bmc
->mac_id
].psta
= psta_bmc
;
5408 update_bmc_sta_support_rate23a(padapter
, psta_bmc
->mac_id
);
5409 Update_RA_Entry23a(padapter
, psta_bmc
);
5413 /* turn on dynamic functions */
5414 rtl8723a_odm_support_ability_set(padapter
, DYNAMIC_ALL_FUNC_ENABLE
);
5416 /* update IOT-releated issue */
5417 update_IOT_info23a(padapter
);
5419 HalSetBrateCfg23a(padapter
, cur_network
->SupportedRates
);
5422 rtl8723a_set_beacon_interval(padapter
, pmlmeinfo
->bcn_interval
);
5424 /* udpate capability */
5425 update_capinfo23a(padapter
, pmlmeinfo
->capability
);
5427 /* WMM, Update EDCA param */
5428 WMMOnAssocRsp23a(padapter
);
5431 HTOnAssocRsp23a(padapter
);
5433 /* Set cur_channel&cur_bwmode&cur_ch_offset */
5434 set_channel_bwmode23a(padapter
, pmlmeext
->cur_channel
, pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
5436 psta
= rtw_get_stainfo23a(pstapriv
, cur_network
->MacAddress
);
5437 if (psta
) /* only for infra. mode */
5439 pmlmeinfo
->FW_sta_info
[psta
->mac_id
].psta
= psta
;
5441 /* DBG_8723A("set_sta_rate23a\n"); */
5443 psta
->wireless_mode
= pmlmeext
->cur_wireless_mode
;
5445 /* set per sta rate after updating HT cap. */
5446 set_sta_rate23a(padapter
, psta
);
5449 hw_var_set_mlme_join(padapter
, 2);
5451 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_STATION_STATE
) {
5452 /* correcting TSF */
5453 rtw_correct_TSF(padapter
);
5455 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5458 rtw_lps_ctrl_wk_cmd23a(padapter
, LPS_CTRL_CONNECT
, 0);
5460 exit_mlmeext_joinbss_event_callback23a
:
5461 DBG_8723A("=>%s\n", __func__
);
5464 void mlmeext_sta_add_event_callback23a(struct rtw_adapter
*padapter
, struct sta_info
*psta
)
5466 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5467 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5469 DBG_8723A("%s\n", __func__
);
5471 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_ADHOC_STATE
)
5473 if (pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
)/* adhoc master or sta_count>1 */
5477 else/* adhoc client */
5479 /* correcting TSF */
5480 rtw_correct_TSF(padapter
);
5483 if (send_beacon23a(padapter
) == _FAIL
)
5485 pmlmeinfo
->FW_sta_info
[psta
->mac_id
].status
= 0;
5487 pmlmeinfo
->state
^= WIFI_FW_ADHOC_STATE
;
5492 pmlmeinfo
->state
|= WIFI_FW_ASSOC_SUCCESS
;
5496 hw_var_set_mlme_join(padapter
, 2);
5499 pmlmeinfo
->FW_sta_info
[psta
->mac_id
].psta
= psta
;
5501 /* rate radaptive */
5502 Update_RA_Entry23a(padapter
, psta
);
5504 /* update adhoc sta_info */
5505 update_sta_info23a(padapter
, psta
);
5508 void mlmeext_sta_del_event_callback23a(struct rtw_adapter
*padapter
)
5510 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5511 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5513 if (is_client_associated_to_ap23a(padapter
) || is_IBSS_empty23a(padapter
))
5515 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
5517 hw_var_set_mlme_disconnect(padapter
);
5518 hw_var_set_bssid(padapter
, null_addr
);
5520 /* restore to initial setting. */
5521 update_tx_basic_rate23a(padapter
, padapter
->registrypriv
.wireless_mode
);
5523 /* switch to the 20M Hz mode after disconnect */
5524 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_20
;
5525 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
5527 /* SelectChannel23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
5528 set_channel_bwmode23a(padapter
, pmlmeext
->cur_channel
, pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
5530 flush_all_cam_entry23a(padapter
);
5532 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
5534 /* set MSR to no link state -> infra. mode */
5535 Set_MSR23a(padapter
, _HW_STATE_STATION_
);
5537 del_timer_sync(&pmlmeext
->link_timer
);
5541 static u8
chk_ap_is_alive(struct rtw_adapter
*padapter
, struct sta_info
*psta
)
5545 if ((sta_rx_data_pkts(psta
) == sta_last_rx_data_pkts(psta
)) &&
5546 sta_rx_beacon_pkts(psta
) == sta_last_rx_beacon_pkts(psta
) &&
5547 sta_rx_probersp_pkts(psta
) == sta_last_rx_probersp_pkts(psta
))
5552 sta_update_last_rx_pkts(psta
);
5556 void linked_status_chk23a(struct rtw_adapter
*padapter
)
5559 struct sta_info
*psta
;
5560 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
5561 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5562 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5563 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
5565 rtw_hal_sreset_linked_status_check23a(padapter
);
5567 if (is_client_associated_to_ap23a(padapter
))
5569 /* linked infrastructure client mode */
5571 int tx_chk
= _SUCCESS
, rx_chk
= _SUCCESS
;
5576 if ((psta
= rtw_get_stainfo23a(pstapriv
, pmlmeinfo
->network
.MacAddress
)) != NULL
)
5578 bool is_p2p_enable
= false;
5580 if (chk_ap_is_alive(padapter
, psta
) == false)
5583 if (pxmitpriv
->last_tx_pkts
== pxmitpriv
->tx_pkts
)
5586 if (pmlmeext
->active_keep_alive_check
&& (rx_chk
== _FAIL
|| tx_chk
== _FAIL
)) {
5587 u8 backup_oper_channel
= 0;
5589 /* switch to correct channel of current network before issue keep-alive frames */
5590 if (rtw_get_oper_ch23a(padapter
) != pmlmeext
->cur_channel
) {
5591 backup_oper_channel
= rtw_get_oper_ch23a(padapter
);
5592 SelectChannel23a(padapter
, pmlmeext
->cur_channel
);
5595 if (rx_chk
!= _SUCCESS
)
5596 issue_probereq23a_ex23a(padapter
, &pmlmeinfo
->network
.Ssid
, psta
->hwaddr
, 3, 1);
5598 if ((tx_chk
!= _SUCCESS
&& pmlmeinfo
->link_count
++ == 0xf) || rx_chk
!= _SUCCESS
) {
5599 tx_chk
= issue_nulldata23a(padapter
, psta
->hwaddr
, 0, 3, 1);
5600 /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
5601 if (tx_chk
== _SUCCESS
&& !is_p2p_enable
)
5605 /* back to the original operation channel */
5606 if (backup_oper_channel
>0)
5607 SelectChannel23a(padapter
, backup_oper_channel
);
5610 if (rx_chk
!= _SUCCESS
) {
5611 if (pmlmeext
->retry
== 0) {
5612 issue_probereq23a(padapter
, &pmlmeinfo
->network
.Ssid
, pmlmeinfo
->network
.MacAddress
);
5613 issue_probereq23a(padapter
, &pmlmeinfo
->network
.Ssid
, pmlmeinfo
->network
.MacAddress
);
5614 issue_probereq23a(padapter
, &pmlmeinfo
->network
.Ssid
, pmlmeinfo
->network
.MacAddress
);
5618 if (tx_chk
!= _SUCCESS
&& pmlmeinfo
->link_count
++ == 0xf)
5619 tx_chk
= issue_nulldata23a(padapter
, NULL
, 0, 1, 0);
5622 if (rx_chk
== _FAIL
) {
5624 if (pmlmeext
->retry
> rx_chk_limit
) {
5625 DBG_8723A_LEVEL(_drv_always_
,
5626 "%s(%s): disconnect or "
5627 "roaming\n", __func__
,
5628 padapter
->pnetdev
->name
);
5629 receive_disconnect23a(padapter
, pmlmeinfo
->network
.MacAddress
,
5630 WLAN_REASON_EXPIRATION_CHK
);
5634 pmlmeext
->retry
= 0;
5637 if (tx_chk
== _FAIL
) {
5638 pmlmeinfo
->link_count
&= 0xf;
5640 pxmitpriv
->last_tx_pkts
= pxmitpriv
->tx_pkts
;
5641 pmlmeinfo
->link_count
= 0;
5644 } /* end of if ((psta = rtw_get_stainfo23a(pstapriv, passoc_res->network.MacAddress)) != NULL) */
5646 else if (is_client_associated_to_ibss23a(padapter
))
5648 /* linked IBSS mode */
5649 /* for each assoc list entry to check the rx pkt counter */
5650 for (i
= IBSS_START_MAC_ID
; i
< NUM_STA
; i
++)
5652 if (pmlmeinfo
->FW_sta_info
[i
].status
== 1)
5654 psta
= pmlmeinfo
->FW_sta_info
[i
].psta
;
5656 if (NULL
== psta
) continue;
5658 if (pmlmeinfo
->FW_sta_info
[i
].rx_pkt
== sta_rx_pkts(psta
))
5661 if (pmlmeinfo
->FW_sta_info
[i
].retry
<3)
5663 pmlmeinfo
->FW_sta_info
[i
].retry
++;
5667 pmlmeinfo
->FW_sta_info
[i
].retry
= 0;
5668 pmlmeinfo
->FW_sta_info
[i
].status
= 0;
5669 report_del_sta_event23a(padapter
, psta
->hwaddr
,
5670 65535/* indicate disconnect caused by no rx */
5676 pmlmeinfo
->FW_sta_info
[i
].retry
= 0;
5677 pmlmeinfo
->FW_sta_info
[i
].rx_pkt
= (u32
)sta_rx_pkts(psta
);
5682 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5687 static void survey_timer_hdl(unsigned long data
)
5689 struct rtw_adapter
*padapter
= (struct rtw_adapter
*)data
;
5690 struct cmd_obj
*ph2c
;
5691 struct sitesurvey_parm
*psurveyPara
;
5692 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
5693 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5695 /* issue rtw_sitesurvey_cmd23a */
5696 if (pmlmeext
->sitesurvey_res
.state
> SCAN_START
) {
5697 if (pmlmeext
->sitesurvey_res
.state
== SCAN_PROCESS
)
5698 pmlmeext
->sitesurvey_res
.channel_idx
++;
5700 if (pmlmeext
->scan_abort
== true) {
5701 pmlmeext
->sitesurvey_res
.channel_idx
=
5702 pmlmeext
->sitesurvey_res
.ch_num
;
5703 DBG_8723A("%s idx:%d\n", __func__
,
5704 pmlmeext
->sitesurvey_res
.channel_idx
);
5706 pmlmeext
->scan_abort
= false;/* reset */
5709 ph2c
= (struct cmd_obj
*)kzalloc(sizeof(struct cmd_obj
),
5712 goto exit_survey_timer_hdl
;
5714 psurveyPara
= (struct sitesurvey_parm
*)
5715 kzalloc(sizeof(struct sitesurvey_parm
), GFP_ATOMIC
);
5718 goto exit_survey_timer_hdl
;
5721 init_h2fwcmd_w_parm_no_rsp(ph2c
, psurveyPara
, GEN_CMD_CODE(_SiteSurvey
));
5722 rtw_enqueue_cmd23a(pcmdpriv
, ph2c
);
5725 exit_survey_timer_hdl
:
5729 static void link_timer_hdl(unsigned long data
)
5731 struct rtw_adapter
*padapter
= (struct rtw_adapter
*)data
;
5732 /* static unsigned int rx_pkt = 0; */
5733 /* static u64 tx_cnt = 0; */
5734 /* struct xmit_priv *pxmitpriv = &padapter->xmitpriv; */
5735 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5736 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5737 /* struct sta_priv *pstapriv = &padapter->stapriv; */
5739 if (pmlmeinfo
->state
& WIFI_FW_AUTH_NULL
)
5741 DBG_8723A("link_timer_hdl:no beacon while connecting\n");
5742 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
5743 report_join_res23a(padapter
, -3);
5745 else if (pmlmeinfo
->state
& WIFI_FW_AUTH_STATE
)
5748 if (++pmlmeinfo
->reauth_count
> REAUTH_LIMIT
)
5750 /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
5752 pmlmeinfo
->state
= 0;
5753 report_join_res23a(padapter
, -1);
5758 /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
5759 /* pmlmeinfo->reauth_count = 0; */
5763 DBG_8723A("link_timer_hdl: auth timeout and try again\n");
5764 pmlmeinfo
->auth_seq
= 1;
5765 issue_auth23a(padapter
, NULL
, 0);
5766 set_link_timer(pmlmeext
, REAUTH_TO
);
5768 else if (pmlmeinfo
->state
& WIFI_FW_ASSOC_STATE
)
5770 /* re-assoc timer */
5771 if (++pmlmeinfo
->reassoc_count
> REASSOC_LIMIT
)
5773 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
5774 report_join_res23a(padapter
, -2);
5778 DBG_8723A("link_timer_hdl: assoc timeout and try again\n");
5779 issue_assocreq23a(padapter
);
5780 set_link_timer(pmlmeext
, REASSOC_TO
);
5786 static void addba_timer_hdl(unsigned long data
)
5788 struct sta_info
*psta
= (struct sta_info
*)data
;
5789 struct ht_priv
*phtpriv
;
5794 phtpriv
= &psta
->htpriv
;
5796 if ((phtpriv
->ht_option
== true) && (phtpriv
->ampdu_enable
== true))
5798 if (phtpriv
->candidate_tid_bitmap
)
5799 phtpriv
->candidate_tid_bitmap
= 0x0;
5804 void init_addba_retry_timer23a(struct sta_info
*psta
)
5806 setup_timer(&psta
->addba_retry_timer
, addba_timer_hdl
,
5807 (unsigned long)psta
);
5810 void init_mlme_ext_timer23a(struct rtw_adapter
*padapter
)
5812 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5814 setup_timer(&pmlmeext
->survey_timer
, survey_timer_hdl
,
5815 (unsigned long)padapter
);
5817 setup_timer(&pmlmeext
->link_timer
, link_timer_hdl
,
5818 (unsigned long)padapter
);
5821 u8
NULL_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
5826 u8
setopmode_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
5829 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5830 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5831 const struct setopmode_parm
*psetop
= (struct setopmode_parm
*)pbuf
;
5833 if (psetop
->mode
== Ndis802_11APMode
) {
5834 pmlmeinfo
->state
= WIFI_FW_AP_STATE
;
5835 type
= _HW_STATE_AP_
;
5836 } else if (psetop
->mode
== Ndis802_11Infrastructure
) {
5837 pmlmeinfo
->state
&= ~(BIT(0)|BIT(1));/* clear state */
5838 pmlmeinfo
->state
|= WIFI_FW_STATION_STATE
;/* set to STATION_STATE */
5839 type
= _HW_STATE_STATION_
;
5840 } else if (psetop
->mode
== Ndis802_11IBSS
)
5841 type
= _HW_STATE_ADHOC_
;
5843 type
= _HW_STATE_NOLINK_
;
5845 hw_var_set_opmode(padapter
, type
);
5846 /* Set_NETYPE0_MSR(padapter, type); */
5851 u8
createbss_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
5853 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5854 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5855 struct wlan_bssid_ex
*pnetwork
= &pmlmeinfo
->network
;
5856 const struct wlan_bssid_ex
*pparm
= (struct wlan_bssid_ex
*)pbuf
;
5857 /* u32 initialgain; */
5859 if (pparm
->InfrastructureMode
== Ndis802_11APMode
) {
5860 #ifdef CONFIG_8723AU_AP_MODE
5862 if (pmlmeinfo
->state
== WIFI_FW_AP_STATE
)
5870 /* below is for ad-hoc master */
5871 if (pparm
->InfrastructureMode
== Ndis802_11IBSS
) {
5872 rtw_joinbss_reset23a(padapter
);
5874 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_20
;
5875 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
5876 pmlmeinfo
->ERP_enable
= 0;
5877 pmlmeinfo
->WMM_enable
= 0;
5878 pmlmeinfo
->HT_enable
= 0;
5879 pmlmeinfo
->HT_caps_enable
= 0;
5880 pmlmeinfo
->HT_info_enable
= 0;
5881 pmlmeinfo
->agg_enable_bitmap
= 0;
5882 pmlmeinfo
->candidate_tid_bitmap
= 0;
5884 /* disable dynamic functions, such as high power, DIG */
5885 rtl8723a_odm_support_ability_backup(padapter
);
5887 rtl8723a_odm_support_ability_clr(padapter
,
5888 DYNAMIC_FUNC_DISABLE
);
5890 /* cancel link timer */
5891 del_timer_sync(&pmlmeext
->link_timer
);
5894 flush_all_cam_entry23a(padapter
);
5896 if (pparm
->IELength
> MAX_IE_SZ
)/* Check pbuf->IELength */
5897 return H2C_PARAMETERS_ERROR
;
5899 memcpy(pnetwork
, pparm
, sizeof(struct wlan_bssid_ex
));
5901 start_create_ibss23a(padapter
);
5907 u8
join_cmd_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
5909 struct ndis_802_11_var_ies
* pIE
;
5910 struct registry_priv
*pregpriv
= &padapter
->registrypriv
;
5911 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5912 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5913 struct wlan_bssid_ex
*pnetwork
= &pmlmeinfo
->network
;
5914 const struct wlan_bssid_ex
*pparm
= (struct wlan_bssid_ex
*)pbuf
;
5915 struct HT_info_element
*pht_info
;
5917 /* u32 initialgain; */
5920 /* check already connecting to AP or not */
5921 if (pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
)
5923 if (pmlmeinfo
->state
& WIFI_FW_STATION_STATE
)
5924 issue_deauth23a_ex23a(padapter
, pnetwork
->MacAddress
,
5925 WLAN_REASON_DEAUTH_LEAVING
, 5, 100);
5927 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
5930 flush_all_cam_entry23a(padapter
);
5932 del_timer_sync(&pmlmeext
->link_timer
);
5934 /* set MSR to nolink -> infra. mode */
5935 /* Set_MSR23a(padapter, _HW_STATE_NOLINK_); */
5936 Set_MSR23a(padapter
, _HW_STATE_STATION_
);
5938 hw_var_set_mlme_disconnect(padapter
);
5941 rtw_joinbss_reset23a(padapter
);
5943 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_20
;
5944 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
5945 pmlmeinfo
->ERP_enable
= 0;
5946 pmlmeinfo
->WMM_enable
= 0;
5947 pmlmeinfo
->HT_enable
= 0;
5948 pmlmeinfo
->HT_caps_enable
= 0;
5949 pmlmeinfo
->HT_info_enable
= 0;
5950 pmlmeinfo
->agg_enable_bitmap
= 0;
5951 pmlmeinfo
->candidate_tid_bitmap
= 0;
5952 pmlmeinfo
->bwmode_updated
= false;
5953 /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
5955 if (pparm
->IELength
> MAX_IE_SZ
)/* Check pbuf->IELength */
5956 return H2C_PARAMETERS_ERROR
;
5958 memcpy(pnetwork
, pbuf
, sizeof(struct wlan_bssid_ex
));
5960 /* Check AP vendor to move rtw_joinbss_cmd23a() */
5961 /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP23a(pnetwork->IEs,
5962 pnetwork->IELength); */
5964 for (i
= sizeof(struct ndis_802_11_fixed_ies
); i
< pnetwork
->IELength
;)
5966 pIE
= (struct ndis_802_11_var_ies
*)(pnetwork
->IEs
+ i
);
5968 switch (pIE
->ElementID
)
5970 case WLAN_EID_VENDOR_SPECIFIC
:/* Get WMM IE. */
5971 if (!memcmp(pIE
->data
, WMM_OUI23A
, 4))
5972 pmlmeinfo
->WMM_enable
= 1;
5975 case WLAN_EID_HT_CAPABILITY
: /* Get HT Cap IE. */
5976 pmlmeinfo
->HT_caps_enable
= 1;
5979 case WLAN_EID_HT_OPERATION
: /* Get HT Info IE. */
5980 pmlmeinfo
->HT_info_enable
= 1;
5982 /* spec case only for cisco's ap because cisco's ap
5983 * issue assoc rsp using mcs rate @40MHz or @20MHz */
5984 pht_info
= (struct HT_info_element
*)(pIE
->data
);
5986 if ((pregpriv
->cbw40_enable
) &&
5987 (pht_info
->infos
[0] & BIT(2))) {
5988 /* switch to the 40M Hz mode according to AP */
5989 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_40
;
5990 switch (pht_info
->infos
[0] & 0x3)
5993 pmlmeext
->cur_ch_offset
=
5994 HAL_PRIME_CHNL_OFFSET_LOWER
;
5998 pmlmeext
->cur_ch_offset
=
5999 HAL_PRIME_CHNL_OFFSET_UPPER
;
6003 pmlmeext
->cur_ch_offset
=
6004 HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
6008 DBG_8723A("set ch/bw before connected\n");
6016 i
+= (pIE
->Length
+ 2);
6019 hw_var_set_bssid(padapter
, pmlmeinfo
->network
.MacAddress
);
6020 hw_var_set_mlme_join(padapter
, 0);
6022 /* cancel link timer */
6023 del_timer_sync(&pmlmeext
->link_timer
);
6025 start_clnt_join23a(padapter
);
6030 u8
disconnect_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6032 const struct disconnect_parm
*param
= (struct disconnect_parm
*)pbuf
;
6033 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
6034 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
6035 struct wlan_bssid_ex
*pnetwork
= &pmlmeinfo
->network
;
6037 if (is_client_associated_to_ap23a(padapter
))
6039 issue_deauth23a_ex23a(padapter
, pnetwork
->MacAddress
, WLAN_REASON_DEAUTH_LEAVING
, param
->deauth_timeout_ms
/100, 100);
6042 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
6044 /* pmlmeinfo->state = WIFI_FW_NULL_STATE; */
6046 hw_var_set_mlme_disconnect(padapter
);
6047 hw_var_set_bssid(padapter
, null_addr
);
6049 /* restore to initial setting. */
6050 update_tx_basic_rate23a(padapter
, padapter
->registrypriv
.wireless_mode
);
6052 if (((pmlmeinfo
->state
& 0x03) == WIFI_FW_ADHOC_STATE
) ||
6053 ((pmlmeinfo
->state
& 0x03) == WIFI_FW_AP_STATE
))
6054 rtl8723a_set_bcn_func(padapter
, 0); /* Stop BCN */
6056 /* set MSR to no link state -> infra. mode */
6057 Set_MSR23a(padapter
, _HW_STATE_STATION_
);
6059 pmlmeinfo
->state
= WIFI_FW_NULL_STATE
;
6061 /* switch to the 20M Hz mode after disconnect */
6062 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_20
;
6063 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
6065 set_channel_bwmode23a(padapter
, pmlmeext
->cur_channel
, pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
6067 flush_all_cam_entry23a(padapter
);
6069 del_timer_sync(&pmlmeext
->link_timer
);
6071 rtw_free_uc_swdec_pending_queue23a(padapter
);
6077 rtw_scan_ch_decision(struct rtw_adapter
*padapter
,
6078 struct rtw_ieee80211_channel
*out
, u32 out_num
,
6079 const struct rtw_ieee80211_channel
*in
, u32 in_num
)
6082 int scan_ch_num
= 0;
6084 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
6086 /* clear out first */
6087 memset(out
, 0, sizeof(struct rtw_ieee80211_channel
)*out_num
);
6089 /* acquire channels from in */
6091 for (i
= 0;i
<in_num
;i
++) {
6092 if (in
[i
].hw_value
&& !(in
[i
].flags
& IEEE80211_CHAN_DISABLED
)
6093 && (set_idx
= rtw_ch_set_search_ch23a(pmlmeext
->channel_set
, in
[i
].hw_value
)) >= 0
6096 memcpy(&out
[j
], &in
[i
], sizeof(struct rtw_ieee80211_channel
));
6098 if (pmlmeext
->channel_set
[set_idx
].ScanType
== SCAN_PASSIVE
)
6099 out
[j
].flags
&= IEEE80211_CHAN_NO_IR
;
6107 /* if out is empty, use channel_set as default */
6109 for (i
= 0;i
<pmlmeext
->max_chan_nums
;i
++) {
6110 out
[i
].hw_value
= pmlmeext
->channel_set
[i
].ChannelNum
;
6112 if (pmlmeext
->channel_set
[i
].ScanType
== SCAN_PASSIVE
)
6113 out
[i
].flags
&= IEEE80211_CHAN_NO_IR
;
6119 if (padapter
->setband
== GHZ_24
) { /* 2.4G */
6120 for (i
= 0; i
< j
; i
++) {
6121 if (out
[i
].hw_value
> 35)
6123 sizeof(struct rtw_ieee80211_channel
));
6128 } else if (padapter
->setband
== GHZ_50
) { /* 5G */
6129 for (i
= 0; i
< j
; i
++) {
6130 if (out
[i
].hw_value
> 35) {
6131 memcpy(&out
[scan_ch_num
++], &out
[i
], sizeof(struct rtw_ieee80211_channel
));
6141 u8
sitesurvey_cmd_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6143 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
6144 const struct sitesurvey_parm
*pparm
= (struct sitesurvey_parm
*)pbuf
;
6145 u8 bdelayscan
= false;
6149 if (pmlmeext
->sitesurvey_res
.state
== SCAN_DISABLE
) {
6150 pmlmeext
->sitesurvey_res
.state
= SCAN_START
;
6151 pmlmeext
->sitesurvey_res
.bss_cnt
= 0;
6152 pmlmeext
->sitesurvey_res
.channel_idx
= 0;
6154 for (i
= 0; i
< RTW_SSID_SCAN_AMOUNT
; i
++) {
6155 if (pparm
->ssid
[i
].ssid_len
) {
6156 memcpy(pmlmeext
->sitesurvey_res
.ssid
[i
].ssid
,
6157 pparm
->ssid
[i
].ssid
, IW_ESSID_MAX_SIZE
);
6158 pmlmeext
->sitesurvey_res
.ssid
[i
].ssid_len
=
6159 pparm
->ssid
[i
].ssid_len
;
6161 pmlmeext
->sitesurvey_res
.ssid
[i
].ssid_len
= 0;
6165 pmlmeext
->sitesurvey_res
.ch_num
=
6166 rtw_scan_ch_decision(padapter
,
6167 pmlmeext
->sitesurvey_res
.ch
,
6168 RTW_CHANNEL_SCAN_AMOUNT
,
6169 pparm
->ch
, pparm
->ch_num
);
6171 pmlmeext
->sitesurvey_res
.scan_mode
= pparm
->scan_mode
;
6173 /* issue null data if associating to the AP */
6174 if (is_client_associated_to_ap23a(padapter
)) {
6175 pmlmeext
->sitesurvey_res
.state
= SCAN_TXNULL
;
6177 /* switch to correct channel of current network
6178 before issue keep-alive frames */
6179 if (rtw_get_oper_ch23a(padapter
) != pmlmeext
->cur_channel
)
6180 SelectChannel23a(padapter
, pmlmeext
->cur_channel
);
6182 issue_nulldata23a(padapter
, NULL
, 1, 3, 500);
6188 /* delay 50ms to protect nulldata(1). */
6189 set_survey_timer(pmlmeext
, 50);
6194 if ((pmlmeext
->sitesurvey_res
.state
== SCAN_START
) ||
6195 (pmlmeext
->sitesurvey_res
.state
== SCAN_TXNULL
)) {
6196 /* disable dynamic functions, such as high power, DIG */
6197 rtl8723a_odm_support_ability_backup(padapter
);
6198 rtl8723a_odm_support_ability_clr(padapter
,
6199 DYNAMIC_FUNC_DISABLE
);
6201 /* config the initial gain under scaning, need to
6202 write the BB registers */
6203 if (wdev_to_priv(padapter
->rtw_wdev
)->p2p_enabled
== true)
6208 rtl8723a_set_initial_gain(padapter
, initialgain
);
6210 /* set MSR to no link state */
6211 Set_MSR23a(padapter
, _HW_STATE_NOLINK_
);
6213 rtl8723a_mlme_sitesurvey(padapter
, 1);
6215 pmlmeext
->sitesurvey_res
.state
= SCAN_PROCESS
;
6218 site_survey23a(padapter
);
6223 u8
setauth_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6225 const struct setauth_parm
*pparm
= (struct setauth_parm
*)pbuf
;
6226 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
6227 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
6229 if (pparm
->mode
< 4)
6231 pmlmeinfo
->auth_algo
= pparm
->mode
;
6237 u8
setkey_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6239 unsigned short ctrl
;
6240 const struct setkey_parm
*pparm
= (struct setkey_parm
*)pbuf
;
6241 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
6242 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
6243 unsigned char null_sta
[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
6245 /* main tx key for wep. */
6247 pmlmeinfo
->key_index
= pparm
->keyid
;
6250 ctrl
= BIT(15) | ((pparm
->algorithm
) << 2) | pparm
->keyid
;
6252 DBG_8723A_LEVEL(_drv_always_
, "set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) "
6253 "keyid:%d\n", pparm
->algorithm
, pparm
->keyid
);
6254 rtl8723a_cam_write(padapter
, pparm
->keyid
, ctrl
, null_sta
, pparm
->key
);
6256 /* allow multicast packets to driver */
6257 rtl8723a_on_rcr_am(padapter
);
6262 u8
set_stakey_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6265 u8 cam_id
;/* cam_entry */
6266 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
6267 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
6268 const struct set_stakey_parm
*pparm
= (struct set_stakey_parm
*)pbuf
;
6271 /* 0~3 for default key */
6273 /* for concurrent mode (ap+sta): */
6274 /* default key is disable, using sw encrypt/decrypt */
6275 /* cam_entry = 4 for sta mode (macid = 0) */
6276 /* cam_entry(macid+3) = 5 ~ N for ap mode (aid = 1~N, macid = 2 ~N) */
6278 /* for concurrent mode (sta+sta): */
6279 /* default key is disable, using sw encrypt/decrypt */
6280 /* cam_entry = 4 mapping to macid = 0 */
6281 /* cam_entry = 5 mapping to macid = 2 */
6285 DBG_8723A_LEVEL(_drv_always_
, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) camid:%d\n",
6286 pparm
->algorithm
, cam_id
);
6287 if ((pmlmeinfo
->state
&0x03) == WIFI_FW_AP_STATE
)
6290 struct sta_info
*psta
;
6291 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
6293 if (pparm
->algorithm
== _NO_PRIVACY_
) /* clear cam entry */
6295 clear_cam_entry23a(padapter
, pparm
->id
);
6296 return H2C_SUCCESS_RSP
;
6299 psta
= rtw_get_stainfo23a(pstapriv
, pparm
->addr
);
6302 ctrl
= (BIT(15) | ((pparm
->algorithm
) << 2));
6304 DBG_8723A("r871x_set_stakey_hdl23a(): enc_algorithm =%d\n", pparm
->algorithm
);
6306 if ((psta
->mac_id
<1) || (psta
->mac_id
>(NUM_STA
-4)))
6308 DBG_8723A("r871x_set_stakey_hdl23a():set_stakey failed, mac_id(aid) =%d\n", psta
->mac_id
);
6309 return H2C_REJECTED
;
6312 cam_id
= (psta
->mac_id
+ 3);/* 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */
6314 DBG_8723A("Write CAM, mac_addr =%x:%x:%x:%x:%x:%x, cam_entry =%d\n", pparm
->addr
[0],
6315 pparm
->addr
[1], pparm
->addr
[2], pparm
->addr
[3], pparm
->addr
[4],
6316 pparm
->addr
[5], cam_id
);
6318 rtl8723a_cam_write(padapter
, cam_id
, ctrl
,
6319 pparm
->addr
, pparm
->key
);
6321 return H2C_SUCCESS_RSP
;
6326 DBG_8723A("r871x_set_stakey_hdl23a(): sta has been free\n");
6327 return H2C_REJECTED
;
6332 /* below for sta mode */
6334 if (pparm
->algorithm
== _NO_PRIVACY_
) /* clear cam entry */
6336 clear_cam_entry23a(padapter
, pparm
->id
);
6340 ctrl
= BIT(15) | ((pparm
->algorithm
) << 2);
6342 rtl8723a_cam_write(padapter
, cam_id
, ctrl
, pparm
->addr
, pparm
->key
);
6344 pmlmeinfo
->enc_algo
= pparm
->algorithm
;
6349 u8
add_ba_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6351 const struct addBaReq_parm
*pparm
= (struct addBaReq_parm
*)pbuf
;
6352 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
6353 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
6355 struct sta_info
*psta
= rtw_get_stainfo23a(&padapter
->stapriv
, pparm
->addr
);
6360 if (((pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
) &&
6361 (pmlmeinfo
->HT_enable
)) ||
6362 ((pmlmeinfo
->state
& 0x03) == WIFI_FW_AP_STATE
)) {
6363 issue_action_BA23a(padapter
, pparm
->addr
,
6364 WLAN_ACTION_ADDBA_REQ
, (u16
)pparm
->tid
);
6365 mod_timer(&psta
->addba_retry_timer
,
6366 jiffies
+ msecs_to_jiffies(ADDBA_TO
));
6368 psta
->htpriv
.candidate_tid_bitmap
&= ~CHKBIT(pparm
->tid
);
6373 u8
set_tx_beacon_cmd23a(struct rtw_adapter
* padapter
)
6375 struct cmd_obj
*ph2c
;
6376 struct Tx_Beacon_param
*ptxBeacon_parm
;
6377 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
6378 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
6379 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
6385 ph2c
= (struct cmd_obj
*)kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
6391 ptxBeacon_parm
= (struct Tx_Beacon_param
*)
6392 kzalloc(sizeof(struct Tx_Beacon_param
), GFP_ATOMIC
);
6393 if (!ptxBeacon_parm
) {
6399 memcpy(&ptxBeacon_parm
->network
, &pmlmeinfo
->network
,
6400 sizeof(struct wlan_bssid_ex
));
6402 len_diff
= update_hidden_ssid(
6403 ptxBeacon_parm
->network
.IEs
+_BEACON_IE_OFFSET_
,
6404 ptxBeacon_parm
->network
.IELength
-_BEACON_IE_OFFSET_
,
6405 pmlmeinfo
->hidden_ssid_mode
);
6406 ptxBeacon_parm
->network
.IELength
+= len_diff
;
6408 init_h2fwcmd_w_parm_no_rsp(ph2c
, ptxBeacon_parm
, GEN_CMD_CODE(_TX_Beacon
));
6410 res
= rtw_enqueue_cmd23a(pcmdpriv
, ph2c
);
6419 u8
mlme_evt_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6421 u8 evt_code
, evt_seq
;
6423 const struct C2HEvent_Header
*c2h
;
6424 void (*event_callback
)(struct rtw_adapter
*dev
, const u8
*pbuf
);
6426 c2h
= (struct C2HEvent_Header
*)pbuf
;
6431 /* checking if event code is valid */
6432 if (evt_code
>= MAX_C2HEVT
) {
6433 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("\nEvent Code(%d) mismatch!\n", evt_code
));
6437 /* checking if event size match the event parm size */
6438 if ((wlanevents
[evt_code
].parmsize
!= 0) &&
6439 (wlanevents
[evt_code
].parmsize
!= evt_sz
)) {
6440 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
6441 evt_code
, wlanevents
[evt_code
].parmsize
, evt_sz
));
6445 event_callback
= wlanevents
[evt_code
].event_callback
;
6446 event_callback(padapter
, pbuf
+ sizeof(struct C2HEvent_Header
));
6453 u8
h2c_msg_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6456 return H2C_PARAMETERS_ERROR
;
6461 u8
tx_beacon_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6463 if (send_beacon23a(padapter
) == _FAIL
)
6465 DBG_8723A("issue_beacon23a, fail!\n");
6466 return H2C_PARAMETERS_ERROR
;
6468 #ifdef CONFIG_8723AU_AP_MODE
6469 else /* tx bc/mc frames after update TIM */
6471 struct sta_info
*psta_bmc
;
6472 struct list_head
*plist
, *phead
, *ptmp
;
6473 struct xmit_frame
*pxmitframe
;
6474 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
6475 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
6477 /* for BC/MC Frames */
6478 psta_bmc
= rtw_get_bcmc_stainfo23a(padapter
);
6482 if ((pstapriv
->tim_bitmap
&BIT(0)) && (psta_bmc
->sleepq_len
>0))
6484 msleep(10);/* 10ms, ATIM(HIQ) Windows */
6485 /* spin_lock_bh(&psta_bmc->sleep_q.lock); */
6486 spin_lock_bh(&pxmitpriv
->lock
);
6488 phead
= get_list_head(&psta_bmc
->sleep_q
);
6490 list_for_each_safe(plist
, ptmp
, phead
) {
6491 pxmitframe
= container_of(plist
,
6495 list_del_init(&pxmitframe
->list
);
6497 psta_bmc
->sleepq_len
--;
6498 if (psta_bmc
->sleepq_len
>0)
6499 pxmitframe
->attrib
.mdata
= 1;
6501 pxmitframe
->attrib
.mdata
= 0;
6503 pxmitframe
->attrib
.triggered
= 1;
6505 pxmitframe
->attrib
.qsel
= 0x11;/* HIQ */
6507 rtw_hal_xmit23aframe_enqueue(padapter
, pxmitframe
);
6510 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
6511 spin_unlock_bh(&pxmitpriv
->lock
);
6520 u8
set_ch_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6522 const struct set_ch_parm
*set_ch_parm
;
6523 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
6526 return H2C_PARAMETERS_ERROR
;
6528 set_ch_parm
= (struct set_ch_parm
*)pbuf
;
6530 DBG_8723A(FUNC_NDEV_FMT
" ch:%u, bw:%u, ch_offset:%u\n",
6531 FUNC_NDEV_ARG(padapter
->pnetdev
),
6532 set_ch_parm
->ch
, set_ch_parm
->bw
, set_ch_parm
->ch_offset
);
6534 pmlmeext
->cur_channel
= set_ch_parm
->ch
;
6535 pmlmeext
->cur_ch_offset
= set_ch_parm
->ch_offset
;
6536 pmlmeext
->cur_bwmode
= set_ch_parm
->bw
;
6538 set_channel_bwmode23a(padapter
, set_ch_parm
->ch
, set_ch_parm
->ch_offset
, set_ch_parm
->bw
);
6543 u8
set_chplan_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6545 const struct SetChannelPlan_param
*setChannelPlan_param
;
6546 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
6549 return H2C_PARAMETERS_ERROR
;
6551 setChannelPlan_param
= (struct SetChannelPlan_param
*)pbuf
;
6553 pmlmeext
->max_chan_nums
= init_channel_set(padapter
, setChannelPlan_param
->channel_plan
, pmlmeext
->channel_set
);
6554 init_channel_list(padapter
, pmlmeext
->channel_set
, pmlmeext
->max_chan_nums
, &pmlmeext
->channel_list
);
6559 u8
led_blink_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6561 struct LedBlink_param
*ledBlink_param
;
6564 return H2C_PARAMETERS_ERROR
;
6566 ledBlink_param
= (struct LedBlink_param
*)pbuf
;
6571 u8
set_csa_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6573 return H2C_REJECTED
;
6576 /* TDLS_WRCR : write RCR DATA BIT */
6577 /* TDLS_SD_PTI : issue peer traffic indication */
6578 /* TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure */
6579 /* TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame */
6580 /* TDLS_DONE_CH_SEN: channel sensing and report candidate channel */
6581 /* TDLS_OFF_CH : first time set channel to off channel */
6582 /* TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel */
6583 /* TDLS_P_OFF_CH : periodically go to off channel */
6584 /* TDLS_P_BASE_CH : periodically go back to base channel */
6585 /* TDLS_RS_RCR : restore RCR */
6586 /* TDLS_CKALV_PH1 : check alive timer phase1 */
6587 /* TDLS_CKALV_PH2 : check alive timer phase2 */
6588 /* TDLS_FREE_STA : free tdls sta */
6589 u8
tdls_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6591 return H2C_REJECTED
;