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>
25 #include <linux/ieee80211.h>
27 #ifdef CONFIG_8723AU_BT_COEXIST
28 #include <rtl8723a_hal.h>
31 static struct mlme_handler mlme_sta_tbl[]={
32 {"OnAssocReq23a", &OnAssocReq23a},
33 {"OnAssocRsp23a", &OnAssocRsp23a},
34 {"OnReAssocReq", &OnAssocReq23a},
35 {"OnReAssocRsp", &OnAssocRsp23a},
36 {"OnProbeReq23a", &OnProbeReq23a},
37 {"OnProbeRsp23a", &OnProbeRsp23a},
39 /*----------------------------------------------------------
41 -----------------------------------------------------------*/
42 {"DoReserved23a", &DoReserved23a},
43 {"DoReserved23a", &DoReserved23a},
44 {"OnBeacon23a", &OnBeacon23a},
45 {"OnATIM", &OnAtim23a},
46 {"OnDisassoc23a", &OnDisassoc23a},
47 {"OnAuth23a", &OnAuth23aClient23a},
48 {"OnDeAuth23a", &OnDeAuth23a},
49 {"OnAction23a", &OnAction23a},
52 static struct action_handler OnAction23a_tbl[]={
53 {WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct23a},
54 {WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction23a_qos},
55 {WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction23a_dls},
56 {WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction23a_back23a},
57 {WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public23a},
58 {WLAN_CATEGORY_HT, "ACTION_HT", &OnAction23a_ht},
59 {WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved23a},
60 {WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction23a_wmm},
61 {WLAN_CATEGORY_VENDOR_SPECIFIC, "ACTION_P2P", &OnAction23a_p2p},
64 static u8 null_addr[ETH_ALEN]= {0, 0, 0, 0, 0, 0};
66 /**************************************************
67 OUI definitions for the vendor specific IE
68 ***************************************************/
69 unsigned char RTW_WPA_OUI23A[] = {0x00, 0x50, 0xf2, 0x01};
70 unsigned char WMM_OUI23A[] = {0x00, 0x50, 0xf2, 0x02};
71 unsigned char WPS_OUI23A[] = {0x00, 0x50, 0xf2, 0x04};
72 unsigned char P2P_OUI23A[] = {0x50, 0x6F, 0x9A, 0x09};
73 unsigned char WFD_OUI23A[] = {0x50, 0x6F, 0x9A, 0x0A};
75 unsigned char WMM_INFO_OUI23A[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
76 unsigned char WMM_PARA_OUI23A[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
78 unsigned char WPA_TKIP_CIPHER23A[4] = {0x00, 0x50, 0xf2, 0x02};
79 unsigned char RSN_TKIP_CIPHER23A[4] = {0x00, 0x0f, 0xac, 0x02};
82 /********************************************************
84 *********************************************************/
85 unsigned char MCS_rate_2R23A[16] = {
86 0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
87 unsigned char MCS_rate_1R23A[16] = {
88 0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
90 /********************************************************
91 ChannelPlan definitions
92 *********************************************************/
94 static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
95 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x00, RT_CHANNEL_DOMAIN_2G_WORLD , Passive scan CH 12, 13 */
96 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
97 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
98 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
99 {{10, 11, 12, 13}, 4}, /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
100 {{}, 0}, /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */
103 static struct rt_channel_plan_5g RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
104 {{}, 0}, /* 0x00, RT_CHANNEL_DOMAIN_5G_NULL */
105 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19}, /* 0x01, RT_CHANNEL_DOMAIN_5G_ETSI1 */
106 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24}, /* 0x02, RT_CHANNEL_DOMAIN_5G_ETSI2 */
107 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 149, 153, 157, 161, 165}, 22}, /* 0x03, RT_CHANNEL_DOMAIN_5G_ETSI3 */
108 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165}, 24}, /* 0x04, RT_CHANNEL_DOMAIN_5G_FCC1 */
109 {{36, 40, 44, 48, 149, 153, 157, 161, 165}, 9}, /* 0x05, RT_CHANNEL_DOMAIN_5G_FCC2 */
110 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165}, 13}, /* 0x06, RT_CHANNEL_DOMAIN_5G_FCC3 */
111 {{36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161}, 12}, /* 0x07, RT_CHANNEL_DOMAIN_5G_FCC4 */
112 {{149, 153, 157, 161, 165}, 5}, /* 0x08, RT_CHANNEL_DOMAIN_5G_FCC5 */
113 {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, /* 0x09, RT_CHANNEL_DOMAIN_5G_FCC6 */
114 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 20}, /* 0x0A, RT_CHANNEL_DOMAIN_5G_FCC7_IC1 */
115 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 149, 153, 157, 161, 165}, 20}, /* 0x0B, RT_CHANNEL_DOMAIN_5G_KCC1 */
116 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 19}, /* 0x0C, RT_CHANNEL_DOMAIN_5G_MKK1 */
117 {{36, 40, 44, 48, 52, 56, 60, 64}, 8}, /* 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 */
118 {{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}, 11}, /* 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 */
119 {{56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165}, 15}, /* 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 */
120 {{56, 60, 64, 149, 153, 157, 161, 165}, 8}, /* 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 */
122 /* Driver self defined for old channel plan Compatible , Remember to modify if have new channel plan definition ===== */
123 {{36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165}, 21}, /* 0x11, RT_CHANNEL_DOMAIN_5G_FCC */
124 {{36, 40, 44, 48}, 4}, /* 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS */
125 {{36, 40, 44, 48, 149, 153, 157, 161}, 8}, /* 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS */
128 static struct rt_channel_plan_map RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
129 /* 0x00 ~ 0x1F , Old Define ===== */
130 {0x02, 0x11}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
131 {0x02, 0x0A}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
132 {0x01, 0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
133 {0x01, 0x00}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
134 {0x01, 0x00}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
135 {0x03, 0x00}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */
136 {0x03, 0x00}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
137 {0x01, 0x09}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
138 {0x03, 0x09}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
139 {0x03, 0x00}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
140 {0x00, 0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
141 {0x02, 0x0F}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
142 {0x01, 0x08}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
143 {0x02, 0x06}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
144 {0x02, 0x0B}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
145 {0x02, 0x09}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
146 {0x01, 0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
147 {0x02, 0x05}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
148 {0x01, 0x12}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
149 {0x00, 0x04}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
150 {0x02, 0x10}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
151 {0x00, 0x12}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
152 {0x00, 0x13}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
153 {0x03, 0x12}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
154 {0x05, 0x08}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
155 {0x02, 0x08}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
156 {0x00, 0x00}, /* 0x1A, */
157 {0x00, 0x00}, /* 0x1B, */
158 {0x00, 0x00}, /* 0x1C, */
159 {0x00, 0x00}, /* 0x1D, */
160 {0x00, 0x00}, /* 0x1E, */
161 {0x05, 0x04}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
162 /* 0x20 ~ 0x7F , New Define ===== */
163 {0x00, 0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
164 {0x01, 0x00}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
165 {0x02, 0x00}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
166 {0x03, 0x00}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
167 {0x04, 0x00}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
168 {0x02, 0x04}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
169 {0x00, 0x01}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
170 {0x03, 0x0C}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
171 {0x00, 0x0B}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
172 {0x00, 0x05}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
173 {0x00, 0x00}, /* 0x2A, */
174 {0x00, 0x00}, /* 0x2B, */
175 {0x00, 0x00}, /* 0x2C, */
176 {0x00, 0x00}, /* 0x2D, */
177 {0x00, 0x00}, /* 0x2E, */
178 {0x00, 0x00}, /* 0x2F, */
179 {0x00, 0x06}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
180 {0x00, 0x07}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
181 {0x00, 0x08}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
182 {0x00, 0x09}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
183 {0x02, 0x0A}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
184 {0x00, 0x02}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
185 {0x00, 0x03}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
186 {0x03, 0x0D}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
187 {0x03, 0x0E}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
188 {0x02, 0x0F}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
189 {0x00, 0x00}, /* 0x3A, */
190 {0x00, 0x00}, /* 0x3B, */
191 {0x00, 0x00}, /* 0x3C, */
192 {0x00, 0x00}, /* 0x3D, */
193 {0x00, 0x00}, /* 0x3E, */
194 {0x00, 0x00}, /* 0x3F, */
195 {0x02, 0x10}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
196 {0x03, 0x00}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */
199 static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03, 0x02}; /* use the conbination for max channel numbers */
201 static struct fwevent wlanevents[] =
203 {0, rtw_dummy_event_callback23a}, /*0*/
211 {0, &rtw_survey_event_cb23a}, /*8*/
212 {sizeof (struct surveydone_event), &rtw_surveydone_event_callback23a}, /*9*/
214 {0, &rtw23a_joinbss_event_cb}, /*10*/
215 {sizeof(struct stassoc_event), &rtw_stassoc_event_callback23a},
216 {sizeof(struct stadel_event), &rtw_stadel_event_callback23a},
217 {0, &rtw_atimdone_event_callback23a},
218 {0, rtw_dummy_event_callback23a},
223 {0, rtw23a_fwdbg_event_callback},
227 {0, &rtw_cpwm_event_callback23a},
233 * Search the @param channel_num in given @param channel_set
234 * @ch_set: the given channel set
235 * @ch: the given channel number
237 * return the index of channel_num in channel_set, -1 if not found
239 int rtw_ch_set_search_ch23a(struct rt_channel_info *ch_set, const u32 ch)
242 for (i = 0; ch_set[i]. ChannelNum != 0; i++) {
243 if (ch == ch_set[i].ChannelNum)
247 if (i >= ch_set[i].ChannelNum)
252 /****************************************************************************
254 Following are the initialization functions for WiFi MLME
256 *****************************************************************************/
258 int init_hw_mlme_ext23a(struct rtw_adapter *padapter)
260 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
262 set_channel_bwmode23a(padapter, pmlmeext->cur_channel,
263 pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
267 static void init_mlme_ext_priv23a_value(struct rtw_adapter* padapter)
269 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
270 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
271 unsigned char mixed_datarate[NumRates] = {
272 _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
273 _9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_,
274 _48M_RATE_, _54M_RATE_, 0xff};
275 unsigned char mixed_basicrate[NumRates] = {
276 _1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,
277 _12M_RATE_, _24M_RATE_, 0xff,};
279 atomic_set(&pmlmeext->event_seq, 0);
280 /* reset to zero when disconnect at client mode */
281 pmlmeext->mgnt_seq = 0;
283 pmlmeext->cur_channel = padapter->registrypriv.channel;
284 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
285 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
289 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
291 memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
292 memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
294 if (pmlmeext->cur_channel > 14)
295 pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
297 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
299 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
300 pmlmeext->sitesurvey_res.channel_idx = 0;
301 pmlmeext->sitesurvey_res.bss_cnt = 0;
302 pmlmeext->scan_abort = false;
304 pmlmeinfo->state = WIFI_FW_NULL_STATE;
305 pmlmeinfo->reauth_count = 0;
306 pmlmeinfo->reassoc_count = 0;
307 pmlmeinfo->link_count = 0;
308 pmlmeinfo->auth_seq = 0;
309 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
310 pmlmeinfo->key_index = 0;
313 pmlmeinfo->enc_algo = _NO_PRIVACY_;
314 pmlmeinfo->authModeToggle = 0;
316 memset(pmlmeinfo->chg_txt, 0, 128);
318 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
319 pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
321 pmlmeinfo->dialogToken = 0;
323 pmlmeext->action_public_rxseq = 0xffff;
324 pmlmeext->action_public_dialog_token = 0xff;
327 static int has_channel(struct rt_channel_info *channel_set,
328 u8 chanset_size, u8 chan) {
331 for (i = 0; i < chanset_size; i++) {
332 if (channel_set[i].ChannelNum == chan)
339 static void init_channel_list(struct rtw_adapter *padapter,
340 struct rt_channel_info *channel_set,
342 struct p2p_channels *channel_list) {
344 struct p2p_oper_class_map op_class[] = {
345 { IEEE80211G, 81, 1, 13, 1, BW20 },
346 { IEEE80211G, 82, 14, 14, 1, BW20 },
347 { IEEE80211A, 115, 36, 48, 4, BW20 },
348 { IEEE80211A, 116, 36, 44, 8, BW40PLUS },
349 { IEEE80211A, 117, 40, 48, 8, BW40MINUS },
350 { IEEE80211A, 124, 149, 161, 4, BW20 },
351 { IEEE80211A, 125, 149, 169, 4, BW20 },
352 { IEEE80211A, 126, 149, 157, 8, BW40PLUS },
353 { IEEE80211A, 127, 153, 161, 8, BW40MINUS },
354 { -1, 0, 0, 0, 0, BW20 }
361 for (op = 0; op_class[op].op_class; op++) {
363 struct p2p_oper_class_map *o = &op_class[op];
364 struct p2p_reg_class *reg = NULL;
366 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
367 if (!has_channel(channel_set, chanset_size, ch))
370 if ((0 == padapter->registrypriv.ht_enable) &&
374 if ((0 == (padapter->registrypriv.cbw40_enable & BIT(1))) &&
375 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
379 reg = &channel_list->reg_class[cla];
381 reg->reg_class = o->op_class;
384 reg->channel[reg->channels] = ch;
388 channel_list->reg_classes = cla;
391 static u8 init_channel_set(struct rtw_adapter* padapter, u8 ChannelPlan,
392 struct rt_channel_info *channel_set)
394 u8 index, chanset_size = 0;
395 u8 b5GBand = false, b2_4GBand = false;
396 u8 Index2G = 0, Index5G = 0;
398 memset(channel_set, 0, sizeof(struct rt_channel_info)*MAX_CHANNEL_NUM);
400 if (ChannelPlan >= RT_CHANNEL_DOMAIN_MAX &&
401 ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) {
402 DBG_8723A("ChannelPlan ID %x error !!!!!\n", ChannelPlan);
406 if (padapter->registrypriv.wireless_mode & WIRELESS_11G) {
408 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
409 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
411 Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
414 if (padapter->registrypriv.wireless_mode & WIRELESS_11A) {
416 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
417 Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
419 Index5G = RTW_ChannelPlanMap[ChannelPlan].Index5G;
423 for (index = 0; index<RTW_ChannelPlan2G[Index2G].Len; index++) {
424 channel_set[chanset_size].ChannelNum =
425 RTW_ChannelPlan2G[Index2G].Channel[index];
427 if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == ChannelPlan) ||
428 /* Channel 1~11 is active, and 12~14 is passive */
429 (RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G == ChannelPlan)){
430 if (channel_set[chanset_size].ChannelNum >= 1 &&
431 channel_set[chanset_size].ChannelNum <= 11)
432 channel_set[chanset_size].ScanType =
434 else if ((channel_set[chanset_size].ChannelNum >= 12 &&
435 channel_set[chanset_size].ChannelNum <= 14))
436 channel_set[chanset_size].ScanType =
438 } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 ==
440 RT_CHANNEL_DOMAIN_WORLD_WIDE_5G ==
442 RT_CHANNEL_DOMAIN_2G_WORLD == Index2G) {
443 /* channel 12~13, passive scan */
444 if (channel_set[chanset_size].ChannelNum <= 11)
445 channel_set[chanset_size].ScanType =
448 channel_set[chanset_size].ScanType =
451 channel_set[chanset_size].ScanType =
459 for (index = 0;index<RTW_ChannelPlan5G[Index5G].Len;index++) {
460 if (RTW_ChannelPlan5G[Index5G].Channel[index] <= 48 ||
461 RTW_ChannelPlan5G[Index5G].Channel[index] >= 149) {
462 channel_set[chanset_size].ChannelNum =
463 RTW_ChannelPlan5G[Index5G].Channel[index];
464 if (RT_CHANNEL_DOMAIN_WORLD_WIDE_5G ==
466 /* passive scan for all 5G channels */
467 channel_set[chanset_size].ScanType =
470 channel_set[chanset_size].ScanType =
472 DBG_8723A("%s(): channel_set[%d].ChannelNum = "
473 "%d\n", __func__, chanset_size,
474 channel_set[chanset_size].ChannelNum);
483 int init_mlme_ext_priv23a(struct rtw_adapter* padapter)
486 struct registry_priv* pregistrypriv = &padapter->registrypriv;
487 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
488 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
489 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
491 pmlmeext->padapter = padapter;
493 init_mlme_ext_priv23a_value(padapter);
494 pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
496 init_mlme_ext_timer23a(padapter);
498 #ifdef CONFIG_8723AU_AP_MODE
499 init_mlme_ap_info23a(padapter);
502 pmlmeext->max_chan_nums = init_channel_set(padapter,
503 pmlmepriv->ChannelPlan,
504 pmlmeext->channel_set);
505 init_channel_list(padapter, pmlmeext->channel_set,
506 pmlmeext->max_chan_nums, &pmlmeext->channel_list);
508 pmlmeext->chan_scan_time = SURVEY_TO;
509 pmlmeext->mlmeext_init = true;
511 pmlmeext->active_keep_alive_check = true;
515 void free_mlme_ext_priv23a (struct mlme_ext_priv *pmlmeext)
517 struct rtw_adapter *padapter = pmlmeext->padapter;
522 if (padapter->bDriverStopped == true) {
523 del_timer_sync(&pmlmeext->survey_timer);
524 del_timer_sync(&pmlmeext->link_timer);
525 /* del_timer_sync(&pmlmeext->ADDBA_timer); */
530 _mgt_dispatcher23a(struct rtw_adapter *padapter, struct mlme_handler *ptable,
531 struct recv_frame *precv_frame)
533 struct sk_buff *skb = precv_frame->pkt;
534 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
537 /* receive the frames that ra(a1) is my address
538 or ra(a1) is bc address. */
539 if (!ether_addr_equal(hdr->addr1, myid(&padapter->eeprompriv))&&
540 !is_broadcast_ether_addr(hdr->addr1))
543 ptable->func(padapter, precv_frame);
547 void mgt_dispatcher23a(struct rtw_adapter *padapter,
548 struct recv_frame *precv_frame)
551 struct mlme_handler *ptable;
552 #ifdef CONFIG_8723AU_AP_MODE
553 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
554 #endif /* CONFIG_8723AU_AP_MODE */
555 struct sk_buff *skb = precv_frame->pkt;
556 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
558 struct sta_info *psta;
560 if (!ieee80211_is_mgmt(hdr->frame_control))
563 /* receive the frames that ra(a1) is my address or ra(a1) is
565 if (!ether_addr_equal(hdr->addr1, myid(&padapter->eeprompriv)) &&
566 !is_broadcast_ether_addr(hdr->addr1))
569 ptable = mlme_sta_tbl;
571 stype = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE;
575 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_,
576 ("Currently we do not support reserved sub-fr-type ="
582 psta = rtw_get_stainfo23a(&padapter->stapriv, hdr->addr2);
585 if (ieee80211_has_retry(hdr->frame_control)) {
586 if (precv_frame->attrib.seq_num ==
587 psta->RxMgmtFrameSeqNum) {
588 /* drop the duplicate management frame */
589 DBG_8723A("Drop duplicate management frame "
590 "with seq_num = %d.\n",
591 precv_frame->attrib.seq_num);
595 psta->RxMgmtFrameSeqNum = precv_frame->attrib.seq_num;
598 #ifdef CONFIG_8723AU_AP_MODE
601 case IEEE80211_STYPE_AUTH:
602 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
603 ptable->func = &OnAuth23a;
605 ptable->func = &OnAuth23aClient23a;
607 case IEEE80211_STYPE_ASSOC_REQ:
608 case IEEE80211_STYPE_REASSOC_REQ:
609 _mgt_dispatcher23a(padapter, ptable, precv_frame);
611 case IEEE80211_STYPE_PROBE_REQ:
612 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
613 _mgt_dispatcher23a(padapter, ptable, precv_frame);
615 _mgt_dispatcher23a(padapter, ptable, precv_frame);
617 case IEEE80211_STYPE_BEACON:
618 _mgt_dispatcher23a(padapter, ptable, precv_frame);
620 case IEEE80211_STYPE_ACTION:
621 /* if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) */
622 _mgt_dispatcher23a(padapter, ptable, precv_frame);
625 _mgt_dispatcher23a(padapter, ptable, precv_frame);
626 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)
627 rtw_hostapd_mlme_rx23a(padapter, precv_frame);
631 _mgt_dispatcher23a(padapter, ptable, precv_frame);
635 #ifdef CONFIG_8723AU_P2P
636 static u32 p2p_listen_state_process(struct rtw_adapter *padapter,
639 bool response = true;
641 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == false ||
642 padapter->mlmepriv.wps_probe_resp_ie == NULL ||
643 padapter->mlmepriv.p2p_probe_resp_ie == NULL) {
644 DBG_8723A("DON'T issue_probersp23a_p2p23a: p2p_enabled:%d, "
645 "wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p\n",
646 wdev_to_priv(padapter->rtw_wdev)->p2p_enabled,
647 padapter->mlmepriv.wps_probe_resp_ie,
648 padapter->mlmepriv.p2p_probe_resp_ie);
652 if (response == true)
653 issue_probersp23a_p2p23a(padapter, da);
657 #endif /* CONFIG_8723AU_P2P */
659 /****************************************************************************
661 Following are the callback functions for each subtype of the management frames
663 *****************************************************************************/
665 unsigned int OnProbeReq23a(struct rtw_adapter *padapter,
666 struct recv_frame *precv_frame)
670 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
671 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
672 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
673 struct wlan_bssid_ex *cur = &pmlmeinfo->network;
674 struct sk_buff *skb = precv_frame->pkt;
675 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
676 u8 *pframe = skb->data;
678 u8 is_valid_p2p_probereq = false;
680 #ifdef CONFIG_8723AU_P2P
681 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
682 u8 wifi_test_chk_rate = 1;
684 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
685 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
686 !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
687 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
688 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)) {
689 /* mcs_rate = 0 -> CCK 1M rate */
690 /* mcs_rate = 1 -> CCK 2M rate */
691 /* mcs_rate = 2 -> CCK 5.5M rate */
692 /* mcs_rate = 3 -> CCK 11M rate */
693 /* In the P2P mode, the driver should not support
696 /* IOT issue: Google Nexus7 use 1M rate to send
697 p2p_probe_req after GO nego completed and Nexus7
699 if (wifi_test_chk_rate == 1) {
700 if ((is_valid_p2p_probereq =
701 process_probe_req_p2p_ie23a(pwdinfo, pframe,
703 if (rtw_p2p_chk_role(pwdinfo,
705 u8 *sa = ieee80211_get_SA(hdr);
706 p2p_listen_state_process(padapter, sa);
710 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
718 #endif /* CONFIG_8723AU_P2P */
720 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
724 if (check_fwstate(pmlmepriv, _FW_LINKED) == false &&
725 check_fwstate(pmlmepriv,
726 WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE) == false) {
730 p = rtw_get_ie23a(pframe + sizeof(struct ieee80211_hdr_3addr) +
731 _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
732 len - sizeof(struct ieee80211_hdr_3addr) -
733 _PROBEREQ_IE_OFFSET_);
735 /* check (wildcard) SSID */
737 if (is_valid_p2p_probereq == true) {
738 goto _issue_probersp23a;
742 memcmp((void *)(p+2), cur->Ssid.ssid,
743 cur->Ssid.ssid_len)) ||
744 (ielen == 0 && pmlmeinfo->hidden_ssid_mode)) {
750 if (check_fwstate(pmlmepriv, _FW_LINKED) == true &&
751 pmlmepriv->cur_network.join_res == true) {
752 /* DBG_8723A("+issue_probersp23a during ap mode\n"); */
753 issue_probersp23a(padapter, ieee80211_get_SA(hdr),
754 is_valid_p2p_probereq);
761 unsigned int OnProbeRsp23a(struct rtw_adapter *padapter,
762 struct recv_frame *precv_frame)
764 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
765 #ifdef CONFIG_8723AU_P2P
766 struct sk_buff *skb = precv_frame->pkt;
767 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
768 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
771 #ifdef CONFIG_8723AU_P2P
772 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) {
773 if (pwdinfo->tx_prov_disc_info.benable == true) {
774 if (ether_addr_equal(pwdinfo->tx_prov_disc_info.peerIFAddr,
776 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
777 pwdinfo->tx_prov_disc_info.benable = false;
778 issue_p2p_provision_request23a(padapter,
779 pwdinfo->tx_prov_disc_info.ssid.ssid,
780 pwdinfo->tx_prov_disc_info.ssid.ssid_len,
781 pwdinfo->tx_prov_disc_info.peerDevAddr);
783 else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
785 pwdinfo->tx_prov_disc_info.benable = false;
786 issue_p2p_provision_request23a(padapter,
789 pwdinfo->tx_prov_disc_info.peerDevAddr);
794 } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
795 if (pwdinfo->nego_req_info.benable == true) {
796 DBG_8723A("[%s] P2P State is GONEGO ING!\n", __func__);
797 if (ether_addr_equal(pwdinfo->nego_req_info.peerDevAddr,
799 pwdinfo->nego_req_info.benable = false;
800 issue_p2p_GO_request23a(padapter, pwdinfo->nego_req_info.peerDevAddr);
803 } else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ)) {
804 if (pwdinfo->invitereq_info.benable == true) {
805 DBG_8723A("[%s] P2P_STATE_TX_INVITE_REQ!\n", __func__);
806 if (ether_addr_equal(
807 pwdinfo->invitereq_info.peer_macaddr,
809 pwdinfo->invitereq_info.benable = false;
810 issue_p2p_invitation_request23a(padapter, pwdinfo->invitereq_info.peer_macaddr);
816 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
817 report_survey_event23a(padapter, precv_frame);
824 unsigned int OnBeacon23a(struct rtw_adapter *padapter,
825 struct recv_frame *precv_frame)
828 struct sta_info *psta;
829 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
830 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
831 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
832 struct sta_priv *pstapriv = &padapter->stapriv;
833 struct sk_buff *skb = precv_frame->pkt;
834 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
835 u8 *pframe = skb->data;
837 struct wlan_bssid_ex *pbss;
842 p = rtw_get_ie23a(pframe + sizeof(struct ieee80211_hdr_3addr) +
843 _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ielen,
844 len - sizeof(struct ieee80211_hdr_3addr) -
846 if ((p != NULL) && (ielen > 0)) {
847 if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D)) {
848 /* Invalid value 0x2D is detected in Extended Supported
849 * Rates (ESR) IE. Try to fix the IE length to avoid
850 * failed Beacon parsing.
852 DBG_8723A("[WIFIDBG] Error in ESR IE is detected in "
853 "Beacon of BSSID: %pM. Fix the length of "
854 "ESR IE to avoid failed Beacon parsing.\n",
856 *(p + 1) = ielen - 1;
860 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
861 report_survey_event23a(padapter, precv_frame);
865 if (ether_addr_equal(hdr->addr3, get_my_bssid23a(&pmlmeinfo->network))){
866 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
867 /* we should update current network before auth,
868 or some IE is wrong */
869 pbss = (struct wlan_bssid_ex *)
870 kmalloc(sizeof(struct wlan_bssid_ex),
873 if (collect_bss_info23a(padapter, precv_frame,
875 update_network23a(&pmlmepriv->cur_network.network, pbss, padapter, true);
876 rtw_get_bcn_info23a(&pmlmepriv->cur_network);
881 /* check the vendor of the assoc AP */
882 pmlmeinfo->assoc_AP_vendor = check_assoc_AP23a(pframe + sizeof(struct ieee80211_hdr_3addr), len-sizeof(struct ieee80211_hdr_3addr));
884 /* update TSF Value */
885 update_TSF23a(pmlmeext, pframe, len);
888 start_clnt_auth23a(padapter);
893 if (((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) &&
894 (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
895 psta = rtw_get_stainfo23a(pstapriv, hdr->addr2);
897 ret = rtw_check_bcn_info23a(padapter, pframe,
900 DBG_8723A_LEVEL(_drv_always_,
903 receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress, 65535);
906 /* update WMM, ERP in the beacon */
907 /* todo: the timer is used instead of
908 the number of the beacon received */
909 if ((sta_rx_pkts(psta) & 0xf) == 0) {
910 /* DBG_8723A("update_bcn_info\n"); */
911 update_beacon23a_info(padapter, pframe,
915 #ifdef CONFIG_8723AU_P2P
916 process_p2p_ps_ie23a(padapter, (pframe + sizeof(struct ieee80211_hdr_3addr)), (len - sizeof(struct ieee80211_hdr_3addr)));
917 #endif /* CONFIG_8723AU_P2P */
919 } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
920 psta = rtw_get_stainfo23a(pstapriv, hdr->addr2);
922 /* update WMM, ERP in the beacon */
923 /* todo: the timer is used instead of the
924 number of the beacon received */
925 if ((sta_rx_pkts(psta) & 0xf) == 0) {
926 /* DBG_8723A("update_bcn_info\n"); */
927 update_beacon23a_info(padapter, pframe,
931 /* allocate a new CAM entry for IBSS station */
932 cam_idx = allocate_fw_sta_entry23a(padapter);
933 if (cam_idx == NUM_STA)
936 /* get supported rate */
937 if (update_sta_support_rate23a(padapter, (pframe + sizeof(struct ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_), (len - sizeof(struct ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_), cam_idx) == _FAIL) {
938 pmlmeinfo->FW_sta_info[cam_idx].status = 0;
942 /* update TSF Value */
943 update_TSF23a(pmlmeext, pframe, len);
945 /* report sta add event */
946 report_add_sta_event23a(padapter, hdr->addr2,
957 unsigned int OnAuth23a(struct rtw_adapter *padapter,
958 struct recv_frame *precv_frame)
960 #ifdef CONFIG_8723AU_AP_MODE
961 unsigned int auth_mode, seq, ie_len;
962 unsigned char *sa, *p;
965 static struct sta_info stat;
966 struct sta_info *pstat = NULL;
967 struct sta_priv *pstapriv = &padapter->stapriv;
968 struct security_priv *psecuritypriv = &padapter->securitypriv;
969 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
970 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
971 struct sk_buff *skb = precv_frame->pkt;
972 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
973 u8 *pframe = skb->data;
976 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
979 DBG_8723A("+OnAuth23a\n");
983 auth_mode = psecuritypriv->dot11AuthAlgrthm;
984 seq = cpu_to_le16(*(u16*)((unsigned long)pframe +
985 sizeof(struct ieee80211_hdr_3addr) + 2));
986 algorithm = cpu_to_le16(*(u16*)((unsigned long)pframe +
987 sizeof(struct ieee80211_hdr_3addr)));
989 DBG_8723A("auth alg =%x, seq =%X\n", algorithm, seq);
991 if (auth_mode == 2 &&
992 psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
993 psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
996 /* rx a shared-key auth but shared not enabled, or */
997 /* rx a open-system auth but shared-key is enabled */
998 if ((algorithm > 0 && auth_mode == 0) ||
999 (algorithm == 0 && auth_mode == 1)) {
1000 DBG_8723A("auth rejected due to bad alg [alg =%d, auth_mib "
1001 "=%d] %02X%02X%02X%02X%02X%02X\n",
1002 algorithm, auth_mode,
1003 sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
1005 status = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
1010 if (rtw_access_ctrl23a(padapter, sa) == false) {
1011 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1015 pstat = rtw_get_stainfo23a(pstapriv, sa);
1017 /* allocate a new one */
1018 DBG_8723A("going to alloc stainfo for sa ="MAC_FMT"\n",
1020 pstat = rtw_alloc_stainfo23a(pstapriv, sa);
1022 DBG_8723A(" Exceed the upper limit of supported "
1024 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1028 pstat->state = WIFI_FW_AUTH_NULL;
1029 pstat->auth_seq = 0;
1031 /* pstat->flags = 0; */
1032 /* pstat->capability = 0; */
1034 spin_lock_bh(&pstapriv->asoc_list_lock);
1035 if (!list_empty(&pstat->asoc_list)) {
1036 list_del_init(&pstat->asoc_list);
1037 pstapriv->asoc_list_cnt--;
1038 if (pstat->expire_to > 0)
1040 /* TODO: STA re_auth within expire_to */
1043 spin_unlock_bh(&pstapriv->asoc_list_lock);
1046 /* TODO: STA re_auth and auth timeout */
1050 spin_lock_bh(&pstapriv->auth_list_lock);
1051 if (list_empty(&pstat->auth_list)) {
1052 list_add_tail(&pstat->auth_list, &pstapriv->auth_list);
1053 pstapriv->auth_list_cnt++;
1055 spin_unlock_bh(&pstapriv->auth_list_lock);
1057 if (pstat->auth_seq == 0)
1058 pstat->expire_to = pstapriv->auth_to;
1060 if ((pstat->auth_seq + 1) != seq) {
1061 DBG_8723A("(1)auth rejected because out of seq [rx_seq =%d, "
1062 "exp_seq =%d]!\n", seq, pstat->auth_seq+1);
1063 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1067 if (algorithm == 0 && (auth_mode == 0 || auth_mode == 2)) {
1069 pstat->state &= ~WIFI_FW_AUTH_NULL;
1070 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1071 pstat->expire_to = pstapriv->assoc_to;
1072 pstat->authalg = algorithm;
1074 DBG_8723A("(2)auth rejected because out of seq "
1075 "[rx_seq =%d, exp_seq =%d]!\n",
1076 seq, pstat->auth_seq+1);
1077 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1080 } else { /* shared system or auto authentication */
1082 /* prepare for the challenging txt... */
1083 pstat->state &= ~WIFI_FW_AUTH_NULL;
1084 pstat->state |= WIFI_FW_AUTH_STATE;
1085 pstat->authalg = algorithm;
1086 pstat->auth_seq = 2;
1087 } else if (seq == 3) {
1088 /* checking for challenging txt... */
1089 DBG_8723A("checking for challenging txt...\n");
1091 p = rtw_get_ie23a(pframe +
1092 sizeof(struct ieee80211_hdr_3addr) +
1093 4 + _AUTH_IE_OFFSET_, _CHLGETXT_IE_,
1094 (int *)&ie_len, len -
1095 sizeof(struct ieee80211_hdr_3addr) -
1096 _AUTH_IE_OFFSET_ - 4);
1098 if ((p == NULL) || (ie_len<= 0)) {
1099 DBG_8723A("auth rejected because challenge "
1101 status = WLAN_STATUS_CHALLENGE_FAIL;
1105 if (!memcmp((void *)(p + 2), pstat->chg_txt, 128)) {
1106 pstat->state &= (~WIFI_FW_AUTH_STATE);
1107 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1108 /* challenging txt is correct... */
1109 pstat->expire_to = pstapriv->assoc_to;
1111 DBG_8723A("auth rejected because challenge "
1113 status = WLAN_STATUS_CHALLENGE_FAIL;
1117 DBG_8723A("(3)auth rejected because out of seq "
1118 "[rx_seq =%d, exp_seq =%d]!\n",
1119 seq, pstat->auth_seq+1);
1120 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1125 /* Now, we are going to issue_auth23a... */
1126 pstat->auth_seq = seq + 1;
1128 issue_auth23a(padapter, pstat, (unsigned short)WLAN_STATUS_SUCCESS);
1130 if (pstat->state & WIFI_FW_AUTH_SUCCESS)
1131 pstat->auth_seq = 0;
1138 rtw_free_stainfo23a(padapter, pstat);
1141 memset((char *)pstat, '\0', sizeof(stat));
1142 pstat->auth_seq = 2;
1143 memcpy(pstat->hwaddr, sa, 6);
1145 issue_auth23a(padapter, pstat, (unsigned short)status);
1151 unsigned int OnAuth23aClient23a(struct rtw_adapter *padapter,
1152 struct recv_frame *precv_frame)
1154 unsigned int seq, len, status, algthm, offset;
1156 unsigned int go2asoc = 0;
1157 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1158 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1159 struct sk_buff *skb = precv_frame->pkt;
1160 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1161 u8 *pframe = skb->data;
1162 uint pkt_len = skb->len;
1164 DBG_8723A("%s\n", __func__);
1166 /* check A1 matches or not */
1167 if (!ether_addr_equal(myid(&padapter->eeprompriv),
1168 ieee80211_get_DA(hdr)))
1171 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
1174 offset = ieee80211_has_protected(hdr->frame_control) ? 4: 0;
1176 algthm = le16_to_cpu(*(unsigned short *)((unsigned long)pframe + sizeof(struct ieee80211_hdr_3addr) + offset));
1177 seq = le16_to_cpu(*(unsigned short *)((unsigned long)pframe + sizeof(struct ieee80211_hdr_3addr) + offset + 2));
1178 status = le16_to_cpu(*(unsigned short *)((unsigned long)pframe + sizeof(struct ieee80211_hdr_3addr) + offset + 4));
1182 DBG_8723A("clnt auth fail, status: %d\n", status);
1183 if (status == 13)/* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
1185 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1186 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
1188 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
1189 /* pmlmeinfo->reauth_count = 0; */
1192 set_link_timer(pmlmeext, 1);
1198 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1200 /* legendary shared system */
1201 p = rtw_get_ie23a(pframe + sizeof(struct ieee80211_hdr_3addr) + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
1202 pkt_len - sizeof(struct ieee80211_hdr_3addr) - _AUTH_IE_OFFSET_);
1206 /* DBG_8723A("marc: no challenge text?\n"); */
1210 memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
1211 pmlmeinfo->auth_seq = 3;
1212 issue_auth23a(padapter, NULL, 0);
1213 set_link_timer(pmlmeext, REAUTH_TO);
1225 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1236 /* this is also illegal */
1237 /* DBG_8723A("marc: clnt auth failed due to illegal seq =%x\n", seq); */
1243 DBG_8723A_LEVEL(_drv_always_, "auth success, start assoc\n");
1244 start_clnt_assoc23a(padapter);
1250 /* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
1255 unsigned int OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1257 #ifdef CONFIG_8723AU_AP_MODE
1258 u16 capab_info, listen_interval;
1259 struct rtw_ieee802_11_elems elems;
1260 struct sta_info *pstat;
1261 unsigned char reassoc, *p, *pos, *wpa_ie;
1262 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
1263 int i, ie_len, wpa_ie_len, left;
1264 unsigned char supportRate[16];
1266 unsigned short status = WLAN_STATUS_SUCCESS;
1267 unsigned short ie_offset;
1268 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1269 struct security_priv *psecuritypriv = &padapter->securitypriv;
1270 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1271 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1272 struct wlan_bssid_ex *cur = &pmlmeinfo->network;
1273 struct sta_priv *pstapriv = &padapter->stapriv;
1274 struct sk_buff *skb = precv_frame->pkt;
1275 u8 *pframe = skb->data;
1276 uint pkt_len = skb->len;
1277 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1279 #ifdef CONFIG_8723AU_P2P
1280 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1281 u8 p2p_status_code = P2P_STATUS_SUCCESS;
1284 u8 wfd_ie[MAX_WFD_IE_LEN] = { 0x00 };
1286 #endif /* CONFIG_8723AU_P2P */
1288 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1291 frame_control = hdr->frame_control;
1292 if (ieee80211_is_assoc_req(frame_control)) {
1294 ie_offset = _ASOCREQ_IE_OFFSET_;
1295 } else { /* WIFI_REASSOCREQ */
1297 ie_offset = _REASOCREQ_IE_OFFSET_;
1300 if (pkt_len < sizeof(struct ieee80211_hdr_3addr) + ie_offset) {
1301 DBG_8723A("handle_assoc(reassoc =%d) - too short payload (len =%lu)"
1302 "\n", reassoc, (unsigned long)pkt_len);
1306 pstat = rtw_get_stainfo23a(pstapriv, hdr->addr2);
1308 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
1309 goto asoc_class2_error;
1312 capab_info = get_unaligned_le16(pframe + sizeof(struct ieee80211_hdr_3addr));
1313 /* capab_info = le16_to_cpu(*(unsigned short *)(pframe + sizeof(struct ieee80211_hdr_3addr))); */
1314 /* listen_interval = le16_to_cpu(*(unsigned short *)(pframe + sizeof(struct ieee80211_hdr_3addr)+2)); */
1315 listen_interval = get_unaligned_le16(pframe + sizeof(struct ieee80211_hdr_3addr)+2);
1317 left = pkt_len - (sizeof(struct ieee80211_hdr_3addr) + ie_offset);
1318 pos = pframe + (sizeof(struct ieee80211_hdr_3addr) + ie_offset);
1320 DBG_8723A("%s\n", __func__);
1322 /* check if this stat has been successfully authenticated/assocated */
1323 if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS))
1325 if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS))
1327 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA;
1328 goto asoc_class2_error;
1332 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
1333 pstat->state |= WIFI_FW_ASSOC_STATE;
1338 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
1339 pstat->state |= WIFI_FW_ASSOC_STATE;
1342 pstat->capability = capab_info;
1344 /* now parse all ieee802_11 ie to point to elems */
1345 if (rtw_ieee802_11_parse_elems23a(pos, left, &elems, 1) == ParseFailed ||
1347 DBG_8723A("STA " MAC_FMT " sent invalid association request\n",
1348 MAC_ARG(pstat->hwaddr));
1349 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1350 goto OnAssocReq23aFail;
1353 /* now we should check all the fields... */
1355 p = rtw_get_ie23a(pframe + sizeof(struct ieee80211_hdr_3addr) + ie_offset, _SSID_IE_, &ie_len,
1356 pkt_len - sizeof(struct ieee80211_hdr_3addr) - ie_offset);
1359 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1362 if (ie_len == 0) /* broadcast ssid, however it is not allowed in assocreq */
1363 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1365 /* check if ssid match */
1366 if (memcmp((void *)(p+2), cur->Ssid.ssid, cur->Ssid.ssid_len))
1367 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1369 if (ie_len != cur->Ssid.ssid_len)
1370 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1373 if (WLAN_STATUS_SUCCESS != status)
1374 goto OnAssocReq23aFail;
1376 /* check if the supported rate is ok */
1377 p = rtw_get_ie23a(pframe + sizeof(struct ieee80211_hdr_3addr) + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - sizeof(struct ieee80211_hdr_3addr) - ie_offset);
1379 DBG_8723A("Rx a sta assoc-req which supported rate is empty!\n");
1380 /* use our own rate set as statoin used */
1381 /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
1382 /* supportRateNum = AP_BSSRATE_LEN; */
1384 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1385 goto OnAssocReq23aFail;
1387 memcpy(supportRate, p+2, ie_len);
1388 supportRateNum = ie_len;
1390 p = rtw_get_ie23a(pframe + sizeof(struct ieee80211_hdr_3addr) + ie_offset, _EXT_SUPPORTEDRATES_IE_, &ie_len,
1391 pkt_len - sizeof(struct ieee80211_hdr_3addr) - ie_offset);
1394 if (supportRateNum<= sizeof(supportRate))
1396 memcpy(supportRate+supportRateNum, p+2, ie_len);
1397 supportRateNum += ie_len;
1402 /* todo: mask supportRate between AP & STA -> move to update raid */
1403 /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */
1405 /* update station supportRate */
1406 pstat->bssratelen = supportRateNum;
1407 memcpy(pstat->bssrateset, supportRate, supportRateNum);
1408 Update23aTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
1410 /* check RSN/WPA/WPS */
1411 pstat->dot8021xalg = 0;
1413 pstat->wpa_group_cipher = 0;
1414 pstat->wpa2_group_cipher = 0;
1415 pstat->wpa_pairwise_cipher = 0;
1416 pstat->wpa2_pairwise_cipher = 0;
1417 memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
1418 if ((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
1420 int group_cipher = 0, pairwise_cipher = 0;
1422 wpa_ie = elems.rsn_ie;
1423 wpa_ie_len = elems.rsn_ie_len;
1425 if (rtw_parse_wpa2_ie23a(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1426 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1427 pstat->wpa_psk |= BIT(1);
1429 pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher;
1430 pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher;
1432 if (!pstat->wpa2_group_cipher)
1433 status = WLAN_REASON_INVALID_GROUP_CIPHER;
1435 if (!pstat->wpa2_pairwise_cipher)
1436 status = WLAN_REASON_INVALID_PAIRWISE_CIPHER;
1438 status = WLAN_STATUS_INVALID_IE;
1441 } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
1443 int group_cipher = 0, pairwise_cipher = 0;
1445 wpa_ie = elems.wpa_ie;
1446 wpa_ie_len = elems.wpa_ie_len;
1448 if (rtw_parse_wpa_ie23a(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1449 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1450 pstat->wpa_psk |= BIT(0);
1452 pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher;
1453 pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher;
1455 if (!pstat->wpa_group_cipher)
1456 status = WLAN_STATUS_INVALID_GROUP_CIPHER;
1458 if (!pstat->wpa_pairwise_cipher)
1459 status = WLAN_STATUS_INVALID_PAIRWISE_CIPHER;
1462 status = WLAN_STATUS_INVALID_IE;
1470 if (WLAN_STATUS_SUCCESS != status)
1471 goto OnAssocReq23aFail;
1473 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
1474 if (wpa_ie == NULL) {
1476 DBG_8723A("STA included WPS IE in "
1477 "(Re)Association Request - assume WPS is "
1479 pstat->flags |= WLAN_STA_WPS;
1481 DBG_8723A("STA did not include WPA/RSN IE "
1482 "in (Re)Association Request - possible WPS "
1484 pstat->flags |= WLAN_STA_MAYBE_WPS;
1487 /* AP support WPA/RSN, and sta is going to do WPS, but AP is not ready */
1488 /* that the selected registrar of AP is _FLASE */
1489 if ((psecuritypriv->wpa_psk > 0) &&
1490 (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS))) {
1491 if (pmlmepriv->wps_beacon_ie) {
1492 u8 selected_registrar = 0;
1494 rtw_get_wps_attr_content23a(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len,
1495 WPS_ATTR_SELECTED_REGISTRAR, &selected_registrar, NULL);
1497 if (!selected_registrar) {
1498 DBG_8723A("selected_registrar is false , or AP is not ready to do WPS\n");
1500 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1502 goto OnAssocReq23aFail;
1509 if (psecuritypriv->wpa_psk == 0) {
1510 DBG_8723A("STA " MAC_FMT ": WPA/RSN IE in association "
1511 "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr));
1513 status = WLAN_STATUS_INVALID_IE;
1515 goto OnAssocReq23aFail;
1519 DBG_8723A("STA included WPS IE in "
1520 "(Re)Association Request - WPS is "
1522 pstat->flags |= WLAN_STA_WPS;
1525 copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2);
1529 memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
1533 /* check if there is WMM IE & support WWM-PS */
1534 pstat->flags &= ~WLAN_STA_WME;
1535 pstat->qos_option = 0;
1536 pstat->qos_info = 0;
1537 pstat->has_legacy_ac = true;
1538 pstat->uapsd_vo = 0;
1539 pstat->uapsd_vi = 0;
1540 pstat->uapsd_be = 0;
1541 pstat->uapsd_bk = 0;
1542 if (pmlmepriv->qospriv.qos_option)
1544 p = pframe + sizeof(struct ieee80211_hdr_3addr) + ie_offset; ie_len = 0;
1547 p = rtw_get_ie23a(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - sizeof(struct ieee80211_hdr_3addr) - ie_offset);
1549 if (!memcmp(p+2, WMM_IE, 6)) {
1551 pstat->flags |= WLAN_STA_WME;
1553 pstat->qos_option = 1;
1554 pstat->qos_info = *(p+8);
1556 pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
1558 if ((pstat->qos_info&0xf) != 0xf)
1559 pstat->has_legacy_ac = true;
1561 pstat->has_legacy_ac = false;
1563 if (pstat->qos_info&0xf)
1565 if (pstat->qos_info&BIT(0))
1566 pstat->uapsd_vo = BIT(0)|BIT(1);
1568 pstat->uapsd_vo = 0;
1570 if (pstat->qos_info&BIT(1))
1571 pstat->uapsd_vi = BIT(0)|BIT(1);
1573 pstat->uapsd_vi = 0;
1575 if (pstat->qos_info&BIT(2))
1576 pstat->uapsd_bk = BIT(0)|BIT(1);
1578 pstat->uapsd_bk = 0;
1580 if (pstat->qos_info&BIT(3))
1581 pstat->uapsd_be = BIT(0)|BIT(1);
1583 pstat->uapsd_be = 0;
1597 /* save HT capabilities in the sta object */
1598 memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap));
1599 if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct ieee80211_ht_cap))
1601 pstat->flags |= WLAN_STA_HT;
1603 pstat->flags |= WLAN_STA_WME;
1605 memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct ieee80211_ht_cap));
1608 pstat->flags &= ~WLAN_STA_HT;
1610 if ((pmlmepriv->htpriv.ht_option == false) && (pstat->flags&WLAN_STA_HT))
1612 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1613 goto OnAssocReq23aFail;
1616 if ((pstat->flags & WLAN_STA_HT) &&
1617 ((pstat->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||
1618 (pstat->wpa_pairwise_cipher&WPA_CIPHER_TKIP)))
1620 DBG_8723A("HT: " MAC_FMT " tried to "
1621 "use TKIP with HT association\n", MAC_ARG(pstat->hwaddr));
1623 /* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */
1624 /* goto OnAssocReq23aFail; */
1628 pstat->flags |= WLAN_STA_NONERP;
1629 for (i = 0; i < pstat->bssratelen; i++) {
1630 if ((pstat->bssrateset[i] & 0x7f) > 22) {
1631 pstat->flags &= ~WLAN_STA_NONERP;
1636 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1637 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
1639 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1641 if (status != WLAN_STATUS_SUCCESS)
1642 goto OnAssocReq23aFail;
1644 #ifdef CONFIG_8723AU_P2P
1645 pstat->is_p2p_device = false;
1646 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
1648 if ((p2pie = rtw_get_p2p_ie23a(pframe + sizeof(struct ieee80211_hdr_3addr) + ie_offset, pkt_len - sizeof(struct ieee80211_hdr_3addr) - ie_offset, NULL, &p2pielen)))
1650 pstat->is_p2p_device = true;
1651 if ((p2p_status_code = (u8)process_assoc_req_p2p_ie23a(pwdinfo, pframe, pkt_len, pstat))>0)
1653 pstat->p2p_status_code = p2p_status_code;
1654 status = WLAN_STATUS_CAPS_UNSUPPORTED;
1655 goto OnAssocReq23aFail;
1658 #ifdef CONFIG_8723AU_P2P
1659 if (rtw_get_wfd_ie(pframe + sizeof(struct ieee80211_hdr_3addr) + ie_offset, pkt_len - sizeof(struct ieee80211_hdr_3addr) - ie_offset, wfd_ie, &wfd_ielen))
1661 u8 attr_content[ 10 ] = { 0x00 };
1662 u32 attr_contentlen = 0;
1664 DBG_8723A("[%s] WFD IE Found!!\n", __func__);
1665 rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
1666 if (attr_contentlen)
1668 pwdinfo->wfd_info->peer_rtsp_ctrlport = get_unaligned_be16(attr_content + 2);
1669 DBG_8723A("[%s] Peer PORT NUM = %d\n", __func__, pwdinfo->wfd_info->peer_rtsp_ctrlport);
1674 pstat->p2p_status_code = p2p_status_code;
1675 #endif /* CONFIG_8723AU_P2P */
1677 /* TODO: identify_proprietary_vendor_ie(); */
1678 /* Realtek proprietary IE */
1679 /* identify if this is Broadcom sta */
1680 /* identify if this is ralink sta */
1681 /* Customer proprietary IE */
1683 /* get a unique AID */
1684 if (pstat->aid > 0) {
1685 DBG_8723A(" old AID %d\n", pstat->aid);
1687 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
1688 if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
1691 if (pstat->aid > NUM_STA)
1692 pstat->aid = NUM_STA;
1693 if (pstat->aid > pstapriv->max_num_sta) {
1697 DBG_8723A(" no room for more AIDs\n");
1699 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1701 goto OnAssocReq23aFail;
1704 pstapriv->sta_aid[pstat->aid - 1] = pstat;
1705 DBG_8723A("allocate new AID = (%d)\n", pstat->aid);
1709 pstat->state &= (~WIFI_FW_ASSOC_STATE);
1710 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
1712 spin_lock_bh(&pstapriv->auth_list_lock);
1713 if (!list_empty(&pstat->auth_list)) {
1714 list_del_init(&pstat->auth_list);
1715 pstapriv->auth_list_cnt--;
1717 spin_unlock_bh(&pstapriv->auth_list_lock);
1719 spin_lock_bh(&pstapriv->asoc_list_lock);
1720 if (list_empty(&pstat->asoc_list)) {
1721 pstat->expire_to = pstapriv->expire_to;
1722 list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list);
1723 pstapriv->asoc_list_cnt++;
1725 spin_unlock_bh(&pstapriv->asoc_list_lock);
1727 /* now the station is qualified to join our BSS... */
1728 if (pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) &&
1729 (WLAN_STATUS_SUCCESS == status)) {
1730 #ifdef CONFIG_8723AU_AP_MODE
1731 /* 1 bss_cap_update & sta_info_update23a */
1732 bss_cap_update_on_sta_join23a(padapter, pstat);
1733 sta_info_update23a(padapter, pstat);
1735 /* issue assoc rsp before notify station join event. */
1736 if (ieee80211_is_assoc_req(frame_control))
1737 issue_asocrsp23a(padapter, status, pstat, WIFI_ASSOCRSP);
1739 issue_asocrsp23a(padapter, status, pstat, WIFI_REASSOCRSP);
1741 /* 2 - report to upper layer */
1742 DBG_8723A("indicate_sta_join_event to upper layer - hostapd\n");
1743 rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
1745 /* 3-(1) report sta add event */
1746 report_add_sta_event23a(padapter, pstat->hwaddr, pstat->aid);
1754 #ifdef CONFIG_8723AU_AP_MODE
1755 issue_deauth23a(padapter, hdr->addr2, status);
1762 #ifdef CONFIG_8723AU_AP_MODE
1764 if (ieee80211_is_assoc_req(frame_control))
1765 issue_asocrsp23a(padapter, status, pstat, WIFI_ASSOCRSP);
1767 issue_asocrsp23a(padapter, status, pstat, WIFI_REASSOCRSP);
1770 #endif /* CONFIG_8723AU_AP_MODE */
1775 unsigned int OnAssocRsp23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1779 unsigned short status;
1780 struct ndis_802_11_var_ies *pIE;
1781 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1782 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1783 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1784 struct sk_buff *skb = precv_frame->pkt;
1785 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1786 u8 *pframe = skb->data;
1787 uint pkt_len = skb->len;
1789 DBG_8723A("%s\n", __func__);
1791 /* check A1 matches or not */
1792 if (!ether_addr_equal(myid(&padapter->eeprompriv),
1793 ieee80211_get_DA(hdr)))
1796 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
1799 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
1802 del_timer_sync(&pmlmeext->link_timer);
1805 if ((status = le16_to_cpu(*(unsigned short *)(pframe + sizeof(struct ieee80211_hdr_3addr) + 2))) > 0)
1807 DBG_8723A("assoc reject, status code: %d\n", status);
1808 pmlmeinfo->state = WIFI_FW_NULL_STATE;
1810 goto report_assoc_result;
1813 /* get capabilities */
1814 pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + sizeof(struct ieee80211_hdr_3addr)));
1817 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
1820 res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + sizeof(struct ieee80211_hdr_3addr) + 4))&0x3fff);
1822 /* following are moved to join event callback function */
1823 /* to handle HT, WMM, rate adaptive, update MAC reg */
1824 /* for not to handle the synchronous IO in the tasklet */
1825 for (i = (6 + sizeof(struct ieee80211_hdr_3addr)); i < pkt_len;) {
1826 pIE = (struct ndis_802_11_var_ies *)(pframe + i);
1828 switch (pIE->ElementID)
1830 case _VENDOR_SPECIFIC_IE_:
1831 if (!memcmp(pIE->data, WMM_PARA_OUI23A, 6))/* WMM */
1832 WMM_param_handler23a(padapter, pIE);
1833 #if defined(CONFIG_8723AU_P2P)
1834 else if (!memcmp(pIE->data, WFD_OUI23A, 4)) { /* WFD */
1835 DBG_8723A("[%s] Found WFD IE\n", __func__);
1836 WFD_info_handler(padapter, pIE);
1841 case _HT_CAPABILITY_IE_: /* HT caps */
1842 HT_caps_handler23a(padapter, pIE);
1845 case _HT_EXTRA_INFO_IE_: /* HT info */
1846 HT_info_handler23a(padapter, pIE);
1850 ERP_IE_handler23a(padapter, pIE);
1856 i += (pIE->Length + 2);
1859 pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
1860 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
1862 /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
1863 UpdateBrateTbl23a(padapter, pmlmeinfo->network.SupportedRates);
1865 report_assoc_result:
1866 pmlmepriv->assoc_rsp_len = 0;
1868 kfree(pmlmepriv->assoc_rsp);
1869 pmlmepriv->assoc_rsp = kmalloc(pkt_len, GFP_ATOMIC);
1870 if (pmlmepriv->assoc_rsp) {
1871 memcpy(pmlmepriv->assoc_rsp, pframe, pkt_len);
1872 pmlmepriv->assoc_rsp_len = pkt_len;
1875 kfree(pmlmepriv->assoc_rsp);
1877 report_join_res23a(padapter, res);
1882 unsigned int OnDeAuth23a(struct rtw_adapter *padapter,
1883 struct recv_frame *precv_frame)
1885 unsigned short reason;
1886 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1887 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1888 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1889 struct sk_buff *skb = precv_frame->pkt;
1890 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1891 u8 *pframe = skb->data;
1892 #ifdef CONFIG_8723AU_P2P
1893 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1894 #endif /* CONFIG_8723AU_P2P */
1897 if (!ether_addr_equal(hdr->addr3, get_my_bssid23a(&pmlmeinfo->network)))
1900 #ifdef CONFIG_8723AU_P2P
1901 if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
1902 mod_timer(&pwdinfo->reset_ch_sitesurvey,
1903 jiffies + msecs_to_jiffies(10));
1905 #endif /* CONFIG_8723AU_P2P */
1907 reason = le16_to_cpu(*(unsigned short *)(pframe + sizeof(struct ieee80211_hdr_3addr)));
1909 DBG_8723A("%s Reason code(%d)\n", __func__, reason);
1911 #ifdef CONFIG_8723AU_AP_MODE
1912 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
1913 struct sta_info *psta;
1914 struct sta_priv *pstapriv = &padapter->stapriv;
1916 DBG_8723A_LEVEL(_drv_always_, "ap recv deauth reason code(%d) "
1917 "sta:%pM\n", reason, hdr->addr2);
1919 psta = rtw_get_stainfo23a(pstapriv, hdr->addr2);
1923 spin_lock_bh(&pstapriv->asoc_list_lock);
1924 if (!list_empty(&psta->asoc_list)) {
1925 list_del_init(&psta->asoc_list);
1926 pstapriv->asoc_list_cnt--;
1927 updated = ap_free_sta23a(padapter, psta,
1930 spin_unlock_bh(&pstapriv->asoc_list_lock);
1932 associated_clients_update23a(padapter, updated);
1940 DBG_8723A_LEVEL(_drv_always_, "sta recv deauth reason code(%d) "
1941 "sta:%pM\n", reason, hdr->addr3);
1943 receive_disconnect23a(padapter, hdr->addr3, reason);
1945 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
1949 unsigned int OnDisassoc23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
1951 unsigned short reason;
1952 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1953 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1954 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1955 struct sk_buff *skb = precv_frame->pkt;
1956 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1957 u8 *pframe = skb->data;
1958 #ifdef CONFIG_8723AU_P2P
1959 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1960 #endif /* CONFIG_8723AU_P2P */
1963 if (!ether_addr_equal(hdr->addr3, get_my_bssid23a(&pmlmeinfo->network)))
1966 #ifdef CONFIG_8723AU_P2P
1967 if (pwdinfo->rx_invitereq_info.scan_op_ch_only)
1969 mod_timer(&pwdinfo->reset_ch_sitesurvey,
1970 jiffies + msecs_to_jiffies(10));
1972 #endif /* CONFIG_8723AU_P2P */
1974 reason = le16_to_cpu(*(unsigned short *)
1975 (pframe + sizeof(struct ieee80211_hdr_3addr)));
1977 DBG_8723A("%s Reason code(%d)\n", __func__, reason);
1979 #ifdef CONFIG_8723AU_AP_MODE
1980 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1981 struct sta_info *psta;
1982 struct sta_priv *pstapriv = &padapter->stapriv;
1984 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason code(%d)"
1985 " sta:%pM\n", reason, hdr->addr2);
1987 psta = rtw_get_stainfo23a(pstapriv, hdr->addr2);
1991 spin_lock_bh(&pstapriv->asoc_list_lock);
1992 if (!list_empty(&psta->asoc_list)) {
1993 list_del_init(&psta->asoc_list);
1994 pstapriv->asoc_list_cnt--;
1995 updated = ap_free_sta23a(padapter, psta,
1998 spin_unlock_bh(&pstapriv->asoc_list_lock);
2000 associated_clients_update23a(padapter, updated);
2008 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason "
2009 "code(%d) sta:%pM\n", reason, hdr->addr3);
2011 receive_disconnect23a(padapter, hdr->addr3, reason);
2013 pmlmepriv->LinkDetectInfo.bBusyTraffic = false;
2017 unsigned int OnAtim23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2019 DBG_8723A("%s\n", __func__);
2023 unsigned int on_action_spct23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2028 unsigned int OnAction23a_qos(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2033 unsigned int OnAction23a_dls(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2038 unsigned int OnAction23a_back23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
2041 struct sta_info *psta = NULL;
2042 struct recv_reorder_ctrl *preorder_ctrl;
2043 unsigned char *frame_body;
2044 unsigned char category, action;
2045 unsigned short tid, status, reason_code = 0;
2046 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2047 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2048 struct sk_buff *skb = precv_frame->pkt;
2049 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2050 u8 *pframe = skb->data;
2051 struct sta_priv *pstapriv = &padapter->stapriv;
2053 /* check RA matches or not */
2054 if (!ether_addr_equal(myid(&padapter->eeprompriv), hdr->addr1))
2057 DBG_8723A("%s\n", __func__);
2059 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
2060 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
2064 psta = rtw_get_stainfo23a(pstapriv, addr);
2069 frame_body = (unsigned char *)
2070 (pframe + sizeof(struct ieee80211_hdr_3addr));
2072 category = frame_body[0];
2073 if (category == WLAN_CATEGORY_BACK) { /* representing Block Ack */
2074 if (!pmlmeinfo->HT_enable)
2076 action = frame_body[1];
2077 DBG_8723A("%s, action =%d\n", __func__, action);
2079 case WLAN_ACTION_ADDBA_REQ: /* ADDBA request */
2080 memcpy(&pmlmeinfo->ADDBA_req, &frame_body[2],
2081 sizeof(struct ADDBA_request));
2082 process_addba_req23a(padapter,
2083 (u8 *)&pmlmeinfo->ADDBA_req, addr);
2084 if (pmlmeinfo->bAcceptAddbaReq == true)
2085 issue_action_BA23a(padapter, addr,
2086 WLAN_ACTION_ADDBA_RESP, 0);
2088 /* reject ADDBA Req */
2089 issue_action_BA23a(padapter, addr,
2090 WLAN_ACTION_ADDBA_RESP, 37);
2093 case WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
2094 status = get_unaligned_le16(&frame_body[3]);
2095 tid = ((frame_body[5] >> 2) & 0x7);
2096 if (status == 0) { /* successful */
2097 DBG_8723A("agg_enable for TID =%d\n", tid);
2098 psta->htpriv.agg_enable_bitmap |= 1 << tid;
2099 psta->htpriv.candidate_tid_bitmap &=
2102 psta->htpriv.agg_enable_bitmap &= ~CHKBIT(tid);
2105 case WLAN_ACTION_DELBA: /* DELBA */
2106 if ((frame_body[3] & BIT(3)) == 0) {
2107 psta->htpriv.agg_enable_bitmap &=
2108 ~(1 << ((frame_body[3] >> 4) & 0xf));
2109 psta->htpriv.candidate_tid_bitmap &=
2110 ~(1 << ((frame_body[3] >> 4) & 0xf));
2112 /* reason_code = frame_body[4] | (frame_body[5] << 8); */
2113 reason_code = get_unaligned_le16(&frame_body[4]);
2114 } else if ((frame_body[3] & BIT(3)) == BIT(3)) {
2115 tid = (frame_body[3] >> 4) & 0x0F;
2117 preorder_ctrl = &psta->recvreorder_ctrl[tid];
2118 preorder_ctrl->enable = false;
2119 preorder_ctrl->indicate_seq = 0xffff;
2122 DBG_8723A("%s(): DELBA: %x(%x)\n", __func__,
2123 pmlmeinfo->agg_enable_bitmap, reason_code);
2124 /* todo: how to notify the host while receiving
2134 #ifdef CONFIG_8723AU_P2P
2136 static int get_reg_classes_full_count(struct p2p_channels channel_list) {
2140 for (i = 0; i < channel_list.reg_classes; i++)
2141 cnt += channel_list.reg_class[i].channels;
2146 void issue_p2p_GO_request23a(struct rtw_adapter *padapter, u8* raddr)
2148 unsigned char category = WLAN_CATEGORY_PUBLIC;
2149 u8 action = P2P_PUB_ACTION_ACTION;
2150 u32 p2poui = cpu_to_be32(P2POUI);
2151 u8 oui_subtype = P2P_GO_NEGO_REQ;
2152 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
2153 u8 wpsielen = 0, p2pielen = 0;
2154 u16 len_channellist_attr = 0;
2155 #ifdef CONFIG_8723AU_P2P
2157 #endif /* CONFIG_8723AU_P2P */
2159 struct xmit_frame *pmgntframe;
2160 struct pkt_attrib *pattrib;
2161 unsigned char *pframe;
2162 struct ieee80211_hdr *pwlanhdr;
2163 unsigned short *fctrl;
2164 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2165 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2166 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2168 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
2171 DBG_8723A("[%s] In\n", __func__);
2172 /* update attribute */
2173 pattrib = &pmgntframe->attrib;
2174 update_mgntframe_attrib23a(padapter, pattrib);
2176 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2178 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2179 pwlanhdr = (struct ieee80211_hdr *)pframe;
2181 fctrl = &pwlanhdr->frame_control;
2184 ether_addr_copy(pwlanhdr->addr1, raddr);
2185 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
2186 ether_addr_copy(pwlanhdr->addr3, myid(&padapter->eeprompriv));
2188 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2189 pmlmeext->mgnt_seq++;
2190 SetFrameSubType(pframe, WIFI_ACTION);
2192 pframe += sizeof(struct ieee80211_hdr_3addr);
2193 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
2195 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
2196 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
2197 pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *)&p2poui,
2199 pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
2200 pwdinfo->negotiation_dialog_token = 1; /*Initialize the dialog value*/
2201 pframe = rtw_set_fixed_ie23a(pframe, 1,
2202 &pwdinfo->negotiation_dialog_token,
2208 *(u32*) (wpsie) = cpu_to_be32(WPSOUI);
2213 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
2217 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0001);
2221 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
2223 /* Device Password ID */
2225 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
2229 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0002);
2234 if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN)
2236 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
2238 else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN)
2240 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
2242 else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC)
2244 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
2249 pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
2251 /* P2P IE Section. */
2255 p2pie[p2pielen++] = 0x50;
2256 p2pie[p2pielen++] = 0x6F;
2257 p2pie[p2pielen++] = 0x9A;
2258 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
2260 /* Commented by Albert 20110306 */
2261 /* According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes */
2262 /* 1. P2P Capability */
2263 /* 2. Group Owner Intent */
2264 /* 3. Configuration Timeout */
2265 /* 4. Listen Channel */
2266 /* 5. Extended Listen Timing */
2267 /* 6. Intended P2P Interface Address */
2268 /* 7. Channel List */
2269 /* 8. P2P Device Info */
2270 /* 9. Operating Channel */
2272 /* P2P Capability */
2274 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
2277 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
2281 /* Device Capability Bitmap, 1 byte */
2282 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
2284 /* Group Capability Bitmap, 1 byte */
2285 if (pwdinfo->persistent_supported)
2287 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
2291 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
2294 /* Group Owner Intent */
2296 p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
2299 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0001);
2303 /* Todo the tie breaker bit. */
2304 p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
2306 /* Configuration Timeout */
2308 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
2311 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
2315 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
2316 p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
2318 /* Listen Channel */
2320 p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
2323 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0005);
2327 /* Country String */
2328 p2pie[p2pielen++] = 'X';
2329 p2pie[p2pielen++] = 'X';
2331 /* The third byte should be set to 0x04. */
2332 /* Described in the "Operating Channel Attribute" section. */
2333 p2pie[p2pielen++] = 0x04;
2335 /* Operating Class */
2336 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
2338 /* Channel Number */
2339 p2pie[p2pielen++] = pwdinfo->listen_channel; /* listening channel number */
2341 /* Extended Listen Timing ATTR */
2343 p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
2346 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0004);
2350 /* Availability Period */
2351 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF);
2354 /* Availability Interval */
2355 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF);
2358 /* Intended P2P Interface Address */
2360 p2pie[p2pielen++] = P2P_ATTR_INTENTED_IF_ADDR;
2363 *(u16*) (p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
2367 memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
2368 p2pielen += ETH_ALEN;
2372 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
2375 /* Country String(3) */
2376 /* + (Operating Class (1) + Number of Channels(1)) * Operation Classes (?) */
2377 /* + number of channels in all classes */
2378 len_channellist_attr = 3
2379 + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
2380 + get_reg_classes_full_count(pmlmeext->channel_list);
2382 *(u16*) (p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
2386 /* Country String */
2387 p2pie[p2pielen++] = 'X';
2388 p2pie[p2pielen++] = 'X';
2390 /* The third byte should be set to 0x04. */
2391 /* Described in the "Operating Channel Attribute" section. */
2392 p2pie[p2pielen++] = 0x04;
2394 /* Channel Entry List */
2398 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
2399 /* Operating Class */
2400 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
2402 /* Number of Channels */
2403 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
2406 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
2407 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
2414 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
2417 /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
2418 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
2419 *(u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
2423 /* P2P Device Address */
2424 memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
2425 p2pielen += ETH_ALEN;
2428 /* This field should be big endian. Noted by P2P specification. */
2430 *(u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
2434 /* Primary Device Type */
2436 *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
2440 *(u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI);
2443 /* Sub Category ID */
2444 *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
2447 /* Number of Secondary Device Types */
2448 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
2452 *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
2456 *(u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
2460 memcpy(p2pie + p2pielen, pwdinfo->device_name,
2461 pwdinfo->device_name_len);
2462 p2pielen += pwdinfo->device_name_len;
2464 /* Operating Channel */
2466 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
2469 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0005);
2473 /* Country String */
2474 p2pie[p2pielen++] = 'X';
2475 p2pie[p2pielen++] = 'X';
2477 /* The third byte should be set to 0x04. */
2478 /* Described in the "Operating Channel Attribute" section. */
2479 p2pie[p2pielen++] = 0x04;
2481 /* Operating Class */
2482 if (pwdinfo->operating_channel <= 14)
2484 /* Operating Class */
2485 p2pie[p2pielen++] = 0x51;
2487 else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48))
2489 /* Operating Class */
2490 p2pie[p2pielen++] = 0x73;
2494 /* Operating Class */
2495 p2pie[p2pielen++] = 0x7c;
2498 /* Channel Number */
2499 p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
2501 pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
2503 #ifdef CONFIG_8723AU_P2P
2504 wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
2506 pattrib->pktlen += wfdielen;
2507 #endif /* CONFIG_8723AU_P2P */
2509 pattrib->last_txcmdsz = pattrib->pktlen;
2511 dump_mgntframe23a(padapter, pmgntframe);
2516 static void issue_p2p_GO_response(struct rtw_adapter *padapter, u8* raddr, u8* frame_body, uint len, u8 result)
2519 unsigned char category = WLAN_CATEGORY_PUBLIC;
2520 u8 action = P2P_PUB_ACTION_ACTION;
2521 u32 p2poui = cpu_to_be32(P2POUI);
2522 u8 oui_subtype = P2P_GO_NEGO_RESP;
2523 u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
2526 u16 wps_devicepassword_id = 0x0000;
2527 uint wps_devicepassword_id_len = 0;
2528 u16 len_channellist_attr = 0;
2530 struct xmit_frame *pmgntframe;
2531 struct pkt_attrib *pattrib;
2532 unsigned char *pframe;
2533 struct ieee80211_hdr *pwlanhdr;
2534 unsigned short *fctrl;
2535 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2536 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2537 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2538 #ifdef CONFIG_8723AU_P2P
2540 #endif /* CONFIG_8723AU_P2P */
2542 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
2545 DBG_8723A("[%s] In, result = %d\n", __func__, result);
2546 /* update attribute */
2547 pattrib = &pmgntframe->attrib;
2548 update_mgntframe_attrib23a(padapter, pattrib);
2550 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2552 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2553 pwlanhdr = (struct ieee80211_hdr *)pframe;
2555 fctrl = &pwlanhdr->frame_control;
2558 ether_addr_copy(pwlanhdr->addr1, raddr);
2559 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
2560 ether_addr_copy(pwlanhdr->addr3, myid(&padapter->eeprompriv));
2562 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2563 pmlmeext->mgnt_seq++;
2564 SetFrameSubType(pframe, WIFI_ACTION);
2566 pframe += sizeof(struct ieee80211_hdr_3addr);
2567 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
2569 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
2570 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
2571 pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *) &p2poui,
2573 pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
2574 /* The Dialog Token of provisioning discovery request frame. */
2575 pwdinfo->negotiation_dialog_token = frame_body[7];
2576 pframe = rtw_set_fixed_ie23a(pframe, 1,
2577 &pwdinfo->negotiation_dialog_token,
2580 /* Commented by Albert 20110328 */
2581 /* Try to get the device password ID from the WPS IE of group
2582 negotiation request frame */
2583 /* WiFi Direct test plan 5.1.15 */
2584 rtw_get_wps_ie23a(frame_body + _PUBLIC_ACTION_IE_OFFSET_,
2585 len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
2586 rtw_get_wps_attr_content23a(wpsie, wpsielen, WPS_ATTR_DEVICE_PWID,
2587 (u8 *)&wps_devicepassword_id,
2588 &wps_devicepassword_id_len);
2589 wps_devicepassword_id = be16_to_cpu(wps_devicepassword_id);
2591 memset(wpsie, 0x00, 255);
2597 *(u32*) (wpsie) = cpu_to_be32(WPSOUI);
2602 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
2606 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0001);
2610 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
2612 /* Device Password ID */
2614 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
2618 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0002);
2622 if (wps_devicepassword_id == WPS_DPID_USER_SPEC) {
2623 *(u16*) (wpsie + wpsielen) =
2624 cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
2625 } else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC) {
2626 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
2628 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
2632 /* Commented by Kurt 20120113 */
2633 /* If some device wants to do p2p handshake without sending prov_disc_req */
2634 /* We have to get peer_req_cm from here. */
2635 if (!memcmp(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3)) {
2636 if (wps_devicepassword_id == WPS_DPID_USER_SPEC) {
2637 memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3);
2638 } else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC) {
2639 memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3);
2641 memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3);
2645 pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, wpsielen,
2646 (unsigned char *) wpsie, &pattrib->pktlen);
2648 /* P2P IE Section. */
2652 p2pie[p2pielen++] = 0x50;
2653 p2pie[p2pielen++] = 0x6F;
2654 p2pie[p2pielen++] = 0x9A;
2655 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
2657 /* Commented by Albert 20100908 */
2658 /* According to the P2P Specification, the group negoitation
2659 response frame should contain 9 P2P attributes */
2661 /* 2. P2P Capability */
2662 /* 3. Group Owner Intent */
2663 /* 4. Configuration Timeout */
2664 /* 5. Operating Channel */
2665 /* 6. Intended P2P Interface Address */
2666 /* 7. Channel List */
2667 /* 8. Device Info */
2668 /* 9. Group ID (Only GO) */
2674 p2pie[p2pielen++] = P2P_ATTR_STATUS;
2677 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0001);
2681 p2pie[p2pielen++] = result;
2683 /* P2P Capability */
2685 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
2688 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
2692 /* Device Capability Bitmap, 1 byte */
2694 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
2695 /* Commented by Albert 2011/03/08 */
2696 /* According to the P2P specification */
2697 /* if the sending device will be client, the P2P
2698 Capability should be reserved of group negotation
2700 p2pie[p2pielen++] = 0;
2702 /* Be group owner or meet the error case */
2703 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
2706 /* Group Capability Bitmap, 1 byte */
2707 if (pwdinfo->persistent_supported) {
2708 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN |
2709 P2P_GRPCAP_PERSISTENT_GROUP;
2711 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
2714 /* Group Owner Intent */
2716 p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
2719 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0001);
2723 if (pwdinfo->peer_intent & 0x01) {
2724 /* Peer's tie breaker bit is 1, our tie breaker
2726 p2pie[p2pielen++] = (pwdinfo->intent << 1);
2728 /* Peer's tie breaker bit is 0, our tie breaker bit
2730 p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
2733 /* Configuration Timeout */
2735 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
2738 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
2742 /* 2 seconds needed to be the P2P GO */
2743 p2pie[p2pielen++] = 200;
2744 /* 2 seconds needed to be the P2P Client */
2745 p2pie[p2pielen++] = 200;
2747 /* Operating Channel */
2749 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
2752 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0005);
2756 /* Country String */
2757 p2pie[p2pielen++] = 'X';
2758 p2pie[p2pielen++] = 'X';
2760 /* The third byte should be set to 0x04. */
2761 /* Described in the "Operating Channel Attribute" section. */
2762 p2pie[p2pielen++] = 0x04;
2764 /* Operating Class */
2765 if (pwdinfo->operating_channel <= 14) {
2766 /* Operating Class */
2767 p2pie[p2pielen++] = 0x51;
2768 } else if ((pwdinfo->operating_channel >= 36) &&
2769 (pwdinfo->operating_channel <= 48)) {
2770 /* Operating Class */
2771 p2pie[p2pielen++] = 0x73;
2773 /* Operating Class */
2774 p2pie[p2pielen++] = 0x7c;
2777 /* Channel Number */
2778 /* operating channel number */
2779 p2pie[p2pielen++] = pwdinfo->operating_channel;
2781 /* Intended P2P Interface Address */
2783 p2pie[p2pielen++] = P2P_ATTR_INTENTED_IF_ADDR;
2786 *(u16*) (p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
2790 memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
2791 p2pielen += ETH_ALEN;
2795 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
2797 /* Country String(3) */
2798 /* + (Operating Class (1) + Number of Channels(1)) *
2799 Operation Classes (?) */
2800 /* + number of channels in all classes */
2801 len_channellist_attr = 3 +
2802 (1 + 1) * (u16)pmlmeext->channel_list.reg_classes +
2803 get_reg_classes_full_count(pmlmeext->channel_list);
2805 *(u16*) (p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
2810 /* Country String */
2811 p2pie[p2pielen++] = 'X';
2812 p2pie[p2pielen++] = 'X';
2814 /* The third byte should be set to 0x04. */
2815 /* Described in the "Operating Channel Attribute" section. */
2816 p2pie[p2pielen++] = 0x04;
2818 /* Channel Entry List */
2820 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
2821 /* Operating Class */
2823 pmlmeext->channel_list.reg_class[j].reg_class;
2825 /* Number of Channels */
2827 pmlmeext->channel_list.reg_class[j].channels;
2831 i < pmlmeext->channel_list.reg_class[j].channels; i++) {
2833 pmlmeext->channel_list.reg_class[j].channel[i];
2839 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
2842 /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) +
2843 Primary Device Type (8bytes) */
2844 /* + NumofSecondDevType (1byte) + WPS Device Name ID field
2845 (2bytes) + WPS Device Name Len field (2bytes) */
2846 *(u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
2850 /* P2P Device Address */
2851 memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
2852 p2pielen += ETH_ALEN;
2855 /* This field should be big endian. Noted by P2P specification. */
2857 *(u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
2861 /* Primary Device Type */
2863 *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
2867 *(u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI);
2870 /* Sub Category ID */
2871 *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
2874 /* Number of Secondary Device Types */
2875 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
2879 *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
2883 *(u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
2887 memcpy(p2pie + p2pielen, pwdinfo->device_name,
2888 pwdinfo->device_name_len);
2889 p2pielen += pwdinfo->device_name_len;
2891 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
2893 /* Group ID Attribute */
2895 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
2898 *(u16*) (p2pie + p2pielen) =
2899 cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
2903 /* p2P Device Address */
2904 memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);
2905 p2pielen += ETH_ALEN;
2908 memcpy(p2pie + p2pielen, pwdinfo->nego_ssid,
2909 pwdinfo->nego_ssidlen);
2910 p2pielen += pwdinfo->nego_ssidlen;
2914 pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, p2pielen,
2915 (unsigned char *) p2pie, &pattrib->pktlen);
2917 #ifdef CONFIG_8723AU_P2P
2918 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
2920 pattrib->pktlen += wfdielen;
2921 #endif /* CONFIG_8723AU_P2P */
2923 pattrib->last_txcmdsz = pattrib->pktlen;
2925 dump_mgntframe23a(padapter, pmgntframe);
2930 static void issue_p2p_GO_confirm(struct rtw_adapter *padapter, u8* raddr,
2934 unsigned char category = WLAN_CATEGORY_PUBLIC;
2935 u8 action = P2P_PUB_ACTION_ACTION;
2936 u32 p2poui = cpu_to_be32(P2POUI);
2937 u8 oui_subtype = P2P_GO_NEGO_CONF;
2938 u8 p2pie[ 255 ] = { 0x00 };
2940 struct xmit_frame *pmgntframe;
2941 struct pkt_attrib *pattrib;
2942 unsigned char *pframe;
2943 struct ieee80211_hdr *pwlanhdr;
2944 unsigned short *fctrl;
2945 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2946 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2947 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2948 #ifdef CONFIG_8723AU_P2P
2950 #endif /* CONFIG_8723AU_P2P */
2952 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
2955 DBG_8723A("[%s] In\n", __func__);
2956 /* update attribute */
2957 pattrib = &pmgntframe->attrib;
2958 update_mgntframe_attrib23a(padapter, pattrib);
2960 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2962 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2963 pwlanhdr = (struct ieee80211_hdr *)pframe;
2965 fctrl = &pwlanhdr->frame_control;
2968 ether_addr_copy(pwlanhdr->addr1, raddr);
2969 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
2970 ether_addr_copy(pwlanhdr->addr3, myid(&padapter->eeprompriv));
2972 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2973 pmlmeext->mgnt_seq++;
2974 SetFrameSubType(pframe, WIFI_ACTION);
2976 pframe += sizeof(struct ieee80211_hdr_3addr);
2977 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
2979 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
2980 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
2981 pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *)&p2poui,
2983 pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
2984 pframe = rtw_set_fixed_ie23a(pframe, 1,
2985 &pwdinfo->negotiation_dialog_token,
2989 p2pie[p2pielen++] = 0x50;
2990 p2pie[p2pielen++] = 0x6F;
2991 p2pie[p2pielen++] = 0x9A;
2992 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
2994 /* Commented by Albert 20110306 */
2995 /* According to the P2P Specification, the group negoitation
2996 request frame should contain 5 P2P attributes */
2998 /* 2. P2P Capability */
2999 /* 3. Operating Channel */
3000 /* 4. Channel List */
3001 /* 5. Group ID (if this WiFi is GO) */
3005 p2pie[p2pielen++] = P2P_ATTR_STATUS;
3008 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0001);
3012 p2pie[p2pielen++] = result;
3014 /* P2P Capability */
3016 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
3019 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
3023 /* Device Capability Bitmap, 1 byte */
3024 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
3026 /* Group Capability Bitmap, 1 byte */
3027 if (pwdinfo->persistent_supported) {
3028 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN |
3029 P2P_GRPCAP_PERSISTENT_GROUP;
3031 p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
3034 /* Operating Channel */
3036 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
3039 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0005);
3043 /* Country String */
3044 p2pie[p2pielen++] = 'X';
3045 p2pie[p2pielen++] = 'X';
3047 /* The third byte should be set to 0x04. */
3048 /* Described in the "Operating Channel Attribute" section. */
3049 p2pie[p2pielen++] = 0x04;
3051 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
3052 if (pwdinfo->peer_operating_ch <= 14) {
3053 /* Operating Class */
3054 p2pie[p2pielen++] = 0x51;
3055 } else if ((pwdinfo->peer_operating_ch >= 36) &&
3056 (pwdinfo->peer_operating_ch <= 48)) {
3057 /* Operating Class */
3058 p2pie[p2pielen++] = 0x73;
3060 /* Operating Class */
3061 p2pie[p2pielen++] = 0x7c;
3064 p2pie[p2pielen++] = pwdinfo->peer_operating_ch;
3066 if (pwdinfo->operating_channel <= 14) {
3067 /* Operating Class */
3068 p2pie[p2pielen++] = 0x51;
3070 else if ((pwdinfo->operating_channel >= 36) &&
3071 (pwdinfo->operating_channel <= 48)) {
3072 /* Operating Class */
3073 p2pie[p2pielen++] = 0x73;
3075 /* Operating Class */
3076 p2pie[p2pielen++] = 0x7c;
3079 /* Channel Number */
3080 /* Use the listen channel as the operating channel */
3081 p2pie[p2pielen++] = pwdinfo->operating_channel;
3086 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
3089 *(u16*) (p2pie + p2pielen) =
3090 cpu_to_le16(pwdinfo->channel_list_attr_len);
3094 memcpy(p2pie + p2pielen, pwdinfo->channel_list_attr,
3095 pwdinfo->channel_list_attr_len);
3096 p2pielen += pwdinfo->channel_list_attr_len;
3098 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
3099 /* Group ID Attribute */
3101 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
3104 *(u16*) (p2pie + p2pielen) =
3105 cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
3109 /* p2P Device Address */
3110 memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN);
3111 p2pielen += ETH_ALEN;
3114 memcpy(p2pie + p2pielen, pwdinfo->nego_ssid,
3115 pwdinfo->nego_ssidlen);
3116 p2pielen += pwdinfo->nego_ssidlen;
3119 pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, p2pielen,
3120 (unsigned char *)p2pie, &pattrib->pktlen);
3122 #ifdef CONFIG_8723AU_P2P
3123 wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
3125 pattrib->pktlen += wfdielen;
3126 #endif /* CONFIG_8723AU_P2P */
3128 pattrib->last_txcmdsz = pattrib->pktlen;
3130 dump_mgntframe23a(padapter, pmgntframe);
3135 void issue_p2p_invitation_request23a(struct rtw_adapter *padapter, u8* raddr)
3137 unsigned char category = WLAN_CATEGORY_PUBLIC;
3138 u8 action = P2P_PUB_ACTION_ACTION;
3139 u32 p2poui = cpu_to_be32(P2POUI);
3140 u8 oui_subtype = P2P_INVIT_REQ;
3141 u8 p2pie[ 255 ] = { 0x00 };
3144 u16 len_channellist_attr = 0;
3145 #ifdef CONFIG_8723AU_P2P
3147 #endif /* CONFIG_8723AU_P2P */
3149 struct xmit_frame *pmgntframe;
3150 struct pkt_attrib *pattrib;
3151 unsigned char *pframe;
3152 struct ieee80211_hdr *pwlanhdr;
3153 unsigned short *fctrl;
3154 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3155 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3156 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3158 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3161 /* update attribute */
3162 pattrib = &pmgntframe->attrib;
3163 update_mgntframe_attrib23a(padapter, pattrib);
3165 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3167 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3168 pwlanhdr = (struct ieee80211_hdr *)pframe;
3170 fctrl = &pwlanhdr->frame_control;
3173 ether_addr_copy(pwlanhdr->addr1, raddr);
3174 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3175 ether_addr_copy(pwlanhdr->addr3, raddr);
3177 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3178 pmlmeext->mgnt_seq++;
3179 SetFrameSubType(pframe, WIFI_ACTION);
3181 pframe += sizeof(struct ieee80211_hdr_3addr);
3182 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3184 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
3185 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
3186 pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *) &p2poui,
3188 pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
3189 pframe = rtw_set_fixed_ie23a(pframe, 1, &dialogToken, &pattrib->pktlen);
3191 /* P2P IE Section. */
3195 p2pie[p2pielen++] = 0x50;
3196 p2pie[p2pielen++] = 0x6F;
3197 p2pie[p2pielen++] = 0x9A;
3198 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
3200 /* Commented by Albert 20101011 */
3201 /* According to the P2P Specification, the P2P Invitation
3202 request frame should contain 7 P2P attributes */
3203 /* 1. Configuration Timeout */
3204 /* 2. Invitation Flags */
3205 /* 3. Operating Channel (Only GO) */
3206 /* 4. P2P Group BSSID (Should be included if I am the GO) */
3207 /* 5. Channel List */
3208 /* 6. P2P Group ID */
3209 /* 7. P2P Device Info */
3211 /* Configuration Timeout */
3213 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
3216 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
3220 /* 2 seconds needed to be the P2P GO */
3221 p2pie[p2pielen++] = 200;
3222 /* 2 seconds needed to be the P2P Client */
3223 p2pie[p2pielen++] = 200;
3225 /* Invitation Flags */
3227 p2pie[p2pielen++] = P2P_ATTR_INVITATION_FLAGS;
3230 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0001);
3234 p2pie[p2pielen++] = P2P_INVITATION_FLAGS_PERSISTENT;
3236 /* Operating Channel */
3238 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
3241 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0005);
3245 /* Country String */
3246 p2pie[p2pielen++] = 'X';
3247 p2pie[p2pielen++] = 'X';
3249 /* The third byte should be set to 0x04. */
3250 /* Described in the "Operating Channel Attribute" section. */
3251 p2pie[p2pielen++] = 0x04;
3253 /* Operating Class */
3254 if (pwdinfo->invitereq_info.operating_ch <= 14)
3255 p2pie[p2pielen++] = 0x51;
3256 else if ((pwdinfo->invitereq_info.operating_ch >= 36) &&
3257 (pwdinfo->invitereq_info.operating_ch <= 48))
3258 p2pie[p2pielen++] = 0x73;
3260 p2pie[p2pielen++] = 0x7c;
3262 /* Channel Number */
3263 /* operating channel number */
3264 p2pie[p2pielen++] = pwdinfo->invitereq_info.operating_ch;
3266 if (ether_addr_equal(myid(&padapter->eeprompriv),
3267 pwdinfo->invitereq_info.go_bssid)) {
3268 /* P2P Group BSSID */
3270 p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
3273 *(u16*) (p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
3277 /* P2P Device Address for GO */
3278 memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid,
3280 p2pielen += ETH_ALEN;
3285 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
3288 /* Country String(3) */
3289 /* + (Operating Class (1) + Number of Channels(1)) *
3290 Operation Classes (?) */
3291 /* + number of channels in all classes */
3292 len_channellist_attr = 3 +
3293 (1 + 1) * (u16)pmlmeext->channel_list.reg_classes +
3294 get_reg_classes_full_count(pmlmeext->channel_list);
3296 *(u16*) (p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
3300 /* Country String */
3301 p2pie[p2pielen++] = 'X';
3302 p2pie[p2pielen++] = 'X';
3304 /* The third byte should be set to 0x04. */
3305 /* Described in the "Operating Channel Attribute" section. */
3306 p2pie[p2pielen++] = 0x04;
3308 /* Channel Entry List */
3309 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
3310 /* Operating Class */
3312 pmlmeext->channel_list.reg_class[j].reg_class;
3314 /* Number of Channels */
3316 pmlmeext->channel_list.reg_class[j].channels;
3320 i < pmlmeext->channel_list.reg_class[j].channels; i++) {
3322 pmlmeext->channel_list.reg_class[j].channel[i];
3328 p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
3331 *(u16*) (p2pie + p2pielen) =
3332 cpu_to_le16(6 + pwdinfo->invitereq_info.ssidlen);
3336 /* P2P Device Address for GO */
3337 memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN);
3338 p2pielen += ETH_ALEN;
3341 memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid,
3342 pwdinfo->invitereq_info.ssidlen);
3343 p2pielen += pwdinfo->invitereq_info.ssidlen;
3347 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
3350 /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) +
3351 Primary Device Type (8bytes) */
3352 /* + NumofSecondDevType (1byte) + WPS Device Name ID field
3353 (2bytes) + WPS Device Name Len field (2bytes) */
3354 *(u16*) (p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
3358 /* P2P Device Address */
3359 memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv), ETH_ALEN);
3360 p2pielen += ETH_ALEN;
3363 /* This field should be big endian. Noted by P2P specification. */
3364 *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
3367 /* Primary Device Type */
3369 *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
3373 *(u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI);
3376 /* Sub Category ID */
3377 *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
3380 /* Number of Secondary Device Types */
3381 p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
3385 *(u16*) (p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
3389 *(u16*) (p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
3393 memcpy(p2pie + p2pielen, pwdinfo->device_name,
3394 pwdinfo->device_name_len);
3395 p2pielen += pwdinfo->device_name_len;
3397 pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, p2pielen,
3398 (unsigned char *) p2pie, &pattrib->pktlen);
3400 #ifdef CONFIG_8723AU_P2P
3401 wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
3403 pattrib->pktlen += wfdielen;
3404 #endif /* CONFIG_8723AU_P2P */
3406 pattrib->last_txcmdsz = pattrib->pktlen;
3408 dump_mgntframe23a(padapter, pmgntframe);
3413 void issue_p2p_invitation_response23a(struct rtw_adapter *padapter, u8 *raddr,
3414 u8 dialogToken, u8 status_code)
3416 unsigned char category = WLAN_CATEGORY_PUBLIC;
3417 u8 action = P2P_PUB_ACTION_ACTION;
3418 u32 p2poui = cpu_to_be32(P2POUI);
3419 u8 oui_subtype = P2P_INVIT_RESP;
3420 u8 p2pie[ 255 ] = { 0x00 };
3422 u16 len_channellist_attr = 0;
3423 #ifdef CONFIG_8723AU_P2P
3425 #endif /* CONFIG_8723AU_P2P */
3428 struct xmit_frame *pmgntframe;
3429 struct pkt_attrib *pattrib;
3430 unsigned char *pframe;
3431 struct ieee80211_hdr *pwlanhdr;
3432 unsigned short *fctrl;
3433 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3434 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3435 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3437 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3440 /* update attribute */
3441 pattrib = &pmgntframe->attrib;
3442 update_mgntframe_attrib23a(padapter, pattrib);
3444 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3446 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3447 pwlanhdr = (struct ieee80211_hdr *)pframe;
3449 fctrl = &pwlanhdr->frame_control;
3452 ether_addr_copy(pwlanhdr->addr1, raddr);
3453 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3454 ether_addr_copy(pwlanhdr->addr3, raddr);
3456 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3457 pmlmeext->mgnt_seq++;
3458 SetFrameSubType(pframe, WIFI_ACTION);
3460 pframe += sizeof(struct ieee80211_hdr_3addr);
3461 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3463 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
3464 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
3465 pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *)&p2poui,
3467 pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
3468 pframe = rtw_set_fixed_ie23a(pframe, 1, &dialogToken, &pattrib->pktlen);
3470 /* P2P IE Section. */
3474 p2pie[p2pielen++] = 0x50;
3475 p2pie[p2pielen++] = 0x6F;
3476 p2pie[p2pielen++] = 0x9A;
3477 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
3479 /* Commented by Albert 20101005 */
3480 /* According to the P2P Specification, the P2P Invitation
3481 response frame should contain 5 P2P attributes */
3483 /* 2. Configuration Timeout */
3484 /* 3. Operating Channel (Only GO) */
3485 /* 4. P2P Group BSSID (Only GO) */
3486 /* 5. Channel List */
3490 p2pie[p2pielen++] = P2P_ATTR_STATUS;
3493 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0001);
3497 /* When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE. */
3498 /* Sent the event receiving the P2P Invitation Req frame
3500 /* DMP had to compare the MAC address to find out the profile. */
3501 /* So, the WiFi driver will send the
3502 P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB. */
3503 /* If the UI found the corresponding profile, the WiFi driver
3504 sends the P2P Invitation Req */
3505 /* to NB to rebuild the persistent group. */
3506 p2pie[p2pielen++] = status_code;
3508 /* Configuration Timeout */
3510 p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
3513 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
3517 /* 2 seconds needed to be the P2P GO */
3518 p2pie[p2pielen++] = 200;
3519 /* 2 seconds needed to be the P2P Client */
3520 p2pie[p2pielen++] = 200;
3522 if (status_code == P2P_STATUS_SUCCESS) {
3523 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
3524 /* The P2P Invitation request frame asks this
3525 Wi-Fi device to be the P2P GO */
3526 /* In this case, the P2P Invitation response
3527 frame should carry the two more P2P attributes. */
3528 /* First one is operating channel attribute. */
3529 /* Second one is P2P Group BSSID attribute. */
3531 /* Operating Channel */
3533 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
3536 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0005);
3540 /* Country String */
3541 p2pie[p2pielen++] = 'X';
3542 p2pie[p2pielen++] = 'X';
3544 /* The third byte should be set to 0x04. */
3545 /* Described in the "Operating Channel Attribute"
3547 p2pie[p2pielen++] = 0x04;
3549 /* Operating Class */
3551 p2pie[p2pielen++] = 0x51;
3553 /* Channel Number */
3554 /* operating channel number */
3555 p2pie[p2pielen++] = pwdinfo->operating_channel;
3557 /* P2P Group BSSID */
3559 p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
3562 *(u16*) (p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
3566 /* P2P Device Address for GO */
3567 memcpy(p2pie + p2pielen, myid(&padapter->eeprompriv),
3569 p2pielen += ETH_ALEN;
3574 p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
3577 /* Country String(3) */
3578 /* + (Operating Class (1) + Number of Channels(1)) *
3579 Operation Classes (?) */
3580 /* + number of channels in all classes */
3581 len_channellist_attr = 3 +
3582 (1 + 1) * (u16)pmlmeext->channel_list.reg_classes +
3583 get_reg_classes_full_count(pmlmeext->channel_list);
3585 *(u16*) (p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
3589 /* Country String */
3590 p2pie[p2pielen++] = 'X';
3591 p2pie[p2pielen++] = 'X';
3593 /* The third byte should be set to 0x04. */
3594 /* Described in the "Operating Channel Attribute" section. */
3595 p2pie[p2pielen++] = 0x04;
3597 /* Channel Entry List */
3598 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
3599 /* Operating Class */
3601 pmlmeext->channel_list.reg_class[j].reg_class;
3603 /* Number of Channels */
3605 pmlmeext->channel_list.reg_class[j].channels;
3609 i < pmlmeext->channel_list.reg_class[j].channels;
3611 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
3616 pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, p2pielen,
3617 (unsigned char *)p2pie, &pattrib->pktlen);
3619 #ifdef CONFIG_8723AU_P2P
3620 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
3622 pattrib->pktlen += wfdielen;
3623 #endif /* CONFIG_8723AU_P2P */
3625 pattrib->last_txcmdsz = pattrib->pktlen;
3627 dump_mgntframe23a(padapter, pmgntframe);
3632 void issue_p2p_provision_request23a(struct rtw_adapter *padapter, u8 *pssid,
3633 u8 ussidlen, u8 *pdev_raddr)
3635 unsigned char category = WLAN_CATEGORY_PUBLIC;
3636 u8 action = P2P_PUB_ACTION_ACTION;
3638 u32 p2poui = cpu_to_be32(P2POUI);
3639 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
3640 u8 wpsie[100] = { 0x00 };
3643 #ifdef CONFIG_8723AU_P2P
3645 #endif /* CONFIG_8723AU_P2P */
3646 struct xmit_frame *pmgntframe;
3647 struct pkt_attrib *pattrib;
3648 unsigned char *pframe;
3649 struct ieee80211_hdr *pwlanhdr;
3650 unsigned short *fctrl;
3651 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3652 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3653 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3655 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3658 DBG_8723A("[%s] In\n", __func__);
3659 /* update attribute */
3660 pattrib = &pmgntframe->attrib;
3661 update_mgntframe_attrib23a(padapter, pattrib);
3663 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3665 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3666 pwlanhdr = (struct ieee80211_hdr *)pframe;
3668 fctrl = &pwlanhdr->frame_control;
3671 ether_addr_copy(pwlanhdr->addr1, pdev_raddr);
3672 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
3673 ether_addr_copy(pwlanhdr->addr3, pdev_raddr);
3675 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3676 pmlmeext->mgnt_seq++;
3677 SetFrameSubType(pframe, WIFI_ACTION);
3679 pframe += sizeof(struct ieee80211_hdr_3addr);
3680 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
3682 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
3683 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
3684 pframe = rtw_set_fixed_ie23a(pframe, 4, (unsigned char *)&p2poui,
3686 pframe = rtw_set_fixed_ie23a(pframe, 1, &oui_subtype, &pattrib->pktlen);
3687 pframe = rtw_set_fixed_ie23a(pframe, 1, &dialogToken, &pattrib->pktlen);
3689 p2pielen = build_prov_disc_request_p2p_ie23a(pwdinfo, pframe, pssid,
3690 ussidlen, pdev_raddr);
3693 pattrib->pktlen += p2pielen;
3697 *(u32*) (wpsie) = cpu_to_be32(WPSOUI);
3702 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
3706 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0001);
3710 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
3714 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
3718 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0002);
3722 *(u16*) (wpsie + wpsielen) = cpu_to_be16(pwdinfo->tx_prov_disc_info.wps_config_method_request);
3725 pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, wpsielen,
3726 (unsigned char *) wpsie, &pattrib->pktlen);
3728 #ifdef CONFIG_8723AU_P2P
3729 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
3731 pattrib->pktlen += wfdielen;
3732 #endif /* CONFIG_8723AU_P2P */
3734 pattrib->last_txcmdsz = pattrib->pktlen;
3736 dump_mgntframe23a(padapter, pmgntframe);
3741 static u8 is_matched_in_profilelist(u8 *peermacaddr,
3742 struct profile_info *profileinfo)
3744 u8 i, match_result = 0;
3746 DBG_8723A("[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __func__,
3747 peermacaddr[0], peermacaddr[1], peermacaddr[2],
3748 peermacaddr[3], peermacaddr[4], peermacaddr[5]);
3750 for (i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++) {
3751 DBG_8723A("[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X "
3752 "%.2X\n", __func__, profileinfo->peermac[0],
3753 profileinfo->peermac[1], profileinfo->peermac[2],
3754 profileinfo->peermac[3], profileinfo->peermac[4],
3755 profileinfo->peermac[5]);
3756 if (ether_addr_equal(peermacaddr, profileinfo->peermac)) {
3758 DBG_8723A("[%s] Match!\n", __func__);
3763 return match_result;
3766 void issue_probersp23a_p2p23a(struct rtw_adapter *padapter, unsigned char *da)
3768 struct xmit_frame *pmgntframe;
3769 struct pkt_attrib *pattrib;
3770 unsigned char *pframe;
3771 struct ieee80211_hdr *pwlanhdr;
3772 unsigned short *fctrl;
3774 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
3775 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3776 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3777 u16 beacon_interval = 100;
3779 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
3780 u8 wpsie[255] = { 0x00 };
3781 u32 wpsielen = 0, p2pielen = 0;
3782 #ifdef CONFIG_8723AU_P2P
3784 #endif /* CONFIG_8723AU_P2P */
3785 struct cfg80211_wifidirect_info *pcfg80211_wdinfo =
3786 &padapter->cfg80211_wdinfo;
3787 struct ieee80211_channel *ieee_ch =
3788 &pcfg80211_wdinfo->remain_on_ch_channel;
3790 (u8)ieee80211_frequency_to_channel(ieee_ch->center_freq);
3792 /* DBG_8723A("%s\n", __func__); */
3794 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
3799 /* update attribute */
3800 pattrib = &pmgntframe->attrib;
3801 update_mgntframe_attrib23a(padapter, pattrib);
3803 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3805 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3806 pwlanhdr = (struct ieee80211_hdr *)pframe;
3808 mac = myid(&padapter->eeprompriv);
3810 fctrl = &pwlanhdr->frame_control;
3812 ether_addr_copy(pwlanhdr->addr1, da);
3813 ether_addr_copy(pwlanhdr->addr2, mac);
3815 /* Use the device address for BSSID field. */
3816 ether_addr_copy(pwlanhdr->addr3, mac);
3818 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3819 pmlmeext->mgnt_seq++;
3820 SetFrameSubType(fctrl, WIFI_PROBERSP);
3822 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
3823 pattrib->pktlen = pattrib->hdrlen;
3824 pframe += pattrib->hdrlen;
3826 /* timestamp will be inserted by hardware */
3828 pattrib->pktlen += 8;
3830 /* beacon interval: 2 bytes */
3831 memcpy(pframe, (unsigned char *) &beacon_interval, 2);
3833 pattrib->pktlen += 2;
3835 /* capability info: 2 bytes */
3836 /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of
3837 WiFi Direct Spec) */
3838 capInfo |= cap_ShortPremble;
3839 capInfo |= cap_ShortSlot;
3841 memcpy(pframe, (unsigned char *) &capInfo, 2);
3843 pattrib->pktlen += 2;
3846 pframe = rtw_set_ie23a(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid,
3849 /* supported rates... */
3850 /* Use the OFDM rate in the P2P probe response frame.
3851 (6(B), 9(B), 12, 18, 24, 36, 48, 54) */
3852 pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_, 8,
3853 pwdinfo->support_rate, &pattrib->pktlen);
3855 /* DS parameter set */
3856 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled &&
3857 listen_channel != 0) {
3858 pframe = rtw_set_ie23a(pframe, _DSSET_IE_, 1, (unsigned char *)
3859 &listen_channel, &pattrib->pktlen);
3861 pframe = rtw_set_ie23a(pframe, _DSSET_IE_, 1, (unsigned char *)
3862 &pwdinfo->listen_channel,
3866 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled) {
3867 if (pmlmepriv->wps_probe_resp_ie &&
3868 pmlmepriv->p2p_probe_resp_ie) {
3870 memcpy(pframe, pmlmepriv->wps_probe_resp_ie,
3871 pmlmepriv->wps_probe_resp_ie_len);
3872 pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
3873 pframe += pmlmepriv->wps_probe_resp_ie_len;
3876 memcpy(pframe, pmlmepriv->p2p_probe_resp_ie,
3877 pmlmepriv->p2p_probe_resp_ie_len);
3878 pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
3879 pframe += pmlmepriv->p2p_probe_resp_ie_len;
3884 /* Noted by Albert 20100907 */
3885 /* According to the WPS specification, all the WPS
3886 attribute is presented by Big Endian. */
3890 *(u32*) (wpsie) = cpu_to_be32(WPSOUI);
3895 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
3899 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0001);
3903 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
3905 /* WiFi Simple Config State */
3907 *(u16*) (wpsie + wpsielen) =
3908 cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
3912 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0001);
3916 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG;
3920 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
3924 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0001);
3928 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
3932 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
3936 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0010);
3940 memcpy(wpsie + wpsielen, myid(&padapter->eeprompriv), ETH_ALEN);
3945 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
3949 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0007);
3953 memcpy(wpsie + wpsielen, "Realtek", 7);
3958 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
3962 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0006);
3966 memcpy(wpsie + wpsielen, "8192CU", 6);
3971 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
3975 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0001);
3979 wpsie[ wpsielen++ ] = 0x31; /* character 1 */
3983 *(u16*) (wpsie + wpsielen) =
3984 cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
3988 *(u16*) (wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
3992 memcpy(wpsie + wpsielen, "123456", ETH_ALEN);
3993 wpsielen += ETH_ALEN;
3995 /* Primary Device Type */
3997 *(u16*) (wpsie + wpsielen) =
3998 cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
4002 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0008);
4007 *(u16*) (wpsie + wpsielen) =
4008 cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
4012 *(u32*) (wpsie + wpsielen) = cpu_to_be32(WPSOUI);
4015 /* Sub Category ID */
4016 *(u16*) (wpsie + wpsielen) =
4017 cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
4022 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
4026 *(u16*) (wpsie + wpsielen) =
4027 cpu_to_be16(pwdinfo->device_name_len);
4031 if (pwdinfo->device_name_len) {
4032 memcpy(wpsie + wpsielen, pwdinfo->device_name,
4033 pwdinfo->device_name_len);
4034 wpsielen += pwdinfo->device_name_len;
4039 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
4043 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0002);
4047 *(u16*) (wpsie + wpsielen) =
4048 cpu_to_be16(pwdinfo->supported_wps_cm);
4051 pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, wpsielen,
4052 (unsigned char *)wpsie,
4055 p2pielen = build_probe_resp_p2p_ie23a(pwdinfo, pframe);
4057 pattrib->pktlen += p2pielen;
4060 #ifdef CONFIG_8723AU_P2P
4061 if (pwdinfo->wfd_info->wfd_enable) {
4062 wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
4064 pattrib->pktlen += wfdielen;
4065 } else if (pmlmepriv->wfd_probe_resp_ie &&
4066 pmlmepriv->wfd_probe_resp_ie_len > 0) {
4068 memcpy(pframe, pmlmepriv->wfd_probe_resp_ie,
4069 pmlmepriv->wfd_probe_resp_ie_len);
4070 pattrib->pktlen += pmlmepriv->wfd_probe_resp_ie_len;
4071 pframe += pmlmepriv->wfd_probe_resp_ie_len;
4073 #endif /* CONFIG_8723AU_P2P */
4075 pattrib->last_txcmdsz = pattrib->pktlen;
4077 dump_mgntframe23a(padapter, pmgntframe);
4082 static int _issue23a_probereq_p2p(struct rtw_adapter *padapter, u8 *da,
4086 struct xmit_frame *pmgntframe;
4087 struct pkt_attrib *pattrib;
4088 unsigned char *pframe;
4089 struct ieee80211_hdr *pwlanhdr;
4090 unsigned short *fctrl;
4092 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
4093 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4094 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4095 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
4096 u8 wpsie[255] = {0x00}, p2pie[255] = {0x00};
4097 u16 wpsielen = 0, p2pielen = 0;
4098 #ifdef CONFIG_8723AU_P2P
4100 #endif /* CONFIG_8723AU_P2P */
4101 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4103 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
4106 /* update attribute */
4107 pattrib = &pmgntframe->attrib;
4108 update_mgntframe_attrib23a(padapter, pattrib);
4110 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4112 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4113 pwlanhdr = (struct ieee80211_hdr *)pframe;
4115 mac = myid(&padapter->eeprompriv);
4117 fctrl = &pwlanhdr->frame_control;
4121 ether_addr_copy(pwlanhdr->addr1, da);
4122 ether_addr_copy(pwlanhdr->addr3, da);
4124 if ((pwdinfo->p2p_info.scan_op_ch_only) ||
4125 (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
4126 /* This two flags will be set when this is
4127 only the P2P client mode. */
4128 ether_addr_copy(pwlanhdr->addr1,
4129 pwdinfo->p2p_peer_interface_addr);
4130 ether_addr_copy(pwlanhdr->addr3,
4131 pwdinfo->p2p_peer_interface_addr);
4133 /* broadcast probe request frame */
4134 ether_addr_copy(pwlanhdr->addr1, bc_addr);
4135 ether_addr_copy(pwlanhdr->addr3, bc_addr);
4138 ether_addr_copy(pwlanhdr->addr2, mac);
4140 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4141 pmlmeext->mgnt_seq++;
4142 SetFrameSubType(pframe, WIFI_PROBEREQ);
4144 pframe += sizeof (struct ieee80211_hdr_3addr);
4145 pattrib->pktlen = sizeof (struct ieee80211_hdr_3addr);
4147 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) {
4148 pframe = rtw_set_ie23a(pframe, _SSID_IE_,
4149 pwdinfo->tx_prov_disc_info.ssid.ssid_len,
4150 pwdinfo->tx_prov_disc_info.ssid.ssid,
4153 pframe = rtw_set_ie23a(pframe, _SSID_IE_,
4154 P2P_WILDCARD_SSID_LEN,
4155 pwdinfo->p2p_wildcard_ssid,
4158 /* Use the OFDM rate in the P2P probe request frame.
4159 (6(B), 9(B), 12(B), 24(B), 36, 48, 54) */
4160 pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_, 8,
4161 pwdinfo->support_rate, &pattrib->pktlen);
4163 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled) {
4164 if (pmlmepriv->wps_probe_req_ie &&
4165 pmlmepriv->p2p_probe_req_ie) {
4167 memcpy(pframe, pmlmepriv->wps_probe_req_ie,
4168 pmlmepriv->wps_probe_req_ie_len);
4169 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
4170 pframe += pmlmepriv->wps_probe_req_ie_len;
4173 memcpy(pframe, pmlmepriv->p2p_probe_req_ie,
4174 pmlmepriv->p2p_probe_req_ie_len);
4175 pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
4176 pframe += pmlmepriv->p2p_probe_req_ie_len;
4181 /* Noted by Albert 20110221 */
4182 /* According to the WPS specification, all the WPS
4183 attribute is presented by Big Endian. */
4187 *(u32*) (wpsie) = cpu_to_be32(WPSOUI);
4192 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
4196 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0001);
4200 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
4202 if (pmlmepriv->wps_probe_req_ie == NULL) {
4205 *(u16*) (wpsie + wpsielen) =
4206 cpu_to_be16(WPS_ATTR_UUID_E);
4210 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0010);
4214 memcpy(wpsie + wpsielen, myid(&padapter->eeprompriv),
4220 *(u16*) (wpsie + wpsielen) =
4221 cpu_to_be16(WPS_ATTR_CONF_METHOD);
4225 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0002);
4229 *(u16*) (wpsie + wpsielen) =
4230 cpu_to_be16(pwdinfo->supported_wps_cm);
4236 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
4240 *(u16*) (wpsie + wpsielen) =
4241 cpu_to_be16(pwdinfo->device_name_len);
4245 memcpy(wpsie + wpsielen, pwdinfo->device_name,
4246 pwdinfo->device_name_len);
4247 wpsielen += pwdinfo->device_name_len;
4249 /* Primary Device Type */
4251 *(u16*) (wpsie + wpsielen) =
4252 cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
4256 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0008);
4261 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_RTK_WIDI);
4265 *(u32*) (wpsie + wpsielen) = cpu_to_be32(WPSOUI);
4268 /* Sub Category ID */
4269 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_RTK_DMP);
4272 /* Device Password ID */
4274 *(u16*) (wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
4278 *(u16*) (wpsie + wpsielen) = cpu_to_be16(0x0002);
4282 /* Registrar-specified */
4283 *(u16*) (wpsie + wpsielen) =
4284 cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
4287 pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, wpsielen,
4288 (unsigned char *)wpsie,
4293 p2pie[p2pielen++] = 0x50;
4294 p2pie[p2pielen++] = 0x6F;
4295 p2pie[p2pielen++] = 0x9A;
4296 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
4298 /* Commented by Albert 20110221 */
4299 /* According to the P2P Specification, the probe request
4300 frame should contain 5 P2P attributes */
4301 /* 1. P2P Capability */
4302 /* 2. P2P Device ID if this probe request wants to
4303 find the specific P2P device */
4304 /* 3. Listen Channel */
4305 /* 4. Extended Listen Timing */
4306 /* 5. Operating Channel if this WiFi is working as
4307 the group owner now */
4309 /* P2P Capability */
4311 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
4314 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
4318 /* Device Capability Bitmap, 1 byte */
4319 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
4321 /* Group Capability Bitmap, 1 byte */
4322 if (pwdinfo->persistent_supported)
4323 p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP |
4324 DMP_P2P_GRPCAP_SUPPORT;
4326 p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
4328 /* Listen Channel */
4330 p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
4333 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0005);
4337 /* Country String */
4338 p2pie[p2pielen++] = 'X';
4339 p2pie[p2pielen++] = 'X';
4341 /* The third byte should be set to 0x04. */
4342 /* Described in the "Operating Channel Attribute" section. */
4343 p2pie[p2pielen++] = 0x04;
4345 /* Operating Class */
4346 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
4348 /* Channel Number */
4349 /* listen channel */
4350 p2pie[p2pielen++] = pwdinfo->listen_channel;
4352 /* Extended Listen Timing */
4354 p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
4357 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0004);
4361 /* Availability Period */
4362 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF);
4365 /* Availability Interval */
4366 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF);
4369 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
4370 /* Operating Channel (if this WiFi is working as
4371 the group owner now) */
4373 p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
4376 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0005);
4380 /* Country String */
4381 p2pie[p2pielen++] = 'X';
4382 p2pie[p2pielen++] = 'X';
4384 /* The third byte should be set to 0x04. */
4385 /* Described in the "Operating Channel Attribute"
4387 p2pie[p2pielen++] = 0x04;
4389 /* Operating Class */
4390 p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
4392 /* Channel Number */
4393 /* operating channel number */
4394 p2pie[p2pielen++] = pwdinfo->operating_channel;
4397 pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, p2pielen,
4398 (unsigned char *)p2pie,
4401 if (pmlmepriv->wps_probe_req_ie) {
4403 memcpy(pframe, pmlmepriv->wps_probe_req_ie,
4404 pmlmepriv->wps_probe_req_ie_len);
4405 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
4406 pframe += pmlmepriv->wps_probe_req_ie_len;
4410 #ifdef CONFIG_8723AU_P2P
4411 if (pwdinfo->wfd_info->wfd_enable) {
4412 wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe);
4414 pattrib->pktlen += wfdielen;
4415 } else if (pmlmepriv->wfd_probe_req_ie &&
4416 pmlmepriv->wfd_probe_req_ie_len>0) {
4418 memcpy(pframe, pmlmepriv->wfd_probe_req_ie,
4419 pmlmepriv->wfd_probe_req_ie_len);
4420 pattrib->pktlen += pmlmepriv->wfd_probe_req_ie_len;
4421 pframe += pmlmepriv->wfd_probe_req_ie_len;
4423 #endif /* CONFIG_8723AU_P2P */
4425 pattrib->last_txcmdsz = pattrib->pktlen;
4427 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
4428 ("issuing probe_req, tx_len =%d\n", pattrib->last_txcmdsz));
4431 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
4433 dump_mgntframe23a(padapter, pmgntframe);
4441 inline void issue23a_probereq_p2p(struct rtw_adapter *adapter, u8 *da)
4443 _issue23a_probereq_p2p(adapter, da, false);
4446 int issue23a_probereq_p2p_ex(struct rtw_adapter *adapter, u8 *da,
4447 int try_cnt, int wait_ms)
4451 unsigned long start = jiffies;
4454 ret = _issue23a_probereq_p2p(adapter, da,
4455 wait_ms > 0 ? true : false);
4459 if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
4462 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
4465 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
4472 if (try_cnt && wait_ms) {
4474 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d "
4475 "in %u ms\n", FUNC_ADPT_ARG(adapter),
4476 MAC_ARG(da), rtw_get_oper_ch23a(adapter),
4477 ret == _SUCCESS?", acked":"", i, try_cnt,
4478 jiffies_to_msecs(jiffies - start));
4480 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
4481 FUNC_ADPT_ARG(adapter),
4482 rtw_get_oper_ch23a(adapter),
4483 ret == _SUCCESS?", acked":"", i, try_cnt,
4484 jiffies_to_msecs(jiffies - start));
4490 #endif /* CONFIG_8723AU_P2P */
4492 static s32 rtw_action_public_decache(struct recv_frame *recv_frame, s32 token)
4494 struct rtw_adapter *adapter = recv_frame->adapter;
4495 struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
4496 struct sk_buff *skb = recv_frame->pkt;
4497 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
4500 seq_ctrl = ((recv_frame->attrib.seq_num&0xffff) << 4) |
4501 (recv_frame->attrib.frag_num & 0xf);
4503 if (ieee80211_has_retry(hdr->frame_control)) {
4505 if ((seq_ctrl == mlmeext->action_public_rxseq) &&
4506 (token == mlmeext->action_public_dialog_token)) {
4507 DBG_8723A(FUNC_ADPT_FMT" seq_ctrl = 0x%x, "
4508 "rxseq = 0x%x, token:%d\n",
4509 FUNC_ADPT_ARG(adapter), seq_ctrl,
4510 mlmeext->action_public_rxseq, token);
4514 if (seq_ctrl == mlmeext->action_public_rxseq) {
4515 DBG_8723A(FUNC_ADPT_FMT" seq_ctrl = 0x%x, "
4517 FUNC_ADPT_ARG(adapter), seq_ctrl,
4518 mlmeext->action_public_rxseq);
4524 mlmeext->action_public_rxseq = seq_ctrl;
4527 mlmeext->action_public_dialog_token = token;
4532 static unsigned int on_action_public23a_p2p(struct recv_frame *precv_frame)
4534 struct sk_buff *skb = precv_frame->pkt;
4535 u8 *pframe = skb->data;
4538 #ifdef CONFIG_8723AU_P2P
4539 struct rtw_adapter *padapter = precv_frame->adapter;
4540 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
4541 uint len = skb->len;
4544 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
4545 u8 result = P2P_STATUS_SUCCESS;
4546 #endif /* CONFIG_8723AU_P2P */
4548 frame_body = (unsigned char *)
4549 (pframe + sizeof(struct ieee80211_hdr_3addr));
4551 dialogToken = frame_body[7];
4553 if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
4556 #ifdef CONFIG_8723AU_P2P
4557 del_timer_sync(&pwdinfo->reset_ch_sitesurvey);
4558 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled) {
4559 rtw_cfg80211_rx_p2p_action_public(padapter, pframe, len);
4561 /* Do nothing if the driver doesn't enable the P2P function. */
4562 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
4565 len -= sizeof(struct ieee80211_hdr_3addr);
4567 switch (frame_body[ 6 ])/* OUI Subtype */
4569 case P2P_GO_NEGO_REQ:
4570 DBG_8723A("[%s] Got GO Nego Req Frame\n", __func__);
4571 memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
4573 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
4575 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
4578 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
4580 /* Commented by Albert 20110526 */
4581 /* In this case, this means the previous nego fail doesn't be reset yet. */
4582 del_timer_sync(&pwdinfo->restore_p2p_state_timer);
4583 /* Restore the previous p2p state */
4584 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
4585 DBG_8723A("[%s] Restore the previous p2p state to %d\n", __func__, rtw_p2p_state(pwdinfo));
4588 /* Commented by Kurt 20110902 */
4589 /* Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
4590 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
4591 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
4593 /* Commented by Kurt 20120113 */
4594 /* Get peer_dev_addr here if peer doesn't issue prov_disc frame. */
4595 if (is_zero_ether_addr(pwdinfo->rx_prov_disc_info.peerDevAddr))
4596 ether_addr_copy(pwdinfo->rx_prov_disc_info.peerDevAddr, hdr->addr2);
4598 result = process_p2p_group_negotation_req23a(pwdinfo, frame_body, len);
4599 issue_p2p_GO_response(padapter, hdr->addr2,
4600 frame_body, len, result);
4602 /* Commented by Albert 20110718 */
4603 /* No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer. */
4604 mod_timer(&pwdinfo->restore_p2p_state_timer,
4605 jiffies + msecs_to_jiffies(5000));
4608 case P2P_GO_NEGO_RESP:
4609 DBG_8723A("[%s] Got GO Nego Resp Frame\n", __func__);
4611 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
4613 /* Commented by Albert 20110425 */
4614 /* The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function. */
4615 del_timer_sync(&pwdinfo->restore_p2p_state_timer);
4616 pwdinfo->nego_req_info.benable = false;
4617 result = process_p2p_group_negotation_resp23a(pwdinfo, frame_body, len);
4618 issue_p2p_GO_confirm(pwdinfo->padapter,
4621 if (result == P2P_STATUS_SUCCESS) {
4622 if (rtw_p2p_role(pwdinfo) ==
4624 pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
4625 pwdinfo->p2p_info.scan_op_ch_only = 1;
4626 mod_timer(&pwdinfo->reset_ch_sitesurvey2, jiffies + msecs_to_jiffies(P2P_RESET_SCAN_CH));
4630 /* Reset the dialog token for group negotiation frames. */
4631 pwdinfo->negotiation_dialog_token = 1;
4633 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
4635 mod_timer(&pwdinfo->restore_p2p_state_timer, jiffies + msecs_to_jiffies(5000));
4638 DBG_8723A("[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __func__);
4643 case P2P_GO_NEGO_CONF:
4645 DBG_8723A("[%s] Got GO Nego Confirm Frame\n", __func__);
4646 result = process_p2p_group_negotation_confirm23a(pwdinfo, frame_body, len);
4647 if (P2P_STATUS_SUCCESS == result)
4649 if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT)
4651 pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
4652 pwdinfo->p2p_info.scan_op_ch_only = 1;
4653 mod_timer(&pwdinfo->reset_ch_sitesurvey2, jiffies + msecs_to_jiffies(P2P_RESET_SCAN_CH));
4659 /* Added by Albert 2010/10/05 */
4660 /* Received the P2P Invite Request frame. */
4662 DBG_8723A("[%s] Got invite request frame!\n", __func__);
4663 if ((p2p_ie = rtw_get_p2p_ie23a(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)))
4665 /* Parse the necessary information from the P2P Invitation Request frame. */
4666 /* For example: The MAC address of sending this P2P Invitation Request frame. */
4667 u32 attr_contentlen = 0;
4668 u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
4669 struct group_id_info group_id;
4670 u8 invitation_flag = 0;
4672 rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
4673 if (attr_contentlen)
4676 rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
4677 /* Commented by Albert 20120510 */
4678 /* Copy to the pwdinfo->p2p_peer_interface_addr. */
4679 /* So that the WFD UI (or Sigma) can get the peer interface address by using the following command. */
4680 /* #> iwpriv wlan0 p2p_get peer_ifa */
4681 /* After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant. */
4683 if (attr_contentlen)
4685 DBG_8723A("[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __func__,
4686 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
4687 pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
4688 pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
4691 if (invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT)
4693 /* Re-invoke the persistent group. */
4695 memset(&group_id, 0x00, sizeof(struct group_id_info));
4696 rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, (u8*) &group_id, &attr_contentlen);
4697 if (attr_contentlen) {
4698 if (ether_addr_equal(group_id.go_device_addr, myid(&padapter->eeprompriv))) {
4699 /* The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO. */
4700 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO);
4701 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
4702 status_code = P2P_STATUS_SUCCESS;
4706 /* The p2p device sending this p2p invitation request wants to be the persistent GO. */
4707 if (is_matched_in_profilelist(pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[ 0 ]))
4709 u8 operatingch_info[5] = { 0x00 };
4710 if (rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen))
4712 if (rtw_ch_set_search_ch23a(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4]))
4714 /* The operating channel is acceptable for this device. */
4715 pwdinfo->rx_invitereq_info.operation_ch[0]= operatingch_info[4];
4716 pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
4717 mod_timer(&pwdinfo->reset_ch_sitesurvey, jiffies + msecs_to_jiffies(P2P_RESET_SCAN_CH));
4718 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
4719 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
4720 status_code = P2P_STATUS_SUCCESS;
4724 /* The operating channel isn't supported by this device. */
4725 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
4726 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
4727 status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
4728 mod_timer(&pwdinfo->restore_p2p_state_timer, jiffies + msecs_to_jiffies(3000));
4732 /* Commented by Albert 20121130 */
4733 /* Intel will use the different P2P IE to store the operating channel information */
4734 /* Workaround for Intel WiDi 3.5 */
4735 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
4736 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
4737 status_code = P2P_STATUS_SUCCESS;
4742 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
4744 status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
4750 DBG_8723A("[%s] P2P Group ID Attribute NOT FOUND!\n", __func__);
4751 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
4756 /* Received the invitation to join a P2P group. */
4758 memset(&group_id, 0x00, sizeof(struct group_id_info));
4759 rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, (u8*) &group_id, &attr_contentlen);
4760 if (attr_contentlen)
4762 if (ether_addr_equal(group_id.go_device_addr, myid(&padapter->eeprompriv))) {
4763 /* In this case, the GO can't be myself. */
4764 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
4765 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
4769 /* The p2p device sending this p2p invitation request wants to join an existing P2P group */
4770 /* Commented by Albert 2012/06/28 */
4771 /* In this case, this Wi-Fi device should use the iwpriv command to get the peer device address. */
4772 /* The peer device address should be the destination address for the provisioning discovery request. */
4773 /* Then, this Wi-Fi device should use the iwpriv command to get the peer interface address. */
4774 /* The peer interface address should be the address for WPS mac address */
4775 ether_addr_copy(pwdinfo->p2p_peer_device_addr, group_id.go_device_addr);
4776 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
4777 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN);
4778 status_code = P2P_STATUS_SUCCESS;
4783 DBG_8723A("[%s] P2P Group ID Attribute NOT FOUND!\n", __func__);
4784 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
4790 DBG_8723A("[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __func__);
4791 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
4794 DBG_8723A("[%s] status_code = %d\n", __func__, status_code);
4796 pwdinfo->inviteresp_info.token = frame_body[ 7 ];
4797 issue_p2p_invitation_response23a(padapter, hdr->addr2, pwdinfo->inviteresp_info.token, status_code);
4801 case P2P_INVIT_RESP:
4803 u8 attr_content = 0x00;
4804 u32 attr_contentlen = 0;
4806 DBG_8723A("[%s] Got invite response frame!\n", __func__);
4807 del_timer_sync(&pwdinfo->restore_p2p_state_timer);
4808 if ((p2p_ie = rtw_get_p2p_ie23a(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)))
4810 rtw_get_p2p_attr23a_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
4812 if (attr_contentlen == 1)
4814 DBG_8723A("[%s] Status = %d\n", __func__, attr_content);
4815 pwdinfo->invitereq_info.benable = false;
4817 if (attr_content == P2P_STATUS_SUCCESS)
4819 if (ether_addr_equal(pwdinfo->invitereq_info.go_bssid, myid(&padapter->eeprompriv))) {
4820 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
4824 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
4826 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_OK);
4830 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
4831 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
4836 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
4837 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
4842 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
4843 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
4846 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL)) {
4847 mod_timer(&pwdinfo->restore_p2p_state_timer, jiffies + msecs_to_jiffies(5000));
4851 case P2P_DEVDISC_REQ:
4853 process_p2p_devdisc_req23a(pwdinfo, pframe, len);
4857 case P2P_DEVDISC_RESP:
4859 process_p2p_devdisc_resp23a(pwdinfo, pframe, len);
4863 case P2P_PROVISION_DISC_REQ:
4864 DBG_8723A("[%s] Got Provisioning Discovery Request Frame\n", __func__);
4865 process_p2p_provdisc_req23a(pwdinfo, pframe, len);
4866 ether_addr_copy(pwdinfo->rx_prov_disc_info.peerDevAddr, hdr->addr2);
4869 /* Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
4870 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
4871 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
4873 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
4874 mod_timer(&pwdinfo->restore_p2p_state_timer,
4875 jiffies + msecs_to_jiffies(P2P_PROVISION_TIMEOUT));
4878 case P2P_PROVISION_DISC_RESP:
4879 /* Commented by Albert 20110707 */
4880 /* Should we check the pwdinfo->tx_prov_disc_info.bsent flag here?? */
4881 DBG_8723A("[%s] Got Provisioning Discovery Response Frame\n", __func__);
4882 /* Commented by Albert 20110426 */
4883 /* The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function. */
4884 del_timer_sync(&pwdinfo->restore_p2p_state_timer);
4885 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
4886 process_p2p_provdisc_resp23a(pwdinfo, pframe);
4887 mod_timer(&pwdinfo->restore_p2p_state_timer,
4888 jiffies + msecs_to_jiffies(P2P_PROVISION_TIMEOUT));
4893 #endif /* CONFIG_8723AU_P2P */
4898 static unsigned int on_action_public23a_vendor(struct recv_frame *precv_frame)
4900 unsigned int ret = _FAIL;
4901 struct sk_buff *skb = precv_frame->pkt;
4902 u8 *pframe = skb->data;
4903 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
4905 if (!memcmp(frame_body + 2, P2P_OUI23A, 4)) {
4906 ret = on_action_public23a_p2p(precv_frame);
4913 on_action_public23a_default(struct recv_frame *precv_frame, u8 action)
4915 unsigned int ret = _FAIL;
4916 struct sk_buff *skb = precv_frame->pkt;
4917 u8 *pframe = skb->data;
4918 uint frame_len = skb->len;
4919 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
4921 struct rtw_adapter *adapter = precv_frame->adapter;
4925 token = frame_body[2];
4927 if (rtw_action_public_decache(precv_frame, token) == _FAIL)
4930 cnt += sprintf((msg+cnt), "%s(token:%u)",
4931 action_public_str23a(action), token);
4932 rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
4940 unsigned int on_action_public23a(struct rtw_adapter *padapter,
4941 struct recv_frame *precv_frame)
4943 unsigned int ret = _FAIL;
4944 struct sk_buff *skb = precv_frame->pkt;
4945 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
4946 u8 *pframe = skb->data;
4947 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr);
4948 u8 category, action;
4950 /* check RA matches or not */
4951 if (!ether_addr_equal(myid(&padapter->eeprompriv), hdr->addr1))
4954 category = frame_body[0];
4955 if (category != WLAN_CATEGORY_PUBLIC)
4958 action = frame_body[1];
4960 case ACT_PUBLIC_VENDOR:
4961 ret = on_action_public23a_vendor(precv_frame);
4964 ret = on_action_public23a_default(precv_frame, action);
4972 unsigned int OnAction23a_ht(struct rtw_adapter *padapter,
4973 struct recv_frame *precv_frame)
4978 unsigned int OnAction23a_wmm(struct rtw_adapter *padapter,
4979 struct recv_frame *precv_frame)
4984 unsigned int OnAction23a_p2p(struct rtw_adapter *padapter,
4985 struct recv_frame *precv_frame)
4987 #ifdef CONFIG_8723AU_P2P
4989 u8 category, OUI_Subtype, dialogToken = 0;
4990 struct sk_buff *skb = precv_frame->pkt;
4991 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
4992 u8 *pframe = skb->data;
4993 uint len = skb->len;
4994 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
4996 DBG_8723A("%s\n", __func__);
4998 /* check RA matches or not */
4999 if (!ether_addr_equal(myid(&padapter->eeprompriv), hdr->addr1))
5002 frame_body = (unsigned char *)
5003 (pframe + sizeof(struct ieee80211_hdr_3addr));
5005 category = frame_body[0];
5006 if (category != WLAN_CATEGORY_VENDOR_SPECIFIC)
5009 if (cpu_to_be32(*((u32*) (frame_body + 1))) != P2POUI)
5012 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled) {
5013 rtw_cfg80211_rx_action_p2p(padapter, pframe, len);
5016 len -= sizeof(struct ieee80211_hdr_3addr);
5017 OUI_Subtype = frame_body[5];
5018 dialogToken = frame_body[6];
5020 switch (OUI_Subtype)
5022 case P2P_NOTICE_OF_ABSENCE:
5025 case P2P_PRESENCE_REQUEST:
5026 process_p2p_presence_req23a(pwdinfo, pframe, len);
5029 case P2P_PRESENCE_RESPONSE:
5032 case P2P_GO_DISC_REQUEST:
5039 #endif /* CONFIG_8723AU_P2P */
5044 unsigned int OnAction23a(struct rtw_adapter *padapter,
5045 struct recv_frame *precv_frame)
5048 unsigned char category;
5049 struct action_handler *ptable;
5050 unsigned char *frame_body;
5051 struct sk_buff *skb = precv_frame->pkt;
5052 u8 *pframe = skb->data;
5054 frame_body = (unsigned char *)
5055 (pframe + sizeof(struct ieee80211_hdr_3addr));
5057 category = frame_body[0];
5060 i < sizeof(OnAction23a_tbl) / sizeof(struct action_handler); i++) {
5061 ptable = &OnAction23a_tbl[i];
5063 if (category == ptable->num)
5064 ptable->func(padapter, precv_frame);
5070 unsigned int DoReserved23a(struct rtw_adapter *padapter,
5071 struct recv_frame *precv_frame)
5076 struct xmit_frame *alloc_mgtxmitframe23a(struct xmit_priv *pxmitpriv)
5078 struct xmit_frame *pmgntframe;
5079 struct xmit_buf *pxmitbuf;
5081 pmgntframe = rtw_alloc_xmitframe23a_ext(pxmitpriv);
5084 DBG_8723A(FUNC_ADPT_FMT" alloc xmitframe fail\n",
5085 FUNC_ADPT_ARG(pxmitpriv->adapter));
5089 pxmitbuf = rtw_alloc_xmitbuf23a_ext(pxmitpriv);
5091 DBG_8723A(FUNC_ADPT_FMT" alloc xmitbuf fail\n",
5092 FUNC_ADPT_ARG(pxmitpriv->adapter));
5093 rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
5098 pmgntframe->frame_tag = MGNT_FRAMETAG;
5099 pmgntframe->pxmitbuf = pxmitbuf;
5100 pmgntframe->buf_addr = pxmitbuf->pbuf;
5101 pxmitbuf->priv_data = pmgntframe;
5107 /****************************************************************************
5109 Following are some TX fuctions for WiFi MLME
5111 *****************************************************************************/
5113 void update_mgnt_tx_rate23a(struct rtw_adapter *padapter, u8 rate)
5115 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5117 pmlmeext->tx_rate = rate;
5118 DBG_8723A("%s(): rate = %x\n", __func__, rate);
5121 void update_mgntframe_attrib23a(struct rtw_adapter *padapter,
5122 struct pkt_attrib *pattrib)
5124 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5126 memset((u8 *)pattrib, 0, sizeof(struct pkt_attrib));
5128 pattrib->hdrlen = 24;
5129 pattrib->nr_frags = 1;
5130 pattrib->priority = 7;
5131 pattrib->mac_id = 0;
5132 pattrib->qsel = 0x12;
5134 pattrib->pktlen = 0;
5136 if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
5137 pattrib->raid = 6;/* b mode */
5139 pattrib->raid = 5;/* a/g mode */
5141 pattrib->encrypt = _NO_PRIVACY_;
5142 pattrib->bswenc = false;
5144 pattrib->qos_en = false;
5145 pattrib->ht_en = false;
5146 pattrib->bwmode = HT_CHANNEL_WIDTH_20;
5147 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5148 pattrib->sgi = false;
5150 pattrib->seqnum = pmlmeext->mgnt_seq;
5152 pattrib->retry_ctrl = true;
5155 void dump_mgntframe23a(struct rtw_adapter *padapter,
5156 struct xmit_frame *pmgntframe)
5158 if (padapter->bSurpriseRemoved == true ||
5159 padapter->bDriverStopped == true)
5162 rtw_hal_mgnt_xmit23a(padapter, pmgntframe);
5165 s32 dump_mgntframe23a_and_wait(struct rtw_adapter *padapter,
5166 struct xmit_frame *pmgntframe, int timeout_ms)
5170 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5171 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
5172 struct submit_ctx sctx;
5174 if (padapter->bSurpriseRemoved == true ||
5175 padapter->bDriverStopped == true)
5178 rtw_sctx_init23a(&sctx, timeout_ms);
5179 pxmitbuf->sctx = &sctx;
5181 ret = rtw_hal_mgnt_xmit23a(padapter, pmgntframe);
5183 if (ret == _SUCCESS)
5184 ret = rtw_sctx_wait23a(&sctx);
5186 spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL);
5187 pxmitbuf->sctx = NULL;
5188 spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL);
5193 s32 dump_mgntframe23a_and_wait_ack23a(struct rtw_adapter *padapter,
5194 struct xmit_frame *pmgntframe)
5197 u32 timeout_ms = 500;/* 500ms */
5198 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5200 if (padapter->bSurpriseRemoved == true ||
5201 padapter->bDriverStopped == true)
5204 mutex_lock(&pxmitpriv->ack_tx_mutex);
5205 pxmitpriv->ack_tx = true;
5207 pmgntframe->ack_report = 1;
5208 if (rtw_hal_mgnt_xmit23a(padapter, pmgntframe) == _SUCCESS) {
5209 ret = rtw_ack_tx_wait23a(pxmitpriv, timeout_ms);
5212 pxmitpriv->ack_tx = false;
5213 mutex_unlock(&pxmitpriv->ack_tx_mutex);
5218 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
5226 ssid_ie = rtw_get_ie23a(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
5228 /* DBG_8723A("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n",
5229 __func__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
5231 if (ssid_ie && ssid_len_ori > 0) {
5232 switch (hidden_ssid_mode)
5235 next_ie = ssid_ie + 2 + ssid_len_ori;
5238 remain_len = ies_len -(next_ie-ies);
5241 memcpy(ssid_ie+2, next_ie, remain_len);
5242 len_diff -= ssid_len_ori;
5246 memset(&ssid_ie[2], 0, ssid_len_ori);
5256 void issue_beacon23a(struct rtw_adapter *padapter, int timeout_ms)
5258 struct xmit_frame *pmgntframe;
5259 struct pkt_attrib *pattrib;
5260 unsigned char *pframe;
5261 struct ieee80211_hdr *pwlanhdr;
5262 unsigned short *fctrl;
5263 unsigned int rate_len;
5264 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5265 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5266 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5267 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5268 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
5269 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
5270 #ifdef CONFIG_8723AU_P2P
5271 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
5272 #endif /* CONFIG_8723AU_P2P */
5278 /* DBG_8723A("%s\n", __func__); */
5280 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL) {
5281 DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
5284 #ifdef CONFIG_8723AU_AP_MODE
5285 spin_lock_bh(&pmlmepriv->bcn_update_lock);
5288 /* update attribute */
5289 pattrib = &pmgntframe->attrib;
5290 update_mgntframe_attrib23a(padapter, pattrib);
5291 pattrib->qsel = 0x10;
5293 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5295 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5296 pwlanhdr = (struct ieee80211_hdr *)pframe;
5298 fctrl = &pwlanhdr->frame_control;
5301 ether_addr_copy(pwlanhdr->addr1, bc_addr);
5302 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
5303 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(cur_network));
5305 SetSeqNum(pwlanhdr, 0 /*pmlmeext->mgnt_seq*/);
5306 /* pmlmeext->mgnt_seq++; */
5307 SetFrameSubType(pframe, WIFI_BEACON);
5309 pframe += sizeof(struct ieee80211_hdr_3addr);
5310 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
5312 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) {
5313 /* DBG_8723A("ie len =%d\n", cur_network->IELength); */
5314 #ifdef CONFIG_8723AU_P2P
5315 /* for P2P : Primary Device Type & Device Name */
5317 wps_ie = rtw_get_wps_ie23a(cur_network->IEs + _FIXED_IE_LENGTH_,
5318 cur_network->IELength -
5319 _FIXED_IE_LENGTH_, NULL, &wps_ielen);
5321 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wps_ie &&
5323 uint wps_offset, remainder_ielen;
5324 u8 *premainder_ie, *pframe_wscie;
5326 wps_offset = (uint)(wps_ie - cur_network->IEs);
5328 premainder_ie = wps_ie + wps_ielen;
5330 remainder_ielen = cur_network->IELength - wps_offset -
5333 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled) {
5334 if (pmlmepriv->wps_beacon_ie &&
5335 pmlmepriv->wps_beacon_ie_len>0) {
5336 memcpy(pframe, cur_network->IEs,
5338 pframe += wps_offset;
5339 pattrib->pktlen += wps_offset;
5341 memcpy(pframe, pmlmepriv->wps_beacon_ie,
5342 pmlmepriv->wps_beacon_ie_len);
5343 pframe += pmlmepriv->wps_beacon_ie_len;
5345 pmlmepriv->wps_beacon_ie_len;
5347 /* copy remainder_ie to pframe */
5348 memcpy(pframe, premainder_ie,
5350 pframe += remainder_ielen;
5351 pattrib->pktlen += remainder_ielen;
5353 memcpy(pframe, cur_network->IEs,
5354 cur_network->IELength);
5355 pframe += cur_network->IELength;
5357 cur_network->IELength;
5360 pframe_wscie = pframe + wps_offset;
5361 memcpy(pframe, cur_network->IEs,
5362 wps_offset + wps_ielen);
5363 pframe += (wps_offset + wps_ielen);
5364 pattrib->pktlen += (wps_offset + wps_ielen);
5366 /* now pframe is end of wsc ie, insert Primary
5367 Device Type & Device Name */
5368 /* Primary Device Type */
5370 *(u16*) (pframe + insert_len) =
5371 cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
5375 *(u16*) (pframe + insert_len) =
5376 cpu_to_be16(0x0008);
5381 *(u16*) (pframe + insert_len) =
5382 cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
5386 *(u32*) (pframe + insert_len) =
5387 cpu_to_be32(WPSOUI);
5390 /* Sub Category ID */
5391 *(u16*) (pframe + insert_len) =
5392 cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
5397 *(u16*) (pframe + insert_len) =
5398 cpu_to_be16(WPS_ATTR_DEVICE_NAME);
5402 *(u16*) (pframe + insert_len) =
5403 cpu_to_be16(pwdinfo->device_name_len);
5407 memcpy(pframe + insert_len,
5408 pwdinfo->device_name,
5409 pwdinfo->device_name_len);
5410 insert_len += pwdinfo->device_name_len;
5412 /* update wsc ie length */
5413 *(pframe_wscie+1) = (wps_ielen -2) + insert_len;
5415 /* pframe move to end */
5416 pframe+= insert_len;
5417 pattrib->pktlen += insert_len;
5419 /* copy remainder_ie to pframe */
5420 memcpy(pframe, premainder_ie, remainder_ielen);
5421 pframe += remainder_ielen;
5422 pattrib->pktlen += remainder_ielen;
5425 #endif /* CONFIG_8723AU_P2P */
5426 memcpy(pframe, cur_network->IEs, cur_network->IELength);
5427 len_diff = update_hidden_ssid(pframe + _BEACON_IE_OFFSET_,
5428 cur_network->IELength -
5430 pmlmeinfo->hidden_ssid_mode);
5431 pframe += (cur_network->IELength+len_diff);
5432 pattrib->pktlen += (cur_network->IELength+len_diff);
5434 wps_ie = rtw_get_wps_ie23a(pmgntframe->buf_addr + TXDESC_OFFSET+
5435 sizeof (struct ieee80211_hdr_3addr) +
5436 _BEACON_IE_OFFSET_, pattrib->pktlen -
5437 sizeof (struct ieee80211_hdr_3addr) -
5438 _BEACON_IE_OFFSET_, NULL,
5440 if (wps_ie && wps_ielen > 0) {
5441 rtw_get_wps_attr_content23a(wps_ie, wps_ielen,
5442 WPS_ATTR_SELECTED_REGISTRAR,
5446 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
5448 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
5450 #ifdef CONFIG_8723AU_P2P
5451 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5453 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled) {
5454 len = pmlmepriv->p2p_beacon_ie_len;
5455 if (pmlmepriv->p2p_beacon_ie && len > 0)
5457 pmlmepriv->p2p_beacon_ie, len);
5459 len = build_beacon_p2p_ie23a(pwdinfo, pframe);
5462 pattrib->pktlen += len;
5464 if (true == pwdinfo->wfd_info->wfd_enable) {
5465 len = build_beacon_wfd_ie(pwdinfo, pframe);
5468 if (pmlmepriv->wfd_beacon_ie &&
5469 pmlmepriv->wfd_beacon_ie_len>0) {
5470 len = pmlmepriv->wfd_beacon_ie_len;
5472 pmlmepriv->wfd_beacon_ie, len);
5476 pattrib->pktlen += len;
5478 #endif /* CONFIG_8723AU_P2P */
5483 /* below for ad-hoc mode */
5485 /* timestamp will be inserted by hardware */
5487 pattrib->pktlen += 8;
5489 /* beacon interval: 2 bytes */
5491 memcpy(pframe, (unsigned char *)
5492 rtw_get_beacon_interval23a_from_ie(cur_network->IEs), 2);
5495 pattrib->pktlen += 2;
5497 /* capability info: 2 bytes */
5499 memcpy(pframe, (unsigned char *)
5500 rtw_get_capability23a_from_ie(cur_network->IEs), 2);
5503 pattrib->pktlen += 2;
5506 pframe = rtw_set_ie23a(pframe, _SSID_IE_, cur_network->Ssid.ssid_len,
5507 cur_network->Ssid.ssid, &pattrib->pktlen);
5509 /* supported rates... */
5510 rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
5511 pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_,
5512 ((rate_len > 8)? 8: rate_len),
5513 cur_network->SupportedRates, &pattrib->pktlen);
5515 /* DS parameter set */
5516 pframe = rtw_set_ie23a(pframe, _DSSET_IE_, 1, (unsigned char *)
5517 &cur_network->Configuration.DSConfig,
5520 /* if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
5524 /* IBSS Parameter Set... */
5525 /* ATIMWindow = cur->Configuration.ATIMWindow; */
5527 pframe = rtw_set_ie23a(pframe, _IBSS_PARA_IE_, 2,
5528 (unsigned char *)&ATIMWindow,
5532 pframe = rtw_set_ie23a(pframe, _ERPINFO_IE_, 1,
5533 &erpinfo, &pattrib->pktlen);
5536 /* EXTERNDED SUPPORTED RATE */
5538 pframe = rtw_set_ie23a(pframe, _EXT_SUPPORTEDRATES_IE_,
5540 cur_network->SupportedRates + 8,
5543 /* todo:HT for adhoc */
5547 #ifdef CONFIG_8723AU_AP_MODE
5548 pmlmepriv->update_bcn = false;
5550 spin_unlock_bh(&pmlmepriv->bcn_update_lock);
5553 if ((pattrib->pktlen + TXDESC_SIZE) > 512) {
5554 DBG_8723A("beacon frame too large\n");
5558 pattrib->last_txcmdsz = pattrib->pktlen;
5560 /* DBG_8723A("issue bcn_sz =%d\n", pattrib->last_txcmdsz); */
5562 dump_mgntframe23a_and_wait(padapter, pmgntframe, timeout_ms);
5564 dump_mgntframe23a(padapter, pmgntframe);
5567 void issue_probersp23a(struct rtw_adapter *padapter, unsigned char *da,
5568 u8 is_valid_p2p_probereq)
5570 struct xmit_frame *pmgntframe;
5571 struct pkt_attrib *pattrib;
5572 unsigned char *pframe;
5573 struct ieee80211_hdr *pwlanhdr;
5574 unsigned short *fctrl;
5575 unsigned char *mac, *bssid;
5576 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5577 #ifdef CONFIG_8723AU_AP_MODE
5582 int ssid_ielen_diff;
5586 #if defined(CONFIG_8723AU_AP_MODE) || defined(CONFIG_8723AU_P2P)
5587 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5589 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5590 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5591 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
5592 unsigned int rate_len;
5593 #ifdef CONFIG_8723AU_P2P
5594 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
5595 #endif /* CONFIG_8723AU_P2P */
5597 /* DBG_8723A("%s\n", __func__); */
5599 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
5601 DBG_8723A("%s, alloc mgnt frame fail\n", __func__);
5605 /* update attribute */
5606 pattrib = &pmgntframe->attrib;
5607 update_mgntframe_attrib23a(padapter, pattrib);
5609 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5611 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5612 pwlanhdr = (struct ieee80211_hdr *)pframe;
5614 mac = myid(&padapter->eeprompriv);
5615 bssid = cur_network->MacAddress;
5617 fctrl = &pwlanhdr->frame_control;
5619 ether_addr_copy(pwlanhdr->addr1, da);
5620 ether_addr_copy(pwlanhdr->addr2, mac);
5621 ether_addr_copy(pwlanhdr->addr3, bssid);
5623 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5624 pmlmeext->mgnt_seq++;
5625 SetFrameSubType(fctrl, WIFI_PROBERSP);
5627 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
5628 pattrib->pktlen = pattrib->hdrlen;
5629 pframe += pattrib->hdrlen;
5631 if (cur_network->IELength > MAX_IE_SZ)
5634 #ifdef CONFIG_8723AU_AP_MODE
5635 if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
5636 pwps_ie = rtw_get_wps_ie23a(cur_network->IEs +
5638 cur_network->IELength -
5639 _FIXED_IE_LENGTH_, NULL,
5642 /* inerset & update wps_probe_resp_ie */
5643 if ((pmlmepriv->wps_probe_resp_ie != NULL) && pwps_ie &&
5645 uint wps_offset, remainder_ielen;
5648 wps_offset = (uint)(pwps_ie - cur_network->IEs);
5650 premainder_ie = pwps_ie + wps_ielen;
5652 remainder_ielen = cur_network->IELength - wps_offset -
5655 memcpy(pframe, cur_network->IEs, wps_offset);
5656 pframe += wps_offset;
5657 pattrib->pktlen += wps_offset;
5659 /* to get ie data len */
5660 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];
5661 if ((wps_offset+wps_ielen+2)<= MAX_IE_SZ) {
5662 memcpy(pframe, pmlmepriv->wps_probe_resp_ie,
5664 pframe += wps_ielen+2;
5665 pattrib->pktlen += wps_ielen+2;
5668 if ((wps_offset+wps_ielen+2+remainder_ielen) <=
5670 memcpy(pframe, premainder_ie, remainder_ielen);
5671 pframe += remainder_ielen;
5672 pattrib->pktlen += remainder_ielen;
5675 memcpy(pframe, cur_network->IEs, cur_network->IELength);
5676 pframe += cur_network->IELength;
5677 pattrib->pktlen += cur_network->IELength;
5680 /* retrieve SSID IE from cur_network->Ssid */
5681 ies = pmgntframe->buf_addr + TXDESC_OFFSET +
5682 sizeof(struct ieee80211_hdr_3addr);
5684 ssid_ie = rtw_get_ie23a(ies+_FIXED_IE_LENGTH_, _SSID_IE_,
5686 (pframe-ies)-_FIXED_IE_LENGTH_);
5688 ssid_ielen_diff = cur_network->Ssid.ssid_len - ssid_ielen;
5690 if (ssid_ie && cur_network->Ssid.ssid_len) {
5691 uint remainder_ielen;
5693 remainder_ie = ssid_ie + 2;
5694 remainder_ielen = (pframe-remainder_ie);
5696 DBG_8723A_LEVEL(_drv_warning_, FUNC_ADPT_FMT
5697 " remainder_ielen > MAX_IE_SZ\n",
5698 FUNC_ADPT_ARG(padapter));
5699 if (remainder_ielen > MAX_IE_SZ) {
5700 remainder_ielen = MAX_IE_SZ;
5703 memcpy(buf, remainder_ie, remainder_ielen);
5704 memcpy(remainder_ie+ssid_ielen_diff, buf,
5706 *(ssid_ie+1) = cur_network->Ssid.ssid_len;
5707 memcpy(ssid_ie+2, cur_network->Ssid.ssid,
5708 cur_network->Ssid.ssid_len);
5710 pframe += ssid_ielen_diff;
5711 pattrib->pktlen += ssid_ielen_diff;
5717 /* timestamp will be inserted by hardware */
5719 pattrib->pktlen += 8;
5721 /* beacon interval: 2 bytes */
5723 memcpy(pframe, (unsigned char *)
5724 rtw_get_beacon_interval23a_from_ie(cur_network->IEs), 2);
5727 pattrib->pktlen += 2;
5729 /* capability info: 2 bytes */
5731 memcpy(pframe, (unsigned char *)
5732 rtw_get_capability23a_from_ie(cur_network->IEs), 2);
5735 pattrib->pktlen += 2;
5737 /* below for ad-hoc mode */
5740 pframe = rtw_set_ie23a(pframe, _SSID_IE_,
5741 cur_network->Ssid.ssid_len,
5742 cur_network->Ssid.ssid, &pattrib->pktlen);
5744 /* supported rates... */
5745 rate_len = rtw_get_rateset_len23a(cur_network->SupportedRates);
5746 pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_,
5747 ((rate_len > 8)? 8: rate_len),
5748 cur_network->SupportedRates,
5751 /* DS parameter set */
5752 pframe = rtw_set_ie23a(pframe, _DSSET_IE_, 1, (unsigned char *)
5753 &cur_network->Configuration.DSConfig,
5756 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) {
5759 /* IBSS Parameter Set... */
5760 /* ATIMWindow = cur->Configuration.ATIMWindow; */
5762 pframe = rtw_set_ie23a(pframe, _IBSS_PARA_IE_, 2,
5763 (unsigned char *)&ATIMWindow,
5767 pframe = rtw_set_ie23a(pframe, _ERPINFO_IE_, 1,
5768 &erpinfo, &pattrib->pktlen);
5771 /* EXTERNDED SUPPORTED RATE */
5773 pframe = rtw_set_ie23a(pframe, _EXT_SUPPORTEDRATES_IE_,
5775 cur_network->SupportedRates + 8,
5778 /* todo:HT for adhoc */
5781 #ifdef CONFIG_8723AU_P2P
5782 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && is_valid_p2p_probereq) {
5784 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled) {
5785 /* if pwdinfo->role == P2P_ROLE_DEVICE will call
5786 issue_probersp23a_p2p23a() */
5787 len = pmlmepriv->p2p_go_probe_resp_ie_len;
5788 if (pmlmepriv->p2p_go_probe_resp_ie && len>0)
5789 memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie,
5792 len = build_probe_resp_p2p_ie23a(pwdinfo, pframe);
5795 pattrib->pktlen += len;
5797 if (true == pwdinfo->wfd_info->wfd_enable) {
5798 len = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
5801 if (pmlmepriv->wfd_probe_resp_ie &&
5802 pmlmepriv->wfd_probe_resp_ie_len > 0) {
5803 len = pmlmepriv->wfd_probe_resp_ie_len;
5804 memcpy(pframe, pmlmepriv->wfd_probe_resp_ie,
5809 pattrib->pktlen += len;
5811 #endif /* CONFIG_8723AU_P2P */
5813 pattrib->last_txcmdsz = pattrib->pktlen;
5815 dump_mgntframe23a(padapter, pmgntframe);
5820 static int _issue_probereq23a(struct rtw_adapter *padapter,
5821 struct cfg80211_ssid *pssid, u8 *da, int wait_ack)
5824 struct xmit_frame *pmgntframe;
5825 struct pkt_attrib *pattrib;
5826 unsigned char *pframe;
5827 struct ieee80211_hdr *pwlanhdr;
5828 unsigned short *fctrl;
5830 unsigned char bssrate[NumRates];
5831 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5832 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5833 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5834 int bssrate_len = 0;
5835 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
5837 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
5838 ("+issue_probereq23a\n"));
5840 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
5843 /* update attribute */
5844 pattrib = &pmgntframe->attrib;
5845 update_mgntframe_attrib23a(padapter, pattrib);
5847 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5849 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5850 pwlanhdr = (struct ieee80211_hdr *)pframe;
5852 mac = myid(&padapter->eeprompriv);
5854 fctrl = &pwlanhdr->frame_control;
5858 /* unicast probe request frame */
5859 ether_addr_copy(pwlanhdr->addr1, da);
5860 ether_addr_copy(pwlanhdr->addr3, da);
5862 /* broadcast probe request frame */
5863 ether_addr_copy(pwlanhdr->addr1, bc_addr);
5864 ether_addr_copy(pwlanhdr->addr3, bc_addr);
5867 ether_addr_copy(pwlanhdr->addr2, mac);
5869 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5870 pmlmeext->mgnt_seq++;
5871 SetFrameSubType(pframe, WIFI_PROBEREQ);
5873 pframe += sizeof (struct ieee80211_hdr_3addr);
5874 pattrib->pktlen = sizeof (struct ieee80211_hdr_3addr);
5877 pframe = rtw_set_ie23a(pframe, _SSID_IE_, pssid->ssid_len,
5878 pssid->ssid, &pattrib->pktlen);
5880 pframe = rtw_set_ie23a(pframe, _SSID_IE_, 0, NULL,
5883 get_rate_set23a(padapter, bssrate, &bssrate_len);
5885 if (bssrate_len > 8) {
5886 pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_, 8,
5887 bssrate, &pattrib->pktlen);
5888 pframe = rtw_set_ie23a(pframe, _EXT_SUPPORTEDRATES_IE_,
5889 (bssrate_len - 8), (bssrate + 8),
5892 pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_,
5893 bssrate_len, bssrate, &pattrib->pktlen);
5896 /* add wps_ie for wps2.0 */
5897 if (pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie) {
5898 memcpy(pframe, pmlmepriv->wps_probe_req_ie,
5899 pmlmepriv->wps_probe_req_ie_len);
5900 pframe += pmlmepriv->wps_probe_req_ie_len;
5901 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
5904 pattrib->last_txcmdsz = pattrib->pktlen;
5906 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
5907 ("issuing probe_req, tx_len =%d\n", pattrib->last_txcmdsz));
5910 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
5912 dump_mgntframe23a(padapter, pmgntframe);
5920 inline void issue_probereq23a(struct rtw_adapter *padapter,
5921 struct cfg80211_ssid *pssid, u8 *da)
5923 _issue_probereq23a(padapter, pssid, da, false);
5926 int issue_probereq23a_ex23a(struct rtw_adapter *padapter,
5927 struct cfg80211_ssid *pssid, u8 *da,
5928 int try_cnt, int wait_ms)
5932 unsigned long start = jiffies;
5935 ret = _issue_probereq23a(padapter, pssid, da,
5936 wait_ms > 0 ? true : false);
5940 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
5943 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
5946 } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
5953 if (try_cnt && wait_ms) {
5955 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d "
5956 "in %u ms\n", FUNC_ADPT_ARG(padapter),
5957 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
5958 ret == _SUCCESS?", acked":"", i, try_cnt,
5959 jiffies_to_msecs(jiffies - start));
5961 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
5962 FUNC_ADPT_ARG(padapter),
5963 rtw_get_oper_ch23a(padapter),
5964 ret == _SUCCESS?", acked":"", i, try_cnt,
5965 jiffies_to_msecs(jiffies - start));
5971 /* if psta == NULL, indiate we are station(client) now... */
5972 void issue_auth23a(struct rtw_adapter *padapter, struct sta_info *psta,
5973 unsigned short status)
5975 struct xmit_frame *pmgntframe;
5976 struct pkt_attrib *pattrib;
5977 unsigned char *pframe;
5978 struct ieee80211_hdr *pwlanhdr;
5979 unsigned short *fctrl;
5981 unsigned short val16;
5982 int use_shared_key = 0;
5983 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5984 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5985 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
5987 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
5990 /* update attribute */
5991 pattrib = &pmgntframe->attrib;
5992 update_mgntframe_attrib23a(padapter, pattrib);
5994 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5996 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5997 pwlanhdr = (struct ieee80211_hdr *)pframe;
5999 fctrl = &pwlanhdr->frame_control;
6002 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6003 pmlmeext->mgnt_seq++;
6004 SetFrameSubType(pframe, WIFI_AUTH);
6006 pframe += sizeof(struct ieee80211_hdr_3addr);
6007 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
6009 if (psta) { /* for AP mode */
6010 #ifdef CONFIG_8723AU_AP_MODE
6012 ether_addr_copy(pwlanhdr->addr1, psta->hwaddr);
6013 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
6014 ether_addr_copy(pwlanhdr->addr3, myid(&padapter->eeprompriv));
6016 /* setting auth algo number */
6017 val16 = (u16)psta->authalg;
6019 if (status != WLAN_STATUS_SUCCESS)
6023 val16 = cpu_to_le16(val16);
6027 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_ALGM_NUM_,
6028 (unsigned char *)&val16,
6031 /* setting auth seq number */
6032 val16 = (u16)psta->auth_seq;
6033 val16 = cpu_to_le16(val16);
6034 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_SEQ_NUM_,
6035 (unsigned char *)&val16,
6038 /* setting status code... */
6040 val16 = cpu_to_le16(val16);
6041 pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
6042 (unsigned char *)&val16,
6045 /* added challenging text... */
6046 if ((psta->auth_seq == 2) &&
6047 (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
6048 pframe = rtw_set_ie23a(pframe, _CHLGETXT_IE_, 128,
6049 psta->chg_txt, &pattrib->pktlen);
6052 ether_addr_copy(pwlanhdr->addr1,
6053 get_my_bssid23a(&pmlmeinfo->network));
6054 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
6055 ether_addr_copy(pwlanhdr->addr3,
6056 get_my_bssid23a(&pmlmeinfo->network));
6058 /* setting auth algo number */
6059 /* 0:OPEN System, 1:Shared key */
6060 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;
6062 val16 = cpu_to_le16(val16);
6065 /* DBG_8723A("%s auth_algo = %s auth_seq =%d\n", __func__,
6066 (pmlmeinfo->auth_algo == 0)?"OPEN":"SHARED",
6067 pmlmeinfo->auth_seq); */
6069 /* setting IV for auth seq #3 */
6070 if ((pmlmeinfo->auth_seq == 3) &&
6071 (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
6072 (use_shared_key == 1)) {
6073 /* DBG_8723A("==> iv(%d), key_index(%d)\n",
6074 pmlmeinfo->iv, pmlmeinfo->key_index); */
6075 val32 = ((pmlmeinfo->iv++) |
6076 (pmlmeinfo->key_index << 30));
6077 val32 = cpu_to_le32(val32);
6078 pframe = rtw_set_fixed_ie23a(pframe, 4,
6079 (unsigned char *)&val32,
6082 pattrib->iv_len = 4;
6085 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_ALGM_NUM_,
6086 (unsigned char *)&val16,
6089 /* setting auth seq number */
6090 val16 = pmlmeinfo->auth_seq;
6091 val16 = cpu_to_le16(val16);
6092 pframe = rtw_set_fixed_ie23a(pframe, _AUTH_SEQ_NUM_,
6093 (unsigned char *)&val16,
6096 /* setting status code... */
6098 val16 = cpu_to_le16(val16);
6099 pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
6100 (unsigned char *)&val16,
6103 /* then checking to see if sending challenging text... */
6104 if ((pmlmeinfo->auth_seq == 3) &&
6105 (pmlmeinfo->state & WIFI_FW_AUTH_STATE) &&
6106 (use_shared_key == 1)) {
6107 pframe = rtw_set_ie23a(pframe, _CHLGETXT_IE_, 128,
6113 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
6115 pattrib->encrypt = _WEP40_;
6117 pattrib->icv_len = 4;
6119 pattrib->pktlen += pattrib->icv_len;
6123 pattrib->last_txcmdsz = pattrib->pktlen;
6125 rtw_wep_encrypt23a(padapter, pmgntframe);
6126 DBG_8723A("%s\n", __func__);
6127 dump_mgntframe23a(padapter, pmgntframe);
6132 void issue_asocrsp23a(struct rtw_adapter *padapter, unsigned short status,
6133 struct sta_info *pstat, int pkt_type)
6135 #ifdef CONFIG_8723AU_AP_MODE
6136 struct xmit_frame *pmgntframe;
6137 struct ieee80211_hdr *pwlanhdr;
6138 struct pkt_attrib *pattrib;
6139 unsigned char *pbuf, *pframe;
6141 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6142 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6143 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6144 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6145 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
6146 u8 *ie = pnetwork->IEs;
6147 #ifdef CONFIG_8723AU_P2P
6148 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
6150 #endif /* CONFIG_8723AU_P2P */
6152 DBG_8723A("%s\n", __func__);
6154 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
6157 /* update attribute */
6158 pattrib = &pmgntframe->attrib;
6159 update_mgntframe_attrib23a(padapter, pattrib);
6161 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6163 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6164 pwlanhdr = (struct ieee80211_hdr *)pframe;
6166 pwlanhdr->frame_control = 0;
6168 ether_addr_copy(pwlanhdr->addr1, pstat->hwaddr);
6169 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
6170 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
6172 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6173 pmlmeext->mgnt_seq++;
6174 if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
6175 SetFrameSubType(pwlanhdr, pkt_type);
6179 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
6180 pattrib->pktlen += pattrib->hdrlen;
6181 pframe += pattrib->hdrlen;
6184 val = *(unsigned short *)rtw_get_capability23a_from_ie(ie);
6186 pframe = rtw_set_fixed_ie23a(pframe, _CAPABILITY_,
6187 (unsigned char *)&val, &pattrib->pktlen);
6189 status = cpu_to_le16(status);
6190 pframe = rtw_set_fixed_ie23a(pframe, _STATUS_CODE_,
6191 (unsigned char *)&status,
6194 val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
6195 pframe = rtw_set_fixed_ie23a(pframe, _ASOC_ID_, (unsigned char *)&val,
6198 if (pstat->bssratelen <= 8) {
6199 pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_,
6200 pstat->bssratelen, pstat->bssrateset,
6203 pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_, 8,
6204 pstat->bssrateset, &pattrib->pktlen);
6205 pframe = rtw_set_ie23a(pframe, _EXT_SUPPORTEDRATES_IE_,
6206 pstat->bssratelen - 8,
6207 pstat->bssrateset + 8, &pattrib->pktlen);
6210 if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) {
6213 /* FILL HT CAP INFO IE */
6214 /* p = hostapd_eid_ht_capabilities_info(hapd, p); */
6215 pbuf = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_,
6216 _HT_CAPABILITY_IE_, &ie_len,
6217 pnetwork->IELength - _BEACON_IE_OFFSET_);
6218 if (pbuf && ie_len>0) {
6219 memcpy(pframe, pbuf, ie_len + 2);
6220 pframe += (ie_len + 2);
6221 pattrib->pktlen += (ie_len + 2);
6224 /* FILL HT ADD INFO IE */
6225 /* p = hostapd_eid_ht_operation(hapd, p); */
6226 pbuf = rtw_get_ie23a(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_,
6228 pnetwork->IELength - _BEACON_IE_OFFSET_);
6229 if (pbuf && ie_len > 0) {
6230 memcpy(pframe, pbuf, ie_len + 2);
6231 pframe += (ie_len + 2);
6232 pattrib->pktlen += (ie_len + 2);
6237 if ((pstat->flags & WLAN_STA_WME) && pmlmepriv->qospriv.qos_option) {
6239 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02,
6242 for (pbuf = ie + _BEACON_IE_OFFSET_; ; pbuf += (ie_len + 2)) {
6243 pbuf = rtw_get_ie23a(pbuf, _VENDOR_SPECIFIC_IE_,
6244 &ie_len, (pnetwork->IELength -
6245 _BEACON_IE_OFFSET_ -
6247 if (pbuf && !memcmp(pbuf + 2, WMM_PARA_IE, 6)) {
6248 memcpy(pframe, pbuf, ie_len + 2);
6249 pframe += (ie_len + 2);
6250 pattrib->pktlen += (ie_len + 2);
6255 if ((!pbuf) || (ie_len == 0))
6260 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) {
6261 pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, 6,
6262 REALTEK_96B_IE23A, &pattrib->pktlen);
6265 /* add WPS IE ie for wps 2.0 */
6266 if (pmlmepriv->wps_assoc_resp_ie &&
6267 pmlmepriv->wps_assoc_resp_ie_len > 0) {
6268 memcpy(pframe, pmlmepriv->wps_assoc_resp_ie,
6269 pmlmepriv->wps_assoc_resp_ie_len);
6271 pframe += pmlmepriv->wps_assoc_resp_ie_len;
6272 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
6275 #ifdef CONFIG_8723AU_P2P
6276 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) &&
6277 pwdinfo->wfd_info->wfd_enable) {
6278 wfdielen = build_assoc_resp_wfd_ie(pwdinfo, pframe);
6280 pattrib->pktlen += wfdielen;
6282 #endif /* CONFIG_8723AU_P2P */
6284 pattrib->last_txcmdsz = pattrib->pktlen;
6286 dump_mgntframe23a(padapter, pmgntframe);
6290 void issue_assocreq23a(struct rtw_adapter *padapter)
6293 struct xmit_frame *pmgntframe;
6294 struct pkt_attrib *pattrib;
6295 unsigned char *pframe, *p;
6296 struct ieee80211_hdr *pwlanhdr;
6297 unsigned short *fctrl;
6298 unsigned short val16;
6299 unsigned int i, j, ie_len, index = 0;
6300 unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
6301 struct ndis_802_11_var_ies *pIE;
6302 struct registry_priv *pregpriv = &padapter->registrypriv;
6303 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6304 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6305 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6306 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6307 int bssrate_len = 0, sta_bssrate_len = 0;
6308 #ifdef CONFIG_8723AU_P2P
6309 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
6310 u8 p2pie[255] = { 0x00 };
6313 #endif /* CONFIG_8723AU_P2P */
6315 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
6318 /* update attribute */
6319 pattrib = &pmgntframe->attrib;
6320 update_mgntframe_attrib23a(padapter, pattrib);
6322 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6324 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6325 pwlanhdr = (struct ieee80211_hdr *)pframe;
6327 fctrl = &pwlanhdr->frame_control;
6329 ether_addr_copy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network));
6330 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
6331 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
6333 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6334 pmlmeext->mgnt_seq++;
6335 SetFrameSubType(pframe, WIFI_ASSOCREQ);
6337 pframe += sizeof(struct ieee80211_hdr_3addr);
6338 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
6341 memcpy(pframe, rtw_get_capability23a_from_ie(pmlmeinfo->network.IEs),
6345 pattrib->pktlen += 2;
6347 /* listen interval */
6348 /* todo: listen interval for power saving */
6349 val16 = cpu_to_le16(3);
6350 memcpy(pframe, (unsigned char *)&val16, 2);
6352 pattrib->pktlen += 2;
6355 pframe = rtw_set_ie23a(pframe, _SSID_IE_,
6356 pmlmeinfo->network.Ssid.ssid_len,
6357 pmlmeinfo->network.Ssid.ssid, &pattrib->pktlen);
6359 /* supported rate & extended supported rate */
6361 get_rate_set23a(padapter, sta_bssrate, &sta_bssrate_len);
6362 /* DBG_8723A("sta_bssrate_len =%d\n", sta_bssrate_len); */
6364 /* for JAPAN, channel 14 can only uses B Mode(CCK) */
6365 if (pmlmeext->cur_channel == 14)
6366 sta_bssrate_len = 4;
6368 /* for (i = 0; i < sta_bssrate_len; i++) { */
6369 /* DBG_8723A("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
6372 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
6373 if (pmlmeinfo->network.SupportedRates[i] == 0)
6375 DBG_8723A("network.SupportedRates[%d]=%02X\n", i,
6376 pmlmeinfo->network.SupportedRates[i]);
6379 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
6380 if (pmlmeinfo->network.SupportedRates[i] == 0)
6383 /* Check if the AP's supported rates are also
6384 supported by STA. */
6385 for (j = 0; j < sta_bssrate_len; j++) {
6386 /* Avoid the proprietary data rate (22Mbps) of
6387 Handlink WSG-4000 AP */
6388 if ((pmlmeinfo->network.SupportedRates[i] |
6389 IEEE80211_BASIC_RATE_MASK) ==
6390 (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) {
6391 /* DBG_8723A("match i = %d, j =%d\n", i, j); */
6396 if (j == sta_bssrate_len) {
6397 /* the rate is not supported by STA */
6398 DBG_8723A("%s(): the rate[%d]=%02X is not supported by "
6399 "STA!\n", __func__, i,
6400 pmlmeinfo->network.SupportedRates[i]);
6402 /* the rate is supported by STA */
6403 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
6407 bssrate_len = index;
6408 DBG_8723A("bssrate_len = %d\n", bssrate_len);
6410 if (bssrate_len == 0) {
6411 rtw_free_xmitbuf23a(pxmitpriv, pmgntframe->pxmitbuf);
6412 rtw_free_xmitframe23a(pxmitpriv, pmgntframe);
6413 goto exit; /* don't connect to AP if no joint supported rate */
6416 if (bssrate_len > 8) {
6417 pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_, 8,
6418 bssrate, &pattrib->pktlen);
6419 pframe = rtw_set_ie23a(pframe, _EXT_SUPPORTEDRATES_IE_,
6420 (bssrate_len - 8), (bssrate + 8),
6423 pframe = rtw_set_ie23a(pframe, _SUPPORTEDRATES_IE_,
6424 bssrate_len, bssrate, &pattrib->pktlen);
6427 p = rtw_get_ie23a((pmlmeinfo->network.IEs +
6428 sizeof(struct ndis_802_11_fixed_ies)), _RSN_IE_2_,
6429 &ie_len, (pmlmeinfo->network.IELength -
6430 sizeof(struct ndis_802_11_fixed_ies)));
6432 pframe = rtw_set_ie23a(pframe, _RSN_IE_2_, ie_len, (p + 2),
6436 if (padapter->mlmepriv.htpriv.ht_option == true) {
6437 p = rtw_get_ie23a((pmlmeinfo->network.IEs +
6438 sizeof(struct ndis_802_11_fixed_ies)),
6439 _HT_CAPABILITY_IE_, &ie_len,
6440 (pmlmeinfo->network.IELength -
6441 sizeof(struct ndis_802_11_fixed_ies)));
6442 if ((p != NULL) && (!(is_ap_in_tkip23a(padapter)))) {
6443 memcpy(&pmlmeinfo->HT_caps, (p + 2),
6444 sizeof(struct HT_caps_element));
6446 /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
6447 if (pregpriv->cbw40_enable == 0) {
6448 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &= (~(BIT(6) | BIT(1)));
6450 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= BIT(1);
6453 /* todo: disable SM power save mode */
6454 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |=
6457 rtw23a_hal_get_hwreg(padapter, HW_VAR_RF_TYPE,
6459 /* switch (pregpriv->rf_config) */
6464 if (pregpriv->rx_stbc)
6465 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);/* RX STBC One spatial stream */
6467 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R23A, 16);
6474 /* enable for 2.4/5 GHz */
6475 if ((pregpriv->rx_stbc == 0x3) ||
6476 ((pmlmeext->cur_wireless_mode &
6478 /* enable for 2.4GHz */
6479 (pregpriv->rx_stbc == 0x1)) ||
6480 ((pmlmeext->cur_wireless_mode &
6482 (pregpriv->rx_stbc == 0x2)) ||
6483 /* enable for 5GHz */
6484 (pregpriv->wifi_spec == 1)) {
6485 DBG_8723A("declare supporting RX "
6487 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0200);/* RX STBC two spatial stream */
6489 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R23A, 16);
6492 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info =
6493 cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
6495 #ifdef CONFIG_8723AU_BT_COEXIST
6496 if (BT_1Ant(padapter) == true) {
6498 pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para &= (u8)~IEEE80211_HT_AMPDU_PARM_FACTOR;
6499 /* pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para |= MAX_AMPDU_FACTOR_8K */
6503 pframe = rtw_set_ie23a(pframe, _HT_CAPABILITY_IE_,
6505 (u8 *)&pmlmeinfo->HT_caps,
6510 /* vendor specific IE, such as WPA, WMM, WPS */
6511 for (i = sizeof(struct ndis_802_11_fixed_ies);
6512 i < pmlmeinfo->network.IELength;) {
6513 pIE = (struct ndis_802_11_var_ies *)
6514 (pmlmeinfo->network.IEs + i);
6516 switch (pIE->ElementID)
6518 case _VENDOR_SPECIFIC_IE_:
6519 if (!memcmp(pIE->data, RTW_WPA_OUI23A, 4) ||
6520 !memcmp(pIE->data, WMM_OUI23A, 4) ||
6521 !memcmp(pIE->data, WPS_OUI23A, 4)) {
6522 if (!padapter->registrypriv.wifi_spec) {
6523 /* Commented by Kurt 20110629 */
6524 /* In some older APs, WPS handshake */
6525 /* would be fail if we append vender
6526 extensions informations to AP */
6527 if (!memcmp(pIE->data, WPS_OUI23A, 4))
6530 pframe = rtw_set_ie23a(pframe,
6531 _VENDOR_SPECIFIC_IE_,
6532 pIE->Length, pIE->data,
6541 i += (pIE->Length + 2);
6544 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
6545 pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_, 6,
6546 REALTEK_96B_IE23A, &pattrib->pktlen);
6548 #ifdef CONFIG_8723AU_P2P
6550 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled) {
6551 if (pmlmepriv->p2p_assoc_req_ie &&
6552 pmlmepriv->p2p_assoc_req_ie_len>0) {
6553 memcpy(pframe, pmlmepriv->p2p_assoc_req_ie,
6554 pmlmepriv->p2p_assoc_req_ie_len);
6555 pframe += pmlmepriv->p2p_assoc_req_ie_len;
6556 pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
6559 if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
6560 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
6561 /* Should add the P2P IE in the association
6566 p2pie[p2pielen++] = 0x50;
6567 p2pie[p2pielen++] = 0x6F;
6568 p2pie[p2pielen++] = 0x9A;
6569 p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
6571 /* Commented by Albert 20101109 */
6572 /* According to the P2P Specification, the
6573 association request frame should contain
6575 /* 1. P2P Capability */
6576 /* 2. Extended Listen Timing */
6577 /* 3. Device Info */
6578 /* Commented by Albert 20110516 */
6579 /* 4. P2P Interface */
6581 /* P2P Capability */
6583 p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
6586 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0002);
6590 /* Device Capability Bitmap, 1 byte */
6591 p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
6593 /* Group Capability Bitmap, 1 byte */
6594 if (pwdinfo->persistent_supported)
6596 P2P_GRPCAP_PERSISTENT_GROUP |
6597 DMP_P2P_GRPCAP_SUPPORT;
6599 p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
6601 /* Extended Listen Timing */
6603 p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
6606 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x0004);
6610 /* Availability Period */
6611 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF);
6614 /* Availability Interval */
6615 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0xFFFF);
6620 p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
6623 /* 21 -> P2P Device Address (6bytes) + Config
6624 Methods (2bytes) + Primary Device
6626 /* + NumofSecondDevType (1byte) + WPS Device
6627 Name ID field (2bytes) + WPS Device Name
6628 Len field (2bytes) */
6629 *(u16*) (p2pie + p2pielen) =
6630 cpu_to_le16(21 + pwdinfo->device_name_len);
6634 /* P2P Device Address */
6635 memcpy(p2pie + p2pielen,
6636 myid(&padapter->eeprompriv), ETH_ALEN);
6637 p2pielen += ETH_ALEN;
6640 /* This field should be big endian.
6641 Noted by P2P specification. */
6642 if ((pwdinfo->ui_got_wps_info ==
6643 P2P_GOT_WPSINFO_PEER_DISPLAY_PIN) ||
6644 (pwdinfo->ui_got_wps_info ==
6645 P2P_GOT_WPSINFO_SELF_DISPLAY_PIN))
6646 *(u16*) (p2pie + p2pielen) =
6647 cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
6649 *(u16*) (p2pie + p2pielen) =
6650 cpu_to_be16(WPS_CONFIG_METHOD_PBC);
6654 /* Primary Device Type */
6656 *(u16*) (p2pie + p2pielen) =
6657 cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
6661 *(u32*) (p2pie + p2pielen) = cpu_to_be32(WPSOUI);
6664 /* Sub Category ID */
6665 *(u16*) (p2pie + p2pielen) =
6666 cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
6669 /* Number of Secondary Device Types */
6670 /* No Secondary Device Type List */
6671 p2pie[p2pielen++] = 0x00;
6675 *(u16*) (p2pie + p2pielen) =
6676 cpu_to_be16(WPS_ATTR_DEVICE_NAME);
6680 *(u16*) (p2pie + p2pielen) =
6681 cpu_to_be16(pwdinfo->device_name_len);
6685 memcpy(p2pie + p2pielen, pwdinfo->device_name,
6686 pwdinfo->device_name_len);
6687 p2pielen += pwdinfo->device_name_len;
6691 p2pie[p2pielen++] = P2P_ATTR_INTERFACE;
6694 *(u16*) (p2pie + p2pielen) = cpu_to_le16(0x000D);
6698 memcpy(p2pie + p2pielen, pwdinfo->device_addr,
6699 ETH_ALEN); /* P2P Device Address */
6700 p2pielen += ETH_ALEN;
6702 /* P2P Interface Address Count */
6703 p2pie[p2pielen++] = 1;
6705 memcpy(p2pie + p2pielen, pwdinfo->device_addr,
6706 ETH_ALEN); /* P2P Interface Address List */
6707 p2pielen += ETH_ALEN;
6709 pframe = rtw_set_ie23a(pframe, _VENDOR_SPECIFIC_IE_,
6710 p2pielen, (unsigned char *)p2pie,
6713 /* wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);*/
6714 /* pframe += wfdielen; */
6715 /* pattrib->pktlen += wfdielen; */
6719 if (true == pwdinfo->wfd_info->wfd_enable) {
6720 wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);
6722 pattrib->pktlen += wfdielen;
6723 } else if (pmlmepriv->wfd_assoc_req_ie != NULL &&
6724 pmlmepriv->wfd_assoc_req_ie_len > 0) {
6726 memcpy(pframe, pmlmepriv->wfd_assoc_req_ie,
6727 pmlmepriv->wfd_assoc_req_ie_len);
6728 pattrib->pktlen += pmlmepriv->wfd_assoc_req_ie_len;
6729 pframe += pmlmepriv->wfd_assoc_req_ie_len;
6731 #endif /* CONFIG_8723AU_P2P */
6733 pattrib->last_txcmdsz = pattrib->pktlen;
6734 dump_mgntframe23a(padapter, pmgntframe);
6739 pmlmepriv->assoc_req_len = 0;
6740 if (ret == _SUCCESS) {
6741 kfree(pmlmepriv->assoc_req);
6742 pmlmepriv->assoc_req = kmalloc(pattrib->pktlen, GFP_ATOMIC);
6743 if (pmlmepriv->assoc_req) {
6744 memcpy(pmlmepriv->assoc_req, pwlanhdr,
6746 pmlmepriv->assoc_req_len = pattrib->pktlen;
6749 kfree(pmlmepriv->assoc_req);
6754 /* when wait_ack is ture, this function shoule be called at process context */
6755 static int _issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
6756 unsigned int power_mode, int wait_ack)
6759 struct xmit_frame *pmgntframe;
6760 struct pkt_attrib *pattrib;
6761 unsigned char *pframe;
6762 struct ieee80211_hdr *pwlanhdr;
6763 unsigned short *fctrl;
6764 struct xmit_priv *pxmitpriv;
6765 struct mlme_ext_priv *pmlmeext;
6766 struct mlme_ext_info *pmlmeinfo;
6768 /* DBG_8723A("%s:%d\n", __func__, power_mode); */
6773 pxmitpriv = &padapter->xmitpriv;
6774 pmlmeext = &padapter->mlmeextpriv;
6775 pmlmeinfo = &pmlmeext->mlmext_info;
6777 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
6780 /* update attribute */
6781 pattrib = &pmgntframe->attrib;
6782 update_mgntframe_attrib23a(padapter, pattrib);
6783 pattrib->retry_ctrl = false;
6785 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6787 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6788 pwlanhdr = (struct ieee80211_hdr *)pframe;
6790 fctrl = &pwlanhdr->frame_control;
6793 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
6795 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
6801 ether_addr_copy(pwlanhdr->addr1, da);
6802 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
6803 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
6805 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6806 pmlmeext->mgnt_seq++;
6807 SetFrameSubType(pframe, WIFI_DATA_NULL);
6809 pframe += sizeof(struct ieee80211_hdr_3addr);
6810 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
6812 pattrib->last_txcmdsz = pattrib->pktlen;
6815 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
6817 dump_mgntframe23a(padapter, pmgntframe);
6825 /* when wait_ms >0 , this function shoule be called at process context */
6826 /* da == NULL for station mode */
6827 int issue_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
6828 unsigned int power_mode, int try_cnt, int wait_ms)
6832 unsigned long start = jiffies;
6833 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6834 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6836 /* da == NULL, assum it's null data for sta to ap*/
6838 da = get_my_bssid23a(&pmlmeinfo->network);
6841 ret = _issue_nulldata23a(padapter, da, power_mode,
6842 wait_ms > 0 ? true : false);
6846 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
6849 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
6852 } while((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
6859 if (try_cnt && wait_ms) {
6861 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d "
6862 "in %u ms\n", FUNC_ADPT_ARG(padapter),
6863 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
6864 ret == _SUCCESS?", acked":"", i, try_cnt,
6865 jiffies_to_msecs(jiffies - start));
6867 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
6868 FUNC_ADPT_ARG(padapter),
6869 rtw_get_oper_ch23a(padapter),
6870 ret == _SUCCESS?", acked":"", i, try_cnt,
6871 jiffies_to_msecs(jiffies - start));
6877 /* when wait_ack is ture, this function shoule be called at process context */
6878 static int _issue_qos_nulldata23a(struct rtw_adapter *padapter,
6879 unsigned char *da, u16 tid, int wait_ack)
6882 struct xmit_frame *pmgntframe;
6883 struct pkt_attrib *pattrib;
6884 unsigned char *pframe;
6885 struct ieee80211_hdr *pwlanhdr;
6886 unsigned short *fctrl, *qc;
6887 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6888 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6889 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6891 DBG_8723A("%s\n", __func__);
6893 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
6896 /* update attribute */
6897 pattrib = &pmgntframe->attrib;
6898 update_mgntframe_attrib23a(padapter, pattrib);
6900 pattrib->hdrlen += 2;
6901 pattrib->qos_en = true;
6903 pattrib->ack_policy = 0;
6906 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6908 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6909 pwlanhdr = (struct ieee80211_hdr *)pframe;
6911 fctrl = &pwlanhdr->frame_control;
6914 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
6916 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
6922 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
6924 SetPriority(qc, tid);
6926 SetEOSP(qc, pattrib->eosp);
6928 SetAckpolicy(qc, pattrib->ack_policy);
6930 ether_addr_copy(pwlanhdr->addr1, da);
6931 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
6932 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
6934 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6935 pmlmeext->mgnt_seq++;
6936 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
6938 pframe += sizeof(struct ieee80211_qos_hdr);
6939 pattrib->pktlen = sizeof(struct ieee80211_qos_hdr);
6941 pattrib->last_txcmdsz = pattrib->pktlen;
6944 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
6946 dump_mgntframe23a(padapter, pmgntframe);
6954 /* when wait_ms >0 , this function shoule be called at process context */
6955 /* da == NULL for station mode */
6956 int issue_qos_nulldata23a(struct rtw_adapter *padapter, unsigned char *da,
6957 u16 tid, int try_cnt, int wait_ms)
6961 unsigned long start = jiffies;
6962 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6963 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
6965 /* da == NULL, assum it's null data for sta to ap*/
6967 da = get_my_bssid23a(&pmlmeinfo->network);
6970 ret = _issue_qos_nulldata23a(padapter, da, tid,
6971 wait_ms > 0 ? true : false);
6975 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
6978 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
6980 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
6987 if (try_cnt && wait_ms) {
6989 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d "
6990 "in %u ms\n", FUNC_ADPT_ARG(padapter),
6991 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
6992 ret == _SUCCESS?", acked":"", i, try_cnt,
6993 jiffies_to_msecs(jiffies - start));
6995 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
6996 FUNC_ADPT_ARG(padapter),
6997 rtw_get_oper_ch23a(padapter),
6998 ret == _SUCCESS?", acked":"", i, try_cnt,
6999 jiffies_to_msecs(jiffies - start));
7005 static int _issue_deauth23a(struct rtw_adapter *padapter, unsigned char *da,
7006 unsigned short reason, u8 wait_ack)
7008 struct xmit_frame *pmgntframe;
7009 struct pkt_attrib *pattrib;
7010 unsigned char *pframe;
7011 struct ieee80211_hdr *pwlanhdr;
7012 unsigned short *fctrl;
7013 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7014 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
7015 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
7017 #ifdef CONFIG_8723AU_P2P
7018 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
7019 #endif /* CONFIG_8723AU_P2P */
7021 /* DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
7023 #ifdef CONFIG_8723AU_P2P
7024 if (!(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) &&
7025 (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
7026 mod_timer(&pwdinfo->reset_ch_sitesurvey,
7027 jiffies + msecs_to_jiffies(10));
7029 #endif /* CONFIG_8723AU_P2P */
7031 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
7034 /* update attribute */
7035 pattrib = &pmgntframe->attrib;
7036 update_mgntframe_attrib23a(padapter, pattrib);
7037 pattrib->retry_ctrl = false;
7039 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7041 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7042 pwlanhdr = (struct ieee80211_hdr *)pframe;
7044 fctrl = &pwlanhdr->frame_control;
7047 ether_addr_copy(pwlanhdr->addr1, da);
7048 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
7049 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
7051 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7052 pmlmeext->mgnt_seq++;
7053 SetFrameSubType(pframe, WIFI_DEAUTH);
7055 pframe += sizeof(struct ieee80211_hdr_3addr);
7056 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
7058 reason = cpu_to_le16(reason);
7059 pframe = rtw_set_fixed_ie23a(pframe, WLAN_REASON_PREV_AUTH_NOT_VALID,
7060 (unsigned char *)&reason,
7063 pattrib->last_txcmdsz = pattrib->pktlen;
7066 ret = dump_mgntframe23a_and_wait_ack23a(padapter, pmgntframe);
7068 dump_mgntframe23a(padapter, pmgntframe);
7076 int issue_deauth23a(struct rtw_adapter *padapter, unsigned char *da,
7077 unsigned short reason)
7079 DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
7080 return _issue_deauth23a(padapter, da, reason, false);
7083 int issue_deauth23a_ex23a(struct rtw_adapter *padapter, u8 *da,
7084 unsigned short reason, int try_cnt, int wait_ms)
7088 unsigned long start = jiffies;
7091 ret = _issue_deauth23a(padapter, da, reason,
7092 wait_ms >0 ? true : false);
7096 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
7099 if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
7102 } while((i < try_cnt) && ((ret == _FAIL)||(wait_ms == 0)));
7109 if (try_cnt && wait_ms) {
7111 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d "
7112 "in %u ms\n", FUNC_ADPT_ARG(padapter),
7113 MAC_ARG(da), rtw_get_oper_ch23a(padapter),
7114 ret == _SUCCESS?", acked":"", i, try_cnt,
7115 jiffies_to_msecs(jiffies - start));
7117 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
7118 FUNC_ADPT_ARG(padapter),
7119 rtw_get_oper_ch23a(padapter),
7120 ret == _SUCCESS?", acked":"", i, try_cnt,
7121 jiffies_to_msecs(jiffies - start));
7127 void issue_action_spct_ch_switch23a(struct rtw_adapter *padapter,
7128 u8 *ra, u8 new_ch, u8 ch_offset)
7130 struct xmit_frame *pmgntframe;
7131 struct pkt_attrib *pattrib;
7132 unsigned char *pframe;
7133 struct ieee80211_hdr *pwlanhdr;
7134 unsigned short *fctrl;
7135 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7136 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
7137 u8 category, action;
7139 DBG_8723A(FUNC_NDEV_FMT" ra ="MAC_FMT", ch:%u, offset:%u\n",
7140 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra),
7143 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
7146 /* update attribute */
7147 pattrib = &pmgntframe->attrib;
7148 update_mgntframe_attrib23a(padapter, pattrib);
7150 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7152 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7153 pwlanhdr = (struct ieee80211_hdr *)pframe;
7155 fctrl = &pwlanhdr->frame_control;
7158 ether_addr_copy(pwlanhdr->addr1, ra); /* RA */
7159 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv)); /* TA */
7160 ether_addr_copy(pwlanhdr->addr3, ra); /* DA = RA */
7162 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7163 pmlmeext->mgnt_seq++;
7164 SetFrameSubType(pframe, WIFI_ACTION);
7166 pframe += sizeof(struct ieee80211_hdr_3addr);
7167 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
7169 /* category, action */
7170 category = WLAN_CATEGORY_SPECTRUM_MGMT;
7171 action = WLAN_ACTION_SPCT_CHL_SWITCH;
7173 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
7174 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
7176 pframe = rtw_set_ie23a_ch_switch (pframe, &pattrib->pktlen, 0,
7178 pframe = rtw_set_ie23a_secondary_ch_offset(pframe, &pattrib->pktlen,
7179 hal_ch_offset_to_secondary_ch_offset23a(ch_offset));
7181 pattrib->last_txcmdsz = pattrib->pktlen;
7183 dump_mgntframe23a(padapter, pmgntframe);
7186 void issue_action_BA23a(struct rtw_adapter *padapter, unsigned char *raddr,
7187 unsigned char action, unsigned short status)
7189 u8 category = WLAN_CATEGORY_BACK;
7193 u16 BA_timeout_value;
7194 u16 BA_starting_seqctrl;
7195 int max_rx_ampdu_factor;
7196 struct xmit_frame *pmgntframe;
7197 struct pkt_attrib *pattrib;
7199 struct ieee80211_hdr *pwlanhdr;
7201 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7202 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
7203 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
7204 struct sta_info *psta;
7205 struct sta_priv *pstapriv = &padapter->stapriv;
7206 struct registry_priv *pregpriv = &padapter->registrypriv;
7207 #ifdef CONFIG_8723AU_BT_COEXIST
7208 u8 tendaAPMac[] = {0xC8, 0x3A, 0x35};
7211 DBG_8723A("%s, category =%d, action =%d, status =%d\n",
7212 __func__, category, action, status);
7214 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
7217 /* update attribute */
7218 pattrib = &pmgntframe->attrib;
7219 update_mgntframe_attrib23a(padapter, pattrib);
7221 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7223 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7224 pwlanhdr = (struct ieee80211_hdr *)pframe;
7226 fctrl = &pwlanhdr->frame_control;
7229 /* memcpy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network), ETH_ALEN); */
7230 ether_addr_copy(pwlanhdr->addr1, raddr);
7231 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
7232 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
7234 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7235 pmlmeext->mgnt_seq++;
7236 SetFrameSubType(pframe, WIFI_ACTION);
7238 pframe += sizeof(struct ieee80211_hdr_3addr);
7239 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
7241 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
7242 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
7244 status = cpu_to_le16(status);
7251 case 0: /* ADDBA req */
7253 pmlmeinfo->dialogToken++;
7254 } while (pmlmeinfo->dialogToken == 0);
7255 pframe = rtw_set_fixed_ie23a(pframe, 1, &pmlmeinfo->dialogToken,
7258 #ifdef CONFIG_8723AU_BT_COEXIST
7259 if ((BT_1Ant(padapter) == true) &&
7260 ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
7261 memcmp(raddr, tendaAPMac, 3))) {
7262 /* A-MSDU NOT Supported */
7264 /* immediate Block Ack */
7265 BA_para_set |= (1 << 1) &
7266 IEEE80211_ADDBA_PARAM_POLICY_MASK;
7268 BA_para_set |= (status << 2) &
7269 IEEE80211_ADDBA_PARAM_TID_MASK;
7270 /* max buffer size is 8 MSDU */
7271 BA_para_set |= (8 << 6) &
7272 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
7276 /* immediate ack & 64 buffer size */
7277 BA_para_set = (0x1002 | ((status & 0xf) << 2));
7279 BA_para_set = cpu_to_le16(BA_para_set);
7280 pframe = rtw_set_fixed_ie23a(pframe, 2,
7281 (unsigned char *)&BA_para_set,
7284 BA_timeout_value = 5000;/* 5ms */
7285 BA_timeout_value = cpu_to_le16(BA_timeout_value);
7286 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)
7290 /* if ((psta = rtw_get_stainfo23a(pstapriv,
7291 pmlmeinfo->network.MacAddress)) != NULL) */
7292 if ((psta = rtw_get_stainfo23a(pstapriv, raddr))) {
7293 start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1;
7295 DBG_8723A("BA_starting_seqctrl = %d for TID =%d\n",
7296 start_seq, status & 0x07);
7298 psta->BA_starting_seqctrl[status & 0x07] = start_seq;
7300 BA_starting_seqctrl = start_seq << 4;
7303 BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
7304 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)&BA_starting_seqctrl, &pattrib->pktlen);
7307 case 1: /* ADDBA rsp */
7308 pframe = rtw_set_fixed_ie23a(pframe, 1, &pmlmeinfo->ADDBA_req.dialog_token, &pattrib->pktlen);
7309 pframe = rtw_set_fixed_ie23a(pframe, 2,
7310 (unsigned char *)&status,
7312 rtw_hal_get_def_var23a(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR,
7313 &max_rx_ampdu_factor);
7314 if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_64K)
7315 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
7316 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_32K)
7317 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800); /* 32 buffer size */
7318 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_16K)
7319 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0400); /* 16 buffer size */
7320 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_8K)
7321 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0200); /* 8 buffer size */
7323 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
7325 #ifdef CONFIG_8723AU_BT_COEXIST
7326 if ((BT_1Ant(padapter) == true) &&
7327 ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
7328 memcmp(raddr, tendaAPMac, 3))) {
7329 /* max buffer size is 8 MSDU */
7330 BA_para_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
7331 BA_para_set |= (8 << 6) &
7332 IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
7336 if (pregpriv->ampdu_amsdu == 0)/* disabled */
7337 BA_para_set = cpu_to_le16(BA_para_set & ~BIT(0));
7338 else if (pregpriv->ampdu_amsdu == 1)/* enabled */
7339 BA_para_set = cpu_to_le16(BA_para_set | BIT(0));
7341 BA_para_set = cpu_to_le16(BA_para_set);
7343 pframe = rtw_set_fixed_ie23a(pframe, 2,
7344 (unsigned char *)&BA_para_set,
7346 pframe = rtw_set_fixed_ie23a(pframe, 2, (unsigned char *)&pmlmeinfo->ADDBA_req.BA_timeout_value, &pattrib->pktlen);
7349 BA_para_set = (status & 0x1F) << 3;
7350 BA_para_set = cpu_to_le16(BA_para_set);
7351 pframe = rtw_set_fixed_ie23a(pframe, 2,
7352 (unsigned char *)&BA_para_set,
7355 reason_code = 37;/* Requested from peer STA as it does not
7356 want to use the mechanism */
7357 reason_code = cpu_to_le16(reason_code);
7358 pframe = rtw_set_fixed_ie23a(pframe, 2,
7359 (unsigned char *)&reason_code,
7367 pattrib->last_txcmdsz = pattrib->pktlen;
7369 dump_mgntframe23a(padapter, pmgntframe);
7372 static void issue_action_BSSCoexistPacket(struct rtw_adapter *padapter)
7374 struct list_head *plist, *phead, *ptmp;
7375 unsigned char category, action;
7376 struct xmit_frame *pmgntframe;
7377 struct pkt_attrib *pattrib;
7378 unsigned char *pframe;
7379 struct ieee80211_hdr *pwlanhdr;
7380 unsigned short *fctrl;
7381 struct wlan_network *pnetwork = NULL;
7382 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7383 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7384 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
7385 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
7386 struct rtw_queue *queue = &pmlmepriv->scanned_queue;
7387 u8 InfoContent[16] = {0};
7390 if ((pmlmepriv->num_FortyMHzIntolerant == 0) || (pmlmepriv->num_sta_no_ht == 0))
7393 if (true == pmlmeinfo->bwmode_updated)
7396 DBG_8723A("%s\n", __func__);
7398 category = WLAN_CATEGORY_PUBLIC;
7399 action = ACT_PUBLIC_BSSCOEXIST;
7401 if ((pmgntframe = alloc_mgtxmitframe23a(pxmitpriv)) == NULL)
7406 /* update attribute */
7407 pattrib = &pmgntframe->attrib;
7408 update_mgntframe_attrib23a(padapter, pattrib);
7410 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7412 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7413 pwlanhdr = (struct ieee80211_hdr *)pframe;
7415 fctrl = &pwlanhdr->frame_control;
7418 ether_addr_copy(pwlanhdr->addr1, get_my_bssid23a(&pmlmeinfo->network));
7419 ether_addr_copy(pwlanhdr->addr2, myid(&padapter->eeprompriv));
7420 ether_addr_copy(pwlanhdr->addr3, get_my_bssid23a(&pmlmeinfo->network));
7422 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7423 pmlmeext->mgnt_seq++;
7424 SetFrameSubType(pframe, WIFI_ACTION);
7426 pframe += sizeof(struct ieee80211_hdr_3addr);
7427 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr);
7429 pframe = rtw_set_fixed_ie23a(pframe, 1, &category, &pattrib->pktlen);
7430 pframe = rtw_set_fixed_ie23a(pframe, 1, &action, &pattrib->pktlen);
7433 if (pmlmepriv->num_FortyMHzIntolerant>0)
7437 iedata |= BIT(2);/* 20 MHz BSS Width Request */
7439 pframe = rtw_set_ie23a(pframe, EID_BSSCoexistence, 1, &iedata, &pattrib->pktlen);
7444 memset(ICS, 0, sizeof(ICS));
7445 if (pmlmepriv->num_sta_no_ht>0)
7449 spin_lock_bh(&pmlmepriv->scanned_queue.lock);
7451 phead = get_list_head(queue);
7452 plist = phead->next;
7454 list_for_each_safe(plist, ptmp, phead) {
7457 struct wlan_bssid_ex *pbss_network;
7459 pnetwork = container_of(plist, struct wlan_network,
7462 pbss_network = &pnetwork->network;
7464 p = rtw_get_ie23a(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
7465 if ((p == NULL) || (len == 0))/* non-HT */
7467 if ((pbss_network->Configuration.DSConfig<= 0) || (pbss_network->Configuration.DSConfig>14))
7470 ICS[0][pbss_network->Configuration.DSConfig]= 1;
7478 spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
7487 /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */
7490 for (j = 1;j<= 14;j++)
7496 InfoContent[k] = j; /* channel number */
7497 /* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */
7503 pframe = rtw_set_ie23a(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &pattrib->pktlen);
7511 pattrib->last_txcmdsz = pattrib->pktlen;
7513 dump_mgntframe23a(padapter, pmgntframe);
7516 unsigned int send_delba23a(struct rtw_adapter *padapter, u8 initiator, u8 *addr)
7518 struct sta_priv *pstapriv = &padapter->stapriv;
7519 struct sta_info *psta = NULL;
7520 /* struct recv_reorder_ctrl *preorder_ctrl; */
7521 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
7522 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
7525 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
7526 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
7529 psta = rtw_get_stainfo23a(pstapriv, addr);
7533 if (initiator == 0) { /* recipient */
7534 for (tid = 0; tid < MAXTID; tid++) {
7535 if (psta->recvreorder_ctrl[tid].enable == true) {
7536 DBG_8723A("rx agg disable tid(%d)\n", tid);
7537 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
7538 psta->recvreorder_ctrl[tid].enable = false;
7539 psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
7542 } else if (initiator == 1) { /* originator */
7543 for (tid = 0; tid < MAXTID; tid++) {
7544 if (psta->htpriv.agg_enable_bitmap & BIT(tid)) {
7545 DBG_8723A("tx agg disable tid(%d)\n", tid);
7546 issue_action_BA23a(padapter, addr, WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
7547 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
7548 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
7556 unsigned int send_beacon23a(struct rtw_adapter *padapter)
7561 unsigned long start = jiffies;
7562 unsigned int passing_time;
7564 rtw_hal_set_hwreg23a(padapter, HW_VAR_BCN_VALID, NULL);
7566 issue_beacon23a(padapter, 100);
7570 rtw23a_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
7572 } while ((poll%10)!= 0 && false == bxmitok &&
7573 !padapter->bSurpriseRemoved &&
7574 !padapter->bDriverStopped);
7576 } while (!bxmitok && issue<100 && !padapter->bSurpriseRemoved &&
7577 !padapter->bDriverStopped);
7579 if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
7582 passing_time = jiffies_to_msecs(jiffies - start);
7585 DBG_8723A("%s fail! %u ms\n", __func__, passing_time);
7589 if (passing_time > 100 || issue > 3)
7590 DBG_8723A("%s success, issue:%d, poll:%d, %u ms\n",
7591 __func__, issue, poll, passing_time);
7596 /****************************************************************************
7598 Following are some utitity fuctions for WiFi MLME
7600 *****************************************************************************/
7602 bool IsLegal5GChannel(struct rtw_adapter *Adapter, u8 channel)
7606 u8 Channel_5G[45] = {36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
7607 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
7608 124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
7610 for (i = 0; i < sizeof(Channel_5G); i++)
7611 if (channel == Channel_5G[i])
7616 void site_survey23a(struct rtw_adapter *padapter)
7618 unsigned char survey_channel = 0, val8;
7619 enum rt_scan_type ScanType = SCAN_PASSIVE;
7620 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
7621 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
7622 u32 initialgain = 0;
7623 #ifdef CONFIG_8723AU_P2P
7624 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
7626 if ((pwdinfo->rx_invitereq_info.scan_op_ch_only) ||
7627 (pwdinfo->p2p_info.scan_op_ch_only)) {
7628 if (pwdinfo->rx_invitereq_info.scan_op_ch_only)
7629 survey_channel = pwdinfo->rx_invitereq_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
7631 survey_channel = pwdinfo->p2p_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
7632 ScanType = SCAN_ACTIVE;
7633 } else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) {
7634 /* The driver is in the find phase, it should go through the social channel. */
7636 survey_channel = pwdinfo->social_chan[pmlmeext->sitesurvey_res.channel_idx];
7637 ch_set_idx = rtw_ch_set_search_ch23a(pmlmeext->channel_set, survey_channel);
7638 if (ch_set_idx >= 0)
7639 ScanType = pmlmeext->channel_set[ch_set_idx].ScanType;
7641 ScanType = SCAN_ACTIVE;
7643 #endif /* CONFIG_8723AU_P2P */
7645 struct rtw_ieee80211_channel *ch;
7646 if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) {
7647 ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
7648 survey_channel = ch->hw_value;
7649 ScanType = (ch->flags & IEEE80211_CHAN_NO_IR) ? SCAN_PASSIVE : SCAN_ACTIVE;
7653 if (survey_channel != 0) {
7654 /* PAUSE 4-AC Queue when site_survey23a */
7655 /* rtw23a_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
7657 /* rtw_hal_set_hwreg23a(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
7658 if (pmlmeext->sitesurvey_res.channel_idx == 0)
7659 set_channel_bwmode23a(padapter, survey_channel,
7660 HAL_PRIME_CHNL_OFFSET_DONT_CARE,
7661 HT_CHANNEL_WIDTH_20);
7663 SelectChannel23a(padapter, survey_channel);
7665 if (ScanType == SCAN_ACTIVE) /* obey the channel plan setting... */
7667 #ifdef CONFIG_8723AU_P2P
7668 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) ||
7669 rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
7672 issue23a_probereq_p2p(padapter, NULL);
7673 issue23a_probereq_p2p(padapter, NULL);
7674 issue23a_probereq_p2p(padapter, NULL);
7677 #endif /* CONFIG_8723AU_P2P */
7680 for (i = 0;i<RTW_SSID_SCAN_AMOUNT;i++) {
7681 if (pmlmeext->sitesurvey_res.ssid[i].ssid_len) {
7682 /* todo: to issue two probe req??? */
7683 issue_probereq23a(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
7684 /* msleep(SURVEY_TO>>1); */
7685 issue_probereq23a(padapter, &pmlmeext->sitesurvey_res.ssid[i], NULL);
7689 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
7690 /* todo: to issue two probe req??? */
7691 issue_probereq23a(padapter, NULL, NULL);
7692 /* msleep(SURVEY_TO>>1); */
7693 issue_probereq23a(padapter, NULL, NULL);
7698 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
7701 /* channel number is 0 or this channel is not valid. */
7704 #ifdef CONFIG_8723AU_P2P
7705 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
7707 if ((pwdinfo->rx_invitereq_info.scan_op_ch_only) || (pwdinfo->p2p_info.scan_op_ch_only))
7709 /* Set the find_phase_state_exchange_cnt to P2P_FINDPHASE_EX_CNT. */
7710 /* This will let the following flow to run the scanning end. */
7711 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
7715 if (rtw_p2p_findphase_ex_is_needed(pwdinfo))
7717 /* Set the P2P State to the listen state of find phase and set the current channel to the listen channel */
7718 set_channel_bwmode23a(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
7719 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
7720 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
7722 initialgain = 0xff; /* restore RX GAIN */
7723 rtw_hal_set_hwreg23a(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
7724 /* turn on dynamic functions */
7725 Restore_DM_Func_Flag23a(padapter);
7726 /* Switch_DM_Func23a(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, true); */
7728 mod_timer(&pwdinfo->find_phase_timer, jiffies +
7729 msecs_to_jiffies(pwdinfo->listen_dwell * 100));
7731 #endif /* CONFIG_8723AU_P2P */
7733 #ifdef CONFIG_8723AU_P2P
7734 if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
7735 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
7736 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
7737 #endif /* CONFIG_8723AU_P2P */
7739 pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
7741 /* switch back to the original channel */
7743 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
7745 /* flush 4-AC Queue after site_survey23a */
7747 /* rtw_hal_set_hwreg23a(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
7750 Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
7752 initialgain = 0xff; /* restore RX GAIN */
7753 rtw_hal_set_hwreg23a(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
7754 /* turn on dynamic functions */
7755 Restore_DM_Func_Flag23a(padapter);
7756 /* Switch_DM_Func23a(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); */
7758 if (is_client_associated_to_ap23a(padapter) == true)
7760 issue_nulldata23a(padapter, NULL, 0, 3, 500);
7764 val8 = 0; /* survey done */
7765 rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
7767 report_surveydone_event23a(padapter);
7769 pmlmeext->chan_scan_time = SURVEY_TO;
7770 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
7772 issue_action_BSSCoexistPacket(padapter);
7773 issue_action_BSSCoexistPacket(padapter);
7774 issue_action_BSSCoexistPacket(padapter);
7782 /* collect bss info from Beacon and Probe request/response frames. */
7783 u8 collect_bss_info23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame, struct wlan_bssid_ex *bssid)
7789 struct sk_buff *skb = precv_frame->pkt;
7790 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
7791 u8 *pframe = skb->data;
7792 u32 packet_len = skb->len;
7794 struct registry_priv *pregistrypriv = &padapter->registrypriv;
7795 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
7796 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
7798 len = packet_len - sizeof(struct ieee80211_hdr_3addr);
7800 if (len > MAX_IE_SZ)
7802 /* DBG_8723A("IE too long for survey event\n"); */
7806 memset(bssid, 0, sizeof(struct wlan_bssid_ex));
7808 if (ieee80211_is_beacon(hdr->frame_control)) {
7809 bssid->reserved = 1;
7810 ie_offset = _BEACON_IE_OFFSET_;
7812 /* FIXME : more type */
7813 if (ieee80211_is_probe_req(hdr->frame_control)) {
7814 ie_offset = _PROBEREQ_IE_OFFSET_;
7815 bssid->reserved = 2;
7816 } else if (ieee80211_is_probe_resp(hdr->frame_control)) {
7817 ie_offset = _PROBERSP_IE_OFFSET_;
7818 bssid->reserved = 3;
7820 bssid->reserved = 0;
7821 ie_offset = _FIXED_IE_LENGTH_;
7825 bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len;
7827 /* below is to copy the information element */
7828 bssid->IELength = len;
7829 memcpy(bssid->IEs, (pframe + sizeof(struct ieee80211_hdr_3addr)), bssid->IELength);
7831 /* get the signal strength */
7832 bssid->Rssi = precv_frame->attrib.phy_info.RecvSignalPower; /* in dBM.raw data */
7833 bssid->PhyInfo.SignalQuality = precv_frame->attrib.phy_info.SignalQuality;/* in percentage */
7834 bssid->PhyInfo.SignalStrength = precv_frame->attrib.phy_info.SignalStrength;/* in percentage */
7837 if ((p = rtw_get_ie23a(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset)) == NULL)
7839 DBG_8723A("marc: cannot find SSID for survey event\n");
7844 if (len > IEEE80211_MAX_SSID_LEN) {
7845 DBG_8723A("%s()-%d: IE too long (%d) for survey "
7846 "event\n", __func__, __LINE__, len);
7849 memcpy(bssid->Ssid.ssid, (p + 2), *(p + 1));
7850 bssid->Ssid.ssid_len = *(p + 1);
7852 bssid->Ssid.ssid_len = 0;
7855 memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
7857 /* checking rate info... */
7859 p = rtw_get_ie23a(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
7862 if (len > NDIS_802_11_LENGTH_RATES_EX)
7864 DBG_8723A("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
7867 memcpy(bssid->SupportedRates, (p + 2), len);
7871 p = rtw_get_ie23a(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
7874 if (len > (NDIS_802_11_LENGTH_RATES_EX-i))
7876 DBG_8723A("%s()-%d: IE too long (%d) for survey event\n", __func__, __LINE__, len);
7879 memcpy(bssid->SupportedRates + i, (p + 2), len);
7884 bssid->NetworkTypeInUse = Ndis802_11OFDM24;
7887 if (bssid->IELength < 12)
7890 /* Checking for DSConfig */
7891 p = rtw_get_ie23a(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
7893 bssid->Configuration.DSConfig = 0;
7894 bssid->Configuration.Length = 0;
7898 bssid->Configuration.DSConfig = *(p + 2);
7901 {/* In 5G, some ap do not have DSSET IE */
7902 /* checking HT info for channel */
7903 p = rtw_get_ie23a(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
7906 struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
7907 bssid->Configuration.DSConfig = HT_info->primary_channel;
7910 { /* use current channel */
7911 bssid->Configuration.DSConfig = rtw_get_oper_ch23a(padapter);
7915 if (ieee80211_is_probe_req(hdr->frame_control)) {
7917 bssid->InfrastructureMode = Ndis802_11Infrastructure;
7918 ether_addr_copy(bssid->MacAddress, hdr->addr2);
7923 memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval23a_from_ie(bssid->IEs), 2);
7924 bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
7926 val16 = rtw_get_capability23a(bssid);
7928 if (val16 & BIT(0)) {
7929 bssid->InfrastructureMode = Ndis802_11Infrastructure;
7930 ether_addr_copy(bssid->MacAddress, hdr->addr2);
7932 bssid->InfrastructureMode = Ndis802_11IBSS;
7933 ether_addr_copy(bssid->MacAddress, hdr->addr3);
7941 bssid->Configuration.ATIMWindow = 0;
7943 /* 20/40 BSS Coexistence check */
7944 if ((pregistrypriv->wifi_spec == 1) && (false == pmlmeinfo->bwmode_updated))
7946 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7948 p = rtw_get_ie23a(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
7950 struct HT_caps_element *pHT_caps;
7951 pHT_caps = (struct HT_caps_element *)(p + 2);
7953 if (pHT_caps->u.HT_cap_element.HT_caps_info & BIT(14))
7954 pmlmepriv->num_FortyMHzIntolerant++;
7957 pmlmepriv->num_sta_no_ht++;
7962 /* mark bss info receving from nearby channel as SignalQuality 101 */
7963 if (bssid->Configuration.DSConfig != rtw_get_oper_ch23a(padapter))
7964 bssid->PhyInfo.SignalQuality = 101;
7969 void start_create_ibss23a(struct rtw_adapter* padapter)
7971 unsigned short caps;
7974 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
7975 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
7976 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
7977 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
7978 pmlmeinfo->bcn_interval = get_beacon_interval23a(pnetwork);
7980 /* update wireless mode */
7981 update_wireless_mode23a(padapter);
7983 /* udpate capability */
7984 caps = rtw_get_capability23a(pnetwork);
7985 update_capinfo23a(padapter, caps);
7986 if (caps&cap_IBSS)/* adhoc master */
7989 rtw_hal_set_hwreg23a(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
7991 /* switch channel */
7992 /* SelectChannel23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
7993 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
7995 beacon_timing_control23a(padapter);
7997 /* set msr to WIFI_FW_ADHOC_STATE */
7998 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
7999 Set_MSR23a(padapter, (pmlmeinfo->state & 0x3));
8002 if (send_beacon23a(padapter) == _FAIL)
8004 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("issuing beacon frame fail....\n"));
8006 report_join_res23a(padapter, -1);
8007 pmlmeinfo->state = WIFI_FW_NULL_STATE;
8011 rtw_hal_set_hwreg23a(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
8013 rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
8015 report_join_res23a(padapter, 1);
8016 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
8021 DBG_8723A("start_create_ibss23a, invalid cap:%x\n", caps);
8026 void start_clnt_join23a(struct rtw_adapter* padapter)
8028 unsigned short caps;
8030 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8031 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8032 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
8035 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
8036 pmlmeinfo->bcn_interval = get_beacon_interval23a(pnetwork);
8038 /* update wireless mode */
8039 update_wireless_mode23a(padapter);
8041 /* udpate capability */
8042 caps = rtw_get_capability23a(pnetwork);
8043 update_capinfo23a(padapter, caps);
8045 /* switch channel */
8046 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
8048 Set_MSR23a(padapter, WIFI_FW_STATION_STATE);
8050 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
8052 rtw_hal_set_hwreg23a(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
8054 /* switch channel */
8055 /* set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
8057 /* here wait for receiving the beacon to start auth */
8058 /* and enable a timer */
8059 beacon_timeout = decide_wait_for_beacon_timeout23a(pmlmeinfo->bcn_interval);
8060 set_link_timer(pmlmeext, beacon_timeout);
8061 mod_timer(&padapter->mlmepriv.assoc_timer, jiffies +
8062 msecs_to_jiffies((REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) + beacon_timeout));
8063 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
8065 else if (caps&cap_IBSS) /* adhoc client */
8067 Set_MSR23a(padapter, WIFI_FW_ADHOC_STATE);
8070 rtw_hal_set_hwreg23a(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
8072 /* switch channel */
8073 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
8075 beacon_timing_control23a(padapter);
8077 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
8079 report_join_res23a(padapter, 1);
8083 /* DBG_8723A("marc: invalid cap:%x\n", caps); */
8088 void start_clnt_auth23a(struct rtw_adapter* padapter)
8090 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8091 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8093 del_timer_sync(&pmlmeext->link_timer);
8095 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
8096 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
8098 pmlmeinfo->auth_seq = 1;
8099 pmlmeinfo->reauth_count = 0;
8100 pmlmeinfo->reassoc_count = 0;
8101 pmlmeinfo->link_count = 0;
8102 pmlmeext->retry = 0;
8104 /* Because of AP's not receiving deauth before */
8105 /* AP may: 1)not response auth or 2)deauth us after link is complete */
8106 /* issue deauth before issuing auth to deal with the situation */
8107 /* Commented by Albert 2012/07/21 */
8108 /* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
8109 issue_deauth23a(padapter, (&pmlmeinfo->network)->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
8111 DBG_8723A_LEVEL(_drv_always_, "start auth\n");
8112 issue_auth23a(padapter, NULL, 0);
8114 set_link_timer(pmlmeext, REAUTH_TO);
8117 void start_clnt_assoc23a(struct rtw_adapter* padapter)
8119 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8120 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8122 del_timer_sync(&pmlmeext->link_timer);
8124 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
8125 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
8127 issue_assocreq23a(padapter);
8129 set_link_timer(pmlmeext, REASSOC_TO);
8132 unsigned int receive_disconnect23a(struct rtw_adapter *padapter, unsigned char *MacAddr, unsigned short reason)
8134 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8135 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8138 if (!ether_addr_equal(MacAddr, get_my_bssid23a(&pmlmeinfo->network)))
8141 DBG_8723A("%s\n", __func__);
8143 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
8145 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
8147 pmlmeinfo->state = WIFI_FW_NULL_STATE;
8148 report_del_sta_event23a(padapter, MacAddr, reason);
8151 else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
8153 pmlmeinfo->state = WIFI_FW_NULL_STATE;
8154 report_join_res23a(padapter, -2);
8161 static void process_80211d(struct rtw_adapter *padapter, struct wlan_bssid_ex *bssid)
8163 struct registry_priv *pregistrypriv;
8164 struct mlme_ext_priv *pmlmeext;
8165 struct rt_channel_info *chplan_new;
8169 pregistrypriv = &padapter->registrypriv;
8170 pmlmeext = &padapter->mlmeextpriv;
8172 /* Adjust channel plan by AP Country IE */
8173 if (pregistrypriv->enable80211d &&
8174 (!pmlmeext->update_channel_plan_by_ap_done))
8178 struct rt_channel_plan chplan_ap;
8179 struct rt_channel_info chplan_sta[MAX_CHANNEL_NUM];
8181 u8 fcn; /* first channel number */
8182 u8 noc; /* number of channel */
8185 ie = rtw_get_ie23a(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
8187 if (len < 6) return;
8193 memset(country, 0, 4);
8194 memcpy(country, p, 3);
8196 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
8197 ("%s: 802.11d country =%s\n", __func__, country));
8200 while ((ie - p) >= 3)
8206 for (j = 0; j < noc; j++)
8208 if (fcn <= 14) channel = fcn + j; /* 2.4 GHz */
8209 else channel = fcn + j*4; /* 5 GHz */
8211 chplan_ap.Channel[i++] = channel;
8216 memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
8217 memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
8218 chplan_new = pmlmeext->channel_set;
8221 if (pregistrypriv->wireless_mode & WIRELESS_11G) {
8223 if ((i == MAX_CHANNEL_NUM) ||
8224 (chplan_sta[i].ChannelNum == 0) ||
8225 (chplan_sta[i].ChannelNum > 14))
8228 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
8231 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
8232 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
8233 chplan_new[k].ScanType = SCAN_ACTIVE;
8237 } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
8238 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
8239 chplan_new[k].ScanType = SCAN_PASSIVE;
8242 } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
8243 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
8244 chplan_new[k].ScanType = SCAN_ACTIVE;
8250 /* change AP not support channel to Passive scan */
8251 while ((i < MAX_CHANNEL_NUM) &&
8252 (chplan_sta[i].ChannelNum != 0) &&
8253 (chplan_sta[i].ChannelNum <= 14)) {
8254 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
8255 chplan_new[k].ScanType = SCAN_PASSIVE;
8260 /* add channel AP supported */
8261 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) {
8262 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
8263 chplan_new[k].ScanType = SCAN_ACTIVE;
8268 /* keep original STA 2.4G channel plan */
8269 while ((i < MAX_CHANNEL_NUM) &&
8270 (chplan_sta[i].ChannelNum != 0) &&
8271 (chplan_sta[i].ChannelNum <= 14)) {
8272 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
8273 chplan_new[k].ScanType = chplan_sta[i].ScanType;
8278 /* skip AP 2.4G channel plan */
8279 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) {
8284 if (pregistrypriv->wireless_mode & WIRELESS_11A) {
8286 if ((i == MAX_CHANNEL_NUM) ||
8287 (chplan_sta[i].ChannelNum == 0))
8290 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
8293 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
8295 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
8296 chplan_new[k].ScanType = SCAN_ACTIVE;
8301 else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
8303 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
8304 /* chplan_new[k].ScanType = chplan_sta[i].ScanType; */
8305 chplan_new[k].ScanType = SCAN_PASSIVE;
8309 else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
8311 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
8312 chplan_new[k].ScanType = SCAN_ACTIVE;
8318 /* change AP not support channel to Passive scan */
8319 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
8320 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
8321 chplan_new[k].ScanType = SCAN_PASSIVE;
8326 /* add channel AP supported */
8327 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0)) {
8328 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
8329 chplan_new[k].ScanType = SCAN_ACTIVE;
8334 /* keep original STA 5G channel plan */
8335 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
8336 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
8337 chplan_new[k].ScanType = chplan_sta[i].ScanType;
8342 pmlmeext->update_channel_plan_by_ap_done = 1;
8345 /* If channel is used by AP, set channel scan type to active */
8346 channel = bssid->Configuration.DSConfig;
8347 chplan_new = pmlmeext->channel_set;
8349 while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) {
8350 if (chplan_new[i].ChannelNum == channel)
8352 if (chplan_new[i].ScanType == SCAN_PASSIVE) {
8353 /* 5G Bnad 2, 3 (DFS) doesn't change to active scan */
8354 if (channel >= 52 && channel <= 144)
8357 chplan_new[i].ScanType = SCAN_ACTIVE;
8358 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
8359 ("%s: change channel %d scan type from passive to active\n",
8360 __func__, channel));
8368 /****************************************************************************
8370 Following are the functions to report events
8372 *****************************************************************************/
8374 void report_survey_event23a(struct rtw_adapter *padapter, struct recv_frame *precv_frame)
8376 struct cmd_obj *pcmd_obj;
8379 struct survey_event *psurvey_evt;
8380 struct C2HEvent_Header *pc2h_evt_hdr;
8381 struct mlme_ext_priv *pmlmeext;
8382 struct cmd_priv *pcmdpriv;
8387 pmlmeext = &padapter->mlmeextpriv;
8388 pcmdpriv = &padapter->cmdpriv;
8390 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
8395 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
8396 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
8402 INIT_LIST_HEAD(&pcmd_obj->list);
8404 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
8405 pcmd_obj->cmdsz = cmdsz;
8406 pcmd_obj->parmbuf = pevtcmd;
8408 pcmd_obj->rsp = NULL;
8409 pcmd_obj->rspsz = 0;
8411 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
8412 pc2h_evt_hdr->len = sizeof(struct survey_event);
8413 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
8414 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
8416 psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
8418 if (collect_bss_info23a(padapter, precv_frame, &psurvey_evt->bss) == _FAIL) {
8424 process_80211d(padapter, &psurvey_evt->bss);
8426 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
8428 pmlmeext->sitesurvey_res.bss_cnt++;
8433 void report_surveydone_event23a(struct rtw_adapter *padapter)
8435 struct cmd_obj *pcmd_obj;
8438 struct surveydone_event *psurveydone_evt;
8439 struct C2HEvent_Header *pc2h_evt_hdr;
8440 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8441 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
8443 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
8448 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
8449 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
8455 INIT_LIST_HEAD(&pcmd_obj->list);
8457 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
8458 pcmd_obj->cmdsz = cmdsz;
8459 pcmd_obj->parmbuf = pevtcmd;
8461 pcmd_obj->rsp = NULL;
8462 pcmd_obj->rspsz = 0;
8464 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
8465 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
8466 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
8467 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
8469 psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
8470 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
8472 DBG_8723A("survey done event(%x)\n", psurveydone_evt->bss_cnt);
8474 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
8479 void report_join_res23a(struct rtw_adapter *padapter, int res)
8481 struct cmd_obj *pcmd_obj;
8484 struct joinbss_event *pjoinbss_evt;
8485 struct C2HEvent_Header *pc2h_evt_hdr;
8486 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8487 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8488 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
8490 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
8495 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
8496 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
8502 INIT_LIST_HEAD(&pcmd_obj->list);
8504 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
8505 pcmd_obj->cmdsz = cmdsz;
8506 pcmd_obj->parmbuf = pevtcmd;
8508 pcmd_obj->rsp = NULL;
8509 pcmd_obj->rspsz = 0;
8511 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
8512 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
8513 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
8514 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
8516 pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
8517 memcpy((unsigned char *)&pjoinbss_evt->network.network,
8518 &pmlmeinfo->network, sizeof(struct wlan_bssid_ex));
8519 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
8521 DBG_8723A("report_join_res23a(%d)\n", res);
8523 rtw_joinbss_event_prehandle23a(padapter, (u8 *)&pjoinbss_evt->network);
8525 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
8530 void report_del_sta_event23a(struct rtw_adapter *padapter, unsigned char* MacAddr, unsigned short reason)
8532 struct cmd_obj *pcmd_obj;
8535 struct sta_info *psta;
8537 struct stadel_event *pdel_sta_evt;
8538 struct C2HEvent_Header *pc2h_evt_hdr;
8539 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8540 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
8542 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
8547 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
8548 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
8554 INIT_LIST_HEAD(&pcmd_obj->list);
8556 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
8557 pcmd_obj->cmdsz = cmdsz;
8558 pcmd_obj->parmbuf = pevtcmd;
8560 pcmd_obj->rsp = NULL;
8561 pcmd_obj->rspsz = 0;
8563 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
8564 pc2h_evt_hdr->len = sizeof(struct stadel_event);
8565 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
8566 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
8568 pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
8569 ether_addr_copy((unsigned char *)&pdel_sta_evt->macaddr, MacAddr);
8570 memcpy((unsigned char *)pdel_sta_evt->rsvd, (unsigned char *)&reason,
8573 psta = rtw_get_stainfo23a(&padapter->stapriv, MacAddr);
8575 mac_id = (int)psta->mac_id;
8579 pdel_sta_evt->mac_id = mac_id;
8581 DBG_8723A("report_del_sta_event23a: delete STA, mac_id =%d\n", mac_id);
8583 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
8588 void report_add_sta_event23a(struct rtw_adapter *padapter, unsigned char* MacAddr, int cam_idx)
8590 struct cmd_obj *pcmd_obj;
8593 struct stassoc_event *padd_sta_evt;
8594 struct C2HEvent_Header *pc2h_evt_hdr;
8595 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8596 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
8598 pcmd_obj = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
8603 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
8604 pevtcmd = kzalloc(cmdsz, GFP_ATOMIC);
8610 INIT_LIST_HEAD(&pcmd_obj->list);
8612 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
8613 pcmd_obj->cmdsz = cmdsz;
8614 pcmd_obj->parmbuf = pevtcmd;
8616 pcmd_obj->rsp = NULL;
8617 pcmd_obj->rspsz = 0;
8619 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
8620 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
8621 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
8622 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq);
8624 padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
8625 ether_addr_copy((unsigned char *)&padd_sta_evt->macaddr, MacAddr);
8626 padd_sta_evt->cam_id = cam_idx;
8628 DBG_8723A("report_add_sta_event23a: add STA\n");
8630 rtw_enqueue_cmd23a(pcmdpriv, pcmd_obj);
8635 /****************************************************************************
8637 Following are the event callback functions
8639 *****************************************************************************/
8641 /* for sta/adhoc mode */
8642 void update_sta_info23a(struct rtw_adapter *padapter, struct sta_info *psta)
8644 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8645 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8646 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8649 VCS_update23a(padapter, psta);
8652 if (pmlmepriv->htpriv.ht_option)
8654 psta->htpriv.ht_option = true;
8656 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
8658 if (support_short_GI23a(padapter, &pmlmeinfo->HT_caps))
8659 psta->htpriv.sgi = true;
8661 psta->qos_option = true;
8666 psta->htpriv.ht_option = false;
8668 psta->htpriv.ampdu_enable = false;
8670 psta->htpriv.sgi = false;
8671 psta->qos_option = false;
8674 psta->htpriv.bwmode = pmlmeext->cur_bwmode;
8675 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
8677 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
8678 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
8681 if (pmlmepriv->qospriv.qos_option)
8682 psta->qos_option = true;
8684 psta->state = _FW_LINKED;
8687 void mlmeext_joinbss_event_callback23a(struct rtw_adapter *padapter, int join_res)
8689 struct sta_info *psta, *psta_bmc;
8690 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8691 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8692 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
8693 struct sta_priv *pstapriv = &padapter->stapriv;
8700 rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
8701 rtw_hal_set_hwreg23a(padapter, HW_VAR_BSSID, null_addr);
8703 /* restore to initial setting. */
8704 update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
8706 goto exit_mlmeext_joinbss_event_callback23a;
8709 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
8712 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
8715 pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc;
8716 update_bmc_sta_support_rate23a(padapter, psta_bmc->mac_id);
8717 Update_RA_Entry23a(padapter, psta_bmc);
8721 /* turn on dynamic functions */
8722 Switch_DM_Func23a(padapter, DYNAMIC_ALL_FUNC_ENABLE, true);
8724 /* update IOT-releated issue */
8725 update_IOT_info23a(padapter);
8727 rtw_hal_set_hwreg23a(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
8730 rtw_hal_set_hwreg23a(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
8732 /* udpate capability */
8733 update_capinfo23a(padapter, pmlmeinfo->capability);
8735 /* WMM, Update EDCA param */
8736 WMMOnAssocRsp23a(padapter);
8739 HTOnAssocRsp23a(padapter);
8741 /* Set cur_channel&cur_bwmode&cur_ch_offset */
8742 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
8744 psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
8745 if (psta) /* only for infra. mode */
8747 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
8749 /* DBG_8723A("set_sta_rate23a\n"); */
8751 psta->wireless_mode = pmlmeext->cur_wireless_mode;
8753 /* set per sta rate after updating HT cap. */
8754 set_sta_rate23a(padapter, psta);
8756 media_status = (psta->mac_id<<8)|1; /* MACID|OPMODE: 1 means connect */
8757 rtw_hal_set_hwreg23a(padapter, HW_VAR_H2C_MEDIA_STATUS_RPT, (u8 *)&media_status);
8761 rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
8763 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
8765 /* correcting TSF */
8766 correct_TSF23a(padapter, pmlmeext);
8768 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
8771 rtw_lps_ctrl_wk_cmd23a(padapter, LPS_CTRL_CONNECT, 0);
8773 exit_mlmeext_joinbss_event_callback23a:
8774 DBG_8723A("=>%s\n", __func__);
8777 void mlmeext_sta_add_event_callback23a(struct rtw_adapter *padapter, struct sta_info *psta)
8779 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8780 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8783 DBG_8723A("%s\n", __func__);
8785 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
8787 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)/* adhoc master or sta_count>1 */
8791 else/* adhoc client */
8793 /* update TSF Value */
8794 /* update_TSF23a(pmlmeext, pframe, len); */
8796 /* correcting TSF */
8797 correct_TSF23a(padapter, pmlmeext);
8800 if (send_beacon23a(padapter) == _FAIL)
8802 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
8804 pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
8809 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
8814 rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
8817 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
8819 /* rate radaptive */
8820 Update_RA_Entry23a(padapter, psta);
8822 /* update adhoc sta_info */
8823 update_sta_info23a(padapter, psta);
8826 void mlmeext_sta_del_event_callback23a(struct rtw_adapter *padapter)
8828 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8829 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8831 if (is_client_associated_to_ap23a(padapter) || is_IBSS_empty23a(padapter))
8833 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
8835 rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_DISCONNECT, NULL);
8836 rtw_hal_set_hwreg23a(padapter, HW_VAR_BSSID, null_addr);
8838 /* restore to initial setting. */
8839 update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
8841 /* switch to the 20M Hz mode after disconnect */
8842 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
8843 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
8845 /* SelectChannel23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
8846 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
8848 flush_all_cam_entry23a(padapter);
8850 pmlmeinfo->state = WIFI_FW_NULL_STATE;
8852 /* set MSR to no link state -> infra. mode */
8853 Set_MSR23a(padapter, _HW_STATE_STATION_);
8855 del_timer_sync(&pmlmeext->link_timer);
8859 /****************************************************************************
8861 Following are the functions for the timer handlers
8863 *****************************************************************************/
8864 void linked23a_rx_sig_stren_disp(struct rtw_adapter *padapter)
8866 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8867 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8869 int UndecoratedSmoothedPWDB;
8870 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
8872 else if ((pmlmeinfo->state&0x03) == _HW_STATE_AP_)
8875 rtw_hal_get_def_var23a(padapter, HW_DEF_RA_INFO_DUMP,&mac_id);
8877 rtw_hal_get_def_var23a(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
8878 DBG_8723A("UndecoratedSmoothedPWDB:%d\n", UndecoratedSmoothedPWDB);
8881 static u8 chk_ap_is_alive(struct rtw_adapter *padapter, struct sta_info *psta)
8885 if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)) &&
8886 sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) &&
8887 sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
8892 sta_update_last_rx_pkts(psta);
8896 void linked_status_chk23a(struct rtw_adapter *padapter)
8899 struct sta_info *psta;
8900 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
8901 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8902 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
8903 struct sta_priv *pstapriv = &padapter->stapriv;
8905 if (padapter->bRxRSSIDisplay)
8906 linked23a_rx_sig_stren_disp(padapter);
8908 rtw_hal_sreset_linked_status_check23a(padapter);
8910 if (is_client_associated_to_ap23a(padapter))
8912 /* linked infrastructure client mode */
8914 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
8919 if ((psta = rtw_get_stainfo23a(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
8921 bool is_p2p_enable = false;
8922 #ifdef CONFIG_8723AU_P2P
8923 is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
8926 if (chk_ap_is_alive(padapter, psta) == false)
8929 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
8932 if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
8933 u8 backup_oper_channel = 0;
8935 /* switch to correct channel of current network before issue keep-alive frames */
8936 if (rtw_get_oper_ch23a(padapter) != pmlmeext->cur_channel) {
8937 backup_oper_channel = rtw_get_oper_ch23a(padapter);
8938 SelectChannel23a(padapter, pmlmeext->cur_channel);
8941 if (rx_chk != _SUCCESS)
8942 issue_probereq23a_ex23a(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1);
8944 if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) {
8945 tx_chk = issue_nulldata23a(padapter, psta->hwaddr, 0, 3, 1);
8946 /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
8947 if (tx_chk == _SUCCESS && !is_p2p_enable)
8951 /* back to the original operation channel */
8952 if (backup_oper_channel>0)
8953 SelectChannel23a(padapter, backup_oper_channel);
8956 if (rx_chk != _SUCCESS) {
8957 if (pmlmeext->retry == 0) {
8958 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
8959 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
8960 issue_probereq23a(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
8964 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf)
8965 tx_chk = issue_nulldata23a(padapter, NULL, 0, 1, 0);
8968 if (rx_chk == _FAIL) {
8970 if (pmlmeext->retry > rx_chk_limit) {
8971 DBG_8723A_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
8972 FUNC_ADPT_ARG(padapter));
8973 receive_disconnect23a(padapter, pmlmeinfo->network.MacAddress,
8974 WLAN_REASON_EXPIRATION_CHK);
8978 pmlmeext->retry = 0;
8981 if (tx_chk == _FAIL) {
8982 pmlmeinfo->link_count &= 0xf;
8984 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
8985 pmlmeinfo->link_count = 0;
8988 } /* end of if ((psta = rtw_get_stainfo23a(pstapriv, passoc_res->network.MacAddress)) != NULL) */
8990 else if (is_client_associated_to_ibss23a(padapter))
8992 /* linked IBSS mode */
8993 /* for each assoc list entry to check the rx pkt counter */
8994 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
8996 if (pmlmeinfo->FW_sta_info[i].status == 1)
8998 psta = pmlmeinfo->FW_sta_info[i].psta;
9000 if (NULL == psta) continue;
9002 if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta))
9005 if (pmlmeinfo->FW_sta_info[i].retry<3)
9007 pmlmeinfo->FW_sta_info[i].retry++;
9011 pmlmeinfo->FW_sta_info[i].retry = 0;
9012 pmlmeinfo->FW_sta_info[i].status = 0;
9013 report_del_sta_event23a(padapter, psta->hwaddr,
9014 65535/* indicate disconnect caused by no rx */
9020 pmlmeinfo->FW_sta_info[i].retry = 0;
9021 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
9026 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
9031 static void survey_timer_hdl(unsigned long data)
9033 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
9034 struct cmd_obj *ph2c;
9035 struct sitesurvey_parm *psurveyPara;
9036 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
9037 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9038 #ifdef CONFIG_8723AU_P2P
9039 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
9042 /* issue rtw_sitesurvey_cmd23a */
9043 if (pmlmeext->sitesurvey_res.state > SCAN_START) {
9044 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
9045 pmlmeext->sitesurvey_res.channel_idx++;
9047 if (pmlmeext->scan_abort == true)
9049 #ifdef CONFIG_8723AU_P2P
9050 if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
9052 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
9053 pmlmeext->sitesurvey_res.channel_idx = 3;
9054 DBG_8723A("%s idx:%d, cnt:%u\n", __func__,
9055 pmlmeext->sitesurvey_res.channel_idx,
9056 pwdinfo->find_phase_state_exchange_cnt);
9060 pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num;
9061 DBG_8723A("%s idx:%d\n", __func__,
9062 pmlmeext->sitesurvey_res.channel_idx);
9065 pmlmeext->scan_abort = false;/* reset */
9068 ph2c = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj),
9071 goto exit_survey_timer_hdl;
9073 psurveyPara = (struct sitesurvey_parm*)
9074 kzalloc(sizeof(struct sitesurvey_parm), GFP_ATOMIC);
9077 goto exit_survey_timer_hdl;
9080 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
9081 rtw_enqueue_cmd23a(pcmdpriv, ph2c);
9084 exit_survey_timer_hdl:
9088 static void link_timer_hdl(unsigned long data)
9090 struct rtw_adapter *padapter = (struct rtw_adapter *)data;
9091 /* static unsigned int rx_pkt = 0; */
9092 /* static u64 tx_cnt = 0; */
9093 /* struct xmit_priv *pxmitpriv = &padapter->xmitpriv; */
9094 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9095 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
9096 /* struct sta_priv *pstapriv = &padapter->stapriv; */
9098 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
9100 DBG_8723A("link_timer_hdl:no beacon while connecting\n");
9101 pmlmeinfo->state = WIFI_FW_NULL_STATE;
9102 report_join_res23a(padapter, -3);
9104 else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE)
9107 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT)
9109 /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
9111 pmlmeinfo->state = 0;
9112 report_join_res23a(padapter, -1);
9117 /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
9118 /* pmlmeinfo->reauth_count = 0; */
9122 DBG_8723A("link_timer_hdl: auth timeout and try again\n");
9123 pmlmeinfo->auth_seq = 1;
9124 issue_auth23a(padapter, NULL, 0);
9125 set_link_timer(pmlmeext, REAUTH_TO);
9127 else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)
9129 /* re-assoc timer */
9130 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT)
9132 pmlmeinfo->state = WIFI_FW_NULL_STATE;
9133 report_join_res23a(padapter, -2);
9137 DBG_8723A("link_timer_hdl: assoc timeout and try again\n");
9138 issue_assocreq23a(padapter);
9139 set_link_timer(pmlmeext, REASSOC_TO);
9145 static void addba_timer_hdl(unsigned long data)
9147 struct sta_info *psta = (struct sta_info *)data;
9148 struct ht_priv *phtpriv;
9153 phtpriv = &psta->htpriv;
9155 if ((phtpriv->ht_option == true) && (phtpriv->ampdu_enable == true))
9157 if (phtpriv->candidate_tid_bitmap)
9158 phtpriv->candidate_tid_bitmap = 0x0;
9163 void init_addba_retry_timer23a(struct sta_info *psta)
9165 setup_timer(&psta->addba_retry_timer, addba_timer_hdl,
9166 (unsigned long)psta);
9169 void init_mlme_ext_timer23a(struct rtw_adapter *padapter)
9171 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9173 setup_timer(&pmlmeext->survey_timer, survey_timer_hdl,
9174 (unsigned long)padapter);
9176 setup_timer(&pmlmeext->link_timer, link_timer_hdl,
9177 (unsigned long)padapter);
9180 u8 NULL_hdl23a(struct rtw_adapter *padapter, u8 *pbuf)
9185 u8 setopmode_hdl23a(struct rtw_adapter *padapter, u8 *pbuf)
9188 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9189 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
9190 struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
9192 if (psetop->mode == Ndis802_11APMode)
9194 pmlmeinfo->state = WIFI_FW_AP_STATE;
9195 type = _HW_STATE_AP_;
9197 else if (psetop->mode == Ndis802_11Infrastructure)
9199 pmlmeinfo->state &= ~(BIT(0)|BIT(1));/* clear state */
9200 pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */
9201 type = _HW_STATE_STATION_;
9203 else if (psetop->mode == Ndis802_11IBSS)
9205 type = _HW_STATE_ADHOC_;
9209 type = _HW_STATE_NOLINK_;
9212 rtw_hal_set_hwreg23a(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
9213 /* Set_NETYPE0_MSR(padapter, type); */
9218 u8 createbss_hdl23a(struct rtw_adapter *padapter, u8 *pbuf)
9220 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9221 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
9222 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
9223 struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
9224 /* u32 initialgain; */
9226 if (pparm->InfrastructureMode == Ndis802_11APMode) {
9227 #ifdef CONFIG_8723AU_AP_MODE
9229 if (pmlmeinfo->state == WIFI_FW_AP_STATE)
9237 /* below is for ad-hoc master */
9238 if (pparm->InfrastructureMode == Ndis802_11IBSS) {
9239 rtw_joinbss_reset23a(padapter);
9241 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
9242 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
9243 pmlmeinfo->ERP_enable = 0;
9244 pmlmeinfo->WMM_enable = 0;
9245 pmlmeinfo->HT_enable = 0;
9246 pmlmeinfo->HT_caps_enable = 0;
9247 pmlmeinfo->HT_info_enable = 0;
9248 pmlmeinfo->agg_enable_bitmap = 0;
9249 pmlmeinfo->candidate_tid_bitmap = 0;
9251 /* disable dynamic functions, such as high power, DIG */
9252 Save_DM_Func_Flag23a(padapter);
9253 Switch_DM_Func23a(padapter, DYNAMIC_FUNC_DISABLE, false);
9255 /* config the initial gain under linking, need to write the BB registers */
9256 /* initialgain = 0x1E; */
9257 /* rtw_hal_set_hwreg23a(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */
9259 /* cancel link timer */
9260 del_timer_sync(&pmlmeext->link_timer);
9263 flush_all_cam_entry23a(padapter);
9265 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
9266 return H2C_PARAMETERS_ERROR;
9268 memcpy(pnetwork, pparm, sizeof(struct wlan_bssid_ex));
9270 start_create_ibss23a(padapter);
9276 u8 join_cmd_hdl23a(struct rtw_adapter *padapter, u8 *pbuf)
9279 struct ndis_802_11_var_ies * pIE;
9280 struct registry_priv *pregpriv = &padapter->registrypriv;
9281 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9282 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
9283 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
9284 struct wlan_bssid_ex *pparm = (struct wlan_bssid_ex *)pbuf;
9285 struct HT_info_element *pht_info;
9287 /* u32 initialgain; */
9290 /* check already connecting to AP or not */
9291 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
9293 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
9294 issue_deauth23a_ex23a(padapter, pnetwork->MacAddress,
9295 WLAN_REASON_DEAUTH_LEAVING, 5, 100);
9297 pmlmeinfo->state = WIFI_FW_NULL_STATE;
9300 flush_all_cam_entry23a(padapter);
9302 del_timer_sync(&pmlmeext->link_timer);
9304 /* set MSR to nolink -> infra. mode */
9305 /* Set_MSR23a(padapter, _HW_STATE_NOLINK_); */
9306 Set_MSR23a(padapter, _HW_STATE_STATION_);
9308 rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_DISCONNECT, NULL);
9311 rtw_joinbss_reset23a(padapter);
9313 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
9314 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
9315 pmlmeinfo->ERP_enable = 0;
9316 pmlmeinfo->WMM_enable = 0;
9317 pmlmeinfo->HT_enable = 0;
9318 pmlmeinfo->HT_caps_enable = 0;
9319 pmlmeinfo->HT_info_enable = 0;
9320 pmlmeinfo->agg_enable_bitmap = 0;
9321 pmlmeinfo->candidate_tid_bitmap = 0;
9322 pmlmeinfo->bwmode_updated = false;
9323 /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
9325 if (pparm->IELength > MAX_IE_SZ)/* Check pbuf->IELength */
9326 return H2C_PARAMETERS_ERROR;
9328 memcpy(pnetwork, pbuf, sizeof(struct wlan_bssid_ex));
9330 /* Check AP vendor to move rtw_joinbss_cmd23a() */
9331 /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP23a(pnetwork->IEs,
9332 pnetwork->IELength); */
9334 for (i = sizeof(struct ndis_802_11_fixed_ies); i < pnetwork->IELength;)
9336 pIE = (struct ndis_802_11_var_ies *)(pnetwork->IEs + i);
9338 switch (pIE->ElementID)
9340 case _VENDOR_SPECIFIC_IE_:/* Get WMM IE. */
9341 if (!memcmp(pIE->data, WMM_OUI23A, 4))
9342 pmlmeinfo->WMM_enable = 1;
9345 case _HT_CAPABILITY_IE_: /* Get HT Cap IE. */
9346 pmlmeinfo->HT_caps_enable = 1;
9349 case _HT_EXTRA_INFO_IE_: /* Get HT Info IE. */
9350 pmlmeinfo->HT_info_enable = 1;
9352 /* spec case only for cisco's ap because cisco's ap
9353 * issue assoc rsp using mcs rate @40MHz or @20MHz */
9354 pht_info = (struct HT_info_element *)(pIE->data);
9356 if ((pregpriv->cbw40_enable) &&
9357 (pht_info->infos[0] & BIT(2))) {
9358 /* switch to the 40M Hz mode according to AP */
9359 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
9360 switch (pht_info->infos[0] & 0x3)
9363 pmlmeext->cur_ch_offset =
9364 HAL_PRIME_CHNL_OFFSET_LOWER;
9368 pmlmeext->cur_ch_offset =
9369 HAL_PRIME_CHNL_OFFSET_UPPER;
9373 pmlmeext->cur_ch_offset =
9374 HAL_PRIME_CHNL_OFFSET_DONT_CARE;
9378 DBG_8723A("set ch/bw before connected\n");
9386 i += (pIE->Length + 2);
9388 /* disable dynamic functions, such as high power, DIG */
9389 /* Switch_DM_Func23a(padapter, DYNAMIC_FUNC_DISABLE, false); */
9391 /* config the initial gain under linking, need to write the BB
9393 /* initialgain = 0x1E; */
9394 /* rtw_hal_set_hwreg23a(padapter, HW_VAR_INITIAL_GAIN,
9395 (u8 *)(&initialgain)); */
9397 rtw_hal_set_hwreg23a(padapter, HW_VAR_BSSID,
9398 pmlmeinfo->network.MacAddress);
9400 rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
9402 /* cancel link timer */
9403 del_timer_sync(&pmlmeext->link_timer);
9405 start_clnt_join23a(padapter);
9410 u8 disconnect_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
9412 struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
9413 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9414 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
9415 struct wlan_bssid_ex *pnetwork = &pmlmeinfo->network;
9418 if (is_client_associated_to_ap23a(padapter))
9420 issue_deauth23a_ex23a(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
9423 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
9425 /* pmlmeinfo->state = WIFI_FW_NULL_STATE; */
9427 rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_DISCONNECT, NULL);
9428 rtw_hal_set_hwreg23a(padapter, HW_VAR_BSSID, null_addr);
9430 /* restore to initial setting. */
9431 update_tx_basic_rate23a(padapter, padapter->registrypriv.wireless_mode);
9433 if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
9437 rtw_hal_set_hwreg23a(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
9440 /* set MSR to no link state -> infra. mode */
9441 Set_MSR23a(padapter, _HW_STATE_STATION_);
9443 pmlmeinfo->state = WIFI_FW_NULL_STATE;
9445 /* switch to the 20M Hz mode after disconnect */
9446 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
9447 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
9449 set_channel_bwmode23a(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
9451 flush_all_cam_entry23a(padapter);
9453 del_timer_sync(&pmlmeext->link_timer);
9455 rtw_free_uc_swdec_pending_queue23a(padapter);
9460 static int rtw_scan_ch_decision(struct rtw_adapter *padapter, struct rtw_ieee80211_channel *out,
9461 u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
9464 int scan_ch_num = 0;
9466 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9468 /* clear out first */
9469 memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
9471 /* acquire channels from in */
9473 for (i = 0;i<in_num;i++) {
9475 DBG_8723A(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
9476 if (in[i].hw_value && !(in[i].flags & IEEE80211_CHAN_DISABLED)
9477 && (set_idx = rtw_ch_set_search_ch23a(pmlmeext->channel_set, in[i].hw_value)) >= 0
9480 memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
9482 if (pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
9483 out[j].flags &= IEEE80211_CHAN_NO_IR;
9491 /* if out is empty, use channel_set as default */
9493 for (i = 0;i<pmlmeext->max_chan_nums;i++) {
9494 out[i].hw_value = pmlmeext->channel_set[i].ChannelNum;
9496 if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
9497 out[i].flags &= IEEE80211_CHAN_NO_IR;
9503 if (padapter->setband == GHZ_24) { /* 2.4G */
9504 for (i = 0; i < j ; i++) {
9505 if (out[i].hw_value > 35)
9507 sizeof(struct rtw_ieee80211_channel));
9512 } else if (padapter->setband == GHZ_50) { /* 5G */
9513 for (i = 0; i < j ; i++) {
9514 if (out[i].hw_value > 35) {
9515 memcpy(&out[scan_ch_num++], &out[i], sizeof(struct rtw_ieee80211_channel));
9525 u8 sitesurvey_cmd_hdl23a(struct rtw_adapter *padapter, u8 *pbuf)
9527 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9528 struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
9529 u8 bdelayscan = false;
9534 if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) {
9535 /* for first time sitesurvey_cmd */
9536 rtw_hal_set_hwreg23a(padapter, HW_VAR_CHECK_TXBUF, NULL);
9538 pmlmeext->sitesurvey_res.state = SCAN_START;
9539 pmlmeext->sitesurvey_res.bss_cnt = 0;
9540 pmlmeext->sitesurvey_res.channel_idx = 0;
9542 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
9543 if (pparm->ssid[i].ssid_len) {
9544 memcpy(pmlmeext->sitesurvey_res.ssid[i].ssid,
9545 pparm->ssid[i].ssid, IW_ESSID_MAX_SIZE);
9546 pmlmeext->sitesurvey_res.ssid[i].ssid_len =
9547 pparm->ssid[i].ssid_len;
9549 pmlmeext->sitesurvey_res.ssid[i].ssid_len = 0;
9553 pmlmeext->sitesurvey_res.ch_num =
9554 rtw_scan_ch_decision(padapter,
9555 pmlmeext->sitesurvey_res.ch,
9556 RTW_CHANNEL_SCAN_AMOUNT,
9557 pparm->ch, pparm->ch_num);
9559 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
9561 /* issue null data if associating to the AP */
9562 if (is_client_associated_to_ap23a(padapter)) {
9563 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
9565 /* switch to correct channel of current network
9566 before issue keep-alive frames */
9567 if (rtw_get_oper_ch23a(padapter) != pmlmeext->cur_channel)
9568 SelectChannel23a(padapter, pmlmeext->cur_channel);
9570 issue_nulldata23a(padapter, NULL, 1, 3, 500);
9576 /* delay 50ms to protect nulldata(1). */
9577 set_survey_timer(pmlmeext, 50);
9582 if ((pmlmeext->sitesurvey_res.state == SCAN_START) ||
9583 (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) {
9584 /* disable dynamic functions, such as high power, DIG */
9585 Save_DM_Func_Flag23a(padapter);
9586 Switch_DM_Func23a(padapter, DYNAMIC_FUNC_DISABLE, false);
9588 /* config the initial gain under scaning, need to
9589 write the BB registers */
9590 if ((wdev_to_priv(padapter->rtw_wdev))->p2p_enabled == true) {
9595 rtw_hal_set_hwreg23a(padapter, HW_VAR_INITIAL_GAIN,
9596 (u8 *)(&initialgain));
9598 /* set MSR to no link state */
9599 Set_MSR23a(padapter, _HW_STATE_NOLINK_);
9601 val8 = 1; /* under site survey */
9602 rtw_hal_set_hwreg23a(padapter, HW_VAR_MLME_SITESURVEY,
9605 pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
9608 site_survey23a(padapter);
9613 u8 setauth_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
9615 struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
9616 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9617 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
9619 if (pparm->mode < 4)
9621 pmlmeinfo->auth_algo = pparm->mode;
9627 u8 setkey_hdl23a(struct rtw_adapter *padapter, u8 *pbuf)
9629 unsigned short ctrl;
9630 struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
9631 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9632 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
9633 unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
9635 /* main tx key for wep. */
9637 pmlmeinfo->key_index = pparm->keyid;
9640 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
9642 DBG_8723A_LEVEL(_drv_always_, "set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) "
9643 "keyid:%d\n", pparm->algorithm, pparm->keyid);
9644 write_cam23a(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
9646 /* allow multicast packets to driver */
9647 padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_ON_RCR_AM, null_addr);
9652 u8 set_stakey_hdl23a(struct rtw_adapter *padapter, u8 *pbuf)
9655 u8 cam_id;/* cam_entry */
9656 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9657 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
9658 struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
9661 /* 0~3 for default key */
9663 /* for concurrent mode (ap+sta): */
9664 /* default key is disable, using sw encrypt/decrypt */
9665 /* cam_entry = 4 for sta mode (macid = 0) */
9666 /* cam_entry(macid+3) = 5 ~ N for ap mode (aid = 1~N, macid = 2 ~N) */
9668 /* for concurrent mode (sta+sta): */
9669 /* default key is disable, using sw encrypt/decrypt */
9670 /* cam_entry = 4 mapping to macid = 0 */
9671 /* cam_entry = 5 mapping to macid = 2 */
9675 DBG_8723A_LEVEL(_drv_always_, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) camid:%d\n",
9676 pparm->algorithm, cam_id);
9677 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
9680 struct sta_info *psta;
9681 struct sta_priv *pstapriv = &padapter->stapriv;
9683 if (pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */
9685 clear_cam_entry23a(padapter, pparm->id);
9686 return H2C_SUCCESS_RSP;
9689 psta = rtw_get_stainfo23a(pstapriv, pparm->addr);
9692 ctrl = (BIT(15) | ((pparm->algorithm) << 2));
9694 DBG_8723A("r871x_set_stakey_hdl23a(): enc_algorithm =%d\n", pparm->algorithm);
9696 if ((psta->mac_id<1) || (psta->mac_id>(NUM_STA-4)))
9698 DBG_8723A("r871x_set_stakey_hdl23a():set_stakey failed, mac_id(aid) =%d\n", psta->mac_id);
9699 return H2C_REJECTED;
9702 cam_id = (psta->mac_id + 3);/* 0~3 for default key, cmd_id = macid + 3, macid = aid+1; */
9704 DBG_8723A("Write CAM, mac_addr =%x:%x:%x:%x:%x:%x, cam_entry =%d\n", pparm->addr[0],
9705 pparm->addr[1], pparm->addr[2], pparm->addr[3], pparm->addr[4],
9706 pparm->addr[5], cam_id);
9708 write_cam23a(padapter, cam_id, ctrl, pparm->addr, pparm->key);
9710 return H2C_SUCCESS_RSP;
9715 DBG_8723A("r871x_set_stakey_hdl23a(): sta has been free\n");
9716 return H2C_REJECTED;
9721 /* below for sta mode */
9723 if (pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */
9725 clear_cam_entry23a(padapter, pparm->id);
9729 ctrl = BIT(15) | ((pparm->algorithm) << 2);
9731 write_cam23a(padapter, cam_id, ctrl, pparm->addr, pparm->key);
9733 pmlmeinfo->enc_algo = pparm->algorithm;
9738 u8 add_ba_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
9740 struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
9741 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9742 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
9744 struct sta_info *psta = rtw_get_stainfo23a(&padapter->stapriv, pparm->addr);
9749 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) &&
9750 (pmlmeinfo->HT_enable)) ||
9751 ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
9752 issue_action_BA23a(padapter, pparm->addr,
9753 WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
9754 mod_timer(&psta->addba_retry_timer,
9755 jiffies + msecs_to_jiffies(ADDBA_TO));
9757 psta->htpriv.candidate_tid_bitmap &= ~CHKBIT(pparm->tid);
9762 u8 set_tx_beacon_cmd23a(struct rtw_adapter* padapter)
9764 struct cmd_obj *ph2c;
9765 struct Tx_Beacon_param *ptxBeacon_parm;
9766 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
9767 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9768 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
9774 ph2c = (struct cmd_obj *)kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
9780 ptxBeacon_parm = (struct Tx_Beacon_param *)
9781 kzalloc(sizeof(struct Tx_Beacon_param), GFP_ATOMIC);
9782 if (!ptxBeacon_parm) {
9788 memcpy(&ptxBeacon_parm->network, &pmlmeinfo->network,
9789 sizeof(struct wlan_bssid_ex));
9791 len_diff = update_hidden_ssid(
9792 ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_,
9793 ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_,
9794 pmlmeinfo->hidden_ssid_mode);
9795 ptxBeacon_parm->network.IELength += len_diff;
9797 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
9799 res = rtw_enqueue_cmd23a(pcmdpriv, ph2c);
9808 u8 mlme_evt_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
9810 u8 evt_code, evt_seq;
9813 void (*event_callback)(struct rtw_adapter *dev, u8 *pbuf);
9814 struct evt_priv *pevt_priv = &padapter->evtpriv;
9816 peventbuf = (uint*)pbuf;
9817 evt_sz = (u16)(*peventbuf&0xffff);
9818 evt_seq = (u8)((*peventbuf>>24)&0x7f);
9819 evt_code = (u8)((*peventbuf>>16)&0xff);
9821 /* checking if event code is valid */
9822 if (evt_code >= MAX_C2HEVT) {
9823 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nEvent Code(%d) mismatch!\n", evt_code));
9827 /* checking if event size match the event parm size */
9828 if ((wlanevents[evt_code].parmsize != 0) &&
9829 (wlanevents[evt_code].parmsize != evt_sz)) {
9830 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
9831 evt_code, wlanevents[evt_code].parmsize, evt_sz));
9835 atomic_inc(&pevt_priv->event_seq);
9840 event_callback = wlanevents[evt_code].event_callback;
9841 event_callback(padapter, (u8*)peventbuf);
9843 pevt_priv->evt_done_cnt++;
9851 u8 h2c_msg_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
9854 return H2C_PARAMETERS_ERROR;
9859 u8 tx_beacon_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
9861 if (send_beacon23a(padapter) == _FAIL)
9863 DBG_8723A("issue_beacon23a, fail!\n");
9864 return H2C_PARAMETERS_ERROR;
9866 #ifdef CONFIG_8723AU_AP_MODE
9867 else /* tx bc/mc frames after update TIM */
9869 struct sta_info *psta_bmc;
9870 struct list_head *plist, *phead, *ptmp;
9871 struct xmit_frame *pxmitframe;
9872 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
9873 struct sta_priv *pstapriv = &padapter->stapriv;
9875 /* for BC/MC Frames */
9876 psta_bmc = rtw_get_bcmc_stainfo23a(padapter);
9880 if ((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0))
9882 msleep(10);/* 10ms, ATIM(HIQ) Windows */
9883 /* spin_lock_bh(&psta_bmc->sleep_q.lock); */
9884 spin_lock_bh(&pxmitpriv->lock);
9886 phead = get_list_head(&psta_bmc->sleep_q);
9888 list_for_each_safe(plist, ptmp, phead) {
9889 pxmitframe = container_of(plist,
9893 list_del_init(&pxmitframe->list);
9895 psta_bmc->sleepq_len--;
9896 if (psta_bmc->sleepq_len>0)
9897 pxmitframe->attrib.mdata = 1;
9899 pxmitframe->attrib.mdata = 0;
9901 pxmitframe->attrib.triggered = 1;
9903 pxmitframe->attrib.qsel = 0x11;/* HIQ */
9905 rtw_hal_xmit23aframe_enqueue(padapter, pxmitframe);
9908 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
9909 spin_unlock_bh(&pxmitpriv->lock);
9918 u8 set_ch_hdl23a(struct rtw_adapter *padapter, u8 *pbuf)
9920 struct set_ch_parm *set_ch_parm;
9921 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9924 return H2C_PARAMETERS_ERROR;
9926 set_ch_parm = (struct set_ch_parm *)pbuf;
9928 DBG_8723A(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
9929 FUNC_NDEV_ARG(padapter->pnetdev),
9930 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
9932 pmlmeext->cur_channel = set_ch_parm->ch;
9933 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
9934 pmlmeext->cur_bwmode = set_ch_parm->bw;
9936 set_channel_bwmode23a(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
9941 u8 set_chplan_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
9943 struct SetChannelPlan_param *setChannelPlan_param;
9944 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9947 return H2C_PARAMETERS_ERROR;
9949 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
9951 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
9952 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
9957 u8 led_blink_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
9959 struct LedBlink_param *ledBlink_param;
9962 return H2C_PARAMETERS_ERROR;
9964 ledBlink_param = (struct LedBlink_param *)pbuf;
9969 u8 set_csa_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
9971 return H2C_REJECTED;
9974 /* TDLS_WRCR : write RCR DATA BIT */
9975 /* TDLS_SD_PTI : issue peer traffic indication */
9976 /* TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure */
9977 /* TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame */
9978 /* TDLS_DONE_CH_SEN: channel sensing and report candidate channel */
9979 /* TDLS_OFF_CH : first time set channel to off channel */
9980 /* TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel */
9981 /* TDLS_P_OFF_CH : periodically go to off channel */
9982 /* TDLS_P_BASE_CH : periodically go back to base channel */
9983 /* TDLS_RS_RCR : restore RCR */
9984 /* TDLS_CKALV_PH1 : check alive timer phase1 */
9985 /* TDLS_CKALV_PH2 : check alive timer phase2 */
9986 /* TDLS_FREE_STA : free tdls sta */
9987 u8 tdls_hdl23a(struct rtw_adapter *padapter, unsigned char *pbuf)
9989 return H2C_REJECTED;