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>
25 #include <rtl8723a_hal.h>
27 static int OnAssocReq23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
28 static int OnAssocRsp23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
29 static int OnProbeReq23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
30 static int OnProbeRsp23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
31 static int DoReserved23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
32 static int OnBeacon23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
33 static int OnAtim23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
34 static int OnDisassoc23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
35 static int OnAuth23aClient23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
36 static int OnDeAuth23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
37 static int OnAction23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
39 static int on_action_spct23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
40 static int OnAction23a_qos(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
41 static int OnAction23a_dls(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
42 static int OnAction23a_back23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
43 static int on_action_public23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
44 static int OnAction23a_ht(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
45 static int OnAction23a_wmm(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
46 static int OnAction23a_p2p(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
48 static void issue_assocreq(struct rtw_adapter
*padapter
);
49 static void issue_probereq(struct rtw_adapter
*padapter
,
50 struct cfg80211_ssid
*pssid
, u8
*da
);
51 static int issue_probereq_ex(struct rtw_adapter
*padapter
,
52 struct cfg80211_ssid
*pssid
,
53 u8
*da
, int try_cnt
, int wait_ms
);
54 static void issue_probersp(struct rtw_adapter
*padapter
, unsigned char *da
);
55 static void issue_auth(struct rtw_adapter
*padapter
, struct sta_info
*psta
,
56 unsigned short status
);
57 static int issue_deauth_ex(struct rtw_adapter
*padapter
, u8
*da
,
58 unsigned short reason
, int try_cnt
, int wait_ms
);
59 static void start_clnt_assoc(struct rtw_adapter
*padapter
);
60 static void start_clnt_auth(struct rtw_adapter
*padapter
);
61 static void start_clnt_join(struct rtw_adapter
*padapter
);
62 static void start_create_ibss(struct rtw_adapter
*padapter
);
63 static struct wlan_bssid_ex
*collect_bss_info(struct rtw_adapter
*padapter
,
64 struct recv_frame
*precv_frame
);
66 #ifdef CONFIG_8723AU_AP_MODE
67 static int OnAuth23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
);
68 static void issue_assocrsp(struct rtw_adapter
*padapter
, unsigned short status
,
69 struct sta_info
*pstat
, u16 pkt_type
);
72 static struct mlme_handler mlme_sta_tbl
[]={
73 {"OnAssocReq23a", &OnAssocReq23a
},
74 {"OnAssocRsp23a", &OnAssocRsp23a
},
75 {"OnReAssocReq", &OnAssocReq23a
},
76 {"OnReAssocRsp", &OnAssocRsp23a
},
77 {"OnProbeReq23a", &OnProbeReq23a
},
78 {"OnProbeRsp23a", &OnProbeRsp23a
},
80 /*----------------------------------------------------------
82 -----------------------------------------------------------*/
83 {"DoReserved23a", &DoReserved23a
},
84 {"DoReserved23a", &DoReserved23a
},
85 {"OnBeacon23a", &OnBeacon23a
},
86 {"OnATIM", &OnAtim23a
},
87 {"OnDisassoc23a", &OnDisassoc23a
},
88 {"OnAuth23a", &OnAuth23aClient23a
},
89 {"OnDeAuth23a", &OnDeAuth23a
},
90 {"OnAction23a", &OnAction23a
},
93 static struct action_handler OnAction23a_tbl
[]={
94 {WLAN_CATEGORY_SPECTRUM_MGMT
, "ACTION_SPECTRUM_MGMT", on_action_spct23a
},
95 {WLAN_CATEGORY_QOS
, "ACTION_QOS", &OnAction23a_qos
},
96 {WLAN_CATEGORY_DLS
, "ACTION_DLS", &OnAction23a_dls
},
97 {WLAN_CATEGORY_BACK
, "ACTION_BACK", &OnAction23a_back23a
},
98 {WLAN_CATEGORY_PUBLIC
, "ACTION_PUBLIC", on_action_public23a
},
99 {WLAN_CATEGORY_HT
, "ACTION_HT", &OnAction23a_ht
},
100 {WLAN_CATEGORY_SA_QUERY
, "ACTION_SA_QUERY", &DoReserved23a
},
101 {WLAN_CATEGORY_WMM
, "ACTION_WMM", &OnAction23a_wmm
},
102 {WLAN_CATEGORY_VENDOR_SPECIFIC
, "ACTION_P2P", &OnAction23a_p2p
},
105 static u8 null_addr
[ETH_ALEN
]= {0, 0, 0, 0, 0, 0};
107 /**************************************************
108 OUI definitions for the vendor specific IE
109 ***************************************************/
110 unsigned char WMM_OUI23A
[] = {0x00, 0x50, 0xf2, 0x02};
111 unsigned char WPS_OUI23A
[] = {0x00, 0x50, 0xf2, 0x04};
112 unsigned char P2P_OUI23A
[] = {0x50, 0x6F, 0x9A, 0x09};
113 unsigned char WFD_OUI23A
[] = {0x50, 0x6F, 0x9A, 0x0A};
115 unsigned char WMM_INFO_OUI23A
[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
116 unsigned char WMM_PARA_OUI23A
[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
118 static unsigned char REALTEK_96B_IE
[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20};
120 /********************************************************
122 *********************************************************/
123 unsigned char MCS_rate_2R23A
[16] = {
124 0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0,
125 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
126 unsigned char MCS_rate_1R23A
[16] = {
127 0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0,
128 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
130 /********************************************************
131 ChannelPlan definitions
132 *********************************************************/
134 static struct rt_channel_plan_2g RTW_ChannelPlan2G
[RT_CHANNEL_DOMAIN_2G_MAX
] = {
135 /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */
136 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
137 /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
138 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13},
139 /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
140 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},
141 /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
142 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
143 /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
144 {{10, 11, 12, 13}, 4},
145 /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */
149 static struct rt_channel_plan_5g RTW_ChannelPlan5G
[RT_CHANNEL_DOMAIN_5G_MAX
] = {
150 /* 0x00, RT_CHANNEL_DOMAIN_5G_NULL */
152 /* 0x01, RT_CHANNEL_DOMAIN_5G_ETSI1 */
153 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
154 116, 120, 124, 128, 132, 136, 140}, 19},
155 /* 0x02, RT_CHANNEL_DOMAIN_5G_ETSI2 */
156 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
157 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24},
158 /* 0x03, RT_CHANNEL_DOMAIN_5G_ETSI3 */
159 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
160 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22},
161 /* 0x04, RT_CHANNEL_DOMAIN_5G_FCC1 */
162 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
163 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24},
164 /* 0x05, RT_CHANNEL_DOMAIN_5G_FCC2 */
165 {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9},
166 /* 0x06, RT_CHANNEL_DOMAIN_5G_FCC3 */
167 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13},
168 /* 0x07, RT_CHANNEL_DOMAIN_5G_FCC4 */
169 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12},
170 /* 0x08, RT_CHANNEL_DOMAIN_5G_FCC5 */
171 {{149, 153, 157, 161, 165}, 5},
172 /* 0x09, RT_CHANNEL_DOMAIN_5G_FCC6 */
173 {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
174 /* 0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1 */
175 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
176 116, 136, 140, 149, 153, 157, 161, 165}, 20},
177 /* 0x0B, RT_CHANNEL_DOMAIN_5G_KCC1 */
178 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
179 116, 120, 124, 149, 153, 157, 161, 165}, 20},
180 /* 0x0C, RT_CHANNEL_DOMAIN_5G_MKK1 */
181 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
182 116, 120, 124, 128, 132, 136, 140}, 19},
183 /* 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 */
184 {{36, 40, 44, 48, 52, 56, 60, 64}, 8},
185 /* 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 */
186 {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11},
187 /* 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 */
188 {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149,
189 153, 157, 161, 165}, 15},
190 /* 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 */
191 {{56, 60, 64, 149, 153, 157, 161, 165}, 8},
193 /* Driver self defined for old channel plan Compatible,
194 Remember to modify if have new channel plan definition ===== */
195 /* 0x11, RT_CHANNEL_DOMAIN_5G_FCC */
196 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
197 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21},
198 /* 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS */
199 {{36, 40, 44, 48}, 4},
200 /* 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS */
201 {{36, 40, 44, 48, 149, 153, 157, 161}, 8},
204 static struct rt_channel_plan_map RTW_ChannelPlanMap
[RT_CHANNEL_DOMAIN_MAX
] = {
205 /* 0x00 ~ 0x1F , Old Define ===== */
206 {0x02, 0x11}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
207 {0x02, 0x0A}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
208 {0x01, 0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
209 {0x01, 0x00}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
210 {0x01, 0x00}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
211 {0x03, 0x00}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */
212 {0x03, 0x00}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
213 {0x01, 0x09}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
214 {0x03, 0x09}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
215 {0x03, 0x00}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
216 {0x00, 0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
217 {0x02, 0x0F}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
218 {0x01, 0x08}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
219 {0x02, 0x06}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
220 {0x02, 0x0B}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
221 {0x02, 0x09}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
222 {0x01, 0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
223 {0x02, 0x05}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
224 {0x01, 0x12}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
225 {0x00, 0x04}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
226 {0x02, 0x10}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
227 {0x00, 0x12}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
228 {0x00, 0x13}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
229 {0x03, 0x12}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
230 {0x05, 0x08}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
231 {0x02, 0x08}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
232 {0x00, 0x00}, /* 0x1A, */
233 {0x00, 0x00}, /* 0x1B, */
234 {0x00, 0x00}, /* 0x1C, */
235 {0x00, 0x00}, /* 0x1D, */
236 {0x00, 0x00}, /* 0x1E, */
237 {0x05, 0x04}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
238 /* 0x20 ~ 0x7F , New Define ===== */
239 {0x00, 0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
240 {0x01, 0x00}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
241 {0x02, 0x00}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
242 {0x03, 0x00}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
243 {0x04, 0x00}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
244 {0x02, 0x04}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
245 {0x00, 0x01}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
246 {0x03, 0x0C}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
247 {0x00, 0x0B}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
248 {0x00, 0x05}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
249 {0x00, 0x00}, /* 0x2A, */
250 {0x00, 0x00}, /* 0x2B, */
251 {0x00, 0x00}, /* 0x2C, */
252 {0x00, 0x00}, /* 0x2D, */
253 {0x00, 0x00}, /* 0x2E, */
254 {0x00, 0x00}, /* 0x2F, */
255 {0x00, 0x06}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
256 {0x00, 0x07}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
257 {0x00, 0x08}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
258 {0x00, 0x09}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
259 {0x02, 0x0A}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
260 {0x00, 0x02}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
261 {0x00, 0x03}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
262 {0x03, 0x0D}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
263 {0x03, 0x0E}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
264 {0x02, 0x0F}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
265 {0x00, 0x00}, /* 0x3A, */
266 {0x00, 0x00}, /* 0x3B, */
267 {0x00, 0x00}, /* 0x3C, */
268 {0x00, 0x00}, /* 0x3D, */
269 {0x00, 0x00}, /* 0x3E, */
270 {0x00, 0x00}, /* 0x3F, */
271 {0x02, 0x10}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
272 {0x03, 0x00}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */
275 static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE
=
276 {0x03, 0x02}; /* use the conbination for max channel numbers */
278 static void dummy_event_callback(struct rtw_adapter
*adapter
, const u8
*pbuf
)
282 static struct fwevent wlanevents
[] =
284 {0, &dummy_event_callback
}, /*0*/
292 {0, &rtw_survey_event_cb23a
}, /*8*/
293 {sizeof (struct surveydone_event
), &rtw_surveydone_event_callback23a
},
294 {0, &rtw23a_joinbss_event_cb
}, /*10*/
295 {sizeof(struct stassoc_event
), &rtw_stassoc_event_callback23a
},
296 {sizeof(struct stadel_event
), &rtw_stadel_event_callback23a
},
297 {0, &dummy_event_callback
},
298 {0, &dummy_event_callback
},
303 {0, &dummy_event_callback
},
307 {0, &dummy_event_callback
},
312 static void rtw_correct_TSF(struct rtw_adapter
*padapter
)
314 hw_var_set_correct_tsf(padapter
);
318 rtw_update_TSF(struct mlme_ext_priv
*pmlmeext
, struct ieee80211_mgmt
*mgmt
)
320 pmlmeext
->TSFValue
= get_unaligned_le64(&mgmt
->u
.beacon
.timestamp
);
324 * Search the @param channel_num in given @param channel_set
325 * @ch_set: the given channel set
326 * @ch: the given channel number
328 * return the index of channel_num in channel_set, -1 if not found
330 int rtw_ch_set_search_ch23a(struct rt_channel_info
*ch_set
, const u32 ch
)
334 for (i
= 0; ch_set
[i
]. ChannelNum
!= 0; i
++) {
335 if (ch
== ch_set
[i
].ChannelNum
)
339 if (i
>= ch_set
[i
].ChannelNum
)
344 /****************************************************************************
346 Following are the initialization functions for WiFi MLME
348 *****************************************************************************/
350 int init_hw_mlme_ext23a(struct rtw_adapter
*padapter
)
352 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
354 set_channel_bwmode23a(padapter
, pmlmeext
->cur_channel
,
355 pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
359 static void init_mlme_ext_priv23a_value(struct rtw_adapter
*padapter
)
361 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
362 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
363 unsigned char mixed_datarate
[NumRates
] = {
364 _1M_RATE_
, _2M_RATE_
, _5M_RATE_
, _11M_RATE_
, _6M_RATE_
,
365 _9M_RATE_
, _12M_RATE_
, _18M_RATE_
, _24M_RATE_
, _36M_RATE_
,
366 _48M_RATE_
, _54M_RATE_
, 0xff};
367 unsigned char mixed_basicrate
[NumRates
] = {
368 _1M_RATE_
, _2M_RATE_
, _5M_RATE_
, _11M_RATE_
, _6M_RATE_
,
369 _12M_RATE_
, _24M_RATE_
, 0xff,};
371 atomic_set(&pmlmeext
->event_seq
, 0);
372 /* reset to zero when disconnect at client mode */
373 pmlmeext
->mgnt_seq
= 0;
375 pmlmeext
->cur_channel
= padapter
->registrypriv
.channel
;
376 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_20
;
377 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
381 pmlmeext
->cur_wireless_mode
= padapter
->registrypriv
.wireless_mode
;
383 memcpy(pmlmeext
->datarate
, mixed_datarate
, NumRates
);
384 memcpy(pmlmeext
->basicrate
, mixed_basicrate
, NumRates
);
386 if (pmlmeext
->cur_channel
> 14)
387 pmlmeext
->tx_rate
= IEEE80211_OFDM_RATE_6MB
;
389 pmlmeext
->tx_rate
= IEEE80211_CCK_RATE_1MB
;
391 pmlmeext
->sitesurvey_res
.state
= SCAN_DISABLE
;
392 pmlmeext
->sitesurvey_res
.channel_idx
= 0;
393 pmlmeext
->sitesurvey_res
.bss_cnt
= 0;
394 pmlmeext
->scan_abort
= false;
396 pmlmeinfo
->state
= MSR_NOLINK
;
397 pmlmeinfo
->reauth_count
= 0;
398 pmlmeinfo
->reassoc_count
= 0;
399 pmlmeinfo
->link_count
= 0;
400 pmlmeinfo
->auth_seq
= 0;
401 pmlmeinfo
->auth_algo
= dot11AuthAlgrthm_Open
;
402 pmlmeinfo
->key_index
= 0;
405 pmlmeinfo
->enc_algo
= 0;
406 pmlmeinfo
->authModeToggle
= 0;
408 memset(pmlmeinfo
->chg_txt
, 0, 128);
410 pmlmeinfo
->slotTime
= SHORT_SLOT_TIME
;
411 pmlmeinfo
->preamble_mode
= PREAMBLE_AUTO
;
413 pmlmeinfo
->dialogToken
= 0;
415 pmlmeext
->action_public_rxseq
= 0xffff;
416 pmlmeext
->action_public_dialog_token
= 0xff;
419 static int has_channel(struct rt_channel_info
*channel_set
,
420 u8 chanset_size
, u8 chan
) {
423 for (i
= 0; i
< chanset_size
; i
++) {
424 if (channel_set
[i
].ChannelNum
== chan
)
431 static void init_channel_list(struct rtw_adapter
*padapter
,
432 struct rt_channel_info
*channel_set
,
434 struct p2p_channels
*channel_list
)
436 struct p2p_oper_class_map op_class
[] = {
437 { IEEE80211G
, 81, 1, 13, 1, BW20
},
438 { IEEE80211G
, 82, 14, 14, 1, BW20
},
439 { IEEE80211A
, 115, 36, 48, 4, BW20
},
440 { IEEE80211A
, 116, 36, 44, 8, BW40PLUS
},
441 { IEEE80211A
, 117, 40, 48, 8, BW40MINUS
},
442 { IEEE80211A
, 124, 149, 161, 4, BW20
},
443 { IEEE80211A
, 125, 149, 169, 4, BW20
},
444 { IEEE80211A
, 126, 149, 157, 8, BW40PLUS
},
445 { IEEE80211A
, 127, 153, 161, 8, BW40MINUS
},
446 { -1, 0, 0, 0, 0, BW20
}
453 for (op
= 0; op_class
[op
].op_class
; op
++) {
455 struct p2p_oper_class_map
*o
= &op_class
[op
];
456 struct p2p_reg_class
*reg
= NULL
;
458 for (ch
= o
->min_chan
; ch
<= o
->max_chan
; ch
+= o
->inc
) {
459 if (!has_channel(channel_set
, chanset_size
, ch
))
462 if ((0 == padapter
->registrypriv
.ht_enable
) &&
466 if ((0 == (padapter
->registrypriv
.cbw40_enable
& BIT(1))) &&
467 ((BW40MINUS
== o
->bw
) || (BW40PLUS
== o
->bw
)))
471 reg
= &channel_list
->reg_class
[cla
];
473 reg
->reg_class
= o
->op_class
;
476 reg
->channel
[reg
->channels
] = ch
;
480 channel_list
->reg_classes
= cla
;
483 static u8
init_channel_set(struct rtw_adapter
*padapter
, u8 cplan
,
484 struct rt_channel_info
*c_set
)
487 u8 b5GBand
= false, b2_4GBand
= false;
488 u8 Index2G
= 0, Index5G
= 0;
490 memset(c_set
, 0, sizeof(struct rt_channel_info
) * MAX_CHANNEL_NUM
);
492 if (cplan
>= RT_CHANNEL_DOMAIN_MAX
&&
493 cplan
!= RT_CHANNEL_DOMAIN_REALTEK_DEFINE
) {
494 DBG_8723A("ChannelPlan ID %x error !!!!!\n", cplan
);
498 if (padapter
->registrypriv
.wireless_mode
& WIRELESS_11G
) {
500 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE
== cplan
)
501 Index2G
= RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE
.Index2G
;
503 Index2G
= RTW_ChannelPlanMap
[cplan
].Index2G
;
506 if (padapter
->registrypriv
.wireless_mode
& WIRELESS_11A
) {
508 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE
== cplan
)
509 Index5G
= RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE
.Index5G
;
511 Index5G
= RTW_ChannelPlanMap
[cplan
].Index5G
;
515 for (i
= 0; i
< RTW_ChannelPlan2G
[Index2G
].Len
; i
++) {
516 c_set
[ch_size
].ChannelNum
=
517 RTW_ChannelPlan2G
[Index2G
].Channel
[i
];
519 if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN
== cplan
) ||
520 /* Channel 1~11 is active, and 12~14 is passive */
521 RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G
== cplan
) {
522 if (c_set
[ch_size
].ChannelNum
>= 1 &&
523 c_set
[ch_size
].ChannelNum
<= 11)
524 c_set
[ch_size
].ScanType
= SCAN_ACTIVE
;
525 else if (c_set
[ch_size
].ChannelNum
>= 12 &&
526 c_set
[ch_size
].ChannelNum
<= 14)
527 c_set
[ch_size
].ScanType
= SCAN_PASSIVE
;
528 } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13
== cplan
||
529 RT_CHANNEL_DOMAIN_WORLD_WIDE_5G
== cplan
||
530 RT_CHANNEL_DOMAIN_2G_WORLD
== Index2G
) {
531 /* channel 12~13, passive scan */
532 if (c_set
[ch_size
].ChannelNum
<= 11)
533 c_set
[ch_size
].ScanType
= SCAN_ACTIVE
;
535 c_set
[ch_size
].ScanType
= SCAN_PASSIVE
;
537 c_set
[ch_size
].ScanType
= SCAN_ACTIVE
;
544 for (i
= 0; i
< RTW_ChannelPlan5G
[Index5G
].Len
; i
++) {
545 if (RTW_ChannelPlan5G
[Index5G
].Channel
[i
] <= 48 ||
546 RTW_ChannelPlan5G
[Index5G
].Channel
[i
] >= 149) {
547 c_set
[ch_size
].ChannelNum
=
548 RTW_ChannelPlan5G
[Index5G
].Channel
[i
];
549 if (RT_CHANNEL_DOMAIN_WORLD_WIDE_5G
== cplan
) {
550 /* passive scan for all 5G channels */
551 c_set
[ch_size
].ScanType
=
554 c_set
[ch_size
].ScanType
=
556 DBG_8723A("%s(): channel_set[%d].ChannelNum = "
557 "%d\n", __func__
, ch_size
,
558 c_set
[ch_size
].ChannelNum
);
567 int init_mlme_ext_priv23a(struct rtw_adapter
*padapter
)
569 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
570 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
571 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
572 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
574 pmlmeext
->padapter
= padapter
;
576 init_mlme_ext_priv23a_value(padapter
);
577 pmlmeinfo
->bAcceptAddbaReq
= pregistrypriv
->bAcceptAddbaReq
;
579 init_mlme_ext_timer23a(padapter
);
581 #ifdef CONFIG_8723AU_AP_MODE
582 init_mlme_ap_info23a(padapter
);
585 pmlmeext
->max_chan_nums
= init_channel_set(padapter
,
586 pmlmepriv
->ChannelPlan
,
587 pmlmeext
->channel_set
);
588 init_channel_list(padapter
, pmlmeext
->channel_set
,
589 pmlmeext
->max_chan_nums
, &pmlmeext
->channel_list
);
591 pmlmeext
->chan_scan_time
= SURVEY_TO
;
592 pmlmeext
->mlmeext_init
= true;
594 pmlmeext
->active_keep_alive_check
= true;
598 void free_mlme_ext_priv23a (struct mlme_ext_priv
*pmlmeext
)
600 struct rtw_adapter
*padapter
= pmlmeext
->padapter
;
605 if (padapter
->bDriverStopped
== true) {
606 del_timer_sync(&pmlmeext
->survey_timer
);
607 del_timer_sync(&pmlmeext
->link_timer
);
608 /* del_timer_sync(&pmlmeext->ADDBA_timer); */
613 _mgt_dispatcher23a(struct rtw_adapter
*padapter
, struct mlme_handler
*ptable
,
614 struct recv_frame
*precv_frame
)
616 struct sk_buff
*skb
= precv_frame
->pkt
;
617 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*) skb
->data
;
620 /* receive the frames that ra(a1) is my address
621 or ra(a1) is bc address. */
622 if (!ether_addr_equal(hdr
->addr1
, myid(&padapter
->eeprompriv
))&&
623 !is_broadcast_ether_addr(hdr
->addr1
))
626 ptable
->func(padapter
, precv_frame
);
630 void mgt_dispatcher23a(struct rtw_adapter
*padapter
,
631 struct recv_frame
*precv_frame
)
633 struct mlme_handler
*ptable
;
634 #ifdef CONFIG_8723AU_AP_MODE
635 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
636 #endif /* CONFIG_8723AU_AP_MODE */
637 struct sk_buff
*skb
= precv_frame
->pkt
;
638 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
639 struct sta_info
*psta
;
643 if (!ieee80211_is_mgmt(mgmt
->frame_control
))
646 /* receive the frames that ra(a1) is my address or ra(a1) is
648 if (!ether_addr_equal(mgmt
->da
, myid(&padapter
->eeprompriv
)) &&
649 !is_broadcast_ether_addr(mgmt
->da
))
652 ptable
= mlme_sta_tbl
;
654 stype
= le16_to_cpu(mgmt
->frame_control
) & IEEE80211_FCTL_STYPE
;
658 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
659 "Currently we do not support reserved sub-fr-type =%d\n",
665 psta
= rtw_get_stainfo23a(&padapter
->stapriv
, mgmt
->sa
);
668 if (ieee80211_has_retry(mgmt
->frame_control
)) {
669 if (precv_frame
->attrib
.seq_num
==
670 psta
->RxMgmtFrameSeqNum
) {
671 /* drop the duplicate management frame */
672 DBG_8723A("Drop duplicate management frame "
673 "with seq_num = %d.\n",
674 precv_frame
->attrib
.seq_num
);
678 psta
->RxMgmtFrameSeqNum
= precv_frame
->attrib
.seq_num
;
681 #ifdef CONFIG_8723AU_AP_MODE
683 case IEEE80211_STYPE_AUTH
:
684 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
))
685 ptable
->func
= &OnAuth23a
;
687 ptable
->func
= &OnAuth23aClient23a
;
689 case IEEE80211_STYPE_ASSOC_REQ
:
690 case IEEE80211_STYPE_REASSOC_REQ
:
691 _mgt_dispatcher23a(padapter
, ptable
, precv_frame
);
693 case IEEE80211_STYPE_PROBE_REQ
:
694 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
))
695 _mgt_dispatcher23a(padapter
, ptable
, precv_frame
);
697 _mgt_dispatcher23a(padapter
, ptable
, precv_frame
);
699 case IEEE80211_STYPE_BEACON
:
700 _mgt_dispatcher23a(padapter
, ptable
, precv_frame
);
702 case IEEE80211_STYPE_ACTION
:
703 /* if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) */
704 _mgt_dispatcher23a(padapter
, ptable
, precv_frame
);
707 _mgt_dispatcher23a(padapter
, ptable
, precv_frame
);
711 _mgt_dispatcher23a(padapter
, ptable
, precv_frame
);
715 /****************************************************************************
717 Following are the callback functions for each subtype of the management frames
719 *****************************************************************************/
722 OnProbeReq23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
725 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
726 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
727 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
728 struct wlan_bssid_ex
*cur
= &pmlmeinfo
->network
;
729 struct sk_buff
*skb
= precv_frame
->pkt
;
730 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
733 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
))
736 if (!check_fwstate(pmlmepriv
, _FW_LINKED
) &&
737 !check_fwstate(pmlmepriv
,
738 WIFI_ADHOC_MASTER_STATE
| WIFI_AP_STATE
))
741 if (unlikely(!ieee80211_is_probe_req(mgmt
->frame_control
))) {
742 printk(KERN_WARNING
"%s: Received non probe request frame\n",
747 len
-= offsetof(struct ieee80211_mgmt
, u
.probe_req
.variable
);
749 ie
= cfg80211_find_ie(WLAN_EID_SSID
, mgmt
->u
.probe_req
.variable
, len
);
751 /* check (wildcard) SSID */
755 if ((ie
[1] && memcmp(ie
+ 2, cur
->Ssid
.ssid
, cur
->Ssid
.ssid_len
)) ||
756 (ie
[1] == 0 && pmlmeinfo
->hidden_ssid_mode
)) {
760 if (check_fwstate(pmlmepriv
, _FW_LINKED
) &&
761 pmlmepriv
->cur_network
.join_res
)
762 issue_probersp(padapter
, mgmt
->sa
);
769 OnProbeRsp23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
771 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
773 if (pmlmeext
->sitesurvey_res
.state
== SCAN_PROCESS
) {
774 report_survey_event23a(padapter
, precv_frame
);
782 OnBeacon23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
785 struct sta_info
*psta
;
786 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
787 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
788 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
789 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
790 struct sk_buff
*skb
= precv_frame
->pkt
;
791 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
792 int pkt_len
= skb
->len
;
793 struct wlan_bssid_ex
*pbss
;
799 pie
= mgmt
->u
.beacon
.variable
;
800 pie_len
= pkt_len
- offsetof(struct ieee80211_mgmt
, u
.beacon
.variable
);
801 p
= rtw_get_ie23a(pie
, WLAN_EID_EXT_SUPP_RATES
, &ielen
, pie_len
);
802 if (p
&& ielen
> 0) {
803 if (p
[1 + ielen
] == 0x2D && p
[2 + ielen
] != 0x2D) {
804 /* Invalid value 0x2D is detected in Extended Supported
805 * Rates (ESR) IE. Try to fix the IE length to avoid
806 * failed Beacon parsing.
808 DBG_8723A("[WIFIDBG] Error in ESR IE is detected in "
809 "Beacon of BSSID: %pM. Fix the length of "
810 "ESR IE to avoid failed Beacon parsing.\n",
816 if (pmlmeext
->sitesurvey_res
.state
== SCAN_PROCESS
) {
817 report_survey_event23a(padapter
, precv_frame
);
821 if (!ether_addr_equal(mgmt
->bssid
,
822 get_my_bssid23a(&pmlmeinfo
->network
)))
825 if (pmlmeinfo
->state
& WIFI_FW_AUTH_NULL
) {
826 /* we should update current network before auth,
827 or some IE is wrong */
828 pbss
= collect_bss_info(padapter
, precv_frame
);
830 update_network23a(&pmlmepriv
->cur_network
.network
, pbss
,
832 rtw_get_bcn_info23a(&pmlmepriv
->cur_network
);
836 /* check the vendor of the assoc AP */
837 pmlmeinfo
->assoc_AP_vendor
=
838 check_assoc_AP23a((u8
*)&mgmt
->u
.beacon
, pkt_len
-
839 offsetof(struct ieee80211_mgmt
, u
));
841 /* update TSF Value */
842 rtw_update_TSF(pmlmeext
, mgmt
);
845 start_clnt_auth(padapter
);
850 if (((pmlmeinfo
->state
& 0x03) == MSR_AP
) &&
851 (pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
)) {
852 psta
= rtw_get_stainfo23a(pstapriv
, mgmt
->sa
);
854 ret
= rtw_check_bcn_info23a(padapter
, mgmt
, pkt_len
);
855 if (ret
!= _SUCCESS
) {
856 DBG_8723A_LEVEL(_drv_always_
, "ap has changed, "
858 receive_disconnect23a(padapter
, pmlmeinfo
->network
.MacAddress
, 65535);
861 /* update WMM, ERP in the beacon */
862 /* todo: the timer is used instead of
863 the number of the beacon received */
864 if ((sta_rx_pkts(psta
) & 0xf) == 0) {
865 /* DBG_8723A("update_bcn_info\n"); */
866 update_beacon23a_info(padapter
, mgmt
,
870 } else if ((pmlmeinfo
->state
&0x03) == MSR_ADHOC
) {
871 psta
= rtw_get_stainfo23a(pstapriv
, mgmt
->sa
);
873 /* update WMM, ERP in the beacon */
874 /* todo: the timer is used instead of the
875 number of the beacon received */
876 if ((sta_rx_pkts(psta
) & 0xf) == 0) {
877 /* DBG_8723A("update_bcn_info\n"); */
878 update_beacon23a_info(padapter
, mgmt
,
882 /* allocate a new CAM entry for IBSS station */
883 cam_idx
= allocate_fw_sta_entry23a(padapter
);
884 if (cam_idx
== NUM_STA
)
887 /* get supported rate */
888 if (update_sta_support_rate23a(padapter
, pie
, pie_len
,
890 pmlmeinfo
->FW_sta_info
[cam_idx
].status
= 0;
894 /* update TSF Value */
895 rtw_update_TSF(pmlmeext
, mgmt
);
897 /* report sta add event */
898 report_add_sta_event23a(padapter
, mgmt
->sa
,
908 #ifdef CONFIG_8723AU_AP_MODE
910 OnAuth23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
912 static struct sta_info stat
;
913 struct sta_info
*pstat
= NULL
;
914 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
915 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
916 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
917 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
918 struct sk_buff
*skb
= precv_frame
->pkt
;
919 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
923 u16 auth_mode
, seq
, algorithm
;
924 int status
, len
= skb
->len
;
926 if ((pmlmeinfo
->state
& 0x03) != MSR_AP
)
929 DBG_8723A("+OnAuth23a\n");
933 auth_mode
= psecuritypriv
->dot11AuthAlgrthm
;
935 pframe
= mgmt
->u
.auth
.variable
;
936 len
= skb
->len
- offsetof(struct ieee80211_mgmt
, u
.auth
.variable
);
938 seq
= le16_to_cpu(mgmt
->u
.auth
.auth_transaction
);
939 algorithm
= le16_to_cpu(mgmt
->u
.auth
.auth_alg
);
941 DBG_8723A("auth alg =%x, seq =%X\n", algorithm
, seq
);
943 if (auth_mode
== 2 &&
944 psecuritypriv
->dot11PrivacyAlgrthm
!= WLAN_CIPHER_SUITE_WEP40
&&
945 psecuritypriv
->dot11PrivacyAlgrthm
!= WLAN_CIPHER_SUITE_WEP104
)
948 /* rx a shared-key auth but shared not enabled, or */
949 /* rx a open-system auth but shared-key is enabled */
950 if ((algorithm
!= WLAN_AUTH_OPEN
&& auth_mode
== 0) ||
951 (algorithm
== WLAN_AUTH_OPEN
&& auth_mode
== 1)) {
952 DBG_8723A("auth rejected due to bad alg [alg =%d, auth_mib "
953 "=%d] %02X%02X%02X%02X%02X%02X\n",
954 algorithm
, auth_mode
,
955 sa
[0], sa
[1], sa
[2], sa
[3], sa
[4], sa
[5]);
957 status
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
962 if (rtw_access_ctrl23a(padapter
, sa
) == false) {
963 status
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
967 pstat
= rtw_get_stainfo23a(pstapriv
, sa
);
969 /* allocate a new one */
970 DBG_8723A("going to alloc stainfo for sa =%pM\n", sa
);
971 pstat
= rtw_alloc_stainfo23a(pstapriv
, sa
, GFP_ATOMIC
);
973 DBG_8723A(" Exceed the upper limit of supported "
975 status
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
979 pstat
->state
= WIFI_FW_AUTH_NULL
;
982 /* pstat->flags = 0; */
983 /* pstat->capability = 0; */
985 spin_lock_bh(&pstapriv
->asoc_list_lock
);
986 if (!list_empty(&pstat
->asoc_list
)) {
987 list_del_init(&pstat
->asoc_list
);
988 pstapriv
->asoc_list_cnt
--;
989 if (pstat
->expire_to
> 0) {
990 /* TODO: STA re_auth within expire_to */
993 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
996 /* TODO: STA re_auth and auth timeout */
1000 spin_lock_bh(&pstapriv
->auth_list_lock
);
1001 if (list_empty(&pstat
->auth_list
)) {
1002 list_add_tail(&pstat
->auth_list
, &pstapriv
->auth_list
);
1003 pstapriv
->auth_list_cnt
++;
1005 spin_unlock_bh(&pstapriv
->auth_list_lock
);
1007 if (pstat
->auth_seq
== 0)
1008 pstat
->expire_to
= pstapriv
->auth_to
;
1010 if ((pstat
->auth_seq
+ 1) != seq
) {
1011 DBG_8723A("(1)auth rejected because out of seq [rx_seq =%d, "
1012 "exp_seq =%d]!\n", seq
, pstat
->auth_seq
+1);
1013 status
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
1017 if (algorithm
== WLAN_AUTH_OPEN
&& (auth_mode
== 0 || auth_mode
== 2)) {
1019 pstat
->state
&= ~WIFI_FW_AUTH_NULL
;
1020 pstat
->state
|= WIFI_FW_AUTH_SUCCESS
;
1021 pstat
->expire_to
= pstapriv
->assoc_to
;
1022 pstat
->authalg
= algorithm
;
1024 DBG_8723A("(2)auth rejected because out of seq "
1025 "[rx_seq =%d, exp_seq =%d]!\n",
1026 seq
, pstat
->auth_seq
+1);
1027 status
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
1030 } else { /* shared system or auto authentication */
1032 /* prepare for the challenging txt... */
1033 pstat
->state
&= ~WIFI_FW_AUTH_NULL
;
1034 pstat
->state
|= WIFI_FW_AUTH_STATE
;
1035 pstat
->authalg
= algorithm
;
1036 pstat
->auth_seq
= 2;
1037 } else if (seq
== 3) {
1038 /* checking for challenging txt... */
1039 DBG_8723A("checking for challenging txt...\n");
1041 p
= cfg80211_find_ie(WLAN_EID_CHALLENGE
, pframe
, len
);
1042 if (!p
|| p
[1] <= 0) {
1043 DBG_8723A("auth rejected because challenge "
1045 status
= WLAN_STATUS_CHALLENGE_FAIL
;
1049 if (!memcmp(p
+ 2, pstat
->chg_txt
, 128)) {
1050 pstat
->state
&= ~WIFI_FW_AUTH_STATE
;
1051 pstat
->state
|= WIFI_FW_AUTH_SUCCESS
;
1052 /* challenging txt is correct... */
1053 pstat
->expire_to
= pstapriv
->assoc_to
;
1055 DBG_8723A("auth rejected because challenge "
1057 status
= WLAN_STATUS_CHALLENGE_FAIL
;
1061 DBG_8723A("(3)auth rejected because out of seq "
1062 "[rx_seq =%d, exp_seq =%d]!\n",
1063 seq
, pstat
->auth_seq
+1);
1064 status
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
1069 /* Now, we are going to issue_auth... */
1070 pstat
->auth_seq
= seq
+ 1;
1072 issue_auth(padapter
, pstat
, WLAN_STATUS_SUCCESS
);
1074 if (pstat
->state
& WIFI_FW_AUTH_SUCCESS
)
1075 pstat
->auth_seq
= 0;
1082 rtw_free_stainfo23a(padapter
, pstat
);
1085 memset((char *)pstat
, '\0', sizeof(stat
));
1086 pstat
->auth_seq
= 2;
1087 ether_addr_copy(pstat
->hwaddr
, sa
);
1089 issue_auth(padapter
, pstat
, (unsigned short)status
);
1096 OnAuth23aClient23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
1098 unsigned int seq
, status
, algthm
;
1099 unsigned int go2asoc
= 0;
1100 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1101 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
1102 struct sk_buff
*skb
= precv_frame
->pkt
;
1103 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
1106 int plen
= skb
->len
;
1108 DBG_8723A("%s\n", __func__
);
1110 /* check A1 matches or not */
1111 if (!ether_addr_equal(myid(&padapter
->eeprompriv
), mgmt
->da
))
1114 if (!(pmlmeinfo
->state
& WIFI_FW_AUTH_STATE
))
1117 pie
= mgmt
->u
.auth
.variable
;
1118 plen
-= offsetof(struct ieee80211_mgmt
, u
.auth
.variable
);
1120 algthm
= le16_to_cpu(mgmt
->u
.auth
.auth_alg
);
1121 seq
= le16_to_cpu(mgmt
->u
.auth
.auth_transaction
);
1122 status
= le16_to_cpu(mgmt
->u
.auth
.status_code
);
1125 DBG_8723A("clnt auth fail, status: %d\n", status
);
1126 /* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
1127 if (status
== WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
) {
1128 if (pmlmeinfo
->auth_algo
== dot11AuthAlgrthm_Shared
)
1129 pmlmeinfo
->auth_algo
= dot11AuthAlgrthm_Open
;
1131 pmlmeinfo
->auth_algo
= dot11AuthAlgrthm_Shared
;
1132 /* pmlmeinfo->reauth_count = 0; */
1135 set_link_timer(pmlmeext
, 1);
1140 if (pmlmeinfo
->auth_algo
== dot11AuthAlgrthm_Shared
) {
1141 /* legendary shared system */
1142 p
= cfg80211_find_ie(WLAN_EID_CHALLENGE
, pie
, plen
);
1145 /* DBG_8723A("marc: no challenge text?\n"); */
1149 memcpy((void *)(pmlmeinfo
->chg_txt
), p
+ 2, p
[1]);
1150 pmlmeinfo
->auth_seq
= 3;
1151 issue_auth(padapter
, NULL
, 0);
1152 set_link_timer(pmlmeext
, REAUTH_TO
);
1159 } else if (seq
== 4) {
1160 if (pmlmeinfo
->auth_algo
== dot11AuthAlgrthm_Shared
)
1165 /* this is also illegal */
1166 /* DBG_8723A("marc: clnt auth failed due to illegal seq =%x\n",
1172 DBG_8723A_LEVEL(_drv_always_
, "auth success, start assoc\n");
1173 start_clnt_assoc(padapter
);
1179 /* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
1184 #ifdef CONFIG_8723AU_AP_MODE
1185 static int rtw_validate_vendor_specific_ies(const u8
*pos
, int elen
)
1189 /* first 3 bytes in vendor specific information element are the IEEE
1190 * OUI of the vendor. The following byte is used a vendor specific
1193 DBG_8723A("short vendor specific information element "
1194 "ignored (len =%i)\n", elen
);
1198 oui
= RTW_GET_BE24(pos
);
1200 case WLAN_OUI_MICROSOFT
:
1201 /* Microsoft/Wi-Fi information elements are further typed and
1204 case WLAN_OUI_TYPE_MICROSOFT_WPA
:
1205 /* Microsoft OUI (00:50:F2) with OUI Type 1:
1206 * real WPA information element */
1208 case WLAN_OUI_TYPE_MICROSOFT_WMM
:
1210 DBG_8723A("short WME information element "
1211 "ignored (len =%i)\n", elen
);
1215 case WME_OUI_SUBTYPE_INFORMATION_ELEMENT
:
1216 case WME_OUI_SUBTYPE_PARAMETER_ELEMENT
:
1218 case WME_OUI_SUBTYPE_TSPEC_ELEMENT
:
1221 DBG_8723A("unknown WME information element "
1222 "ignored (subtype =%d len =%i)\n",
1227 case WLAN_OUI_TYPE_MICROSOFT_WPS
:
1228 /* Wi-Fi Protected Setup (WPS) IE */
1231 DBG_8723A("Unknown Microsoft information element "
1232 "ignored (type =%d len =%i)\n",
1240 case VENDOR_HT_CAPAB_OUI_TYPE
:
1243 DBG_8723A("Unknown Broadcom information element "
1244 "ignored (type =%d len =%i)\n", pos
[3], elen
);
1250 DBG_8723A("unknown vendor specific information element "
1251 "ignored (vendor OUI %02x:%02x:%02x len =%i)\n",
1252 pos
[0], pos
[1], pos
[2], elen
);
1259 static int rtw_validate_frame_ies(const u8
*start
, uint len
)
1261 const u8
*pos
= start
;
1273 DBG_8723A("%s: IEEE 802.11 failed (id =%d elen =%d "
1274 "left =%i)\n", __func__
, id
, elen
, left
);
1280 case WLAN_EID_SUPP_RATES
:
1281 case WLAN_EID_FH_PARAMS
:
1282 case WLAN_EID_DS_PARAMS
:
1283 case WLAN_EID_CF_PARAMS
:
1285 case WLAN_EID_IBSS_PARAMS
:
1286 case WLAN_EID_CHALLENGE
:
1287 case WLAN_EID_ERP_INFO
:
1288 case WLAN_EID_EXT_SUPP_RATES
:
1290 case WLAN_EID_VENDOR_SPECIFIC
:
1291 if (rtw_validate_vendor_specific_ies(pos
, elen
))
1295 case WLAN_EID_PWR_CAPABILITY
:
1296 case WLAN_EID_SUPPORTED_CHANNELS
:
1297 case WLAN_EID_MOBILITY_DOMAIN
:
1298 case WLAN_EID_FAST_BSS_TRANSITION
:
1299 case WLAN_EID_TIMEOUT_INTERVAL
:
1300 case WLAN_EID_HT_CAPABILITY
:
1301 case WLAN_EID_HT_OPERATION
:
1304 DBG_8723A("%s IEEE 802.11 ignored unknown element "
1305 "(id =%d elen =%d)\n", __func__
, id
, elen
);
1321 OnAssocReq23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
1323 #ifdef CONFIG_8723AU_AP_MODE
1324 u16 capab_info
, listen_interval
;
1325 struct sta_info
*pstat
;
1326 unsigned char reassoc
;
1327 int i
, wpa_ie_len
, left
;
1328 unsigned char supportRate
[16];
1330 unsigned short status
= WLAN_STATUS_SUCCESS
;
1331 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1332 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
1333 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1334 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
1335 struct wlan_bssid_ex
*cur
= &pmlmeinfo
->network
;
1336 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1337 struct sk_buff
*skb
= precv_frame
->pkt
;
1338 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
1339 const u8
*pos
, *p
, *wpa_ie
, *wps_ie
;
1340 u8
*pframe
= skb
->data
;
1341 uint pkt_len
= skb
->len
;
1344 if ((pmlmeinfo
->state
& 0x03) != MSR_AP
)
1347 left
= pkt_len
- sizeof(struct ieee80211_hdr_3addr
);
1348 if (ieee80211_is_assoc_req(mgmt
->frame_control
)) {
1350 pos
= mgmt
->u
.assoc_req
.variable
;
1351 left
-= offsetof(struct ieee80211_mgmt
, u
.assoc_req
.variable
);
1352 } else { /* WIFI_REASSOCREQ */
1354 pos
= mgmt
->u
.reassoc_req
.variable
;
1355 left
-= offsetof(struct ieee80211_mgmt
, u
.reassoc_req
.variable
);
1359 DBG_8723A("handle_assoc(reassoc =%d) - too short payload "
1360 "(len =%lu)\n", reassoc
, (unsigned long)pkt_len
);
1364 pstat
= rtw_get_stainfo23a(pstapriv
, mgmt
->sa
);
1366 status
= WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
;
1367 goto asoc_class2_error
;
1370 /* These two are located at the same offsets whether it's an
1371 * assoc_req or a reassoc_req */
1372 capab_info
= get_unaligned_le16(&mgmt
->u
.assoc_req
.capab_info
);
1374 get_unaligned_le16(&mgmt
->u
.assoc_req
.listen_interval
);
1376 DBG_8723A("%s\n", __func__
);
1378 /* check if this stat has been successfully authenticated/assocated */
1379 if (!(pstat
->state
& WIFI_FW_AUTH_SUCCESS
)) {
1380 if (!(pstat
->state
& WIFI_FW_ASSOC_SUCCESS
)) {
1381 status
= WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
;
1382 goto asoc_class2_error
;
1384 pstat
->state
&= (~WIFI_FW_ASSOC_SUCCESS
);
1385 pstat
->state
|= WIFI_FW_ASSOC_STATE
;
1388 pstat
->state
&= (~WIFI_FW_AUTH_SUCCESS
);
1389 pstat
->state
|= WIFI_FW_ASSOC_STATE
;
1392 pstat
->capability
= capab_info
;
1394 /* now parse all ieee802_11 ie to point to elems */
1396 if (rtw_validate_frame_ies(pos
, left
)) {
1397 DBG_8723A("STA %pM sent invalid association request\n",
1399 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1400 goto OnAssocReq23aFail
;
1403 /* now we should check all the fields... */
1405 p
= cfg80211_find_ie(WLAN_EID_SSID
, pos
, left
);
1406 if (!p
|| p
[1] == 0) {
1407 /* broadcast ssid, however it is not allowed in assocreq */
1408 DBG_8723A("STA %pM sent invalid association request lacking an SSID\n",
1410 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1411 goto OnAssocReq23aFail
;
1413 /* check if ssid match */
1414 if (memcmp(p
+ 2, cur
->Ssid
.ssid
, cur
->Ssid
.ssid_len
))
1415 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1417 if (p
[1] != cur
->Ssid
.ssid_len
)
1418 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1421 if (status
!= WLAN_STATUS_SUCCESS
)
1422 goto OnAssocReq23aFail
;
1424 /* check if the supported rate is ok */
1425 p
= cfg80211_find_ie(WLAN_EID_SUPP_RATES
, pos
, left
);
1427 DBG_8723A("Rx a sta assoc-req which supported rate is "
1429 /* use our own rate set as statoin used */
1430 /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
1431 /* supportRateNum = AP_BSSRATE_LEN; */
1433 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1434 goto OnAssocReq23aFail
;
1436 memcpy(supportRate
, p
+ 2, p
[1]);
1437 supportRateNum
= p
[1];
1439 p
= cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES
, pos
, left
);
1441 if (supportRateNum
<= sizeof(supportRate
)) {
1442 memcpy(supportRate
+supportRateNum
, p
+ 2, p
[1]);
1443 supportRateNum
+= p
[1];
1448 /* todo: mask supportRate between AP & STA -> move to update raid */
1449 /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */
1451 /* update station supportRate */
1452 pstat
->bssratelen
= supportRateNum
;
1453 memcpy(pstat
->bssrateset
, supportRate
, supportRateNum
);
1454 Update23aTblForSoftAP(pstat
->bssrateset
, pstat
->bssratelen
);
1456 /* check RSN/WPA/WPS */
1457 pstat
->dot8021xalg
= 0;
1459 pstat
->wpa_group_cipher
= 0;
1460 pstat
->wpa2_group_cipher
= 0;
1461 pstat
->wpa_pairwise_cipher
= 0;
1462 pstat
->wpa2_pairwise_cipher
= 0;
1463 memset(pstat
->wpa_ie
, 0, sizeof(pstat
->wpa_ie
));
1465 wpa_ie
= cfg80211_find_ie(WLAN_EID_RSN
, pos
, left
);
1467 wpa_ie
= cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT
,
1468 WLAN_OUI_TYPE_MICROSOFT_WPA
,
1471 int group_cipher
= 0, pairwise_cipher
= 0;
1473 wpa_ie_len
= wpa_ie
[1];
1474 if (psecuritypriv
->wpa_psk
& BIT(1)) {
1475 r
= rtw_parse_wpa2_ie23a(wpa_ie
, wpa_ie_len
+ 2,
1477 &pairwise_cipher
, NULL
);
1478 if (r
== _SUCCESS
) {
1479 pstat
->dot8021xalg
= 1;/* psk, todo:802.1x */
1480 pstat
->wpa_psk
|= BIT(1);
1482 pstat
->wpa2_group_cipher
= group_cipher
&
1483 psecuritypriv
->wpa2_group_cipher
;
1484 pstat
->wpa2_pairwise_cipher
= pairwise_cipher
&
1485 psecuritypriv
->wpa2_pairwise_cipher
;
1487 status
= WLAN_STATUS_INVALID_IE
;
1488 } else if (psecuritypriv
->wpa_psk
& BIT(0)) {
1489 r
= rtw_parse_wpa_ie23a(wpa_ie
, wpa_ie_len
+ 2,
1490 &group_cipher
, &pairwise_cipher
,
1492 if (r
== _SUCCESS
) {
1493 pstat
->dot8021xalg
= 1;/* psk, todo:802.1x */
1494 pstat
->wpa_psk
|= BIT(0);
1496 pstat
->wpa_group_cipher
= group_cipher
&
1497 psecuritypriv
->wpa_group_cipher
;
1498 pstat
->wpa_pairwise_cipher
= pairwise_cipher
&
1499 psecuritypriv
->wpa_pairwise_cipher
;
1501 status
= WLAN_STATUS_INVALID_IE
;
1506 if (wpa_ie
&& status
== WLAN_STATUS_SUCCESS
) {
1507 if (!pstat
->wpa_group_cipher
)
1508 status
= WLAN_STATUS_INVALID_GROUP_CIPHER
;
1510 if (!pstat
->wpa_pairwise_cipher
)
1511 status
= WLAN_STATUS_INVALID_PAIRWISE_CIPHER
;
1515 if (status
!= WLAN_STATUS_SUCCESS
)
1516 goto OnAssocReq23aFail
;
1518 pstat
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
);
1520 wps_ie
= cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT
,
1521 WLAN_OUI_TYPE_MICROSOFT_WPS
,
1526 DBG_8723A("STA included WPS IE in (Re)Association "
1527 "Request - assume WPS is used\n");
1528 pstat
->flags
|= WLAN_STA_WPS
;
1530 DBG_8723A("STA did not include WPA/RSN IE in (Re)"
1531 "Association Request - possible WPS use\n");
1532 pstat
->flags
|= WLAN_STA_MAYBE_WPS
;
1537 if (psecuritypriv
->wpa_psk
== 0) {
1538 DBG_8723A("STA %pM: WPA/RSN IE in association request, but AP don't support WPA/RSN\n",
1541 status
= WLAN_STATUS_INVALID_IE
;
1543 goto OnAssocReq23aFail
;
1547 DBG_8723A("STA included WPS IE in (Re)Association "
1548 "Request - WPS is used\n");
1549 pstat
->flags
|= WLAN_STA_WPS
;
1552 copy_len
= ((wpa_ie_len
+ 2) > sizeof(pstat
->wpa_ie
)) ?
1553 sizeof(pstat
->wpa_ie
) : (wpa_ie_len
+ 2);
1557 memcpy(pstat
->wpa_ie
, wpa_ie
- 2, copy_len
);
1560 /* check if there is WMM IE & support WWM-PS */
1561 pstat
->flags
&= ~WLAN_STA_WME
;
1562 pstat
->qos_option
= 0;
1563 pstat
->qos_info
= 0;
1564 pstat
->has_legacy_ac
= true;
1565 pstat
->uapsd_vo
= 0;
1566 pstat
->uapsd_vi
= 0;
1567 pstat
->uapsd_be
= 0;
1568 pstat
->uapsd_bk
= 0;
1569 if (pmlmepriv
->qos_option
) {
1570 const u8
*end
= pos
+ left
;
1576 p
= cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT
,
1577 WLAN_OUI_TYPE_MICROSOFT_WMM
,
1580 pstat
->flags
|= WLAN_STA_WME
;
1582 pstat
->qos_option
= 1;
1583 pstat
->qos_info
= *(p
+ 8);
1586 (pstat
->qos_info
>> 5) & 0x3;
1588 if ((pstat
->qos_info
& 0xf) != 0xf)
1589 pstat
->has_legacy_ac
= true;
1591 pstat
->has_legacy_ac
= false;
1593 if (pstat
->qos_info
& 0xf) {
1594 if (pstat
->qos_info
& BIT(0))
1595 pstat
->uapsd_vo
= BIT(0)|BIT(1);
1597 pstat
->uapsd_vo
= 0;
1599 if (pstat
->qos_info
& BIT(1))
1600 pstat
->uapsd_vi
= BIT(0)|BIT(1);
1602 pstat
->uapsd_vi
= 0;
1604 if (pstat
->qos_info
& BIT(2))
1605 pstat
->uapsd_bk
= BIT(0)|BIT(1);
1607 pstat
->uapsd_bk
= 0;
1609 if (pstat
->qos_info
& BIT(3))
1610 pstat
->uapsd_be
= BIT(0)|BIT(1);
1612 pstat
->uapsd_be
= 0;
1623 /* save HT capabilities in the sta object */
1624 memset(&pstat
->htpriv
.ht_cap
, 0, sizeof(struct ieee80211_ht_cap
));
1625 p
= cfg80211_find_ie(WLAN_EID_HT_CAPABILITY
, pos
, left
);
1627 if (p
&& p
[1] >= sizeof(struct ieee80211_ht_cap
)) {
1628 pstat
->flags
|= WLAN_STA_HT
;
1630 pstat
->flags
|= WLAN_STA_WME
;
1632 memcpy(&pstat
->htpriv
.ht_cap
, p
+ 2,
1633 sizeof(struct ieee80211_ht_cap
));
1635 pstat
->flags
&= ~WLAN_STA_HT
;
1637 if (!pmlmepriv
->htpriv
.ht_option
&& pstat
->flags
& WLAN_STA_HT
){
1638 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1639 goto OnAssocReq23aFail
;
1642 if (pstat
->flags
& WLAN_STA_HT
&&
1643 (pstat
->wpa2_pairwise_cipher
& WPA_CIPHER_TKIP
||
1644 pstat
->wpa_pairwise_cipher
& WPA_CIPHER_TKIP
)) {
1645 DBG_8723A("HT: %pM tried to use TKIP with HT association\n",
1648 /* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */
1649 /* goto OnAssocReq23aFail; */
1652 pstat
->flags
|= WLAN_STA_NONERP
;
1653 for (i
= 0; i
< pstat
->bssratelen
; i
++) {
1654 if ((pstat
->bssrateset
[i
] & 0x7f) > 22) {
1655 pstat
->flags
&= ~WLAN_STA_NONERP
;
1660 if (pstat
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
1661 pstat
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
1663 pstat
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
1665 if (status
!= WLAN_STATUS_SUCCESS
)
1666 goto OnAssocReq23aFail
;
1668 /* TODO: identify_proprietary_vendor_ie(); */
1669 /* Realtek proprietary IE */
1670 /* identify if this is Broadcom sta */
1671 /* identify if this is ralink sta */
1672 /* Customer proprietary IE */
1674 /* get a unique AID */
1675 if (pstat
->aid
> 0) {
1676 DBG_8723A(" old AID %d\n", pstat
->aid
);
1678 for (pstat
->aid
= 1; pstat
->aid
<= NUM_STA
; pstat
->aid
++)
1679 if (pstapriv
->sta_aid
[pstat
->aid
- 1] == NULL
)
1682 if (pstat
->aid
> NUM_STA
)
1683 pstat
->aid
= NUM_STA
;
1684 if (pstat
->aid
> pstapriv
->max_num_sta
) {
1688 DBG_8723A(" no room for more AIDs\n");
1690 status
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
1692 goto OnAssocReq23aFail
;
1694 pstapriv
->sta_aid
[pstat
->aid
- 1] = pstat
;
1695 DBG_8723A("allocate new AID = (%d)\n", pstat
->aid
);
1699 pstat
->state
&= ~WIFI_FW_ASSOC_STATE
;
1700 pstat
->state
|= WIFI_FW_ASSOC_SUCCESS
;
1702 spin_lock_bh(&pstapriv
->auth_list_lock
);
1703 if (!list_empty(&pstat
->auth_list
)) {
1704 list_del_init(&pstat
->auth_list
);
1705 pstapriv
->auth_list_cnt
--;
1707 spin_unlock_bh(&pstapriv
->auth_list_lock
);
1709 spin_lock_bh(&pstapriv
->asoc_list_lock
);
1710 if (list_empty(&pstat
->asoc_list
)) {
1711 pstat
->expire_to
= pstapriv
->expire_to
;
1712 list_add_tail(&pstat
->asoc_list
, &pstapriv
->asoc_list
);
1713 pstapriv
->asoc_list_cnt
++;
1715 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
1717 /* now the station is qualified to join our BSS... */
1718 if (pstat
&& pstat
->state
& WIFI_FW_ASSOC_SUCCESS
&&
1719 status
== WLAN_STATUS_SUCCESS
) {
1720 #ifdef CONFIG_8723AU_AP_MODE
1721 /* 1 bss_cap_update & sta_info_update23a */
1722 bss_cap_update_on_sta_join23a(padapter
, pstat
);
1723 sta_info_update23a(padapter
, pstat
);
1725 /* issue assoc rsp before notify station join event. */
1726 if (ieee80211_is_assoc_req(mgmt
->frame_control
))
1727 issue_assocrsp(padapter
, status
, pstat
,
1728 IEEE80211_STYPE_ASSOC_RESP
);
1730 issue_assocrsp(padapter
, status
, pstat
,
1731 IEEE80211_STYPE_REASSOC_RESP
);
1733 /* 2 - report to upper layer */
1734 DBG_8723A("indicate_sta_join_event to upper layer - hostapd\n");
1735 rtw_cfg80211_indicate_sta_assoc(padapter
, pframe
, pkt_len
);
1737 /* 3-(1) report sta add event */
1738 report_add_sta_event23a(padapter
, pstat
->hwaddr
, pstat
->aid
);
1746 #ifdef CONFIG_8723AU_AP_MODE
1747 issue_deauth23a(padapter
, mgmt
->sa
, status
);
1753 #ifdef CONFIG_8723AU_AP_MODE
1755 if (ieee80211_is_assoc_req(mgmt
->frame_control
))
1756 issue_assocrsp(padapter
, status
, pstat
,
1757 IEEE80211_STYPE_ASSOC_RESP
);
1759 issue_assocrsp(padapter
, status
, pstat
,
1760 IEEE80211_STYPE_REASSOC_RESP
);
1763 #endif /* CONFIG_8723AU_AP_MODE */
1769 OnAssocRsp23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
1771 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1772 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1773 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
1774 struct sk_buff
*skb
= precv_frame
->pkt
;
1775 struct ieee80211_mgmt
*pmgmt
= (struct ieee80211_mgmt
*) skb
->data
;
1777 unsigned short status
;
1779 u8
*pframe
= skb
->data
;
1780 int pkt_len
= skb
->len
;
1783 DBG_8723A("%s\n", __func__
);
1785 /* check A1 matches or not */
1786 if (!ether_addr_equal(myid(&padapter
->eeprompriv
), pmgmt
->da
))
1789 if (!(pmlmeinfo
->state
& (WIFI_FW_AUTH_SUCCESS
| WIFI_FW_ASSOC_STATE
)))
1792 if (pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
)
1795 del_timer_sync(&pmlmeext
->link_timer
);
1798 status
= le16_to_cpu(pmgmt
->u
.assoc_resp
.status_code
);
1800 DBG_8723A("assoc reject, status code: %d\n", status
);
1801 pmlmeinfo
->state
= MSR_NOLINK
;
1803 goto report_assoc_result
;
1806 /* get capabilities */
1807 pmlmeinfo
->capability
= le16_to_cpu(pmgmt
->u
.assoc_resp
.capab_info
);
1810 pmlmeinfo
->slotTime
= (pmlmeinfo
->capability
& BIT(10))? 9: 20;
1813 res
= pmlmeinfo
->aid
= le16_to_cpu(pmgmt
->u
.assoc_resp
.aid
) & 0x3fff;
1815 pie
= pframe
+ offsetof(struct ieee80211_mgmt
, u
.assoc_resp
.variable
);
1817 offsetof(struct ieee80211_mgmt
, u
.assoc_resp
.variable
);
1819 p
= cfg80211_find_ie(WLAN_EID_HT_CAPABILITY
,
1820 pmgmt
->u
.assoc_resp
.variable
, pielen
);
1822 HT_caps_handler23a(padapter
, p
);
1824 p
= cfg80211_find_ie(WLAN_EID_HT_OPERATION
,
1825 pmgmt
->u
.assoc_resp
.variable
, pielen
);
1827 HT_info_handler23a(padapter
, p
);
1829 p
= cfg80211_find_ie(WLAN_EID_ERP_INFO
,
1830 pmgmt
->u
.assoc_resp
.variable
, pielen
);
1832 ERP_IE_handler23a(padapter
, p
);
1834 pie
= pframe
+ offsetof(struct ieee80211_mgmt
, u
.assoc_resp
.variable
);
1836 p
= cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT
,
1837 WLAN_OUI_TYPE_MICROSOFT_WMM
,
1838 pie
, pframe
+ pkt_len
- pie
);
1843 /* if this IE is too short, try the next */
1846 /* if this IE is WMM params, we found what we wanted */
1852 WMM_param_handler23a(padapter
, p
);
1854 pmlmeinfo
->state
&= ~WIFI_FW_ASSOC_STATE
;
1855 pmlmeinfo
->state
|= WIFI_FW_ASSOC_SUCCESS
;
1857 /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
1858 UpdateBrateTbl23a(padapter
, pmlmeinfo
->network
.SupportedRates
);
1860 report_assoc_result
:
1861 pmlmepriv
->assoc_rsp_len
= 0;
1863 kfree(pmlmepriv
->assoc_rsp
);
1864 pmlmepriv
->assoc_rsp
= kmalloc(pkt_len
, GFP_ATOMIC
);
1865 if (pmlmepriv
->assoc_rsp
) {
1866 memcpy(pmlmepriv
->assoc_rsp
, pframe
, pkt_len
);
1867 pmlmepriv
->assoc_rsp_len
= pkt_len
;
1870 kfree(pmlmepriv
->assoc_rsp
);
1872 report_join_res23a(padapter
, res
);
1878 OnDeAuth23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
1880 unsigned short reason
;
1881 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1882 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1883 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
1884 struct sk_buff
*skb
= precv_frame
->pkt
;
1885 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
1887 if (!ether_addr_equal(mgmt
->bssid
,
1888 get_my_bssid23a(&pmlmeinfo
->network
)))
1891 reason
= le16_to_cpu(mgmt
->u
.deauth
.reason_code
);
1893 DBG_8723A("%s Reason code(%d)\n", __func__
, reason
);
1895 #ifdef CONFIG_8723AU_AP_MODE
1896 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
1897 struct sta_info
*psta
;
1898 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1900 DBG_8723A_LEVEL(_drv_always_
, "ap recv deauth reason code(%d) "
1901 "sta:%pM\n", reason
, mgmt
->sa
);
1903 psta
= rtw_get_stainfo23a(pstapriv
, mgmt
->sa
);
1907 spin_lock_bh(&pstapriv
->asoc_list_lock
);
1908 if (!list_empty(&psta
->asoc_list
)) {
1909 list_del_init(&psta
->asoc_list
);
1910 pstapriv
->asoc_list_cnt
--;
1911 updated
= ap_free_sta23a(padapter
, psta
,
1914 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
1916 associated_clients_update23a(padapter
, updated
);
1923 DBG_8723A_LEVEL(_drv_always_
, "sta recv deauth reason code(%d) "
1924 "sta:%pM\n", reason
, mgmt
->bssid
);
1926 receive_disconnect23a(padapter
, mgmt
->bssid
, reason
);
1928 pmlmepriv
->LinkDetectInfo
.bBusyTraffic
= false;
1934 OnDisassoc23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
1936 unsigned short reason
;
1937 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1938 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
1939 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
1940 struct sk_buff
*skb
= precv_frame
->pkt
;
1941 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
1943 if (!ether_addr_equal(mgmt
->bssid
,
1944 get_my_bssid23a(&pmlmeinfo
->network
)))
1947 reason
= le16_to_cpu(mgmt
->u
.disassoc
.reason_code
);
1949 DBG_8723A("%s Reason code(%d)\n", __func__
, reason
);
1951 #ifdef CONFIG_8723AU_AP_MODE
1952 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
1953 struct sta_info
*psta
;
1954 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1956 DBG_8723A_LEVEL(_drv_always_
, "ap recv disassoc reason code(%d)"
1957 " sta:%pM\n", reason
, mgmt
->sa
);
1959 psta
= rtw_get_stainfo23a(pstapriv
, mgmt
->sa
);
1963 spin_lock_bh(&pstapriv
->asoc_list_lock
);
1964 if (!list_empty(&psta
->asoc_list
)) {
1965 list_del_init(&psta
->asoc_list
);
1966 pstapriv
->asoc_list_cnt
--;
1967 updated
= ap_free_sta23a(padapter
, psta
,
1970 spin_unlock_bh(&pstapriv
->asoc_list_lock
);
1972 associated_clients_update23a(padapter
, updated
);
1979 DBG_8723A_LEVEL(_drv_always_
, "ap recv disassoc reason "
1980 "code(%d) sta:%pM\n", reason
, mgmt
->bssid
);
1982 receive_disconnect23a(padapter
, mgmt
->bssid
, reason
);
1984 pmlmepriv
->LinkDetectInfo
.bBusyTraffic
= false;
1989 OnAtim23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
1991 DBG_8723A("%s\n", __func__
);
1996 on_action_spct23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
2002 OnAction23a_qos(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
2008 OnAction23a_dls(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
2013 static int OnAction23a_back23a(struct rtw_adapter
*padapter
,
2014 struct recv_frame
*precv_frame
)
2017 struct sta_info
*psta
= NULL
;
2018 struct recv_reorder_ctrl
*preorder_ctrl
;
2019 unsigned char category
, action
;
2020 unsigned short tid
, status
, capab
, params
, reason_code
= 0;
2021 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2022 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
2023 struct sk_buff
*skb
= precv_frame
->pkt
;
2024 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
2025 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
2027 /* check RA matches or not */
2028 if (!ether_addr_equal(myid(&padapter
->eeprompriv
), mgmt
->da
))
2031 DBG_8723A("%s\n", __func__
);
2033 if ((pmlmeinfo
->state
&0x03) != MSR_AP
)
2034 if (!(pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
))
2038 psta
= rtw_get_stainfo23a(pstapriv
, addr
);
2043 category
= mgmt
->u
.action
.category
;
2044 if (category
== WLAN_CATEGORY_BACK
) { /* representing Block Ack */
2045 if (!pmlmeinfo
->HT_enable
)
2047 /* action_code is located in the same place for all
2048 action events, so pick any */
2049 action
= mgmt
->u
.action
.u
.wme_action
.action_code
;
2050 DBG_8723A("%s, action =%d\n", __func__
, action
);
2052 case WLAN_ACTION_ADDBA_REQ
: /* ADDBA request */
2053 memcpy(&pmlmeinfo
->ADDBA_req
,
2054 &mgmt
->u
.action
.u
.addba_req
.dialog_token
,
2055 sizeof(struct ADDBA_request
));
2056 process_addba_req23a(padapter
,
2057 (u8
*)&pmlmeinfo
->ADDBA_req
, addr
);
2058 if (pmlmeinfo
->bAcceptAddbaReq
== true)
2059 issue_action_BA23a(padapter
, addr
,
2060 WLAN_ACTION_ADDBA_RESP
, 0);
2062 /* reject ADDBA Req */
2063 issue_action_BA23a(padapter
, addr
,
2064 WLAN_ACTION_ADDBA_RESP
, 37);
2067 case WLAN_ACTION_ADDBA_RESP
: /* ADDBA response */
2068 status
= get_unaligned_le16(
2069 &mgmt
->u
.action
.u
.addba_resp
.status
);
2070 capab
= get_unaligned_le16(
2071 &mgmt
->u
.action
.u
.addba_resp
.capab
);
2072 tid
= (capab
& IEEE80211_ADDBA_PARAM_TID_MASK
) >> 2;
2073 if (status
== 0) { /* successful */
2074 DBG_8723A("agg_enable for TID =%d\n", tid
);
2075 psta
->htpriv
.agg_enable_bitmap
|= BIT(tid
);
2076 psta
->htpriv
.candidate_tid_bitmap
&= ~BIT(tid
);
2078 psta
->htpriv
.agg_enable_bitmap
&= ~BIT(tid
);
2081 case WLAN_ACTION_DELBA
: /* DELBA */
2082 params
= get_unaligned_le16(
2083 &mgmt
->u
.action
.u
.delba
.params
);
2086 if (params
& IEEE80211_DELBA_PARAM_INITIATOR_MASK
) {
2087 preorder_ctrl
= &psta
->recvreorder_ctrl
[tid
];
2088 preorder_ctrl
->enable
= false;
2089 preorder_ctrl
->indicate_seq
= 0xffff;
2091 psta
->htpriv
.agg_enable_bitmap
&= ~BIT(tid
);
2092 psta
->htpriv
.candidate_tid_bitmap
&= ~BIT(tid
);
2094 reason_code
= get_unaligned_le16(
2095 &mgmt
->u
.action
.u
.delba
.reason_code
);
2096 /* todo: how to notify the host while receiving
2106 static int on_action_public23a(struct rtw_adapter
*padapter
,
2107 struct recv_frame
*precv_frame
)
2109 struct sk_buff
*skb
= precv_frame
->pkt
;
2110 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*) skb
->data
;
2111 u8
*pframe
= skb
->data
;
2114 /* check RA matches or not */
2115 if (!ether_addr_equal(myid(&padapter
->eeprompriv
), hdr
->addr1
))
2118 channel
= rtw_get_oper_ch23a(padapter
);
2120 if (channel
<= RTW_CH_MAX_2G_CHANNEL
)
2121 freq
= ieee80211_channel_to_frequency(channel
,
2122 IEEE80211_BAND_2GHZ
);
2124 freq
= ieee80211_channel_to_frequency(channel
,
2125 IEEE80211_BAND_5GHZ
);
2127 if (cfg80211_rx_mgmt(padapter
->rtw_wdev
, freq
, 0, pframe
,
2135 OnAction23a_ht(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
2141 OnAction23a_wmm(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
2147 OnAction23a_p2p(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
2153 OnAction23a(struct rtw_adapter
*padapter
, struct recv_frame
*precv_frame
)
2157 struct action_handler
*ptable
;
2158 struct sk_buff
*skb
= precv_frame
->pkt
;
2159 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
2161 category
= mgmt
->u
.action
.category
;
2164 i
< sizeof(OnAction23a_tbl
) / sizeof(struct action_handler
); i
++) {
2165 ptable
= &OnAction23a_tbl
[i
];
2167 if (category
== ptable
->num
)
2168 ptable
->func(padapter
, precv_frame
);
2174 static int DoReserved23a(struct rtw_adapter
*padapter
,
2175 struct recv_frame
*precv_frame
)
2180 struct xmit_frame
*alloc_mgtxmitframe23a(struct xmit_priv
*pxmitpriv
)
2182 struct xmit_frame
*pmgntframe
;
2183 struct xmit_buf
*pxmitbuf
;
2185 pmgntframe
= rtw_alloc_xmitframe23a_ext(pxmitpriv
);
2188 DBG_8723A("%s(%s): alloc xmitframe fail\n", __func__
,
2189 pxmitpriv
->adapter
->pnetdev
->name
);
2193 pxmitbuf
= rtw_alloc_xmitbuf23a_ext(pxmitpriv
);
2195 DBG_8723A("%s(%s): alloc xmitbuf fail\n", __func__
,
2196 pxmitpriv
->adapter
->pnetdev
->name
);
2197 rtw_free_xmitframe23a(pxmitpriv
, pmgntframe
);
2202 pmgntframe
->frame_tag
= MGNT_FRAMETAG
;
2203 pmgntframe
->pxmitbuf
= pxmitbuf
;
2204 pmgntframe
->buf_addr
= pxmitbuf
->pbuf
;
2205 pxmitbuf
->priv_data
= pmgntframe
;
2211 /****************************************************************************
2213 Following are some TX functions for WiFi MLME
2215 *****************************************************************************/
2217 void update_mgnt_tx_rate23a(struct rtw_adapter
*padapter
, u8 rate
)
2219 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2221 pmlmeext
->tx_rate
= rate
;
2222 DBG_8723A("%s(): rate = %x\n", __func__
, rate
);
2225 void update_mgntframe_attrib23a(struct rtw_adapter
*padapter
,
2226 struct pkt_attrib
*pattrib
)
2228 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2230 memset((u8
*)pattrib
, 0, sizeof(struct pkt_attrib
));
2232 pattrib
->hdrlen
= 24;
2233 pattrib
->nr_frags
= 1;
2234 pattrib
->priority
= 7;
2235 pattrib
->mac_id
= 0;
2236 pattrib
->qsel
= 0x12;
2238 pattrib
->pktlen
= 0;
2240 if (pmlmeext
->cur_wireless_mode
& WIRELESS_11B
)
2241 pattrib
->raid
= 6;/* b mode */
2243 pattrib
->raid
= 5;/* a/g mode */
2245 pattrib
->encrypt
= 0;
2246 pattrib
->bswenc
= false;
2248 pattrib
->qos_en
= false;
2249 pattrib
->ht_en
= false;
2250 pattrib
->bwmode
= HT_CHANNEL_WIDTH_20
;
2251 pattrib
->ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
2252 pattrib
->sgi
= false;
2254 pattrib
->seqnum
= pmlmeext
->mgnt_seq
;
2256 pattrib
->retry_ctrl
= true;
2259 void dump_mgntframe23a(struct rtw_adapter
*padapter
,
2260 struct xmit_frame
*pmgntframe
)
2262 if (padapter
->bSurpriseRemoved
== true ||
2263 padapter
->bDriverStopped
== true)
2266 rtl8723au_mgnt_xmit(padapter
, pmgntframe
);
2269 int dump_mgntframe23a_and_wait(struct rtw_adapter
*padapter
,
2270 struct xmit_frame
*pmgntframe
, int timeout_ms
)
2274 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
2275 struct xmit_buf
*pxmitbuf
= pmgntframe
->pxmitbuf
;
2276 struct submit_ctx sctx
;
2278 if (padapter
->bSurpriseRemoved
== true ||
2279 padapter
->bDriverStopped
== true)
2282 rtw_sctx_init23a(&sctx
, timeout_ms
);
2283 pxmitbuf
->sctx
= &sctx
;
2285 ret
= rtl8723au_mgnt_xmit(padapter
, pmgntframe
);
2287 if (ret
== _SUCCESS
)
2288 ret
= rtw_sctx_wait23a(&sctx
);
2290 spin_lock_irqsave(&pxmitpriv
->lock_sctx
, irqL
);
2291 pxmitbuf
->sctx
= NULL
;
2292 spin_unlock_irqrestore(&pxmitpriv
->lock_sctx
, irqL
);
2297 int dump_mgntframe23a_and_wait_ack23a(struct rtw_adapter
*padapter
,
2298 struct xmit_frame
*pmgntframe
)
2301 u32 timeout_ms
= 500;/* 500ms */
2302 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
2304 if (padapter
->bSurpriseRemoved
== true ||
2305 padapter
->bDriverStopped
== true)
2308 mutex_lock(&pxmitpriv
->ack_tx_mutex
);
2309 pxmitpriv
->ack_tx
= true;
2311 pmgntframe
->ack_report
= 1;
2312 if (rtl8723au_mgnt_xmit(padapter
, pmgntframe
) == _SUCCESS
)
2313 ret
= rtw_ack_tx_wait23a(pxmitpriv
, timeout_ms
);
2315 pxmitpriv
->ack_tx
= false;
2316 mutex_unlock(&pxmitpriv
->ack_tx_mutex
);
2321 static int update_hidden_ssid(u8
*ies
, u32 ies_len
, u8 hidden_ssid_mode
)
2329 ssid_ie
= rtw_get_ie23a(ies
, WLAN_EID_SSID
, &ssid_len_ori
, ies_len
);
2331 /* DBG_8723A("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n",
2332 __func__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
2334 if (ssid_ie
&& ssid_len_ori
> 0) {
2335 switch (hidden_ssid_mode
) {
2337 next_ie
= ssid_ie
+ 2 + ssid_len_ori
;
2338 remain_len
= ies_len
-(next_ie
-ies
);
2341 memcpy(ssid_ie
+2, next_ie
, remain_len
);
2342 len_diff
-= ssid_len_ori
;
2346 memset(&ssid_ie
[2], 0, ssid_len_ori
);
2356 void issue_beacon23a(struct rtw_adapter
*padapter
, int timeout_ms
)
2358 struct xmit_frame
*pmgntframe
;
2359 struct pkt_attrib
*pattrib
;
2360 unsigned char *pframe
;
2361 struct ieee80211_mgmt
*mgmt
;
2362 unsigned int rate_len
;
2363 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
2364 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2365 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2366 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
2367 struct wlan_bssid_ex
*cur_network
= &pmlmeinfo
->network
;
2368 u8 bc_addr
[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2373 /* DBG_8723A("%s\n", __func__); */
2375 pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
);
2377 DBG_8723A("%s, alloc mgnt frame fail\n", __func__
);
2380 #ifdef CONFIG_8723AU_AP_MODE
2381 spin_lock_bh(&pmlmepriv
->bcn_update_lock
);
2384 /* update attribute */
2385 pattrib
= &pmgntframe
->attrib
;
2386 update_mgntframe_attrib23a(padapter
, pattrib
);
2387 pattrib
->qsel
= 0x10;
2389 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
2391 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
2392 mgmt
= (struct ieee80211_mgmt
*)pframe
;
2394 mgmt
->frame_control
=
2395 cpu_to_le16(IEEE80211_FTYPE_MGMT
| IEEE80211_STYPE_BEACON
);
2398 ether_addr_copy(mgmt
->da
, bc_addr
);
2399 ether_addr_copy(mgmt
->sa
, myid(&padapter
->eeprompriv
));
2400 ether_addr_copy(mgmt
->bssid
, get_my_bssid23a(cur_network
));
2402 /* timestamp will be inserted by hardware */
2404 put_unaligned_le16(cur_network
->beacon_interval
,
2405 &mgmt
->u
.beacon
.beacon_int
);
2407 put_unaligned_le16(cur_network
->capability
,
2408 &mgmt
->u
.beacon
.capab_info
);
2410 pframe
= mgmt
->u
.beacon
.variable
;
2411 pattrib
->pktlen
= offsetof(struct ieee80211_mgmt
, u
.beacon
.variable
);
2413 if ((pmlmeinfo
->state
& 0x03) == MSR_AP
) {
2416 /* DBG_8723A("ie len =%d\n", cur_network->IELength); */
2417 memcpy(pframe
, cur_network
->IEs
, cur_network
->IELength
);
2418 len_diff
= update_hidden_ssid(pframe
, cur_network
->IELength
,
2419 pmlmeinfo
->hidden_ssid_mode
);
2420 pframe
+= (cur_network
->IELength
+len_diff
);
2421 pattrib
->pktlen
+= (cur_network
->IELength
+len_diff
);
2423 iebuf
= mgmt
->u
.beacon
.variable
;
2424 buflen
= pattrib
->pktlen
-
2425 offsetof(struct ieee80211_mgmt
, u
.beacon
.variable
);
2426 wps_ie
= cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT
,
2427 WLAN_OUI_TYPE_MICROSOFT_WPS
,
2430 if (wps_ie
&& wps_ie
[1] > 0) {
2431 rtw_get_wps_attr_content23a(wps_ie
, wps_ie
[1],
2432 WPS_ATTR_SELECTED_REGISTRAR
,
2436 set_fwstate(pmlmepriv
, WIFI_UNDER_WPS
);
2438 _clr_fwstate_(pmlmepriv
, WIFI_UNDER_WPS
);
2444 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SSID
,
2445 cur_network
->Ssid
.ssid_len
,
2446 cur_network
->Ssid
.ssid
, &pattrib
->pktlen
);
2448 /* supported rates... */
2449 rate_len
= rtw_get_rateset_len23a(cur_network
->SupportedRates
);
2450 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SUPP_RATES
,
2451 ((rate_len
> 8)? 8: rate_len
),
2452 cur_network
->SupportedRates
, &pattrib
->pktlen
);
2454 /* DS parameter set */
2455 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_DS_PARAMS
, 1, (unsigned char *)
2456 &cur_network
->DSConfig
, &pattrib
->pktlen
);
2458 /* if ((pmlmeinfo->state&0x03) == MSR_ADHOC) */
2462 /* IBSS Parameter Set... */
2463 /* ATIMWindow = cur->ATIMWindow; */
2465 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_IBSS_PARAMS
, 2,
2466 (unsigned char *)&ATIMWindow
,
2470 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_ERP_INFO
, 1,
2471 &erpinfo
, &pattrib
->pktlen
);
2474 /* EXTERNDED SUPPORTED RATE */
2476 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_EXT_SUPP_RATES
,
2478 cur_network
->SupportedRates
+ 8,
2481 /* todo:HT for adhoc */
2485 #ifdef CONFIG_8723AU_AP_MODE
2486 pmlmepriv
->update_bcn
= false;
2488 spin_unlock_bh(&pmlmepriv
->bcn_update_lock
);
2491 if ((pattrib
->pktlen
+ TXDESC_SIZE
) > 512) {
2492 DBG_8723A("beacon frame too large\n");
2496 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
2498 /* DBG_8723A("issue bcn_sz =%d\n", pattrib->last_txcmdsz); */
2500 dump_mgntframe23a_and_wait(padapter
, pmgntframe
, timeout_ms
);
2502 dump_mgntframe23a(padapter
, pmgntframe
);
2505 static void issue_probersp(struct rtw_adapter
*padapter
, unsigned char *da
)
2507 struct xmit_frame
*pmgntframe
;
2508 struct pkt_attrib
*pattrib
;
2509 unsigned char *pframe
;
2510 struct ieee80211_mgmt
*mgmt
;
2511 unsigned char *mac
, *bssid
;
2512 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
2513 #ifdef CONFIG_8723AU_AP_MODE
2517 int ssid_ielen_diff
;
2520 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2521 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
2522 struct wlan_bssid_ex
*cur_network
= &pmlmeinfo
->network
;
2523 unsigned int rate_len
;
2525 /* DBG_8723A("%s\n", __func__); */
2527 if (cur_network
->IELength
> MAX_IE_SZ
)
2530 pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
);
2532 DBG_8723A("%s, alloc mgnt frame fail\n", __func__
);
2536 /* update attribute */
2537 pattrib
= &pmgntframe
->attrib
;
2538 update_mgntframe_attrib23a(padapter
, pattrib
);
2540 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
2542 pframe
= (u8
*)pmgntframe
->buf_addr
+ TXDESC_OFFSET
;
2543 mgmt
= (struct ieee80211_mgmt
*)pframe
;
2545 mac
= myid(&padapter
->eeprompriv
);
2546 bssid
= cur_network
->MacAddress
;
2548 mgmt
->frame_control
=
2549 cpu_to_le16(IEEE80211_FTYPE_MGMT
| IEEE80211_STYPE_PROBE_RESP
);
2551 ether_addr_copy(mgmt
->da
, da
);
2552 ether_addr_copy(mgmt
->sa
, mac
);
2553 ether_addr_copy(mgmt
->bssid
, bssid
);
2555 mgmt
->seq_ctrl
= cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext
->mgnt_seq
));
2556 pmlmeext
->mgnt_seq
++;
2558 pattrib
->hdrlen
= sizeof(struct ieee80211_hdr_3addr
);
2560 /* timestamp will be inserted by hardware */
2561 put_unaligned_le16(cur_network
->beacon_interval
,
2562 &mgmt
->u
.probe_resp
.beacon_int
);
2564 put_unaligned_le16(cur_network
->capability
,
2565 &mgmt
->u
.probe_resp
.capab_info
);
2567 pframe
= mgmt
->u
.probe_resp
.variable
;
2569 offsetof(struct ieee80211_mgmt
, u
.probe_resp
.variable
);
2571 /* below for ad-hoc mode */
2573 #ifdef CONFIG_8723AU_AP_MODE
2574 if ((pmlmeinfo
->state
& 0x03) == MSR_AP
) {
2575 pwps_ie
= cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT
,
2576 WLAN_OUI_TYPE_MICROSOFT_WPS
,
2578 cur_network
->IELength
);
2580 memcpy(pframe
, cur_network
->IEs
, cur_network
->IELength
);
2581 pframe
+= cur_network
->IELength
;
2582 pattrib
->pktlen
+= cur_network
->IELength
;
2584 /* retrieve SSID IE from cur_network->Ssid */
2586 ssid_ie
= rtw_get_ie23a(mgmt
->u
.probe_resp
.variable
,
2587 WLAN_EID_SSID
, &ssid_ielen
,
2588 pframe
- mgmt
->u
.probe_resp
.variable
);
2590 ssid_ielen_diff
= cur_network
->Ssid
.ssid_len
- ssid_ielen
;
2592 if (ssid_ie
&& cur_network
->Ssid
.ssid_len
) {
2593 uint remainder_ielen
;
2596 remainder_ie
= ssid_ie
+ 2;
2598 remainder_ielen
= pframe
- remainder_ie
;
2600 DBG_8723A_LEVEL(_drv_warning_
, "%s(%s): "
2601 "remainder_ielen > MAX_IE_SZ\n",
2602 __func__
, padapter
->pnetdev
->name
);
2603 if (remainder_ielen
> MAX_IE_SZ
)
2604 remainder_ielen
= MAX_IE_SZ
;
2606 memcpy(buf
, remainder_ie
, remainder_ielen
);
2607 memcpy(remainder_ie
+ ssid_ielen_diff
, buf
,
2609 *(ssid_ie
+ 1) = cur_network
->Ssid
.ssid_len
;
2610 memcpy(ssid_ie
+ 2, cur_network
->Ssid
.ssid
,
2611 cur_network
->Ssid
.ssid_len
);
2613 pframe
+= ssid_ielen_diff
;
2614 pattrib
->pktlen
+= ssid_ielen_diff
;
2620 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SSID
,
2621 cur_network
->Ssid
.ssid_len
,
2622 cur_network
->Ssid
.ssid
,
2625 /* supported rates... */
2626 rate_len
= rtw_get_rateset_len23a(cur_network
->SupportedRates
);
2627 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SUPP_RATES
,
2628 ((rate_len
> 8)? 8: rate_len
),
2629 cur_network
->SupportedRates
,
2632 /* DS parameter set */
2633 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_DS_PARAMS
, 1,
2634 (unsigned char *)&cur_network
->DSConfig
,
2637 if ((pmlmeinfo
->state
& 0x03) == MSR_ADHOC
) {
2640 /* IBSS Parameter Set... */
2641 /* ATIMWindow = cur->ATIMWindow; */
2643 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_IBSS_PARAMS
, 2,
2644 (unsigned char *)&ATIMWindow
,
2648 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_ERP_INFO
, 1,
2649 &erpinfo
, &pattrib
->pktlen
);
2652 /* EXTERNDED SUPPORTED RATE */
2654 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_EXT_SUPP_RATES
,
2656 cur_network
->SupportedRates
+ 8,
2659 /* todo:HT for adhoc */
2662 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
2664 dump_mgntframe23a(padapter
, pmgntframe
);
2669 static int _issue_probereq(struct rtw_adapter
*padapter
,
2670 struct cfg80211_ssid
*pssid
, u8
*da
, int wait_ack
)
2673 struct xmit_frame
*pmgntframe
;
2674 struct pkt_attrib
*pattrib
;
2675 unsigned char *pframe
;
2676 struct ieee80211_hdr
*pwlanhdr
;
2678 unsigned char bssrate
[NumRates
];
2679 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
2680 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2681 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2682 int bssrate_len
= 0;
2683 u8 bc_addr
[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
2685 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
,
2688 pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
);
2692 /* update attribute */
2693 pattrib
= &pmgntframe
->attrib
;
2694 update_mgntframe_attrib23a(padapter
, pattrib
);
2696 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
2698 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
2699 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
2701 mac
= myid(&padapter
->eeprompriv
);
2703 pwlanhdr
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_MGMT
|
2704 IEEE80211_STYPE_PROBE_REQ
);
2707 /* unicast probe request frame */
2708 ether_addr_copy(pwlanhdr
->addr1
, da
);
2709 ether_addr_copy(pwlanhdr
->addr3
, da
);
2711 /* broadcast probe request frame */
2712 ether_addr_copy(pwlanhdr
->addr1
, bc_addr
);
2713 ether_addr_copy(pwlanhdr
->addr3
, bc_addr
);
2716 ether_addr_copy(pwlanhdr
->addr2
, mac
);
2718 pwlanhdr
->seq_ctrl
=
2719 cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext
->mgnt_seq
));
2721 pmlmeext
->mgnt_seq
++;
2723 pframe
+= sizeof (struct ieee80211_hdr_3addr
);
2724 pattrib
->pktlen
= sizeof (struct ieee80211_hdr_3addr
);
2727 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SSID
, pssid
->ssid_len
,
2728 pssid
->ssid
, &pattrib
->pktlen
);
2730 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SSID
, 0, NULL
,
2733 get_rate_set23a(padapter
, bssrate
, &bssrate_len
);
2735 if (bssrate_len
> 8) {
2736 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SUPP_RATES
, 8,
2737 bssrate
, &pattrib
->pktlen
);
2738 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_EXT_SUPP_RATES
,
2739 (bssrate_len
- 8), (bssrate
+ 8),
2742 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SUPP_RATES
,
2743 bssrate_len
, bssrate
, &pattrib
->pktlen
);
2746 /* add wps_ie for wps2.0 */
2747 if (pmlmepriv
->wps_probe_req_ie_len
>0 && pmlmepriv
->wps_probe_req_ie
) {
2748 memcpy(pframe
, pmlmepriv
->wps_probe_req_ie
,
2749 pmlmepriv
->wps_probe_req_ie_len
);
2750 pframe
+= pmlmepriv
->wps_probe_req_ie_len
;
2751 pattrib
->pktlen
+= pmlmepriv
->wps_probe_req_ie_len
;
2754 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
2756 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
,
2757 "issuing probe_req, tx_len =%d\n", pattrib
->last_txcmdsz
);
2760 ret
= dump_mgntframe23a_and_wait_ack23a(padapter
, pmgntframe
);
2762 dump_mgntframe23a(padapter
, pmgntframe
);
2770 static inline void issue_probereq(struct rtw_adapter
*padapter
,
2771 struct cfg80211_ssid
*pssid
, u8
*da
)
2773 _issue_probereq(padapter
, pssid
, da
, false);
2776 static int issue_probereq_ex(struct rtw_adapter
*padapter
,
2777 struct cfg80211_ssid
*pssid
, u8
*da
,
2778 int try_cnt
, int wait_ms
)
2782 unsigned long start
= jiffies
;
2785 ret
= _issue_probereq(padapter
, pssid
, da
,
2786 wait_ms
> 0 ? true : false);
2790 if (padapter
->bDriverStopped
|| padapter
->bSurpriseRemoved
)
2793 if (i
< try_cnt
&& wait_ms
> 0 && ret
== _FAIL
)
2796 } while((i
< try_cnt
) && ((ret
== _FAIL
) || (wait_ms
== 0)));
2803 if (try_cnt
&& wait_ms
) {
2805 DBG_8723A("%s(%s): to %pM, ch:%u%s, %d/%d in %u ms\n",
2806 __func__
, padapter
->pnetdev
->name
,
2807 da
, rtw_get_oper_ch23a(padapter
),
2808 ret
== _SUCCESS
? ", acked" : "", i
, try_cnt
,
2809 jiffies_to_msecs(jiffies
- start
));
2811 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
2812 __func__
, padapter
->pnetdev
->name
,
2813 rtw_get_oper_ch23a(padapter
),
2814 ret
== _SUCCESS
? ", acked" : "", i
, try_cnt
,
2815 jiffies_to_msecs(jiffies
- start
));
2821 /* if psta == NULL, indiate we are station(client) now... */
2822 static void issue_auth(struct rtw_adapter
*padapter
, struct sta_info
*psta
,
2823 unsigned short status
)
2825 struct xmit_frame
*pmgntframe
;
2826 struct pkt_attrib
*pattrib
;
2827 unsigned char *pframe
;
2828 struct ieee80211_mgmt
*mgmt
;
2831 int use_shared_key
= 0;
2832 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
2833 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2834 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
2836 pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
);
2840 /* update attribute */
2841 pattrib
= &pmgntframe
->attrib
;
2842 update_mgntframe_attrib23a(padapter
, pattrib
);
2844 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
2846 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
2847 mgmt
= (struct ieee80211_mgmt
*)pframe
;
2849 mgmt
->frame_control
=
2850 cpu_to_le16(IEEE80211_FTYPE_MGMT
| IEEE80211_STYPE_AUTH
);
2851 mgmt
->seq_ctrl
= cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext
->mgnt_seq
));
2852 pmlmeext
->mgnt_seq
++;
2854 pattrib
->pktlen
= offsetof(struct ieee80211_mgmt
, u
.auth
.variable
);
2856 if (psta
) { /* for AP mode */
2857 #ifdef CONFIG_8723AU_AP_MODE
2858 unsigned short val16
;
2860 ether_addr_copy(mgmt
->da
, psta
->hwaddr
);
2861 ether_addr_copy(mgmt
->sa
, myid(&padapter
->eeprompriv
));
2862 ether_addr_copy(mgmt
->bssid
, myid(&padapter
->eeprompriv
));
2864 /* setting auth algo number */
2865 val16
= (u16
)psta
->authalg
;
2867 if (status
!= WLAN_STATUS_SUCCESS
)
2873 mgmt
->u
.auth
.auth_alg
= cpu_to_le16(val16
);
2875 /* setting auth seq number */
2876 mgmt
->u
.auth
.auth_transaction
=
2877 cpu_to_le16((u16
)psta
->auth_seq
);
2879 /* setting status code... */
2880 mgmt
->u
.auth
.status_code
= cpu_to_le16(status
);
2882 pframe
= mgmt
->u
.auth
.variable
;
2883 /* added challenging text... */
2884 if ((psta
->auth_seq
== 2) &&
2885 (psta
->state
& WIFI_FW_AUTH_STATE
) && (use_shared_key
== 1))
2886 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_CHALLENGE
, 128,
2887 psta
->chg_txt
, &pattrib
->pktlen
);
2890 struct ieee80211_mgmt
*iv_mgmt
;
2892 ether_addr_copy(mgmt
->da
, get_my_bssid23a(&pmlmeinfo
->network
));
2893 ether_addr_copy(mgmt
->sa
, myid(&padapter
->eeprompriv
));
2894 ether_addr_copy(mgmt
->bssid
,
2895 get_my_bssid23a(&pmlmeinfo
->network
));
2897 /* setting auth algo number */
2898 /* 0:OPEN System, 1:Shared key */
2899 if (pmlmeinfo
->auth_algo
== dot11AuthAlgrthm_Shared
) {
2901 auth_algo
= WLAN_AUTH_SHARED_KEY
;
2903 auth_algo
= WLAN_AUTH_OPEN
;
2905 /* DBG_8723A("%s auth_algo = %s auth_seq =%d\n", __func__,
2906 (pmlmeinfo->auth_algo == 0)?"OPEN":"SHARED",
2907 pmlmeinfo->auth_seq); */
2909 /* setting IV for auth seq #3 */
2910 if ((pmlmeinfo
->auth_seq
== 3) &&
2911 (pmlmeinfo
->state
& WIFI_FW_AUTH_STATE
) &&
2912 (use_shared_key
== 1)) {
2913 u32
*piv
= (u32
*)&mgmt
->u
.auth
;
2915 iv_mgmt
= (struct ieee80211_mgmt
*)(pframe
+ 4);
2916 /* DBG_8723A("==> iv(%d), key_index(%d)\n",
2917 pmlmeinfo->iv, pmlmeinfo->key_index); */
2918 val32
= (pmlmeinfo
->iv
& 0x3fffffff) |
2919 (pmlmeinfo
->key_index
<< 30);
2921 put_unaligned_le32(val32
, piv
);
2923 pattrib
->pktlen
+= 4;
2925 pattrib
->iv_len
= IEEE80211_WEP_IV_LEN
;
2929 iv_mgmt
->u
.auth
.auth_alg
= cpu_to_le16(auth_algo
);
2931 /* setting auth seq number */
2932 iv_mgmt
->u
.auth
.auth_transaction
=
2933 cpu_to_le16(pmlmeinfo
->auth_seq
);
2935 /* setting status code... */
2936 iv_mgmt
->u
.auth
.status_code
= cpu_to_le16(status
);
2938 pframe
= iv_mgmt
->u
.auth
.variable
;
2940 /* then checking to see if sending challenging text... */
2941 if ((pmlmeinfo
->auth_seq
== 3) &&
2942 (pmlmeinfo
->state
& WIFI_FW_AUTH_STATE
) &&
2943 (use_shared_key
== 1)) {
2944 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_CHALLENGE
, 128,
2948 mgmt
->frame_control
|=
2949 cpu_to_le16(IEEE80211_FCTL_PROTECTED
);
2951 pattrib
->hdrlen
= sizeof(struct ieee80211_hdr_3addr
);
2953 pattrib
->encrypt
= WLAN_CIPHER_SUITE_WEP40
;
2955 pattrib
->icv_len
= IEEE80211_WEP_ICV_LEN
;
2957 pattrib
->pktlen
+= pattrib
->icv_len
;
2961 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
2963 rtw_wep_encrypt23a(padapter
, pmgntframe
);
2964 DBG_8723A("%s\n", __func__
);
2965 dump_mgntframe23a(padapter
, pmgntframe
);
2970 #ifdef CONFIG_8723AU_AP_MODE
2971 static void issue_assocrsp(struct rtw_adapter
*padapter
, unsigned short status
,
2972 struct sta_info
*pstat
, u16 pkt_type
)
2974 struct xmit_frame
*pmgntframe
;
2975 struct ieee80211_mgmt
*mgmt
;
2976 struct pkt_attrib
*pattrib
;
2977 unsigned char *pframe
;
2978 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
2979 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2980 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
2981 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
2982 struct wlan_bssid_ex
*pnetwork
= &pmlmeinfo
->network
;
2984 u8
*ie
= pnetwork
->IEs
;
2986 DBG_8723A("%s\n", __func__
);
2988 pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
);
2992 /* update attribute */
2993 pattrib
= &pmgntframe
->attrib
;
2994 update_mgntframe_attrib23a(padapter
, pattrib
);
2996 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
2998 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
2999 mgmt
= (struct ieee80211_mgmt
*)pframe
;
3001 mgmt
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_MGMT
| pkt_type
);
3003 ether_addr_copy(mgmt
->da
, pstat
->hwaddr
);
3004 ether_addr_copy(mgmt
->sa
, myid(&padapter
->eeprompriv
));
3005 ether_addr_copy(mgmt
->bssid
, get_my_bssid23a(&pmlmeinfo
->network
));
3007 mgmt
->seq_ctrl
= cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext
->mgnt_seq
));
3009 pmlmeext
->mgnt_seq
++;
3011 pattrib
->hdrlen
= sizeof(struct ieee80211_hdr_3addr
);
3013 offsetof(struct ieee80211_mgmt
, u
.assoc_resp
.variable
);
3015 mgmt
->u
.assoc_resp
.capab_info
= cpu_to_le16(pnetwork
->capability
);
3016 mgmt
->u
.assoc_resp
.status_code
= cpu_to_le16(status
);
3017 mgmt
->u
.assoc_resp
.aid
= cpu_to_le16(pstat
->aid
| BIT(14) | BIT(15));
3019 pframe
= mgmt
->u
.assoc_resp
.variable
;
3021 if (pstat
->bssratelen
<= 8) {
3022 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SUPP_RATES
,
3023 pstat
->bssratelen
, pstat
->bssrateset
,
3026 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SUPP_RATES
, 8,
3027 pstat
->bssrateset
, &pattrib
->pktlen
);
3028 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_EXT_SUPP_RATES
,
3029 pstat
->bssratelen
- 8,
3030 pstat
->bssrateset
+ 8, &pattrib
->pktlen
);
3033 if (pstat
->flags
& WLAN_STA_HT
&& pmlmepriv
->htpriv
.ht_option
) {
3034 /* FILL HT CAP INFO IE */
3035 /* p = hostapd_eid_ht_capabilities_info(hapd, p); */
3036 p
= cfg80211_find_ie(WLAN_EID_HT_CAPABILITY
, ie
,
3037 pnetwork
->IELength
);
3039 memcpy(pframe
, p
, p
[1] + 2);
3040 pframe
+= (p
[1] + 2);
3041 pattrib
->pktlen
+= (p
[1] + 2);
3044 /* FILL HT ADD INFO IE */
3045 /* p = hostapd_eid_ht_operation(hapd, p); */
3046 p
= cfg80211_find_ie(WLAN_EID_HT_OPERATION
, ie
,
3047 pnetwork
->IELength
);
3048 if (p
&& p
[1] > 0) {
3049 memcpy(pframe
, p
, p
[1] + 2);
3050 pframe
+= (p
[1] + 2);
3051 pattrib
->pktlen
+= (p
[1] + 2);
3056 if (pstat
->flags
& WLAN_STA_WME
&& pmlmepriv
->qos_option
) {
3057 unsigned char WMM_PARA_IE
[] = {0x00, 0x50, 0xf2, 0x02,
3061 for (p
= ie
; ; p
+= (ie_len
+ 2)) {
3062 p
= cfg80211_find_ie(WLAN_EID_VENDOR_SPECIFIC
, p
,
3063 pnetwork
->IELength
- (ie_len
+ 2));
3068 if (p
&& !memcmp(p
+ 2, WMM_PARA_IE
, 6)) {
3069 memcpy(pframe
, p
, ie_len
+ 2);
3070 pframe
+= (ie_len
+ 2);
3071 pattrib
->pktlen
+= (ie_len
+ 2);
3076 if (!p
|| ie_len
== 0)
3081 if (pmlmeinfo
->assoc_AP_vendor
== HT_IOT_PEER_REALTEK
) {
3082 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_VENDOR_SPECIFIC
, 6,
3083 REALTEK_96B_IE
, &pattrib
->pktlen
);
3086 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
3088 dump_mgntframe23a(padapter
, pmgntframe
);
3092 static void issue_assocreq(struct rtw_adapter
*padapter
)
3095 struct xmit_frame
*pmgntframe
;
3096 struct pkt_attrib
*pattrib
;
3097 unsigned char *pframe
;
3099 struct ieee80211_mgmt
*mgmt
;
3100 unsigned int i
, j
, index
= 0;
3101 unsigned char rf_type
, bssrate
[NumRates
], sta_bssrate
[NumRates
];
3102 struct registry_priv
*pregpriv
= &padapter
->registrypriv
;
3103 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
3104 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
3105 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3106 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
3107 int bssrate_len
= 0, sta_bssrate_len
= 0, pie_len
;
3110 pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
);
3114 /* update attribute */
3115 pattrib
= &pmgntframe
->attrib
;
3116 update_mgntframe_attrib23a(padapter
, pattrib
);
3118 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
3120 pframe
= (u8
*)pmgntframe
->buf_addr
+ TXDESC_OFFSET
;
3121 mgmt
= (struct ieee80211_mgmt
*)pframe
;
3123 mgmt
->frame_control
=
3124 cpu_to_le16(IEEE80211_FTYPE_MGMT
| IEEE80211_STYPE_ASSOC_REQ
);
3126 ether_addr_copy(mgmt
->da
, get_my_bssid23a(&pmlmeinfo
->network
));
3127 ether_addr_copy(mgmt
->sa
, myid(&padapter
->eeprompriv
));
3128 ether_addr_copy(mgmt
->bssid
, get_my_bssid23a(&pmlmeinfo
->network
));
3130 mgmt
->seq_ctrl
= cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext
->mgnt_seq
));
3131 pmlmeext
->mgnt_seq
++;
3134 put_unaligned_le16(pmlmeinfo
->network
.capability
,
3135 &mgmt
->u
.assoc_req
.capab_info
);
3136 /* todo: listen interval for power saving */
3137 put_unaligned_le16(3, &mgmt
->u
.assoc_req
.listen_interval
);
3139 pframe
= mgmt
->u
.assoc_req
.variable
;
3140 pattrib
->pktlen
= offsetof(struct ieee80211_mgmt
, u
.assoc_req
.variable
);
3143 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SSID
,
3144 pmlmeinfo
->network
.Ssid
.ssid_len
,
3145 pmlmeinfo
->network
.Ssid
.ssid
, &pattrib
->pktlen
);
3147 /* supported rate & extended supported rate */
3149 get_rate_set23a(padapter
, sta_bssrate
, &sta_bssrate_len
);
3150 /* DBG_8723A("sta_bssrate_len =%d\n", sta_bssrate_len); */
3152 /* for JAPAN, channel 14 can only uses B Mode(CCK) */
3153 if (pmlmeext
->cur_channel
== 14)
3154 sta_bssrate_len
= 4;
3156 /* for (i = 0; i < sta_bssrate_len; i++) { */
3157 /* DBG_8723A("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
3160 for (i
= 0; i
< NDIS_802_11_LENGTH_RATES_EX
; i
++) {
3161 if (pmlmeinfo
->network
.SupportedRates
[i
] == 0)
3163 DBG_8723A("network.SupportedRates[%d]=%02X\n", i
,
3164 pmlmeinfo
->network
.SupportedRates
[i
]);
3167 for (i
= 0; i
< NDIS_802_11_LENGTH_RATES_EX
; i
++) {
3168 if (pmlmeinfo
->network
.SupportedRates
[i
] == 0)
3171 /* Check if the AP's supported rates are also
3172 supported by STA. */
3173 for (j
= 0; j
< sta_bssrate_len
; j
++) {
3174 /* Avoid the proprietary data rate (22Mbps) of
3175 Handlink WSG-4000 AP */
3176 if ((pmlmeinfo
->network
.SupportedRates
[i
] |
3177 IEEE80211_BASIC_RATE_MASK
) ==
3178 (sta_bssrate
[j
] | IEEE80211_BASIC_RATE_MASK
)) {
3179 /* DBG_8723A("match i = %d, j =%d\n", i, j); */
3184 if (j
== sta_bssrate_len
) {
3185 /* the rate is not supported by STA */
3186 DBG_8723A("%s(): the rate[%d]=%02X is not supported by "
3187 "STA!\n", __func__
, i
,
3188 pmlmeinfo
->network
.SupportedRates
[i
]);
3190 /* the rate is supported by STA */
3191 bssrate
[index
++] = pmlmeinfo
->network
.SupportedRates
[i
];
3195 bssrate_len
= index
;
3196 DBG_8723A("bssrate_len = %d\n", bssrate_len
);
3198 if (bssrate_len
== 0) {
3199 rtw_free_xmitbuf23a(pxmitpriv
, pmgntframe
->pxmitbuf
);
3200 rtw_free_xmitframe23a(pxmitpriv
, pmgntframe
);
3201 goto exit
; /* don't connect to AP if no joint supported rate */
3204 if (bssrate_len
> 8) {
3205 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SUPP_RATES
, 8,
3206 bssrate
, &pattrib
->pktlen
);
3207 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_EXT_SUPP_RATES
,
3208 (bssrate_len
- 8), (bssrate
+ 8),
3211 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_SUPP_RATES
,
3212 bssrate_len
, bssrate
, &pattrib
->pktlen
);
3216 pie
= pmlmeinfo
->network
.IEs
;
3217 pie_len
= pmlmeinfo
->network
.IELength
;
3219 p
= cfg80211_find_ie(WLAN_EID_RSN
, pie
, pie_len
);
3221 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_RSN
, p
[1], p
+ 2,
3225 if (padapter
->mlmepriv
.htpriv
.ht_option
) {
3226 p
= cfg80211_find_ie(WLAN_EID_HT_CAPABILITY
, pie
, pie_len
);
3228 if (p
&& !is_ap_in_tkip23a(padapter
)) {
3229 struct ieee80211_ht_cap
*cap
= &pmlmeinfo
->ht_cap
;
3231 memcpy(cap
, p
+ 2, sizeof(struct ieee80211_ht_cap
));
3233 /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
3234 if (pregpriv
->cbw40_enable
== 0) {
3235 cap
->cap_info
&= ~cpu_to_le16(
3236 IEEE80211_HT_CAP_SGI_40
|
3237 IEEE80211_HT_CAP_SUP_WIDTH_20_40
);
3239 cap
->cap_info
|= cpu_to_le16(
3240 IEEE80211_HT_CAP_SUP_WIDTH_20_40
);
3243 /* todo: disable SM power save mode */
3244 cap
->cap_info
|= cpu_to_le16(IEEE80211_HT_CAP_SM_PS
);
3246 rf_type
= rtl8723a_get_rf_type(padapter
);
3247 /* switch (pregpriv->rf_config) */
3250 /* RX STBC One spatial stream */
3251 if (pregpriv
->rx_stbc
)
3252 cap
->cap_info
|= cpu_to_le16(1 << IEEE80211_HT_CAP_RX_STBC_SHIFT
);
3254 memcpy(&cap
->mcs
, MCS_rate_1R23A
, 16);
3260 /* enable for 2.4/5 GHz */
3261 if (pregpriv
->rx_stbc
== 0x3 ||
3262 (pmlmeext
->cur_wireless_mode
&
3264 /* enable for 2.4GHz */
3265 pregpriv
->rx_stbc
== 0x1) ||
3266 (pmlmeext
->cur_wireless_mode
&
3268 pregpriv
->rx_stbc
== 0x2) ||
3269 /* enable for 5GHz */
3270 pregpriv
->wifi_spec
== 1) {
3271 DBG_8723A("declare supporting RX "
3273 /* RX STBC two spatial stream */
3274 cap
->cap_info
|= cpu_to_le16(2 << IEEE80211_HT_CAP_RX_STBC_SHIFT
);
3276 memcpy(&cap
->mcs
, MCS_rate_2R23A
, 16);
3280 if (rtl8723a_BT_coexist(padapter
) &&
3281 rtl8723a_BT_using_antenna_1(padapter
)) {
3283 cap
->ampdu_params_info
&=
3284 ~IEEE80211_HT_AMPDU_PARM_FACTOR
;
3285 /* cap->ampdu_params_info |= MAX_AMPDU_FACTOR_8K */
3288 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_HT_CAPABILITY
,
3289 p
[1], (u8
*)&pmlmeinfo
->ht_cap
,
3294 /* vendor specific IE, such as WPA, WMM, WPS */
3295 for (i
= 0; i
< pmlmeinfo
->network
.IELength
;) {
3296 p
= pmlmeinfo
->network
.IEs
+ i
;
3299 case WLAN_EID_VENDOR_SPECIFIC
:
3300 if (!memcmp(p
+ 2, RTW_WPA_OUI23A_TYPE
, 4) ||
3301 !memcmp(p
+ 2, WMM_OUI23A
, 4) ||
3302 !memcmp(p
+ 2, WPS_OUI23A
, 4)) {
3305 if (!padapter
->registrypriv
.wifi_spec
) {
3306 /* Commented by Kurt 20110629 */
3307 /* In some older APs, WPS handshake */
3308 /* would be fail if we append vender
3309 extensions informations to AP */
3310 if (!memcmp(p
+ 2, WPS_OUI23A
, 4))
3313 pframe
= rtw_set_ie23a(pframe
,
3314 WLAN_EID_VENDOR_SPECIFIC
,
3327 if (pmlmeinfo
->assoc_AP_vendor
== HT_IOT_PEER_REALTEK
)
3328 pframe
= rtw_set_ie23a(pframe
, WLAN_EID_VENDOR_SPECIFIC
, 6,
3329 REALTEK_96B_IE
, &pattrib
->pktlen
);
3331 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
3332 dump_mgntframe23a(padapter
, pmgntframe
);
3337 pmlmepriv
->assoc_req_len
= 0;
3338 if (ret
== _SUCCESS
) {
3339 kfree(pmlmepriv
->assoc_req
);
3340 pmlmepriv
->assoc_req
= kmalloc(pattrib
->pktlen
, GFP_ATOMIC
);
3341 if (pmlmepriv
->assoc_req
) {
3342 memcpy(pmlmepriv
->assoc_req
, mgmt
, pattrib
->pktlen
);
3343 pmlmepriv
->assoc_req_len
= pattrib
->pktlen
;
3346 kfree(pmlmepriv
->assoc_req
);
3351 /* when wait_ack is true, this function should be called at process context */
3352 static int _issue_nulldata23a(struct rtw_adapter
*padapter
, unsigned char *da
,
3353 unsigned int power_mode
, int wait_ack
)
3356 struct xmit_frame
*pmgntframe
;
3357 struct pkt_attrib
*pattrib
;
3358 unsigned char *pframe
;
3359 struct ieee80211_hdr
*pwlanhdr
;
3360 struct xmit_priv
*pxmitpriv
;
3361 struct mlme_ext_priv
*pmlmeext
;
3362 struct mlme_ext_info
*pmlmeinfo
;
3364 /* DBG_8723A("%s:%d\n", __func__, power_mode); */
3369 pxmitpriv
= &padapter
->xmitpriv
;
3370 pmlmeext
= &padapter
->mlmeextpriv
;
3371 pmlmeinfo
= &pmlmeext
->mlmext_info
;
3373 pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
);
3377 /* update attribute */
3378 pattrib
= &pmgntframe
->attrib
;
3379 update_mgntframe_attrib23a(padapter
, pattrib
);
3380 pattrib
->retry_ctrl
= false;
3382 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
3384 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
3385 pwlanhdr
= (struct ieee80211_hdr
*)pframe
;
3387 pwlanhdr
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_DATA
|
3388 IEEE80211_STYPE_NULLFUNC
);
3390 if ((pmlmeinfo
->state
&0x03) == MSR_AP
)
3391 pwlanhdr
->frame_control
|= cpu_to_le16(IEEE80211_FCTL_FROMDS
);
3392 else if ((pmlmeinfo
->state
&0x03) == MSR_INFRA
)
3393 pwlanhdr
->frame_control
|= cpu_to_le16(IEEE80211_FCTL_TODS
);
3396 pwlanhdr
->frame_control
|= cpu_to_le16(IEEE80211_FCTL_PM
);
3398 ether_addr_copy(pwlanhdr
->addr1
, da
);
3399 ether_addr_copy(pwlanhdr
->addr2
, myid(&padapter
->eeprompriv
));
3400 ether_addr_copy(pwlanhdr
->addr3
, get_my_bssid23a(&pmlmeinfo
->network
));
3402 pwlanhdr
->seq_ctrl
=
3403 cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext
->mgnt_seq
));
3404 pmlmeext
->mgnt_seq
++;
3406 pframe
+= sizeof(struct ieee80211_hdr_3addr
);
3407 pattrib
->pktlen
= sizeof(struct ieee80211_hdr_3addr
);
3409 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
3412 ret
= dump_mgntframe23a_and_wait_ack23a(padapter
, pmgntframe
);
3414 dump_mgntframe23a(padapter
, pmgntframe
);
3422 /* when wait_ms >0 , this function should be called at process context */
3423 /* da == NULL for station mode */
3424 int issue_nulldata23a(struct rtw_adapter
*padapter
, unsigned char *da
,
3425 unsigned int power_mode
, int try_cnt
, int wait_ms
)
3429 unsigned long start
= jiffies
;
3430 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3431 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
3433 /* da == NULL, assume it's null data for sta to ap*/
3435 da
= get_my_bssid23a(&pmlmeinfo
->network
);
3438 ret
= _issue_nulldata23a(padapter
, da
, power_mode
,
3439 wait_ms
> 0 ? true : false);
3443 if (padapter
->bDriverStopped
|| padapter
->bSurpriseRemoved
)
3446 if (i
< try_cnt
&& wait_ms
> 0 && ret
== _FAIL
)
3449 } while((i
< try_cnt
) && ((ret
== _FAIL
) || (wait_ms
== 0)));
3456 if (try_cnt
&& wait_ms
) {
3458 DBG_8723A("%s(%s): to %pM, ch:%u%s, %d/%d in %u ms\n",
3459 __func__
, padapter
->pnetdev
->name
,
3460 da
, rtw_get_oper_ch23a(padapter
),
3461 ret
== _SUCCESS
? ", acked" : "", i
, try_cnt
,
3462 jiffies_to_msecs(jiffies
- start
));
3464 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3465 __func__
, padapter
->pnetdev
->name
,
3466 rtw_get_oper_ch23a(padapter
),
3467 ret
== _SUCCESS
? ", acked" : "", i
, try_cnt
,
3468 jiffies_to_msecs(jiffies
- start
));
3474 /* when wait_ack is true, this function should be called at process context */
3475 static int _issue_qos_nulldata23a(struct rtw_adapter
*padapter
,
3476 unsigned char *da
, u16 tid
, int wait_ack
)
3479 struct xmit_frame
*pmgntframe
;
3480 struct pkt_attrib
*pattrib
;
3481 unsigned char *pframe
;
3482 struct ieee80211_qos_hdr
*pwlanhdr
;
3483 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
3484 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3485 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
3487 DBG_8723A("%s\n", __func__
);
3489 pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
);
3493 /* update attribute */
3494 pattrib
= &pmgntframe
->attrib
;
3495 update_mgntframe_attrib23a(padapter
, pattrib
);
3497 pattrib
->hdrlen
+= 2;
3498 pattrib
->qos_en
= true;
3500 pattrib
->ack_policy
= 0;
3503 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
3505 pframe
= (u8
*)(pmgntframe
->buf_addr
) + TXDESC_OFFSET
;
3506 pwlanhdr
= (struct ieee80211_qos_hdr
*)pframe
;
3508 pwlanhdr
->frame_control
= cpu_to_le16(IEEE80211_FTYPE_DATA
|
3509 IEEE80211_STYPE_QOS_NULLFUNC
);
3511 if ((pmlmeinfo
->state
&0x03) == MSR_AP
)
3512 pwlanhdr
->frame_control
|= cpu_to_le16(IEEE80211_FCTL_FROMDS
);
3513 else if ((pmlmeinfo
->state
&0x03) == MSR_INFRA
)
3514 pwlanhdr
->frame_control
|= cpu_to_le16(IEEE80211_FCTL_TODS
);
3517 pwlanhdr
->frame_control
|= cpu_to_le16(IEEE80211_FCTL_MOREDATA
);
3519 pwlanhdr
->qos_ctrl
= cpu_to_le16(tid
& IEEE80211_QOS_CTL_TID_MASK
);
3520 pwlanhdr
->qos_ctrl
|= cpu_to_le16((pattrib
->ack_policy
<< 5) &
3521 IEEE80211_QOS_CTL_ACK_POLICY_MASK
);
3523 pwlanhdr
->qos_ctrl
|= cpu_to_le16(IEEE80211_QOS_CTL_EOSP
);
3525 ether_addr_copy(pwlanhdr
->addr1
, da
);
3526 ether_addr_copy(pwlanhdr
->addr2
, myid(&padapter
->eeprompriv
));
3527 ether_addr_copy(pwlanhdr
->addr3
, get_my_bssid23a(&pmlmeinfo
->network
));
3529 pwlanhdr
->seq_ctrl
=
3530 cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext
->mgnt_seq
));
3531 pmlmeext
->mgnt_seq
++;
3533 pframe
+= sizeof(struct ieee80211_qos_hdr
);
3534 pattrib
->pktlen
= sizeof(struct ieee80211_qos_hdr
);
3536 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
3539 ret
= dump_mgntframe23a_and_wait_ack23a(padapter
, pmgntframe
);
3541 dump_mgntframe23a(padapter
, pmgntframe
);
3549 /* when wait_ms >0 , this function should be called at process context */
3550 /* da == NULL for station mode */
3551 int issue_qos_nulldata23a(struct rtw_adapter
*padapter
, unsigned char *da
,
3552 u16 tid
, int try_cnt
, int wait_ms
)
3556 unsigned long start
= jiffies
;
3557 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3558 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
3560 /* da == NULL, assume it's null data for sta to ap*/
3562 da
= get_my_bssid23a(&pmlmeinfo
->network
);
3565 ret
= _issue_qos_nulldata23a(padapter
, da
, tid
,
3566 wait_ms
> 0 ? true : false);
3570 if (padapter
->bDriverStopped
|| padapter
->bSurpriseRemoved
)
3573 if (i
< try_cnt
&& wait_ms
> 0 && ret
== _FAIL
)
3575 } while((i
< try_cnt
) && ((ret
== _FAIL
)||(wait_ms
== 0)));
3582 if (try_cnt
&& wait_ms
) {
3584 DBG_8723A("%s(%s): to %pM, ch:%u%s, %d/%d in %u ms\n",
3585 __func__
, padapter
->pnetdev
->name
,
3586 da
, rtw_get_oper_ch23a(padapter
),
3587 ret
== _SUCCESS
? ", acked" : "", i
, try_cnt
,
3588 jiffies_to_msecs(jiffies
- start
));
3590 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3591 __func__
, padapter
->pnetdev
->name
,
3592 rtw_get_oper_ch23a(padapter
),
3593 ret
== _SUCCESS
? ", acked" : "", i
, try_cnt
,
3594 jiffies_to_msecs(jiffies
- start
));
3600 static int _issue_deauth(struct rtw_adapter
*padapter
, unsigned char *da
,
3601 unsigned short reason
, u8 wait_ack
)
3603 struct xmit_frame
*pmgntframe
;
3604 struct pkt_attrib
*pattrib
;
3605 struct ieee80211_mgmt
*mgmt
;
3606 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
3607 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3608 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
3611 /* DBG_8723A("%s to %pM\n", __func__, da); */
3613 pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
);
3617 /* update attribute */
3618 pattrib
= &pmgntframe
->attrib
;
3619 update_mgntframe_attrib23a(padapter
, pattrib
);
3620 pattrib
->retry_ctrl
= false;
3622 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
3624 mgmt
= (struct ieee80211_mgmt
*)(pmgntframe
->buf_addr
+ TXDESC_OFFSET
);
3626 mgmt
->frame_control
=
3627 cpu_to_le16(IEEE80211_FTYPE_MGMT
| IEEE80211_STYPE_DEAUTH
);
3629 ether_addr_copy(mgmt
->da
, da
);
3630 ether_addr_copy(mgmt
->sa
, myid(&padapter
->eeprompriv
));
3631 ether_addr_copy(mgmt
->bssid
, get_my_bssid23a(&pmlmeinfo
->network
));
3633 mgmt
->seq_ctrl
= cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext
->mgnt_seq
));
3634 pmlmeext
->mgnt_seq
++;
3636 pattrib
->pktlen
= sizeof(struct ieee80211_hdr_3addr
) + 2;
3638 mgmt
->u
.deauth
.reason_code
= cpu_to_le16(reason
);
3640 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
3643 ret
= dump_mgntframe23a_and_wait_ack23a(padapter
, pmgntframe
);
3645 dump_mgntframe23a(padapter
, pmgntframe
);
3653 int issue_deauth23a(struct rtw_adapter
*padapter
, unsigned char *da
,
3654 unsigned short reason
)
3656 DBG_8723A("%s to %pM\n", __func__
, da
);
3657 return _issue_deauth(padapter
, da
, reason
, false);
3660 static int issue_deauth_ex(struct rtw_adapter
*padapter
, u8
*da
,
3661 unsigned short reason
, int try_cnt
, int wait_ms
)
3665 unsigned long start
= jiffies
;
3668 ret
= _issue_deauth(padapter
, da
, reason
,
3669 wait_ms
>0 ? true : false);
3673 if (padapter
->bDriverStopped
|| padapter
->bSurpriseRemoved
)
3676 if (i
< try_cnt
&& wait_ms
> 0 && ret
== _FAIL
)
3679 } while((i
< try_cnt
) && ((ret
== _FAIL
)||(wait_ms
== 0)));
3686 if (try_cnt
&& wait_ms
) {
3688 DBG_8723A("%s(%s): to %pM, ch:%u%s, %d/%d in %u ms\n",
3689 __func__
, padapter
->pnetdev
->name
,
3690 da
, rtw_get_oper_ch23a(padapter
),
3691 ret
== _SUCCESS
? ", acked" : "", i
, try_cnt
,
3692 jiffies_to_msecs(jiffies
- start
));
3694 DBG_8723A("%s(%s):, ch:%u%s, %d/%d in %u ms\n",
3695 __func__
, padapter
->pnetdev
->name
,
3696 rtw_get_oper_ch23a(padapter
),
3697 ret
== _SUCCESS
? ", acked" : "", i
, try_cnt
,
3698 jiffies_to_msecs(jiffies
- start
));
3704 void issue_action_spct_ch_switch23a(struct rtw_adapter
*padapter
,
3705 u8
*ra
, u8 new_ch
, u8 ch_offset
)
3707 struct xmit_frame
*pmgntframe
;
3708 struct pkt_attrib
*pattrib
;
3709 unsigned char *pframe
;
3710 struct ieee80211_mgmt
*mgmt
;
3711 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
3712 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3714 DBG_8723A("%s(%s): ra=%pM, ch:%u, offset:%u\n",
3715 __func__
, padapter
->pnetdev
->name
, ra
, new_ch
, ch_offset
);
3717 pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
);
3721 /* update attribute */
3722 pattrib
= &pmgntframe
->attrib
;
3723 update_mgntframe_attrib23a(padapter
, pattrib
);
3725 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
3727 mgmt
= (struct ieee80211_mgmt
*)(pmgntframe
->buf_addr
+ TXDESC_OFFSET
);
3729 mgmt
->frame_control
=
3730 cpu_to_le16(IEEE80211_FTYPE_MGMT
| IEEE80211_STYPE_ACTION
);
3732 ether_addr_copy(mgmt
->da
, ra
); /* RA */
3733 ether_addr_copy(mgmt
->sa
, myid(&padapter
->eeprompriv
)); /* TA */
3734 ether_addr_copy(mgmt
->bssid
, ra
); /* DA = RA */
3736 mgmt
->seq_ctrl
= cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext
->mgnt_seq
));
3737 pmlmeext
->mgnt_seq
++;
3739 mgmt
->u
.action
.category
= WLAN_CATEGORY_SPECTRUM_MGMT
;
3740 mgmt
->u
.action
.u
.chan_switch
.action_code
= WLAN_ACTION_SPCT_CHL_SWITCH
;
3742 pframe
= mgmt
->u
.action
.u
.chan_switch
.variable
;
3743 pattrib
->pktlen
= offsetof(struct ieee80211_mgmt
,
3744 u
.action
.u
.chan_switch
.variable
);
3746 pframe
= rtw_set_ie23a_ch_switch (pframe
, &pattrib
->pktlen
, 0,
3748 pframe
= rtw_set_ie23a_secondary_ch_offset(pframe
, &pattrib
->pktlen
,
3749 hal_ch_offset_to_secondary_ch_offset23a(ch_offset
));
3751 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
3753 dump_mgntframe23a(padapter
, pmgntframe
);
3756 void issue_action_BA23a(struct rtw_adapter
*padapter
,
3757 const unsigned char *raddr
,
3758 unsigned char action
, unsigned short status
)
3762 u16 BA_starting_seqctrl
;
3764 int max_rx_ampdu_factor
;
3765 struct xmit_frame
*pmgntframe
;
3766 struct pkt_attrib
*pattrib
;
3767 struct ieee80211_mgmt
*mgmt
;
3768 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
3769 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3770 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
3771 struct sta_info
*psta
;
3772 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
3773 struct registry_priv
*pregpriv
= &padapter
->registrypriv
;
3774 u8 tendaAPMac
[] = {0xC8, 0x3A, 0x35};
3776 DBG_8723A("%s, action =%d, status =%d\n", __func__
, action
, status
);
3778 pmgntframe
= alloc_mgtxmitframe23a(pxmitpriv
);
3782 /* update attribute */
3783 pattrib
= &pmgntframe
->attrib
;
3784 update_mgntframe_attrib23a(padapter
, pattrib
);
3786 memset(pmgntframe
->buf_addr
, 0, WLANHDR_OFFSET
+ TXDESC_OFFSET
);
3788 mgmt
= (struct ieee80211_mgmt
*)(pmgntframe
->buf_addr
+ TXDESC_OFFSET
);
3790 mgmt
->frame_control
=
3791 cpu_to_le16(IEEE80211_FTYPE_MGMT
| IEEE80211_STYPE_ACTION
);
3793 ether_addr_copy(mgmt
->da
, raddr
);
3794 ether_addr_copy(mgmt
->sa
, myid(&padapter
->eeprompriv
));
3795 ether_addr_copy(mgmt
->bssid
, get_my_bssid23a(&pmlmeinfo
->network
));
3797 mgmt
->seq_ctrl
= cpu_to_le16(IEEE80211_SN_TO_SEQ(pmlmeext
->mgnt_seq
));
3798 pmlmeext
->mgnt_seq
++;
3800 mgmt
->u
.action
.category
= WLAN_CATEGORY_BACK
;
3802 pattrib
->pktlen
= sizeof(struct ieee80211_hdr_3addr
) + 1;
3805 case WLAN_ACTION_ADDBA_REQ
:
3806 pattrib
->pktlen
+= sizeof(mgmt
->u
.action
.u
.addba_req
);
3808 mgmt
->u
.action
.u
.addba_req
.action_code
= action
;
3811 pmlmeinfo
->dialogToken
++;
3812 } while (pmlmeinfo
->dialogToken
== 0);
3814 mgmt
->u
.action
.u
.addba_req
.dialog_token
=
3815 pmlmeinfo
->dialogToken
;
3817 if (rtl8723a_BT_coexist(padapter
) &&
3818 rtl8723a_BT_using_antenna_1(padapter
) &&
3819 (pmlmeinfo
->assoc_AP_vendor
!= broadcomAP
||
3820 memcmp(raddr
, tendaAPMac
, 3))) {
3821 /* A-MSDU NOT Supported */
3823 /* immediate Block Ack */
3824 BA_para_set
|= (1 << 1) &
3825 IEEE80211_ADDBA_PARAM_POLICY_MASK
;
3827 BA_para_set
|= (status
<< 2) &
3828 IEEE80211_ADDBA_PARAM_TID_MASK
;
3829 /* max buffer size is 8 MSDU */
3830 BA_para_set
|= (8 << 6) &
3831 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK
;
3833 /* immediate ack & 64 buffer size */
3834 BA_para_set
= 0x1002 | ((status
& 0xf) << 2);
3837 put_unaligned_le16(BA_para_set
,
3838 &mgmt
->u
.action
.u
.addba_req
.capab
);
3841 put_unaligned_le16(5000, &mgmt
->u
.action
.u
.addba_req
.timeout
);
3843 psta
= rtw_get_stainfo23a(pstapriv
, raddr
);
3847 idx
= status
& 0x07;
3849 (psta
->sta_xmitpriv
.txseq_tid
[idx
] & 0xfff) + 1;
3851 DBG_8723A("BA_starting_seqctrl = %d for TID =%d\n",
3854 psta
->BA_starting_seqctrl
[idx
] = start_seq
;
3856 BA_starting_seqctrl
= start_seq
<< 4;
3858 BA_starting_seqctrl
= 0;
3860 put_unaligned_le16(BA_starting_seqctrl
,
3861 &mgmt
->u
.action
.u
.addba_req
.start_seq_num
);
3865 case WLAN_ACTION_ADDBA_RESP
:
3866 pattrib
->pktlen
+= sizeof(mgmt
->u
.action
.u
.addba_resp
);
3868 mgmt
->u
.action
.u
.addba_resp
.action_code
= action
;
3869 mgmt
->u
.action
.u
.addba_resp
.dialog_token
=
3870 pmlmeinfo
->ADDBA_req
.dialog_token
;
3871 put_unaligned_le16(status
,
3872 &mgmt
->u
.action
.u
.addba_resp
.status
);
3874 GetHalDefVar8192CUsb(padapter
, HW_VAR_MAX_RX_AMPDU_FACTOR
,
3875 &max_rx_ampdu_factor
);
3877 BA_para
= le16_to_cpu(pmlmeinfo
->ADDBA_req
.BA_para_set
) & 0x3f;
3878 if (max_rx_ampdu_factor
== IEEE80211_HT_MAX_AMPDU_64K
)
3879 BA_para_set
= BA_para
| 0x1000; /* 64 buffer size */
3880 else if (max_rx_ampdu_factor
== IEEE80211_HT_MAX_AMPDU_32K
)
3881 BA_para_set
= BA_para
| 0x0800; /* 32 buffer size */
3882 else if (max_rx_ampdu_factor
== IEEE80211_HT_MAX_AMPDU_16K
)
3883 BA_para_set
= BA_para
| 0x0400; /* 16 buffer size */
3884 else if (max_rx_ampdu_factor
== IEEE80211_HT_MAX_AMPDU_8K
)
3885 BA_para_set
= BA_para
| 0x0200; /* 8 buffer size */
3887 BA_para_set
= BA_para
| 0x1000; /* 64 buffer size */
3889 if (rtl8723a_BT_coexist(padapter
) &&
3890 rtl8723a_BT_using_antenna_1(padapter
) &&
3891 (pmlmeinfo
->assoc_AP_vendor
!= broadcomAP
||
3892 memcmp(raddr
, tendaAPMac
, 3))) {
3893 /* max buffer size is 8 MSDU */
3894 BA_para_set
&= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK
;
3895 BA_para_set
|= (8 << 6) &
3896 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK
;
3899 if (pregpriv
->ampdu_amsdu
== 0)/* disabled */
3900 BA_para_set
&= ~BIT(0);
3901 else if (pregpriv
->ampdu_amsdu
== 1)/* enabled */
3902 BA_para_set
|= BIT(0);
3904 put_unaligned_le16(BA_para_set
,
3905 &mgmt
->u
.action
.u
.addba_resp
.capab
);
3907 mgmt
->u
.action
.u
.addba_resp
.timeout
3908 = pmlmeinfo
->ADDBA_req
.BA_timeout_value
;
3910 pattrib
->pktlen
+= 8;
3912 case WLAN_ACTION_DELBA
:
3913 pattrib
->pktlen
+= sizeof(mgmt
->u
.action
.u
.delba
);
3915 mgmt
->u
.action
.u
.delba
.action_code
= action
;
3916 BA_para_set
= (status
& 0x1F) << 3;
3917 mgmt
->u
.action
.u
.delba
.params
= cpu_to_le16(BA_para_set
);
3918 mgmt
->u
.action
.u
.delba
.reason_code
=
3919 cpu_to_le16(WLAN_REASON_QSTA_NOT_USE
);
3921 pattrib
->pktlen
+= 5;
3927 pattrib
->last_txcmdsz
= pattrib
->pktlen
;
3929 dump_mgntframe23a(padapter
, pmgntframe
);
3932 int send_delba23a(struct rtw_adapter
*padapter
, u8 initiator
, u8
*addr
)
3934 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
3935 struct sta_info
*psta
= NULL
;
3936 /* struct recv_reorder_ctrl *preorder_ctrl; */
3937 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
3938 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
3941 if ((pmlmeinfo
->state
&0x03) != MSR_AP
)
3942 if (!(pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
))
3945 psta
= rtw_get_stainfo23a(pstapriv
, addr
);
3949 if (initiator
== 0) { /* recipient */
3950 for (tid
= 0; tid
< MAXTID
; tid
++) {
3951 if (psta
->recvreorder_ctrl
[tid
].enable
== true) {
3952 DBG_8723A("rx agg disable tid(%d)\n", tid
);
3953 issue_action_BA23a(padapter
, addr
, WLAN_ACTION_DELBA
, (((tid
<<1) |initiator
)&0x1F));
3954 psta
->recvreorder_ctrl
[tid
].enable
= false;
3955 psta
->recvreorder_ctrl
[tid
].indicate_seq
= 0xffff;
3958 } else if (initiator
== 1) { /* originator */
3959 for (tid
= 0; tid
< MAXTID
; tid
++) {
3960 if (psta
->htpriv
.agg_enable_bitmap
& BIT(tid
)) {
3961 DBG_8723A("tx agg disable tid(%d)\n", tid
);
3962 issue_action_BA23a(padapter
, addr
, WLAN_ACTION_DELBA
, (((tid
<<1) |initiator
)&0x1F));
3963 psta
->htpriv
.agg_enable_bitmap
&= ~BIT(tid
);
3964 psta
->htpriv
.candidate_tid_bitmap
&= ~BIT(tid
);
3972 int send_beacon23a(struct rtw_adapter
*padapter
)
3977 unsigned long start
= jiffies
;
3978 unsigned int passing_time
;
3980 rtl8723a_bcn_valid(padapter
);
3982 issue_beacon23a(padapter
, 100);
3986 bxmitok
= rtl8723a_get_bcn_valid(padapter
);
3988 } while ((poll
% 10) != 0 && !bxmitok
&&
3989 !padapter
->bSurpriseRemoved
&&
3990 !padapter
->bDriverStopped
);
3992 } while (!bxmitok
&& issue
<100 && !padapter
->bSurpriseRemoved
&&
3993 !padapter
->bDriverStopped
);
3995 if (padapter
->bSurpriseRemoved
|| padapter
->bDriverStopped
)
3998 passing_time
= jiffies_to_msecs(jiffies
- start
);
4001 DBG_8723A("%s fail! %u ms\n", __func__
, passing_time
);
4005 if (passing_time
> 100 || issue
> 3)
4006 DBG_8723A("%s success, issue:%d, poll:%d, %u ms\n",
4007 __func__
, issue
, poll
, passing_time
);
4012 /****************************************************************************
4014 Following are some utitity functions for WiFi MLME
4016 *****************************************************************************/
4018 bool IsLegal5GChannel(struct rtw_adapter
*Adapter
, u8 channel
)
4022 u8 Channel_5G
[45] = {36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
4023 60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
4024 114, 116, 118, 120, 122, 124, 126, 128, 130, 132,
4025 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
4027 for (i
= 0; i
< sizeof(Channel_5G
); i
++)
4028 if (channel
== Channel_5G
[i
])
4033 static void rtw_site_survey(struct rtw_adapter
*padapter
)
4035 unsigned char survey_channel
= 0;
4036 enum rt_scan_type ScanType
= SCAN_PASSIVE
;
4037 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4038 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4039 struct rtw_ieee80211_channel
*ch
;
4041 if (pmlmeext
->sitesurvey_res
.channel_idx
<
4042 pmlmeext
->sitesurvey_res
.ch_num
) {
4043 ch
= &pmlmeext
->sitesurvey_res
.ch
[pmlmeext
->sitesurvey_res
.channel_idx
];
4044 survey_channel
= ch
->hw_value
;
4045 ScanType
= (ch
->flags
& IEEE80211_CHAN_NO_IR
) ?
4046 SCAN_PASSIVE
: SCAN_ACTIVE
;
4049 if (survey_channel
!= 0) {
4050 /* PAUSE 4-AC Queue when site_survey */
4051 if (pmlmeext
->sitesurvey_res
.channel_idx
== 0)
4052 set_channel_bwmode23a(padapter
, survey_channel
,
4053 HAL_PRIME_CHNL_OFFSET_DONT_CARE
,
4054 HT_CHANNEL_WIDTH_20
);
4056 SelectChannel23a(padapter
, survey_channel
);
4058 if (ScanType
== SCAN_ACTIVE
) /* obey the channel plan setting... */
4062 for (i
= 0;i
<RTW_SSID_SCAN_AMOUNT
;i
++) {
4063 if (pmlmeext
->sitesurvey_res
.ssid
[i
].ssid_len
) {
4064 /* todo: to issue two probe req??? */
4065 issue_probereq(padapter
, &pmlmeext
->sitesurvey_res
.ssid
[i
], NULL
);
4066 /* msleep(SURVEY_TO>>1); */
4067 issue_probereq(padapter
, &pmlmeext
->sitesurvey_res
.ssid
[i
], NULL
);
4071 if (pmlmeext
->sitesurvey_res
.scan_mode
== SCAN_ACTIVE
) {
4072 /* todo: to issue two probe req??? */
4073 issue_probereq(padapter
, NULL
, NULL
);
4074 /* msleep(SURVEY_TO>>1); */
4075 issue_probereq(padapter
, NULL
, NULL
);
4079 set_survey_timer(pmlmeext
, pmlmeext
->chan_scan_time
);
4081 /* channel number is 0 or this channel is not valid. */
4082 pmlmeext
->sitesurvey_res
.state
= SCAN_COMPLETE
;
4084 /* switch back to the original channel */
4086 set_channel_bwmode23a(padapter
, pmlmeext
->cur_channel
,
4087 pmlmeext
->cur_ch_offset
,
4088 pmlmeext
->cur_bwmode
);
4090 /* flush 4-AC Queue after rtw_site_survey */
4094 rtl8723a_set_media_status(padapter
, pmlmeinfo
->state
& 0x3);
4096 /* restore RX GAIN */
4097 rtl8723a_set_initial_gain(padapter
, 0xff);
4098 /* turn on dynamic functions */
4099 rtl8723a_odm_support_ability_restore(padapter
);
4101 if (is_client_associated_to_ap23a(padapter
) == true)
4102 issue_nulldata23a(padapter
, NULL
, 0, 3, 500);
4104 rtl8723a_mlme_sitesurvey(padapter
, 0);
4106 report_surveydone_event23a(padapter
);
4108 pmlmeext
->chan_scan_time
= SURVEY_TO
;
4109 pmlmeext
->sitesurvey_res
.state
= SCAN_DISABLE
;
4115 /* collect bss info from Beacon and Probe request/response frames. */
4116 static struct wlan_bssid_ex
*collect_bss_info(struct rtw_adapter
*padapter
,
4117 struct recv_frame
*precv_frame
)
4119 struct sk_buff
*skb
= precv_frame
->pkt
;
4120 struct ieee80211_mgmt
*mgmt
= (struct ieee80211_mgmt
*) skb
->data
;
4121 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
4122 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4123 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4124 struct wlan_bssid_ex
*bssid
;
4127 unsigned int length
;
4132 bssid
= kzalloc(sizeof(struct wlan_bssid_ex
), GFP_ATOMIC
);
4136 if (ieee80211_is_beacon(mgmt
->frame_control
)) {
4137 length
-= offsetof(struct ieee80211_mgmt
, u
.beacon
.variable
);
4138 pie
= mgmt
->u
.beacon
.variable
;
4139 bssid
->reserved
= 1;
4141 get_unaligned_le16(&mgmt
->u
.beacon
.capab_info
);
4142 bssid
->beacon_interval
=
4143 get_unaligned_le16(&mgmt
->u
.beacon
.beacon_int
);
4144 bssid
->tsf
= get_unaligned_le64(&mgmt
->u
.beacon
.timestamp
);
4145 } else if (ieee80211_is_probe_req(mgmt
->frame_control
)) {
4146 length
-= offsetof(struct ieee80211_mgmt
, u
.probe_req
.variable
);
4147 pie
= mgmt
->u
.probe_req
.variable
;
4148 bssid
->reserved
= 2;
4149 bssid
->capability
= 0;
4150 bssid
->beacon_interval
=
4151 padapter
->registrypriv
.dev_network
.beacon_interval
;
4153 } else if (ieee80211_is_probe_resp(mgmt
->frame_control
)) {
4155 offsetof(struct ieee80211_mgmt
, u
.probe_resp
.variable
);
4156 pie
= mgmt
->u
.probe_resp
.variable
;
4157 bssid
->reserved
= 3;
4159 get_unaligned_le16(&mgmt
->u
.probe_resp
.capab_info
);
4160 bssid
->beacon_interval
=
4161 get_unaligned_le16(&mgmt
->u
.probe_resp
.beacon_int
);
4162 bssid
->tsf
= get_unaligned_le64(&mgmt
->u
.probe_resp
.timestamp
);
4164 length
-= offsetof(struct ieee80211_mgmt
, u
.beacon
.variable
);
4165 pie
= mgmt
->u
.beacon
.variable
;
4166 bssid
->reserved
= 0;
4168 get_unaligned_le16(&mgmt
->u
.beacon
.capab_info
);
4169 bssid
->beacon_interval
=
4170 padapter
->registrypriv
.dev_network
.beacon_interval
;
4174 if (length
> MAX_IE_SZ
) {
4175 /* DBG_8723A("IE too long for survey event\n"); */
4180 bssid
->Length
= offsetof(struct wlan_bssid_ex
, IEs
) + length
;
4182 /* below is to copy the information element */
4183 bssid
->IELength
= length
;
4184 memcpy(bssid
->IEs
, pie
, bssid
->IELength
);
4186 /* get the signal strength */
4187 /* in dBM.raw data */
4188 bssid
->Rssi
= precv_frame
->attrib
.phy_info
.RecvSignalPower
;
4189 bssid
->SignalQuality
=
4190 precv_frame
->attrib
.phy_info
.SignalQuality
;/* in percentage */
4191 bssid
->SignalStrength
=
4192 precv_frame
->attrib
.phy_info
.SignalStrength
;/* in percentage */
4195 p
= cfg80211_find_ie(WLAN_EID_SSID
, bssid
->IEs
, bssid
->IELength
);
4198 DBG_8723A("marc: cannot find SSID for survey event\n");
4202 if (p
[1] > IEEE80211_MAX_SSID_LEN
) {
4203 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4204 "event\n", __func__
, __LINE__
, p
[1]);
4207 memcpy(bssid
->Ssid
.ssid
, p
+ 2, p
[1]);
4208 bssid
->Ssid
.ssid_len
= p
[1];
4210 /* checking rate info... */
4212 p
= cfg80211_find_ie(WLAN_EID_SUPP_RATES
, bssid
->IEs
, bssid
->IELength
);
4214 if (p
[1] > NDIS_802_11_LENGTH_RATES_EX
) {
4215 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4216 "event\n", __func__
, __LINE__
, p
[1]);
4219 memcpy(bssid
->SupportedRates
, p
+ 2, p
[1]);
4223 p
= cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES
, bssid
->IEs
,
4226 if (p
[1] > (NDIS_802_11_LENGTH_RATES_EX
-i
)) {
4227 DBG_8723A("%s()-%d: IE too long (%d) for survey "
4228 "event\n", __func__
, __LINE__
, p
[1]);
4231 memcpy(bssid
->SupportedRates
+ i
, p
+ 2, p
[1]);
4234 /* Checking for DSConfig */
4235 p
= cfg80211_find_ie(WLAN_EID_DS_PARAMS
, bssid
->IEs
, bssid
->IELength
);
4237 bssid
->DSConfig
= 0;
4240 bssid
->DSConfig
= p
[2];
4241 } else {/* In 5G, some ap do not have DSSET IE */
4242 /* checking HT info for channel */
4243 p
= cfg80211_find_ie(WLAN_EID_HT_OPERATION
, bssid
->IEs
,
4246 struct ieee80211_ht_operation
*HT_info
=
4247 (struct ieee80211_ht_operation
*)(p
+ 2);
4248 bssid
->DSConfig
= HT_info
->primary_chan
;
4249 } else /* use current channel */
4250 bssid
->DSConfig
= rtw_get_oper_ch23a(padapter
);
4253 if (ieee80211_is_probe_req(mgmt
->frame_control
)) {
4255 bssid
->ifmode
= NL80211_IFTYPE_STATION
;
4256 ether_addr_copy(bssid
->MacAddress
, mgmt
->sa
);
4261 if (bssid
->capability
& WLAN_CAPABILITY_ESS
) {
4262 bssid
->ifmode
= NL80211_IFTYPE_STATION
;
4263 ether_addr_copy(bssid
->MacAddress
, mgmt
->sa
);
4265 bssid
->ifmode
= NL80211_IFTYPE_ADHOC
;
4266 ether_addr_copy(bssid
->MacAddress
, mgmt
->bssid
);
4269 if (bssid
->capability
& WLAN_CAPABILITY_PRIVACY
)
4274 bssid
->ATIMWindow
= 0;
4276 /* 20/40 BSS Coexistence check */
4277 if (pregistrypriv
->wifi_spec
== 1 &&
4278 pmlmeinfo
->bwmode_updated
== false) {
4279 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
4281 p
= cfg80211_find_ie(WLAN_EID_HT_CAPABILITY
, bssid
->IEs
,
4283 if (p
&& p
[1] > 0) {
4284 struct ieee80211_ht_cap
*pHT_caps
;
4286 pHT_caps
= (struct ieee80211_ht_cap
*)(p
+ 2);
4288 if (pHT_caps
->cap_info
&
4289 cpu_to_le16(IEEE80211_HT_CAP_40MHZ_INTOLERANT
))
4290 pmlmepriv
->num_FortyMHzIntolerant
++;
4292 pmlmepriv
->num_sta_no_ht
++;
4296 /* mark bss info receiving from nearby channel as SignalQuality 101 */
4297 if (bssid
->DSConfig
!= rtw_get_oper_ch23a(padapter
))
4298 bssid
->SignalQuality
= 101;
4306 static void start_create_ibss(struct rtw_adapter
*padapter
)
4308 unsigned short caps
;
4309 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4310 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4311 struct wlan_bssid_ex
*pnetwork
= &pmlmeinfo
->network
;
4313 pmlmeext
->cur_channel
= (u8
)pnetwork
->DSConfig
;
4314 pmlmeinfo
->bcn_interval
= pnetwork
->beacon_interval
;
4316 /* update wireless mode */
4317 update_wireless_mode23a(padapter
);
4319 /* update capability */
4320 caps
= pnetwork
->capability
;
4321 update_capinfo23a(padapter
, caps
);
4322 if (caps
& WLAN_CAPABILITY_IBSS
) { /* adhoc master */
4323 rtl8723a_set_sec_cfg(padapter
, 0xcf);
4325 /* switch channel */
4326 /* SelectChannel23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
4327 set_channel_bwmode23a(padapter
, pmlmeext
->cur_channel
, HAL_PRIME_CHNL_OFFSET_DONT_CARE
, HT_CHANNEL_WIDTH_20
);
4329 rtl8723a_SetBeaconRelatedRegisters(padapter
);
4331 /* set msr to MSR_ADHOC */
4332 pmlmeinfo
->state
= MSR_ADHOC
;
4333 rtl8723a_set_media_status(padapter
, pmlmeinfo
->state
& 0x3);
4336 if (send_beacon23a(padapter
) == _FAIL
) {
4337 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_err_
,
4338 "issuing beacon frame fail....\n");
4340 report_join_res23a(padapter
, -1);
4341 pmlmeinfo
->state
= MSR_NOLINK
;
4343 hw_var_set_bssid(padapter
, padapter
->registrypriv
.dev_network
.MacAddress
);
4344 hw_var_set_mlme_join(padapter
, 0);
4346 report_join_res23a(padapter
, 1);
4347 pmlmeinfo
->state
|= WIFI_FW_ASSOC_SUCCESS
;
4350 DBG_8723A("%s: invalid cap:%x\n", __func__
, caps
);
4355 static void start_clnt_join(struct rtw_adapter
*padapter
)
4357 unsigned short caps
;
4359 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4360 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4361 struct wlan_bssid_ex
*pnetwork
= &pmlmeinfo
->network
;
4364 pmlmeext
->cur_channel
= (u8
)pnetwork
->DSConfig
;
4365 pmlmeinfo
->bcn_interval
= pnetwork
->beacon_interval
;
4367 /* update wireless mode */
4368 update_wireless_mode23a(padapter
);
4370 /* update capability */
4371 caps
= pnetwork
->capability
;
4372 update_capinfo23a(padapter
, caps
);
4373 if (caps
& WLAN_CAPABILITY_ESS
) {
4374 /* switch channel */
4375 set_channel_bwmode23a(padapter
, pmlmeext
->cur_channel
, pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
4377 rtl8723a_set_media_status(padapter
, MSR_INFRA
);
4379 val8
= (pmlmeinfo
->auth_algo
== dot11AuthAlgrthm_8021X
) ?
4382 rtl8723a_set_sec_cfg(padapter
, val8
);
4384 /* switch channel */
4385 /* set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
4387 /* here wait for receiving the beacon to start auth */
4388 /* and enable a timer */
4389 beacon_timeout
= decide_wait_for_beacon_timeout23a(pmlmeinfo
->bcn_interval
);
4390 set_link_timer(pmlmeext
, beacon_timeout
);
4391 mod_timer(&padapter
->mlmepriv
.assoc_timer
, jiffies
+
4392 msecs_to_jiffies((REAUTH_TO
* REAUTH_LIMIT
) + (REASSOC_TO
*REASSOC_LIMIT
) + beacon_timeout
));
4393 pmlmeinfo
->state
= WIFI_FW_AUTH_NULL
| MSR_INFRA
;
4394 } else if (caps
& WLAN_CAPABILITY_IBSS
) { /* adhoc client */
4395 rtl8723a_set_media_status(padapter
, MSR_ADHOC
);
4397 rtl8723a_set_sec_cfg(padapter
, 0xcf);
4399 /* switch channel */
4400 set_channel_bwmode23a(padapter
, pmlmeext
->cur_channel
, pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
4402 rtl8723a_SetBeaconRelatedRegisters(padapter
);
4404 pmlmeinfo
->state
= MSR_ADHOC
;
4406 report_join_res23a(padapter
, 1);
4408 /* DBG_8723A("marc: invalid cap:%x\n", caps); */
4413 static void start_clnt_auth(struct rtw_adapter
*padapter
)
4415 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4416 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4418 del_timer_sync(&pmlmeext
->link_timer
);
4420 pmlmeinfo
->state
&= (~WIFI_FW_AUTH_NULL
);
4421 pmlmeinfo
->state
|= WIFI_FW_AUTH_STATE
;
4423 pmlmeinfo
->auth_seq
= 1;
4424 pmlmeinfo
->reauth_count
= 0;
4425 pmlmeinfo
->reassoc_count
= 0;
4426 pmlmeinfo
->link_count
= 0;
4427 pmlmeext
->retry
= 0;
4429 /* Because of AP's not receiving deauth before */
4430 /* AP may: 1)not response auth or 2)deauth us after link is complete */
4431 /* issue deauth before issuing auth to deal with the situation */
4432 /* Commented by Albert 2012/07/21 */
4433 /* For the Win8 P2P connection, it will be hard to have a
4434 successful connection if this Wi-Fi doesn't connect to it. */
4435 issue_deauth23a(padapter
, (&pmlmeinfo
->network
)->MacAddress
,
4436 WLAN_REASON_DEAUTH_LEAVING
);
4438 DBG_8723A_LEVEL(_drv_always_
, "start auth\n");
4439 issue_auth(padapter
, NULL
, 0);
4441 set_link_timer(pmlmeext
, REAUTH_TO
);
4444 static void start_clnt_assoc(struct rtw_adapter
*padapter
)
4446 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4447 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4449 del_timer_sync(&pmlmeext
->link_timer
);
4451 pmlmeinfo
->state
&= (~(WIFI_FW_AUTH_NULL
| WIFI_FW_AUTH_STATE
));
4452 pmlmeinfo
->state
|= (WIFI_FW_AUTH_SUCCESS
| WIFI_FW_ASSOC_STATE
);
4454 issue_assocreq(padapter
);
4456 set_link_timer(pmlmeext
, REASSOC_TO
);
4459 int receive_disconnect23a(struct rtw_adapter
*padapter
,
4460 unsigned char *MacAddr
, unsigned short reason
)
4462 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4463 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4466 if (!ether_addr_equal(MacAddr
, get_my_bssid23a(&pmlmeinfo
->network
)))
4469 DBG_8723A("%s\n", __func__
);
4471 if ((pmlmeinfo
->state
&0x03) == MSR_INFRA
) {
4472 if (pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
) {
4473 pmlmeinfo
->state
= MSR_NOLINK
;
4474 report_del_sta_event23a(padapter
, MacAddr
, reason
);
4476 } else if (pmlmeinfo
->state
& WIFI_FW_LINKING_STATE
) {
4477 pmlmeinfo
->state
= MSR_NOLINK
;
4478 report_join_res23a(padapter
, -2);
4485 static void process_80211d(struct rtw_adapter
*padapter
,
4486 struct wlan_bssid_ex
*bssid
)
4488 struct registry_priv
*pregistrypriv
;
4489 struct mlme_ext_priv
*pmlmeext
;
4490 struct rt_channel_info
*chplan_new
;
4494 pregistrypriv
= &padapter
->registrypriv
;
4495 pmlmeext
= &padapter
->mlmeextpriv
;
4497 /* Adjust channel plan by AP Country IE */
4498 if (pregistrypriv
->enable80211d
&&
4499 !pmlmeext
->update_channel_plan_by_ap_done
) {
4501 struct rt_channel_plan chplan_ap
;
4502 struct rt_channel_info chplan_sta
[MAX_CHANNEL_NUM
];
4504 u8 fcn
; /* first channel number */
4505 u8 noc
; /* number of channel */
4508 ie
= cfg80211_find_ie(WLAN_EID_COUNTRY
, bssid
->IEs
,
4510 if (!ie
|| ie
[1] < IEEE80211_COUNTRY_IE_MIN_LEN
)
4517 memcpy(country
, p
, 3);
4521 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
,
4522 "%s: 802.11d country =%s\n", __func__
, country
);
4525 while ((ie
- p
) >= 3) {
4530 for (j
= 0; j
< noc
; j
++) {
4532 channel
= fcn
+ j
; /* 2.4 GHz */
4534 channel
= fcn
+ j
* 4; /* 5 GHz */
4536 chplan_ap
.Channel
[i
++] = channel
;
4541 memcpy(chplan_sta
, pmlmeext
->channel_set
, sizeof(chplan_sta
));
4542 memset(pmlmeext
->channel_set
, 0, sizeof(pmlmeext
->channel_set
));
4543 chplan_new
= pmlmeext
->channel_set
;
4546 if (pregistrypriv
->wireless_mode
& WIRELESS_11G
) {
4548 if (i
== MAX_CHANNEL_NUM
||
4549 chplan_sta
[i
].ChannelNum
== 0 ||
4550 chplan_sta
[i
].ChannelNum
> 14)
4553 if (j
== chplan_ap
.Len
||
4554 chplan_ap
.Channel
[j
] > 14)
4557 if (chplan_sta
[i
].ChannelNum
==
4558 chplan_ap
.Channel
[j
]) {
4559 chplan_new
[k
].ChannelNum
=
4560 chplan_ap
.Channel
[j
];
4561 chplan_new
[k
].ScanType
= SCAN_ACTIVE
;
4565 } else if (chplan_sta
[i
].ChannelNum
<
4566 chplan_ap
.Channel
[j
]) {
4567 chplan_new
[k
].ChannelNum
=
4568 chplan_sta
[i
].ChannelNum
;
4569 chplan_new
[k
].ScanType
=
4573 } else if (chplan_sta
[i
].ChannelNum
>
4574 chplan_ap
.Channel
[j
]) {
4575 chplan_new
[k
].ChannelNum
=
4576 chplan_ap
.Channel
[j
];
4577 chplan_new
[k
].ScanType
=
4584 /* change AP not support channel to Passive scan */
4585 while (i
< MAX_CHANNEL_NUM
&&
4586 chplan_sta
[i
].ChannelNum
!= 0 &&
4587 chplan_sta
[i
].ChannelNum
<= 14) {
4588 chplan_new
[k
].ChannelNum
=
4589 chplan_sta
[i
].ChannelNum
;
4590 chplan_new
[k
].ScanType
= SCAN_PASSIVE
;
4595 /* add channel AP supported */
4596 while (j
< chplan_ap
.Len
&& chplan_ap
.Channel
[j
] <= 14){
4597 chplan_new
[k
].ChannelNum
= chplan_ap
.Channel
[j
];
4598 chplan_new
[k
].ScanType
= SCAN_ACTIVE
;
4603 /* keep original STA 2.4G channel plan */
4604 while (i
< MAX_CHANNEL_NUM
&&
4605 chplan_sta
[i
].ChannelNum
!= 0 &&
4606 chplan_sta
[i
].ChannelNum
<= 14) {
4607 chplan_new
[k
].ChannelNum
=
4608 chplan_sta
[i
].ChannelNum
;
4609 chplan_new
[k
].ScanType
= chplan_sta
[i
].ScanType
;
4614 /* skip AP 2.4G channel plan */
4615 while (j
< chplan_ap
.Len
&& chplan_ap
.Channel
[j
] <= 14)
4619 if (pregistrypriv
->wireless_mode
& WIRELESS_11A
) {
4621 if (i
== MAX_CHANNEL_NUM
||
4622 chplan_sta
[i
].ChannelNum
== 0)
4625 if (j
== chplan_ap
.Len
||
4626 chplan_ap
.Channel
[j
] == 0)
4629 if (chplan_sta
[i
].ChannelNum
==
4630 chplan_ap
.Channel
[j
]) {
4631 chplan_new
[k
].ChannelNum
=
4632 chplan_ap
.Channel
[j
];
4633 chplan_new
[k
].ScanType
= SCAN_ACTIVE
;
4637 } else if (chplan_sta
[i
].ChannelNum
<
4638 chplan_ap
.Channel
[j
]) {
4639 chplan_new
[k
].ChannelNum
=
4640 chplan_sta
[i
].ChannelNum
;
4641 chplan_new
[k
].ScanType
= SCAN_PASSIVE
;
4644 } else if (chplan_sta
[i
].ChannelNum
>
4645 chplan_ap
.Channel
[j
]) {
4646 chplan_new
[k
].ChannelNum
=
4647 chplan_ap
.Channel
[j
];
4648 chplan_new
[k
].ScanType
= SCAN_ACTIVE
;
4654 /* change AP not support channel to Passive scan */
4655 while (i
< MAX_CHANNEL_NUM
&&
4656 chplan_sta
[i
].ChannelNum
!= 0) {
4657 chplan_new
[k
].ChannelNum
=
4658 chplan_sta
[i
].ChannelNum
;
4659 chplan_new
[k
].ScanType
= SCAN_PASSIVE
;
4664 /* add channel AP supported */
4665 while (j
< chplan_ap
.Len
&& chplan_ap
.Channel
[j
] != 0) {
4666 chplan_new
[k
].ChannelNum
= chplan_ap
.Channel
[j
];
4667 chplan_new
[k
].ScanType
= SCAN_ACTIVE
;
4672 /* keep original STA 5G channel plan */
4673 while (i
< MAX_CHANNEL_NUM
&&
4674 chplan_sta
[i
].ChannelNum
!= 0) {
4675 chplan_new
[k
].ChannelNum
=
4676 chplan_sta
[i
].ChannelNum
;
4677 chplan_new
[k
].ScanType
= chplan_sta
[i
].ScanType
;
4682 pmlmeext
->update_channel_plan_by_ap_done
= 1;
4685 /* If channel is used by AP, set channel scan type to active */
4686 channel
= bssid
->DSConfig
;
4687 chplan_new
= pmlmeext
->channel_set
;
4689 while (i
< MAX_CHANNEL_NUM
&& chplan_new
[i
].ChannelNum
!= 0) {
4690 if (chplan_new
[i
].ChannelNum
== channel
) {
4691 if (chplan_new
[i
].ScanType
== SCAN_PASSIVE
) {
4692 /* 5G Bnad 2, 3 (DFS) doesn't change
4694 if (channel
>= 52 && channel
<= 144)
4697 chplan_new
[i
].ScanType
= SCAN_ACTIVE
;
4698 RT_TRACE(_module_rtl871x_mlme_c_
, _drv_notice_
,
4699 "%s: change channel %d scan type from passive to active\n",
4708 /****************************************************************************
4710 Following are the functions to report events
4712 *****************************************************************************/
4714 void report_survey_event23a(struct rtw_adapter
*padapter
,
4715 struct recv_frame
*precv_frame
)
4717 struct cmd_obj
*pcmd_obj
;
4720 struct survey_event
*psurvey_evt
;
4721 struct C2HEvent_Header
*pc2h_evt_hdr
;
4722 struct mlme_ext_priv
*pmlmeext
;
4723 struct cmd_priv
*pcmdpriv
;
4728 pmlmeext
= &padapter
->mlmeextpriv
;
4729 pcmdpriv
= &padapter
->cmdpriv
;
4731 pcmd_obj
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
4735 cmdsz
= sizeof(struct survey_event
) + sizeof(struct C2HEvent_Header
);
4736 pevtcmd
= kzalloc(cmdsz
, GFP_ATOMIC
);
4742 pcmd_obj
->cmdcode
= GEN_CMD_CODE(_Set_MLME_EVT
);
4743 pcmd_obj
->cmdsz
= cmdsz
;
4744 pcmd_obj
->parmbuf
= pevtcmd
;
4746 pcmd_obj
->rsp
= NULL
;
4747 pcmd_obj
->rspsz
= 0;
4749 pc2h_evt_hdr
= (struct C2HEvent_Header
*)(pevtcmd
);
4750 pc2h_evt_hdr
->len
= sizeof(struct survey_event
);
4751 pc2h_evt_hdr
->ID
= GEN_EVT_CODE(_Survey
);
4752 pc2h_evt_hdr
->seq
= atomic_inc_return(&pmlmeext
->event_seq
);
4754 psurvey_evt
= (struct survey_event
*)(pevtcmd
+ sizeof(struct C2HEvent_Header
));
4756 psurvey_evt
->bss
= collect_bss_info(padapter
, precv_frame
);
4757 if (!psurvey_evt
->bss
) {
4763 process_80211d(padapter
, psurvey_evt
->bss
);
4765 rtw_enqueue_cmd23a(pcmdpriv
, pcmd_obj
);
4767 pmlmeext
->sitesurvey_res
.bss_cnt
++;
4772 void report_surveydone_event23a(struct rtw_adapter
*padapter
)
4774 struct cmd_obj
*pcmd_obj
;
4777 struct surveydone_event
*psurveydone_evt
;
4778 struct C2HEvent_Header
*pc2h_evt_hdr
;
4779 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4780 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
4782 pcmd_obj
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
4786 cmdsz
= sizeof(struct surveydone_event
) + sizeof(struct C2HEvent_Header
);
4787 pevtcmd
= kzalloc(cmdsz
, GFP_ATOMIC
);
4793 pcmd_obj
->cmdcode
= GEN_CMD_CODE(_Set_MLME_EVT
);
4794 pcmd_obj
->cmdsz
= cmdsz
;
4795 pcmd_obj
->parmbuf
= pevtcmd
;
4797 pcmd_obj
->rsp
= NULL
;
4798 pcmd_obj
->rspsz
= 0;
4800 pc2h_evt_hdr
= (struct C2HEvent_Header
*)(pevtcmd
);
4801 pc2h_evt_hdr
->len
= sizeof(struct surveydone_event
);
4802 pc2h_evt_hdr
->ID
= GEN_EVT_CODE(_SurveyDone
);
4803 pc2h_evt_hdr
->seq
= atomic_inc_return(&pmlmeext
->event_seq
);
4805 psurveydone_evt
= (struct surveydone_event
*)(pevtcmd
+ sizeof(struct C2HEvent_Header
));
4806 psurveydone_evt
->bss_cnt
= pmlmeext
->sitesurvey_res
.bss_cnt
;
4808 DBG_8723A("survey done event(%x)\n", psurveydone_evt
->bss_cnt
);
4810 rtw_enqueue_cmd23a(pcmdpriv
, pcmd_obj
);
4815 void report_join_res23a(struct rtw_adapter
*padapter
, int res
)
4817 struct cmd_obj
*pcmd_obj
;
4820 struct joinbss_event
*pjoinbss_evt
;
4821 struct C2HEvent_Header
*pc2h_evt_hdr
;
4822 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4823 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4824 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
4826 pcmd_obj
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
4830 cmdsz
= sizeof(struct joinbss_event
) + sizeof(struct C2HEvent_Header
);
4831 pevtcmd
= kzalloc(cmdsz
, GFP_ATOMIC
);
4837 pcmd_obj
->cmdcode
= GEN_CMD_CODE(_Set_MLME_EVT
);
4838 pcmd_obj
->cmdsz
= cmdsz
;
4839 pcmd_obj
->parmbuf
= pevtcmd
;
4841 pcmd_obj
->rsp
= NULL
;
4842 pcmd_obj
->rspsz
= 0;
4844 pc2h_evt_hdr
= (struct C2HEvent_Header
*)(pevtcmd
);
4845 pc2h_evt_hdr
->len
= sizeof(struct joinbss_event
);
4846 pc2h_evt_hdr
->ID
= GEN_EVT_CODE(_JoinBss
);
4847 pc2h_evt_hdr
->seq
= atomic_inc_return(&pmlmeext
->event_seq
);
4849 pjoinbss_evt
= (struct joinbss_event
*)(pevtcmd
+ sizeof(struct C2HEvent_Header
));
4850 memcpy((unsigned char *)&pjoinbss_evt
->network
.network
,
4851 &pmlmeinfo
->network
, sizeof(struct wlan_bssid_ex
));
4852 pjoinbss_evt
->network
.join_res
= res
;
4854 DBG_8723A("report_join_res23a(%d)\n", res
);
4856 rtw_joinbss_event_prehandle23a(padapter
, (u8
*)&pjoinbss_evt
->network
);
4858 rtw_enqueue_cmd23a(pcmdpriv
, pcmd_obj
);
4863 void report_del_sta_event23a(struct rtw_adapter
*padapter
,
4864 unsigned char *MacAddr
, unsigned short reason
)
4866 struct cmd_obj
*pcmd_obj
;
4869 struct sta_info
*psta
;
4871 struct stadel_event
*pdel_sta_evt
;
4872 struct C2HEvent_Header
*pc2h_evt_hdr
;
4873 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4874 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
4876 pcmd_obj
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
4880 cmdsz
= sizeof(struct stadel_event
) + sizeof(struct C2HEvent_Header
);
4881 pevtcmd
= kzalloc(cmdsz
, GFP_ATOMIC
);
4887 pcmd_obj
->cmdcode
= GEN_CMD_CODE(_Set_MLME_EVT
);
4888 pcmd_obj
->cmdsz
= cmdsz
;
4889 pcmd_obj
->parmbuf
= pevtcmd
;
4891 pcmd_obj
->rsp
= NULL
;
4892 pcmd_obj
->rspsz
= 0;
4894 pc2h_evt_hdr
= (struct C2HEvent_Header
*)(pevtcmd
);
4895 pc2h_evt_hdr
->len
= sizeof(struct stadel_event
);
4896 pc2h_evt_hdr
->ID
= GEN_EVT_CODE(_DelSTA
);
4897 pc2h_evt_hdr
->seq
= atomic_inc_return(&pmlmeext
->event_seq
);
4899 pdel_sta_evt
= (struct stadel_event
*)(pevtcmd
+ sizeof(struct C2HEvent_Header
));
4900 ether_addr_copy((unsigned char *)&pdel_sta_evt
->macaddr
, MacAddr
);
4901 memcpy((unsigned char *)pdel_sta_evt
->rsvd
, (unsigned char *)&reason
,
4904 psta
= rtw_get_stainfo23a(&padapter
->stapriv
, MacAddr
);
4906 mac_id
= (int)psta
->mac_id
;
4910 pdel_sta_evt
->mac_id
= mac_id
;
4912 DBG_8723A("report_del_sta_event23a: delete STA, mac_id =%d\n", mac_id
);
4914 rtw_enqueue_cmd23a(pcmdpriv
, pcmd_obj
);
4919 void report_add_sta_event23a(struct rtw_adapter
*padapter
,
4920 unsigned char *MacAddr
, int cam_idx
)
4922 struct cmd_obj
*pcmd_obj
;
4925 struct stassoc_event
*padd_sta_evt
;
4926 struct C2HEvent_Header
*pc2h_evt_hdr
;
4927 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4928 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
4930 pcmd_obj
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
4934 cmdsz
= sizeof(struct stassoc_event
) + sizeof(struct C2HEvent_Header
);
4935 pevtcmd
= kzalloc(cmdsz
, GFP_ATOMIC
);
4941 pcmd_obj
->cmdcode
= GEN_CMD_CODE(_Set_MLME_EVT
);
4942 pcmd_obj
->cmdsz
= cmdsz
;
4943 pcmd_obj
->parmbuf
= pevtcmd
;
4945 pcmd_obj
->rsp
= NULL
;
4946 pcmd_obj
->rspsz
= 0;
4948 pc2h_evt_hdr
= (struct C2HEvent_Header
*)(pevtcmd
);
4949 pc2h_evt_hdr
->len
= sizeof(struct stassoc_event
);
4950 pc2h_evt_hdr
->ID
= GEN_EVT_CODE(_AddSTA
);
4951 pc2h_evt_hdr
->seq
= atomic_inc_return(&pmlmeext
->event_seq
);
4953 padd_sta_evt
= (struct stassoc_event
*)(pevtcmd
+ sizeof(struct C2HEvent_Header
));
4954 ether_addr_copy((unsigned char *)&padd_sta_evt
->macaddr
, MacAddr
);
4955 padd_sta_evt
->cam_id
= cam_idx
;
4957 DBG_8723A("report_add_sta_event23a: add STA\n");
4959 rtw_enqueue_cmd23a(pcmdpriv
, pcmd_obj
);
4964 /****************************************************************************
4966 Following are the event callback functions
4968 *****************************************************************************/
4970 /* for sta/adhoc mode */
4971 void update_sta_info23a(struct rtw_adapter
*padapter
, struct sta_info
*psta
)
4973 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
4974 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
4975 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
4978 VCS_update23a(padapter
, psta
);
4981 if (pmlmepriv
->htpriv
.ht_option
) {
4982 psta
->htpriv
.ht_option
= true;
4984 psta
->htpriv
.ampdu_enable
= pmlmepriv
->htpriv
.ampdu_enable
;
4986 if (support_short_GI23a(padapter
, &pmlmeinfo
->ht_cap
))
4987 psta
->htpriv
.sgi
= true;
4989 psta
->qos_option
= true;
4992 psta
->htpriv
.ht_option
= false;
4994 psta
->htpriv
.ampdu_enable
= false;
4996 psta
->htpriv
.sgi
= false;
4997 psta
->qos_option
= false;
5000 psta
->htpriv
.bwmode
= pmlmeext
->cur_bwmode
;
5001 psta
->htpriv
.ch_offset
= pmlmeext
->cur_ch_offset
;
5003 psta
->htpriv
.agg_enable_bitmap
= 0x0;/* reset */
5004 psta
->htpriv
.candidate_tid_bitmap
= 0x0;/* reset */
5007 if (pmlmepriv
->qos_option
)
5008 psta
->qos_option
= true;
5010 psta
->state
= _FW_LINKED
;
5013 void mlmeext_joinbss_event_callback23a(struct rtw_adapter
*padapter
,
5016 struct sta_info
*psta
, *psta_bmc
;
5017 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5018 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5019 struct wlan_bssid_ex
*cur_network
= &pmlmeinfo
->network
;
5020 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
5023 hw_var_set_mlme_join(padapter
, 1);
5024 hw_var_set_bssid(padapter
, null_addr
);
5026 /* restore to initial setting. */
5027 update_tx_basic_rate23a(padapter
,
5028 padapter
->registrypriv
.wireless_mode
);
5030 goto exit_mlmeext_joinbss_event_callback23a
;
5033 if ((pmlmeinfo
->state
&0x03) == MSR_ADHOC
) {
5035 psta_bmc
= rtw_get_bcmc_stainfo23a(padapter
);
5037 pmlmeinfo
->FW_sta_info
[psta_bmc
->mac_id
].psta
= psta_bmc
;
5038 update_bmc_sta_support_rate23a(padapter
, psta_bmc
->mac_id
);
5039 Update_RA_Entry23a(padapter
, psta_bmc
);
5043 /* turn on dynamic functions */
5044 rtl8723a_odm_support_ability_set(padapter
, DYNAMIC_ALL_FUNC_ENABLE
);
5046 /* update IOT-releated issue */
5047 update_IOT_info23a(padapter
);
5049 HalSetBrateCfg23a(padapter
, cur_network
->SupportedRates
);
5052 rtl8723a_set_beacon_interval(padapter
, pmlmeinfo
->bcn_interval
);
5054 /* update capability */
5055 update_capinfo23a(padapter
, pmlmeinfo
->capability
);
5057 /* WMM, Update EDCA param */
5058 WMMOnAssocRsp23a(padapter
);
5061 HTOnAssocRsp23a(padapter
);
5063 /* Set cur_channel&cur_bwmode&cur_ch_offset */
5064 set_channel_bwmode23a(padapter
, pmlmeext
->cur_channel
, pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
5066 psta
= rtw_get_stainfo23a(pstapriv
, cur_network
->MacAddress
);
5067 if (psta
) { /* only for infra. mode */
5068 pmlmeinfo
->FW_sta_info
[psta
->mac_id
].psta
= psta
;
5070 /* DBG_8723A("set_sta_rate23a\n"); */
5072 psta
->wireless_mode
= pmlmeext
->cur_wireless_mode
;
5074 /* set per sta rate after updating HT cap. */
5075 set_sta_rate23a(padapter
, psta
);
5078 hw_var_set_mlme_join(padapter
, 2);
5080 if ((pmlmeinfo
->state
&0x03) == MSR_INFRA
) {
5081 /* correcting TSF */
5082 rtw_correct_TSF(padapter
);
5084 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5087 rtw_lps_ctrl_wk_cmd23a(padapter
, LPS_CTRL_CONNECT
, 0);
5089 exit_mlmeext_joinbss_event_callback23a
:
5090 DBG_8723A("=>%s\n", __func__
);
5093 void mlmeext_sta_add_event_callback23a(struct rtw_adapter
*padapter
,
5094 struct sta_info
*psta
)
5096 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5097 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5099 DBG_8723A("%s\n", __func__
);
5101 if ((pmlmeinfo
->state
& 0x03) == MSR_ADHOC
) {
5102 /* adhoc master or sta_count>1 */
5103 if (pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
) {
5105 } else { /* adhoc client */
5106 /* correcting TSF */
5107 rtw_correct_TSF(padapter
);
5110 if (send_beacon23a(padapter
) != _SUCCESS
) {
5111 pmlmeinfo
->FW_sta_info
[psta
->mac_id
].status
= 0;
5113 pmlmeinfo
->state
^= MSR_ADHOC
;
5118 pmlmeinfo
->state
|= WIFI_FW_ASSOC_SUCCESS
;
5120 hw_var_set_mlme_join(padapter
, 2);
5123 pmlmeinfo
->FW_sta_info
[psta
->mac_id
].psta
= psta
;
5125 /* rate radaptive */
5126 Update_RA_Entry23a(padapter
, psta
);
5128 /* update adhoc sta_info */
5129 update_sta_info23a(padapter
, psta
);
5132 void mlmeext_sta_del_event_callback23a(struct rtw_adapter
*padapter
)
5134 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5135 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5137 if (is_client_associated_to_ap23a(padapter
) ||
5138 is_IBSS_empty23a(padapter
)) {
5139 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
5141 hw_var_set_mlme_disconnect(padapter
);
5142 hw_var_set_bssid(padapter
, null_addr
);
5144 /* restore to initial setting. */
5145 update_tx_basic_rate23a(padapter
,
5146 padapter
->registrypriv
.wireless_mode
);
5148 /* switch to the 20M Hz mode after disconnect */
5149 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_20
;
5150 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
5152 set_channel_bwmode23a(padapter
, pmlmeext
->cur_channel
,
5153 pmlmeext
->cur_ch_offset
,
5154 pmlmeext
->cur_bwmode
);
5156 flush_all_cam_entry23a(padapter
);
5158 pmlmeinfo
->state
= MSR_NOLINK
;
5160 /* set MSR to no link state -> infra. mode */
5161 rtl8723a_set_media_status(padapter
, MSR_INFRA
);
5163 del_timer_sync(&pmlmeext
->link_timer
);
5167 static u8
chk_ap_is_alive(struct rtw_adapter
*padapter
, struct sta_info
*psta
)
5171 if (sta_rx_data_pkts(psta
) == sta_last_rx_data_pkts(psta
) &&
5172 sta_rx_beacon_pkts(psta
) == sta_last_rx_beacon_pkts(psta
) &&
5173 sta_rx_probersp_pkts(psta
) == sta_last_rx_probersp_pkts(psta
))
5178 sta_update_last_rx_pkts(psta
);
5182 void linked_status_chk23a(struct rtw_adapter
*padapter
)
5185 struct sta_info
*psta
;
5186 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
5187 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5188 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5189 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
5191 if (is_client_associated_to_ap23a(padapter
)) {
5192 /* linked infrastructure client mode */
5194 int tx_chk
= _SUCCESS
, rx_chk
= _SUCCESS
;
5199 psta
= rtw_get_stainfo23a(pstapriv
,
5200 pmlmeinfo
->network
.MacAddress
);
5202 bool is_p2p_enable
= false;
5204 if (chk_ap_is_alive(padapter
, psta
) == false)
5207 if (pxmitpriv
->last_tx_pkts
== pxmitpriv
->tx_pkts
)
5210 if (pmlmeext
->active_keep_alive_check
&&
5211 (rx_chk
== _FAIL
|| tx_chk
== _FAIL
)) {
5212 u8 backup_oper_channel
= 0;
5214 /* switch to correct channel of current
5215 network before issue keep-alive frames */
5216 if (rtw_get_oper_ch23a(padapter
) !=
5217 pmlmeext
->cur_channel
) {
5218 backup_oper_channel
=
5219 rtw_get_oper_ch23a(padapter
);
5220 SelectChannel23a(padapter
,
5221 pmlmeext
->cur_channel
);
5224 if (rx_chk
!= _SUCCESS
)
5225 issue_probereq_ex(padapter
, &pmlmeinfo
->network
.Ssid
, psta
->hwaddr
, 3, 1);
5227 if ((tx_chk
!= _SUCCESS
&&
5228 pmlmeinfo
->link_count
++ == 0xf) ||
5229 rx_chk
!= _SUCCESS
) {
5230 tx_chk
= issue_nulldata23a(padapter
,
5233 /* if tx acked and p2p disabled,
5234 set rx_chk _SUCCESS to reset retry
5236 if (tx_chk
== _SUCCESS
&&
5241 /* back to the original operation channel */
5242 if (backup_oper_channel
>0)
5243 SelectChannel23a(padapter
,
5244 backup_oper_channel
);
5246 if (rx_chk
!= _SUCCESS
) {
5247 if (pmlmeext
->retry
== 0) {
5248 issue_probereq(padapter
, &pmlmeinfo
->network
.Ssid
, pmlmeinfo
->network
.MacAddress
);
5249 issue_probereq(padapter
, &pmlmeinfo
->network
.Ssid
, pmlmeinfo
->network
.MacAddress
);
5250 issue_probereq(padapter
, &pmlmeinfo
->network
.Ssid
, pmlmeinfo
->network
.MacAddress
);
5254 if (tx_chk
!= _SUCCESS
&&
5255 pmlmeinfo
->link_count
++ == 0xf)
5256 tx_chk
= issue_nulldata23a(padapter
,
5261 if (rx_chk
== _FAIL
) {
5263 if (pmlmeext
->retry
> rx_chk_limit
) {
5264 DBG_8723A_LEVEL(_drv_always_
,
5265 "%s(%s): disconnect or "
5266 "roaming\n", __func__
,
5267 padapter
->pnetdev
->name
);
5268 receive_disconnect23a(padapter
, pmlmeinfo
->network
.MacAddress
,
5269 WLAN_REASON_EXPIRATION_CHK
);
5273 pmlmeext
->retry
= 0;
5275 if (tx_chk
== _FAIL
)
5276 pmlmeinfo
->link_count
&= 0xf;
5278 pxmitpriv
->last_tx_pkts
= pxmitpriv
->tx_pkts
;
5279 pmlmeinfo
->link_count
= 0;
5283 } else if (is_client_associated_to_ibss23a(padapter
)) {
5284 /* linked IBSS mode */
5285 /* for each assoc list entry to check the rx pkt counter */
5286 for (i
= IBSS_START_MAC_ID
; i
< NUM_STA
; i
++) {
5287 if (pmlmeinfo
->FW_sta_info
[i
].status
== 1) {
5288 psta
= pmlmeinfo
->FW_sta_info
[i
].psta
;
5293 if (pmlmeinfo
->FW_sta_info
[i
].rx_pkt
==
5294 sta_rx_pkts(psta
)) {
5296 if (pmlmeinfo
->FW_sta_info
[i
].retry
<3) {
5297 pmlmeinfo
->FW_sta_info
[i
].retry
++;
5299 pmlmeinfo
->FW_sta_info
[i
].retry
= 0;
5300 pmlmeinfo
->FW_sta_info
[i
].status
= 0;
5301 report_del_sta_event23a(padapter
, psta
->hwaddr
,
5302 65535/* indicate disconnect caused by no rx */
5306 pmlmeinfo
->FW_sta_info
[i
].retry
= 0;
5307 pmlmeinfo
->FW_sta_info
[i
].rx_pkt
= (u32
)sta_rx_pkts(psta
);
5311 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
5315 static void survey_timer_hdl(unsigned long data
)
5317 struct rtw_adapter
*padapter
= (struct rtw_adapter
*)data
;
5318 struct cmd_obj
*ph2c
;
5319 struct sitesurvey_parm
*psurveyPara
;
5320 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
5321 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5323 /* issue rtw_sitesurvey_cmd23a */
5324 if (pmlmeext
->sitesurvey_res
.state
> SCAN_START
) {
5325 if (pmlmeext
->sitesurvey_res
.state
== SCAN_PROCESS
)
5326 pmlmeext
->sitesurvey_res
.channel_idx
++;
5328 if (pmlmeext
->scan_abort
== true) {
5329 pmlmeext
->sitesurvey_res
.channel_idx
=
5330 pmlmeext
->sitesurvey_res
.ch_num
;
5331 DBG_8723A("%s idx:%d\n", __func__
,
5332 pmlmeext
->sitesurvey_res
.channel_idx
);
5334 pmlmeext
->scan_abort
= false;/* reset */
5337 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
5339 goto exit_survey_timer_hdl
;
5341 psurveyPara
= kzalloc(sizeof(struct sitesurvey_parm
),
5345 goto exit_survey_timer_hdl
;
5348 init_h2fwcmd_w_parm_no_rsp(ph2c
, psurveyPara
,
5349 GEN_CMD_CODE(_SiteSurvey
));
5350 rtw_enqueue_cmd23a(pcmdpriv
, ph2c
);
5353 exit_survey_timer_hdl
:
5357 static void link_timer_hdl(unsigned long data
)
5359 struct rtw_adapter
*padapter
= (struct rtw_adapter
*)data
;
5360 /* static unsigned int rx_pkt = 0; */
5361 /* static u64 tx_cnt = 0; */
5362 /* struct xmit_priv *pxmitpriv = &padapter->xmitpriv; */
5363 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5364 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5365 /* struct sta_priv *pstapriv = &padapter->stapriv; */
5367 if (pmlmeinfo
->state
& WIFI_FW_AUTH_NULL
) {
5368 DBG_8723A("link_timer_hdl:no beacon while connecting\n");
5369 pmlmeinfo
->state
= MSR_NOLINK
;
5370 report_join_res23a(padapter
, -3);
5371 } else if (pmlmeinfo
->state
& WIFI_FW_AUTH_STATE
) {
5373 if (++pmlmeinfo
->reauth_count
> REAUTH_LIMIT
) {
5374 /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
5376 pmlmeinfo
->state
= 0;
5377 report_join_res23a(padapter
, -1);
5382 /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
5383 /* pmlmeinfo->reauth_count = 0; */
5387 DBG_8723A("link_timer_hdl: auth timeout and try again\n");
5388 pmlmeinfo
->auth_seq
= 1;
5389 issue_auth(padapter
, NULL
, 0);
5390 set_link_timer(pmlmeext
, REAUTH_TO
);
5391 } else if (pmlmeinfo
->state
& WIFI_FW_ASSOC_STATE
) {
5392 /* re-assoc timer */
5393 if (++pmlmeinfo
->reassoc_count
> REASSOC_LIMIT
) {
5394 pmlmeinfo
->state
= MSR_NOLINK
;
5395 report_join_res23a(padapter
, -2);
5399 DBG_8723A("link_timer_hdl: assoc timeout and try again\n");
5400 issue_assocreq(padapter
);
5401 set_link_timer(pmlmeext
, REASSOC_TO
);
5407 static void addba_timer_hdl(unsigned long data
)
5409 struct sta_info
*psta
= (struct sta_info
*)data
;
5410 struct ht_priv
*phtpriv
;
5415 phtpriv
= &psta
->htpriv
;
5417 if (phtpriv
->ht_option
&& phtpriv
->ampdu_enable
) {
5418 if (phtpriv
->candidate_tid_bitmap
)
5419 phtpriv
->candidate_tid_bitmap
= 0x0;
5423 void init_addba_retry_timer23a(struct sta_info
*psta
)
5425 setup_timer(&psta
->addba_retry_timer
, addba_timer_hdl
,
5426 (unsigned long)psta
);
5429 void init_mlme_ext_timer23a(struct rtw_adapter
*padapter
)
5431 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5433 setup_timer(&pmlmeext
->survey_timer
, survey_timer_hdl
,
5434 (unsigned long)padapter
);
5436 setup_timer(&pmlmeext
->link_timer
, link_timer_hdl
,
5437 (unsigned long)padapter
);
5440 int NULL_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
5445 int setopmode_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
5447 enum nl80211_iftype type
;
5448 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5449 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5450 const struct setopmode_parm
*psetop
= (struct setopmode_parm
*)pbuf
;
5452 switch (psetop
->mode
) {
5453 case NL80211_IFTYPE_P2P_GO
:
5454 case NL80211_IFTYPE_AP
:
5455 pmlmeinfo
->state
= MSR_AP
;
5458 case NL80211_IFTYPE_P2P_CLIENT
:
5459 case NL80211_IFTYPE_STATION
:
5461 pmlmeinfo
->state
&= ~(BIT(0)|BIT(1));
5462 /* set to STATION_STATE */
5463 pmlmeinfo
->state
|= MSR_INFRA
;
5466 case NL80211_IFTYPE_ADHOC
:
5474 hw_var_set_opmode(padapter
, type
);
5475 /* Set_NETYPE0_MSR(padapter, type); */
5480 int createbss_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
5482 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5483 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5484 struct wlan_bssid_ex
*pnetwork
= &pmlmeinfo
->network
;
5485 const struct wlan_bssid_ex
*pparm
= (struct wlan_bssid_ex
*)pbuf
;
5486 /* u32 initialgain; */
5488 if (pparm
->ifmode
== NL80211_IFTYPE_AP
||
5489 pparm
->ifmode
== NL80211_IFTYPE_P2P_GO
) {
5490 #ifdef CONFIG_8723AU_AP_MODE
5491 if (pmlmeinfo
->state
== MSR_AP
) {
5498 /* below is for ad-hoc master */
5499 if (pparm
->ifmode
== NL80211_IFTYPE_ADHOC
) {
5500 rtw_joinbss_reset23a(padapter
);
5502 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_20
;
5503 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
5504 pmlmeinfo
->ERP_enable
= 0;
5505 pmlmeinfo
->WMM_enable
= 0;
5506 pmlmeinfo
->HT_enable
= 0;
5507 pmlmeinfo
->HT_caps_enable
= 0;
5508 pmlmeinfo
->HT_info_enable
= 0;
5510 /* disable dynamic functions, such as high power, DIG */
5511 rtl8723a_odm_support_ability_backup(padapter
);
5513 rtl8723a_odm_support_ability_clr(padapter
,
5514 DYNAMIC_FUNC_DISABLE
);
5516 /* cancel link timer */
5517 del_timer_sync(&pmlmeext
->link_timer
);
5520 flush_all_cam_entry23a(padapter
);
5522 if (pparm
->IELength
> MAX_IE_SZ
)/* Check pbuf->IELength */
5523 return H2C_PARAMETERS_ERROR
;
5525 memcpy(pnetwork
, pparm
, sizeof(struct wlan_bssid_ex
));
5527 start_create_ibss(padapter
);
5533 int join_cmd_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
5535 struct registry_priv
*pregpriv
= &padapter
->registrypriv
;
5536 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5537 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5538 struct wlan_bssid_ex
*pnetwork
= &pmlmeinfo
->network
;
5539 const struct wlan_bssid_ex
*pparm
= (struct wlan_bssid_ex
*)pbuf
;
5540 struct ieee80211_ht_operation
*pht_info
;
5543 /* u32 initialgain; */
5546 /* check already connecting to AP or not */
5547 if (pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
) {
5548 if (pmlmeinfo
->state
& MSR_INFRA
)
5549 issue_deauth_ex(padapter
, pnetwork
->MacAddress
,
5550 WLAN_REASON_DEAUTH_LEAVING
, 5, 100);
5552 pmlmeinfo
->state
= MSR_NOLINK
;
5555 flush_all_cam_entry23a(padapter
);
5557 del_timer_sync(&pmlmeext
->link_timer
);
5559 /* set MSR to nolink -> infra. mode */
5560 rtl8723a_set_media_status(padapter
, MSR_INFRA
);
5562 hw_var_set_mlme_disconnect(padapter
);
5565 rtw_joinbss_reset23a(padapter
);
5567 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_20
;
5568 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
5569 pmlmeinfo
->ERP_enable
= 0;
5570 pmlmeinfo
->WMM_enable
= 0;
5571 pmlmeinfo
->HT_enable
= 0;
5572 pmlmeinfo
->HT_caps_enable
= 0;
5573 pmlmeinfo
->HT_info_enable
= 0;
5574 pmlmeinfo
->bwmode_updated
= false;
5575 /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
5577 if (pparm
->IELength
> MAX_IE_SZ
)/* Check pbuf->IELength */
5578 return H2C_PARAMETERS_ERROR
;
5580 memcpy(pnetwork
, pbuf
, sizeof(struct wlan_bssid_ex
));
5582 /* Check AP vendor to move rtw_joinbss_cmd23a() */
5583 /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP23a(pnetwork->IEs,
5584 pnetwork->IELength); */
5586 for (i
= 0; i
< pnetwork
->IELength
;) {
5587 p
= pnetwork
->IEs
+ i
;
5590 case WLAN_EID_VENDOR_SPECIFIC
:/* Get WMM IE. */
5591 if (!memcmp(p
+ 2, WMM_OUI23A
, 4))
5592 pmlmeinfo
->WMM_enable
= 1;
5595 case WLAN_EID_HT_CAPABILITY
: /* Get HT Cap IE. */
5596 pmlmeinfo
->HT_caps_enable
= 1;
5599 case WLAN_EID_HT_OPERATION
: /* Get HT Info IE. */
5600 pmlmeinfo
->HT_info_enable
= 1;
5602 /* spec case only for cisco's ap because cisco's ap
5603 * issue assoc rsp using mcs rate @40MHz or @20MHz */
5604 pht_info
= (struct ieee80211_ht_operation
*)(p
+ 2);
5606 if (pregpriv
->cbw40_enable
&&
5607 (pht_info
->ht_param
&
5608 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY
)) {
5609 /* switch to the 40M Hz mode according to AP */
5610 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_40
;
5611 switch (pht_info
->ht_param
&
5612 IEEE80211_HT_PARAM_CHA_SEC_OFFSET
) {
5613 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE
:
5614 pmlmeext
->cur_ch_offset
=
5615 HAL_PRIME_CHNL_OFFSET_LOWER
;
5618 case IEEE80211_HT_PARAM_CHA_SEC_BELOW
:
5619 pmlmeext
->cur_ch_offset
=
5620 HAL_PRIME_CHNL_OFFSET_UPPER
;
5624 pmlmeext
->cur_ch_offset
=
5625 HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
5629 DBG_8723A("set ch/bw before connected\n");
5640 hw_var_set_bssid(padapter
, pmlmeinfo
->network
.MacAddress
);
5641 hw_var_set_mlme_join(padapter
, 0);
5643 /* cancel link timer */
5644 del_timer_sync(&pmlmeext
->link_timer
);
5646 start_clnt_join(padapter
);
5651 int disconnect_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
5653 const struct disconnect_parm
*param
= (struct disconnect_parm
*)pbuf
;
5654 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5655 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5656 struct wlan_bssid_ex
*pnetwork
= &pmlmeinfo
->network
;
5658 if (is_client_associated_to_ap23a(padapter
)) {
5659 issue_deauth_ex(padapter
, pnetwork
->MacAddress
,
5660 WLAN_REASON_DEAUTH_LEAVING
,
5661 param
->deauth_timeout_ms
/100, 100);
5664 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
5666 /* pmlmeinfo->state = MSR_NOLINK; */
5668 hw_var_set_mlme_disconnect(padapter
);
5669 hw_var_set_bssid(padapter
, null_addr
);
5671 /* restore to initial setting. */
5672 update_tx_basic_rate23a(padapter
, padapter
->registrypriv
.wireless_mode
);
5674 if ((pmlmeinfo
->state
& 0x03) == MSR_ADHOC
||
5675 (pmlmeinfo
->state
& 0x03) == MSR_AP
)
5676 rtl8723a_set_bcn_func(padapter
, 0); /* Stop BCN */
5678 /* set MSR to no link state -> infra. mode */
5679 rtl8723a_set_media_status(padapter
, MSR_INFRA
);
5681 pmlmeinfo
->state
= MSR_NOLINK
;
5683 /* switch to the 20M Hz mode after disconnect */
5684 pmlmeext
->cur_bwmode
= HT_CHANNEL_WIDTH_20
;
5685 pmlmeext
->cur_ch_offset
= HAL_PRIME_CHNL_OFFSET_DONT_CARE
;
5687 set_channel_bwmode23a(padapter
, pmlmeext
->cur_channel
,
5688 pmlmeext
->cur_ch_offset
, pmlmeext
->cur_bwmode
);
5690 flush_all_cam_entry23a(padapter
);
5692 del_timer_sync(&pmlmeext
->link_timer
);
5694 rtw_free_uc_swdec_pending_queue23a(padapter
);
5700 rtw_scan_ch_decision(struct rtw_adapter
*padapter
,
5701 struct rtw_ieee80211_channel
*out
, u32 out_num
,
5702 const struct rtw_ieee80211_channel
*in
, u32 in_num
)
5705 int scan_ch_num
= 0;
5707 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5709 /* clear out first */
5710 memset(out
, 0, sizeof(struct rtw_ieee80211_channel
)*out_num
);
5712 /* acquire channels from in */
5714 for (i
= 0;i
<in_num
;i
++) {
5715 if (in
[i
].hw_value
&&
5716 !(in
[i
].flags
& IEEE80211_CHAN_DISABLED
) &&
5717 (set_idx
= rtw_ch_set_search_ch23a(pmlmeext
->channel_set
,
5718 in
[i
].hw_value
)) >= 0) {
5719 memcpy(&out
[j
], &in
[i
],
5720 sizeof(struct rtw_ieee80211_channel
));
5722 if (pmlmeext
->channel_set
[set_idx
].ScanType
==
5724 out
[j
].flags
&= IEEE80211_CHAN_NO_IR
;
5732 /* if out is empty, use channel_set as default */
5734 for (i
= 0;i
<pmlmeext
->max_chan_nums
;i
++) {
5735 out
[i
].hw_value
= pmlmeext
->channel_set
[i
].ChannelNum
;
5737 if (pmlmeext
->channel_set
[i
].ScanType
== SCAN_PASSIVE
)
5738 out
[i
].flags
&= IEEE80211_CHAN_NO_IR
;
5744 if (padapter
->setband
== GHZ_24
) { /* 2.4G */
5745 for (i
= 0; i
< j
; i
++) {
5746 if (out
[i
].hw_value
> 35)
5748 sizeof(struct rtw_ieee80211_channel
));
5753 } else if (padapter
->setband
== GHZ_50
) { /* 5G */
5754 for (i
= 0; i
< j
; i
++) {
5755 if (out
[i
].hw_value
> 35) {
5756 memcpy(&out
[scan_ch_num
++], &out
[i
],
5757 sizeof(struct rtw_ieee80211_channel
));
5767 int sitesurvey_cmd_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
5769 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5770 const struct sitesurvey_parm
*pparm
= (struct sitesurvey_parm
*)pbuf
;
5771 u8 bdelayscan
= false;
5775 if (pmlmeext
->sitesurvey_res
.state
== SCAN_DISABLE
) {
5776 pmlmeext
->sitesurvey_res
.state
= SCAN_START
;
5777 pmlmeext
->sitesurvey_res
.bss_cnt
= 0;
5778 pmlmeext
->sitesurvey_res
.channel_idx
= 0;
5780 for (i
= 0; i
< RTW_SSID_SCAN_AMOUNT
; i
++) {
5781 if (pparm
->ssid
[i
].ssid_len
) {
5782 memcpy(pmlmeext
->sitesurvey_res
.ssid
[i
].ssid
,
5783 pparm
->ssid
[i
].ssid
,
5784 IEEE80211_MAX_SSID_LEN
);
5785 pmlmeext
->sitesurvey_res
.ssid
[i
].ssid_len
=
5786 pparm
->ssid
[i
].ssid_len
;
5788 pmlmeext
->sitesurvey_res
.ssid
[i
].ssid_len
= 0;
5792 pmlmeext
->sitesurvey_res
.ch_num
=
5793 rtw_scan_ch_decision(padapter
,
5794 pmlmeext
->sitesurvey_res
.ch
,
5795 RTW_CHANNEL_SCAN_AMOUNT
,
5796 pparm
->ch
, pparm
->ch_num
);
5798 pmlmeext
->sitesurvey_res
.scan_mode
= pparm
->scan_mode
;
5800 /* issue null data if associating to the AP */
5801 if (is_client_associated_to_ap23a(padapter
)) {
5802 pmlmeext
->sitesurvey_res
.state
= SCAN_TXNULL
;
5804 /* switch to correct channel of current network
5805 before issue keep-alive frames */
5806 if (rtw_get_oper_ch23a(padapter
) !=
5807 pmlmeext
->cur_channel
)
5808 SelectChannel23a(padapter
,
5809 pmlmeext
->cur_channel
);
5811 issue_nulldata23a(padapter
, NULL
, 1, 3, 500);
5817 /* delay 50ms to protect nulldata(1). */
5818 set_survey_timer(pmlmeext
, 50);
5823 if (pmlmeext
->sitesurvey_res
.state
== SCAN_START
||
5824 pmlmeext
->sitesurvey_res
.state
== SCAN_TXNULL
) {
5825 /* disable dynamic functions, such as high power, DIG */
5826 rtl8723a_odm_support_ability_backup(padapter
);
5827 rtl8723a_odm_support_ability_clr(padapter
,
5828 DYNAMIC_FUNC_DISABLE
);
5830 /* config the initial gain under scanning, need to
5831 write the BB registers */
5832 if (wdev_to_priv(padapter
->rtw_wdev
)->p2p_enabled
== true)
5837 rtl8723a_set_initial_gain(padapter
, initialgain
);
5839 /* set MSR to no link state */
5840 rtl8723a_set_media_status(padapter
, MSR_NOLINK
);
5842 rtl8723a_mlme_sitesurvey(padapter
, 1);
5844 pmlmeext
->sitesurvey_res
.state
= SCAN_PROCESS
;
5847 rtw_site_survey(padapter
);
5852 int setauth_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
5854 const struct setauth_parm
*pparm
= (struct setauth_parm
*)pbuf
;
5855 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5856 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5858 if (pparm
->mode
< 4)
5859 pmlmeinfo
->auth_algo
= pparm
->mode
;
5864 int setkey_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
5866 unsigned short ctrl
;
5867 const struct setkey_parm
*pparm
= (struct setkey_parm
*)pbuf
;
5868 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5869 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5870 unsigned char null_sta
[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
5872 /* main tx key for wep. */
5874 pmlmeinfo
->key_index
= pparm
->keyid
;
5877 ctrl
= BIT(15) | (pparm
->algorithm
) << 2 | pparm
->keyid
;
5879 DBG_8723A_LEVEL(_drv_always_
, "set group key to hw: alg:%d(WEP40-1 "
5880 "WEP104-5 TKIP-2 AES-4) keyid:%d\n",
5881 pparm
->algorithm
, pparm
->keyid
);
5882 rtl8723a_cam_write(padapter
, pparm
->keyid
, ctrl
, null_sta
, pparm
->key
);
5884 /* allow multicast packets to driver */
5885 rtl8723a_on_rcr_am(padapter
);
5890 int set_stakey_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
5893 u8 cam_id
;/* cam_entry */
5894 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5895 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5896 const struct set_stakey_parm
*pparm
= (struct set_stakey_parm
*)pbuf
;
5899 /* 0~3 for default key */
5901 /* for concurrent mode (ap+sta): */
5902 /* default key is disable, using sw encrypt/decrypt */
5903 /* cam_entry = 4 for sta mode (macid = 0) */
5904 /* cam_entry(macid+3) = 5 ~ N for ap mode (aid = 1~N, macid = 2 ~N) */
5906 /* for concurrent mode (sta+sta): */
5907 /* default key is disable, using sw encrypt/decrypt */
5908 /* cam_entry = 4 mapping to macid = 0 */
5909 /* cam_entry = 5 mapping to macid = 2 */
5913 DBG_8723A_LEVEL(_drv_always_
, "set pairwise key to hw: alg:%d(WEP40-1 "
5914 "WEP104-5 TKIP-2 AES-4) camid:%d\n",
5915 pparm
->algorithm
, cam_id
);
5916 if ((pmlmeinfo
->state
& 0x03) == MSR_AP
) {
5917 struct sta_info
*psta
;
5918 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
5920 if (pparm
->algorithm
== 0) { /* clear cam entry */
5921 clear_cam_entry23a(padapter
, pparm
->id
);
5922 return H2C_SUCCESS_RSP
;
5925 psta
= rtw_get_stainfo23a(pstapriv
, pparm
->addr
);
5927 ctrl
= BIT(15) | (pparm
->algorithm
<< 2);
5929 DBG_8723A("r871x_set_stakey_hdl23a(): enc_algorithm "
5930 "=%d\n", pparm
->algorithm
);
5932 if (psta
->mac_id
< 1 || psta
->mac_id
> (NUM_STA
- 4)) {
5933 DBG_8723A("r871x_set_stakey_hdl23a():set_stakey"
5934 " failed, mac_id(aid) =%d\n",
5936 return H2C_REJECTED
;
5939 /* 0~3 for default key, cmd_id = macid + 3,
5941 cam_id
= psta
->mac_id
+ 3;
5943 DBG_8723A("Write CAM, mac_addr =%x:%x:%x:%x:%x:%x, "
5944 "cam_entry =%d\n", pparm
->addr
[0],
5945 pparm
->addr
[1], pparm
->addr
[2],
5946 pparm
->addr
[3], pparm
->addr
[4],
5947 pparm
->addr
[5], cam_id
);
5949 rtl8723a_cam_write(padapter
, cam_id
, ctrl
,
5950 pparm
->addr
, pparm
->key
);
5952 return H2C_SUCCESS_RSP
;
5954 DBG_8723A("r871x_set_stakey_hdl23a(): sta has been "
5956 return H2C_REJECTED
;
5960 /* below for sta mode */
5962 if (pparm
->algorithm
== 0) { /* clear cam entry */
5963 clear_cam_entry23a(padapter
, pparm
->id
);
5967 ctrl
= BIT(15) | (pparm
->algorithm
<< 2);
5969 rtl8723a_cam_write(padapter
, cam_id
, ctrl
, pparm
->addr
, pparm
->key
);
5971 pmlmeinfo
->enc_algo
= pparm
->algorithm
;
5976 int add_ba_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
5978 const struct addBaReq_parm
*pparm
= (struct addBaReq_parm
*)pbuf
;
5979 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
5980 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
5981 struct sta_info
*psta
;
5983 psta
= rtw_get_stainfo23a(&padapter
->stapriv
, pparm
->addr
);
5988 if (((pmlmeinfo
->state
& WIFI_FW_ASSOC_SUCCESS
) &&
5989 pmlmeinfo
->HT_enable
) ||
5990 (pmlmeinfo
->state
& 0x03) == MSR_AP
) {
5991 issue_action_BA23a(padapter
, pparm
->addr
,
5992 WLAN_ACTION_ADDBA_REQ
, (u16
)pparm
->tid
);
5993 mod_timer(&psta
->addba_retry_timer
,
5994 jiffies
+ msecs_to_jiffies(ADDBA_TO
));
5996 psta
->htpriv
.candidate_tid_bitmap
&= ~BIT(pparm
->tid
);
6001 int set_tx_beacon_cmd23a(struct rtw_adapter
*padapter
)
6003 struct cmd_obj
*ph2c
;
6004 struct Tx_Beacon_param
*ptxBeacon_parm
;
6005 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
6006 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
6007 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
6011 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
6017 ptxBeacon_parm
= kzalloc(sizeof(struct Tx_Beacon_param
), GFP_ATOMIC
);
6018 if (!ptxBeacon_parm
) {
6024 memcpy(&ptxBeacon_parm
->network
, &pmlmeinfo
->network
,
6025 sizeof(struct wlan_bssid_ex
));
6027 len_diff
= update_hidden_ssid(ptxBeacon_parm
->network
.IEs
,
6028 ptxBeacon_parm
->network
.IELength
,
6029 pmlmeinfo
->hidden_ssid_mode
);
6030 ptxBeacon_parm
->network
.IELength
+= len_diff
;
6032 init_h2fwcmd_w_parm_no_rsp(ph2c
, ptxBeacon_parm
,
6033 GEN_CMD_CODE(_TX_Beacon
));
6035 res
= rtw_enqueue_cmd23a(pcmdpriv
, ph2c
);
6041 int mlme_evt_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6043 u8 evt_code
, evt_seq
;
6045 const struct C2HEvent_Header
*c2h
;
6046 void (*event_callback
)(struct rtw_adapter
*dev
, const u8
*pbuf
);
6048 c2h
= (struct C2HEvent_Header
*)pbuf
;
6053 /* checking if event code is valid */
6054 if (evt_code
>= MAX_C2HEVT
) {
6055 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
,
6056 "Event Code(%d) mismatch!\n", evt_code
);
6060 /* checking if event size match the event parm size */
6061 if (wlanevents
[evt_code
].parmsize
!= 0 &&
6062 wlanevents
[evt_code
].parmsize
!= evt_sz
) {
6063 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
,
6064 "Event(%d) Parm Size mismatch (%d vs %d)!\n",
6065 evt_code
, wlanevents
[evt_code
].parmsize
, evt_sz
);
6069 event_callback
= wlanevents
[evt_code
].event_callback
;
6070 event_callback(padapter
, pbuf
+ sizeof(struct C2HEvent_Header
));
6077 int h2c_msg_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6080 return H2C_PARAMETERS_ERROR
;
6085 int tx_beacon_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6087 if (send_beacon23a(padapter
) == _FAIL
) {
6088 DBG_8723A("issue_beacon23a, fail!\n");
6089 return H2C_PARAMETERS_ERROR
;
6091 #ifdef CONFIG_8723AU_AP_MODE
6092 else { /* tx bc/mc frames after update TIM */
6093 struct sta_info
*psta_bmc
;
6094 struct list_head
*plist
, *phead
, *ptmp
;
6095 struct xmit_frame
*pxmitframe
;
6096 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
6097 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
6099 /* for BC/MC Frames */
6100 psta_bmc
= rtw_get_bcmc_stainfo23a(padapter
);
6104 if (pstapriv
->tim_bitmap
& BIT(0) && psta_bmc
->sleepq_len
> 0) {
6105 msleep(10);/* 10ms, ATIM(HIQ) Windows */
6106 /* spin_lock_bh(&psta_bmc->sleep_q.lock); */
6107 spin_lock_bh(&pxmitpriv
->lock
);
6109 phead
= get_list_head(&psta_bmc
->sleep_q
);
6111 list_for_each_safe(plist
, ptmp
, phead
) {
6112 pxmitframe
= container_of(plist
,
6116 list_del_init(&pxmitframe
->list
);
6118 psta_bmc
->sleepq_len
--;
6119 if (psta_bmc
->sleepq_len
>0)
6120 pxmitframe
->attrib
.mdata
= 1;
6122 pxmitframe
->attrib
.mdata
= 0;
6124 pxmitframe
->attrib
.triggered
= 1;
6126 pxmitframe
->attrib
.qsel
= 0x11;/* HIQ */
6128 rtl8723au_hal_xmitframe_enqueue(padapter
,
6132 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
6133 spin_unlock_bh(&pxmitpriv
->lock
);
6141 int set_ch_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6143 const struct set_ch_parm
*set_ch_parm
;
6144 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
6147 return H2C_PARAMETERS_ERROR
;
6149 set_ch_parm
= (struct set_ch_parm
*)pbuf
;
6151 DBG_8723A("%s(%s): ch:%u, bw:%u, ch_offset:%u\n", __func__
,
6152 padapter
->pnetdev
->name
, set_ch_parm
->ch
,
6153 set_ch_parm
->bw
, set_ch_parm
->ch_offset
);
6155 pmlmeext
->cur_channel
= set_ch_parm
->ch
;
6156 pmlmeext
->cur_ch_offset
= set_ch_parm
->ch_offset
;
6157 pmlmeext
->cur_bwmode
= set_ch_parm
->bw
;
6159 set_channel_bwmode23a(padapter
, set_ch_parm
->ch
,
6160 set_ch_parm
->ch_offset
, set_ch_parm
->bw
);
6165 int set_chplan_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6167 const struct SetChannelPlan_param
*setChannelPlan_param
;
6168 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
6171 return H2C_PARAMETERS_ERROR
;
6173 setChannelPlan_param
= (struct SetChannelPlan_param
*)pbuf
;
6175 pmlmeext
->max_chan_nums
=
6176 init_channel_set(padapter
, setChannelPlan_param
->channel_plan
,
6177 pmlmeext
->channel_set
);
6178 init_channel_list(padapter
, pmlmeext
->channel_set
,
6179 pmlmeext
->max_chan_nums
, &pmlmeext
->channel_list
);
6184 int led_blink_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6186 struct LedBlink_param
*ledBlink_param
;
6189 return H2C_PARAMETERS_ERROR
;
6191 ledBlink_param
= (struct LedBlink_param
*)pbuf
;
6196 int set_csa_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6198 return H2C_REJECTED
;
6201 /* TDLS_WRCR : write RCR DATA BIT */
6202 /* TDLS_SD_PTI : issue peer traffic indication */
6203 /* TDLS_CS_OFF : go back to the channel linked with AP,
6204 terminating channel switch procedure */
6205 /* TDLS_INIT_CH_SEN : init channel sensing, receive all data and
6207 /* TDLS_DONE_CH_SEN : channel sensing and report candidate channel */
6208 /* TDLS_OFF_CH : first time set channel to off channel */
6209 /* TDLS_BASE_CH : go back tp the channel linked with AP when set
6210 base channel as target channel */
6211 /* TDLS_P_OFF_CH : periodically go to off channel */
6212 /* TDLS_P_BASE_CH : periodically go back to base channel */
6213 /* TDLS_RS_RCR : restore RCR */
6214 /* TDLS_CKALV_PH1 : check alive timer phase1 */
6215 /* TDLS_CKALV_PH2 : check alive timer phase2 */
6216 /* TDLS_FREE_STA : free tdls sta */
6217 int tdls_hdl23a(struct rtw_adapter
*padapter
, const u8
*pbuf
)
6219 return H2C_REJECTED
;