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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
20 #define _RTW_MLME_EXT_C_
23 #include <osdep_service.h>
24 #include <drv_types.h>
26 #include <rtw_mlme_ext.h>
27 #include <wlan_bssdef.h>
28 #include <mlme_osdep.h>
29 #include <recv_osdep.h>
30 #include <linux/ieee80211.h>
32 #ifdef CONFIG_BT_COEXIST
33 #include <rtl8723a_hal.h>
36 struct mlme_handler mlme_sta_tbl[]={
37 {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
38 {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
39 {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
40 {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
41 {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
42 {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
44 /*----------------------------------------------------------
46 -----------------------------------------------------------*/
47 {0, "DoReserved", &DoReserved},
48 {0, "DoReserved", &DoReserved},
49 {WIFI_BEACON, "OnBeacon", &OnBeacon},
50 {WIFI_ATIM, "OnATIM", &OnAtim},
51 {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
52 {WIFI_AUTH, "OnAuth", &OnAuthClient},
53 {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
54 {WIFI_ACTION, "OnAction", &OnAction},
57 #ifdef _CONFIG_NATIVEAP_MLME_
58 struct mlme_handler mlme_ap_tbl[]={
59 {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
60 {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
61 {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
62 {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
63 {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
64 {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
66 /*----------------------------------------------------------
68 -----------------------------------------------------------*/
69 {0, "DoReserved", &DoReserved},
70 {0, "DoReserved", &DoReserved},
71 {WIFI_BEACON, "OnBeacon", &OnBeacon},
72 {WIFI_ATIM, "OnATIM", &OnAtim},
73 {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
74 {WIFI_AUTH, "OnAuth", &OnAuth},
75 {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
76 {WIFI_ACTION, "OnAction", &OnAction},
80 struct action_handler OnAction_tbl[]={
81 {RTW_WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct},
82 {RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction_qos},
83 {RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction_dls},
84 {RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back},
85 {RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public},
86 {RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved},
87 {RTW_WLAN_CATEGORY_FT, "ACTION_FT", &DoReserved},
88 {RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht},
89 {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved},
90 {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm},
91 {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p},
94 u8 null_addr[ETH_ALEN]= {0,0,0,0,0,0};
96 /**************************************************
97 OUI definitions for the vendor specific IE
98 ***************************************************/
99 unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
100 unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
101 unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
102 unsigned char P2P_OUI[] = {0x50,0x6F,0x9A,0x09};
103 unsigned char WFD_OUI[] = {0x50,0x6F,0x9A,0x0A};
105 unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
106 unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
108 unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
109 unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
111 extern unsigned char REALTEK_96B_IE[];
113 /********************************************************
115 *********************************************************/
116 #ifdef CONFIG_DISABLE_MCS13TO15
117 unsigned char MCS_rate_2R_MCS13TO15_OFF[16] = {0xff, 0x1f, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
118 unsigned char MCS_rate_2R[16] = {0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
119 #else /* CONFIG_DISABLE_MCS13TO15 */
120 unsigned char MCS_rate_2R[16] = {0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
121 #endif /* CONFIG_DISABLE_MCS13TO15 */
122 unsigned char MCS_rate_1R[16] = {0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
124 /********************************************************
125 ChannelPlan definitions
126 *********************************************************/
128 static RT_CHANNEL_PLAN_2G RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
129 {{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 */
130 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
131 {{1,2,3,4,5,6,7,8,9,10,11},11}, /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
132 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
133 {{10,11,12,13},4}, /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
134 {{},0}, /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */
137 static RT_CHANNEL_PLAN_5G RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
138 {{},0}, /* 0x00, RT_CHANNEL_DOMAIN_5G_NULL */
139 {{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 */
140 {{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 */
141 {{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 */
142 {{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 */
143 {{36,40,44,48,149,153,157,161,165},9}, /* 0x05, RT_CHANNEL_DOMAIN_5G_FCC2 */
144 {{36,40,44,48,52,56,60,64,149,153,157,161,165},13}, /* 0x06, RT_CHANNEL_DOMAIN_5G_FCC3 */
145 {{36,40,44,48,52,56,60,64,149,153,157,161},12}, /* 0x07, RT_CHANNEL_DOMAIN_5G_FCC4 */
146 {{149,153,157,161,165},5}, /* 0x08, RT_CHANNEL_DOMAIN_5G_FCC5 */
147 {{36,40,44,48,52,56,60,64},8}, /* 0x09, RT_CHANNEL_DOMAIN_5G_FCC6 */
148 {{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 */
149 {{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 */
150 {{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 */
151 {{36,40,44,48,52,56,60,64},8}, /* 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 */
152 {{100,104,108,112,116,120,124,128,132,136,140},11}, /* 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 */
153 {{56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},15}, /* 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 */
154 {{56,60,64,149,153,157,161,165},8}, /* 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 */
156 /* Driver self defined for old channel plan Compatible ,Remember to modify if have new channel plan definition ===== */
157 {{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 */
158 {{36,40,44,48},4}, /* 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS */
159 {{36,40,44,48,149,153,157,161},8}, /* 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS */
162 static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
163 /* 0x00 ~ 0x1F , Old Define ===== */
164 {0x02,0x11}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
165 {0x02,0x0A}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
166 {0x01,0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
167 {0x01,0x00}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
168 {0x01,0x00}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
169 {0x03,0x00}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */
170 {0x03,0x00}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
171 {0x01,0x09}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
172 {0x03,0x09}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
173 {0x03,0x00}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
174 {0x00,0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
175 {0x02,0x0F}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
176 {0x01,0x08}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
177 {0x02,0x06}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
178 {0x02,0x0B}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
179 {0x02,0x09}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
180 {0x01,0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
181 {0x02,0x05}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
182 {0x01,0x12}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
183 {0x00,0x04}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
184 {0x02,0x10}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
185 {0x00,0x12}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
186 {0x00,0x13}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
187 {0x03,0x12}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
188 {0x05,0x08}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
189 {0x02,0x08}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
190 {0x00,0x00}, /* 0x1A, */
191 {0x00,0x00}, /* 0x1B, */
192 {0x00,0x00}, /* 0x1C, */
193 {0x00,0x00}, /* 0x1D, */
194 {0x00,0x00}, /* 0x1E, */
195 {0x05,0x04}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
196 /* 0x20 ~ 0x7F ,New Define ===== */
197 {0x00,0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
198 {0x01,0x00}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
199 {0x02,0x00}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
200 {0x03,0x00}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
201 {0x04,0x00}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
202 {0x02,0x04}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
203 {0x00,0x01}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
204 {0x03,0x0C}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
205 {0x00,0x0B}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
206 {0x00,0x05}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
207 {0x00,0x00}, /* 0x2A, */
208 {0x00,0x00}, /* 0x2B, */
209 {0x00,0x00}, /* 0x2C, */
210 {0x00,0x00}, /* 0x2D, */
211 {0x00,0x00}, /* 0x2E, */
212 {0x00,0x00}, /* 0x2F, */
213 {0x00,0x06}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
214 {0x00,0x07}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
215 {0x00,0x08}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
216 {0x00,0x09}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
217 {0x02,0x0A}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
218 {0x00,0x02}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
219 {0x00,0x03}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
220 {0x03,0x0D}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
221 {0x03,0x0E}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
222 {0x02,0x0F}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
223 {0x00,0x00}, /* 0x3A, */
224 {0x00,0x00}, /* 0x3B, */
225 {0x00,0x00}, /* 0x3C, */
226 {0x00,0x00}, /* 0x3D, */
227 {0x00,0x00}, /* 0x3E, */
228 {0x00,0x00}, /* 0x3F, */
229 {0x02,0x10}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
230 {0x03,0x00}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */
233 static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03,0x02}; /* use the conbination for max channel numbers */
236 * Search the @param channel_num in given @param channel_set
237 * @ch_set: the given channel set
238 * @ch: the given channel number
240 * return the index of channel_num in channel_set, -1 if not found
242 int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch)
245 for(i=0;ch_set[i].ChannelNum!=0;i++){
246 if(ch == ch_set[i].ChannelNum)
250 if(i >= ch_set[i].ChannelNum)
255 /****************************************************************************
257 Following are the initialization functions for WiFi MLME
259 *****************************************************************************/
261 int init_hw_mlme_ext(_adapter *padapter)
263 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
265 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
269 static void init_mlme_ext_priv_value(_adapter* padapter)
271 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
272 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
278 unsigned char mixed_datarate[NumRates] = {_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_,_9M_RATE_, _12M_RATE_, _18M_RATE_, _24M_RATE_, _36M_RATE_, _48M_RATE_, _54M_RATE_, 0xff};
279 unsigned char mixed_basicrate[NumRates] ={_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _12M_RATE_, _24M_RATE_, 0xff,};
281 ATOMIC_SET(&pmlmeext->event_seq, 0);
282 pmlmeext->mgnt_seq = 0;/* reset to zero when disconnect at client mode */
284 pmlmeext->cur_channel = padapter->registrypriv.channel;
285 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
286 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
290 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
292 /* memcpy(pmlmeext->channel_set, DefaultChannelPlan[padapter->mlmepriv.ChannelPlan].Channel, DefaultChannelPlan[padapter->mlmepriv.ChannelPlan].Len); */
293 /* memcpy(pmlmeext->channel_set, default_channel_set, MAX_CHANNEL_NUM); */
294 memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
295 memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
297 if(pmlmeext->cur_channel > 14)
298 pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
300 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
302 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
303 pmlmeext->sitesurvey_res.channel_idx = 0;
304 pmlmeext->sitesurvey_res.bss_cnt = 0;
305 pmlmeext->scan_abort = _FALSE;
307 pmlmeinfo->state = WIFI_FW_NULL_STATE;
308 pmlmeinfo->reauth_count = 0;
309 pmlmeinfo->reassoc_count = 0;
310 pmlmeinfo->link_count = 0;
311 pmlmeinfo->auth_seq = 0;
312 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
313 pmlmeinfo->key_index = 0;
316 pmlmeinfo->enc_algo = _NO_PRIVACY_;
317 pmlmeinfo->authModeToggle = 0;
319 memset(pmlmeinfo->chg_txt, 0, 128);
321 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
322 pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
324 pmlmeinfo->dialogToken = 0;
326 pmlmeext->action_public_rxseq = 0xffff;
327 pmlmeext->action_public_dialog_token = 0xff;
330 static int has_channel(RT_CHANNEL_INFO *channel_set,
335 for (i = 0; i < chanset_size; i++) {
336 if (channel_set[i].ChannelNum == chan) {
344 static void init_channel_list(_adapter *padapter, RT_CHANNEL_INFO *channel_set,
346 struct p2p_channels *channel_list) {
348 struct p2p_oper_class_map op_class[] = {
349 { IEEE80211G, 81, 1, 13, 1, BW20 },
350 { IEEE80211G, 82, 14, 14, 1, BW20 },
351 { IEEE80211A, 115, 36, 48, 4, BW20 },
352 { IEEE80211A, 116, 36, 44, 8, BW40PLUS },
353 { IEEE80211A, 117, 40, 48, 8, BW40MINUS },
354 { IEEE80211A, 124, 149, 161, 4, BW20 },
355 { IEEE80211A, 125, 149, 169, 4, BW20 },
356 { IEEE80211A, 126, 149, 157, 8, BW40PLUS },
357 { IEEE80211A, 127, 153, 161, 8, BW40MINUS },
358 { -1, 0, 0, 0, 0, BW20 }
365 for (op = 0; op_class[op].op_class; op++) {
367 struct p2p_oper_class_map *o = &op_class[op];
368 struct p2p_reg_class *reg = NULL;
370 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
371 if (!has_channel(channel_set, chanset_size, ch)) {
375 if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc))
378 if ((0 == (padapter->registrypriv.cbw40_enable & BIT(1))) &&
379 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
383 reg = &channel_list->reg_class[cla];
385 reg->reg_class = o->op_class;
388 reg->channel[reg->channels] = ch;
392 channel_list->reg_classes = cla;
395 static u8 init_channel_set(_adapter* padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel_set)
397 u8 index,chanset_size = 0;
398 u8 b5GBand = _FALSE, b2_4GBand = _FALSE;
399 u8 Index2G = 0, Index5G=0;
401 memset(channel_set, 0, sizeof(RT_CHANNEL_INFO)*MAX_CHANNEL_NUM);
403 if(ChannelPlan >= RT_CHANNEL_DOMAIN_MAX && ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE)
405 DBG_8723A("ChannelPlan ID %x error !!!!!\n",ChannelPlan);
409 if(padapter->registrypriv.wireless_mode & WIRELESS_11G)
412 if(RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
413 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
415 Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
418 if(padapter->registrypriv.wireless_mode & WIRELESS_11A)
421 if(RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
422 Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
424 Index5G = RTW_ChannelPlanMap[ChannelPlan].Index5G;
429 for(index=0;index<RTW_ChannelPlan2G[Index2G].Len;index++)
431 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index];
433 if( (RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == ChannelPlan) ||/* Channel 1~11 is active, and 12~14 is passive */
434 (RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G == ChannelPlan) )
436 if(channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
437 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
438 else if((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14))
439 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
441 else if(RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan ||
442 RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan ||
443 RT_CHANNEL_DOMAIN_2G_WORLD == Index2G)/* channel 12~13, passive scan */
445 if(channel_set[chanset_size].ChannelNum <= 11)
446 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
448 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
452 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
461 for(index=0;index<RTW_ChannelPlan5G[Index5G].Len;index++)
464 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
465 if ( channel_set[chanset_size].ChannelNum <= 48
466 || channel_set[chanset_size].ChannelNum >= 149 )
468 if(RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)/* passive scan for all 5G channels */
469 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
471 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
475 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
478 #else /* CONFIG_DFS */
479 if ( RTW_ChannelPlan5G[Index5G].Channel[index] <= 48
480 || RTW_ChannelPlan5G[Index5G].Channel[index] >= 149 ) {
481 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
482 if(RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)/* passive scan for all 5G channels */
483 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
485 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
486 DBG_8723A("%s(): channel_set[%d].ChannelNum = %d\n", __FUNCTION__, chanset_size, channel_set[chanset_size].ChannelNum);
489 #endif /* CONFIG_DFS */
496 int init_mlme_ext_priv(_adapter* padapter)
499 struct registry_priv* pregistrypriv = &padapter->registrypriv;
500 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
501 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
502 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
504 /* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
505 /* memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv)); */
507 pmlmeext->padapter = padapter;
509 /* fill_fwpriv(padapter, &(pmlmeext->fwpriv)); */
511 init_mlme_ext_priv_value(padapter);
512 pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
514 init_mlme_ext_timer(padapter);
516 #ifdef CONFIG_AP_MODE
517 init_mlme_ap_info(padapter);
520 pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan,pmlmeext->channel_set);
521 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
523 pmlmeext->chan_scan_time = SURVEY_TO;
524 pmlmeext->mlmeext_init = _TRUE;
526 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
527 pmlmeext->active_keep_alive_check = _TRUE;
530 #ifdef DBG_FIXED_CHAN
531 pmlmeext->fixed_chan = 0xFF;
537 void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext)
539 _adapter *padapter = pmlmeext->padapter;
544 if (padapter->bDriverStopped == _TRUE)
546 _cancel_timer_ex(&pmlmeext->survey_timer);
547 _cancel_timer_ex(&pmlmeext->link_timer);
548 /* _cancel_timer_ex(&pmlmeext->ADDBA_timer); */
552 static u8 cmp_pkt_chnl_diff(_adapter *padapter,u8* pframe,uint packet_len)
553 { /* if the channel is same, return 0. else return channel differential */
557 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, _DSSET_IE_, &len, packet_len - _BEACON_IE_OFFSET_);
561 if(padapter->mlmeextpriv.cur_channel >= channel)
563 return (padapter->mlmeextpriv.cur_channel - channel);
567 return (channel-padapter->mlmeextpriv.cur_channel);
576 static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
578 u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
579 u8 *pframe = precv_frame->u.hdr.rx_data;
583 /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
584 if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv),
586 memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
591 ptable->func(padapter, precv_frame);
595 void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame)
598 struct mlme_handler *ptable;
599 #ifdef CONFIG_AP_MODE
600 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
601 #endif /* CONFIG_AP_MODE */
602 u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
603 u8 *pframe = precv_frame->u.hdr.rx_data;
604 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe));
606 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
607 ("+mgt_dispatcher: type(0x%x) subtype(0x%x)\n",
608 GetFrameType(pframe), GetFrameSubType(pframe)));
610 if (GetFrameType(pframe) != WIFI_MGT_TYPE)
612 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("mgt_dispatcher: type(0x%x) error!\n", GetFrameType(pframe)));
616 /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
617 if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv),
619 memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
624 ptable = mlme_sta_tbl;
626 index = GetFrameSubType(pframe) >> 4;
629 if((index << 4)==WIFI_ACTION){
630 /* category==public (4), action==TDLS_DISCOVERY_RESPONSE */
631 if(*(pframe+24)==0x04 && *(pframe+25)==TDLS_DISCOVERY_RESPONSE){
632 DBG_8723A("recv tdls discovery response frame\n");
633 On_TDLS_Dis_Rsp(padapter, precv_frame);
636 #endif /* CONFIG_TDLS */
640 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Currently we do not support reserved sub-fr-type=%d\n", index));
648 if (GetRetry(pframe))
650 if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum)
652 /* drop the duplicate management frame */
653 DBG_8723A("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num);
657 psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
663 /* RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("drop due to decache!\n")); */
668 #ifdef CONFIG_AP_MODE
669 switch (GetFrameSubType(pframe))
672 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
673 ptable->func = &OnAuth;
675 ptable->func = &OnAuthClient;
678 case WIFI_REASSOCREQ:
679 _mgt_dispatcher(padapter, ptable, precv_frame);
680 #ifdef CONFIG_HOSTAPD_MLME
681 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
682 rtw_hostapd_mlme_rx(padapter, precv_frame);
686 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
688 #ifdef CONFIG_HOSTAPD_MLME
689 rtw_hostapd_mlme_rx(padapter, precv_frame);
691 _mgt_dispatcher(padapter, ptable, precv_frame);
695 _mgt_dispatcher(padapter, ptable, precv_frame);
698 _mgt_dispatcher(padapter, ptable, precv_frame);
701 /* if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) */
702 _mgt_dispatcher(padapter, ptable, precv_frame);
705 _mgt_dispatcher(padapter, ptable, precv_frame);
706 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
707 rtw_hostapd_mlme_rx(padapter, precv_frame);
712 _mgt_dispatcher(padapter, ptable, precv_frame);
718 u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da)
720 bool response = _TRUE;
722 #ifdef CONFIG_IOCTL_CFG80211
723 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == _FALSE
724 || padapter->mlmepriv.wps_probe_resp_ie == NULL
725 || padapter->mlmepriv.p2p_probe_resp_ie == NULL
728 DBG_8723A("DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p\n",
729 wdev_to_priv(padapter->rtw_wdev)->p2p_enabled,
730 padapter->mlmepriv.wps_probe_resp_ie,
731 padapter->mlmepriv.p2p_probe_resp_ie);
736 /* do nothing if the device name is empty */
737 if ( !padapter->wdinfo.device_name_len )
743 if (response == _TRUE)
744 issue_probersp_p2p( padapter, da);
748 #endif /* CONFIG_P2P */
750 /****************************************************************************
752 Following are the callback functions for each subtype of the management frames
754 *****************************************************************************/
756 unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame)
760 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
761 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
762 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
763 WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
764 u8 *pframe = precv_frame->u.hdr.rx_data;
765 uint len = precv_frame->u.hdr.len;
766 u8 is_valid_p2p_probereq = _FALSE;
769 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
770 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
771 u8 wifi_test_chk_rate = 1;
773 if ( !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
774 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
775 !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
776 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
777 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
780 /* Commented by Albert 2011/03/17 */
781 /* mcs_rate = 0 -> CCK 1M rate */
782 /* mcs_rate = 1 -> CCK 2M rate */
783 /* mcs_rate = 2 -> CCK 5.5M rate */
784 /* mcs_rate = 3 -> CCK 11M rate */
785 /* In the P2P mode, the driver should not support the CCK rate */
787 /* Commented by Kurt 2012/10/16 */
788 /* IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client */
789 #ifdef CONFIG_WIFI_TEST
790 if ( pattrib->mcs_rate <= 3 )
792 wifi_test_chk_rate = 0;
794 #endif /* CONFIG_WIFI_TEST */
796 if( wifi_test_chk_rate == 1 )
798 if((is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len)) == _TRUE)
800 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE))
802 #ifndef CONFIG_IOCTL_CFG80211
804 report_survey_event(padapter, precv_frame);
806 p2p_listen_state_process( padapter, get_sa(pframe));
811 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
820 #endif /* CONFIG_P2P */
822 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE))
827 if(check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE &&
828 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)==_FALSE)
833 /* DBG_8723A("+OnProbeReq\n"); */
835 #ifdef CONFIG_CONCURRENT_MODE
836 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
837 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
839 /* don't process probe req */
844 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
845 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
847 /* check (wildcard) SSID */
850 if(is_valid_p2p_probereq == _TRUE)
852 goto _issue_probersp;
856 memcmp((void *)(p+2), cur->Ssid.Ssid,
857 cur->Ssid.SsidLength)) ||
858 (ielen == 0 && pmlmeinfo->hidden_ssid_mode))
865 if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
866 pmlmepriv->cur_network.join_res == _TRUE)
868 /* DBG_8723A("+issue_probersp during ap mode\n"); */
869 issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
877 unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
879 struct sta_info *psta;
880 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
881 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
882 struct sta_priv *pstapriv = &padapter->stapriv;
883 u8 *pframe = precv_frame->u.hdr.rx_data;
885 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
889 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
891 if ( _TRUE == pwdinfo->tx_prov_disc_info.benable )
893 if (!memcmp(pwdinfo->tx_prov_disc_info.peerIFAddr,
894 GetAddr2Ptr(pframe), ETH_ALEN))
896 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
898 pwdinfo->tx_prov_disc_info.benable = _FALSE;
899 issue_p2p_provision_request( padapter,
900 pwdinfo->tx_prov_disc_info.ssid.Ssid,
901 pwdinfo->tx_prov_disc_info.ssid.SsidLength,
902 pwdinfo->tx_prov_disc_info.peerDevAddr );
904 else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
906 pwdinfo->tx_prov_disc_info.benable = _FALSE;
907 issue_p2p_provision_request( padapter,
910 pwdinfo->tx_prov_disc_info.peerDevAddr );
916 else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
918 if ( _TRUE == pwdinfo->nego_req_info.benable )
920 DBG_8723A( "[%s] P2P State is GONEGO ING!\n", __FUNCTION__ );
921 if (!memcmp(pwdinfo->nego_req_info.peerDevAddr,
922 GetAddr2Ptr(pframe), ETH_ALEN))
924 pwdinfo->nego_req_info.benable = _FALSE;
925 issue_p2p_GO_request( padapter, pwdinfo->nego_req_info.peerDevAddr);
929 else if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) )
931 if ( _TRUE == pwdinfo->invitereq_info.benable )
933 DBG_8723A( "[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__ );
934 if (!memcmp( pwdinfo->invitereq_info.peer_macaddr,
935 GetAddr2Ptr(pframe), ETH_ALEN))
937 pwdinfo->invitereq_info.benable = _FALSE;
938 issue_p2p_invitation_request( padapter, pwdinfo->invitereq_info.peer_macaddr );
944 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
946 report_survey_event(padapter, precv_frame);
947 #ifdef CONFIG_CONCURRENT_MODE
948 report_survey_event(padapter->pbuddy_adapter, precv_frame);
950 #ifdef CONFIG_DUALMAC_CONCURRENT
951 dc_report_survey_event(padapter, precv_frame);
959 unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
962 struct sta_info *psta;
963 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
964 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
965 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
966 struct sta_priv *pstapriv = &padapter->stapriv;
967 u8 *pframe = precv_frame->u.hdr.rx_data;
968 uint len = precv_frame->u.hdr.len;
974 #ifdef CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR
975 p = rtw_get_ie(pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, _EXT_SUPPORTEDRATES_IE_, &ielen, precv_frame->u.hdr.len -sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_);
976 if ((p != NULL) && (ielen > 0))
978 if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D))
980 /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */
981 DBG_8723A("[WIFIDBG] Error in ESR IE is detected in Beacon of BSSID:"MAC_FMT". Fix the length of ESR IE to avoid failed Beacon parsing.\n", MAC_ARG(GetAddr3Ptr(pframe)));
982 *(p + 1) = ielen - 1;
987 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
989 report_survey_event(padapter, precv_frame);
990 #ifdef CONFIG_CONCURRENT_MODE
991 report_survey_event(padapter->pbuddy_adapter, precv_frame);
994 #ifdef CONFIG_DUALMAC_CONCURRENT
995 dc_report_survey_event(padapter, precv_frame);
1001 if (!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network),
1003 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
1005 /* we should update current network before auth, or some IE is wrong */
1006 pbss = (WLAN_BSSID_EX*)rtw_malloc(sizeof(WLAN_BSSID_EX));
1008 if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
1009 update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
1010 rtw_get_bcn_info(&(pmlmepriv->cur_network));
1012 rtw_mfree((u8*)pbss, sizeof(WLAN_BSSID_EX));
1015 /* check the vendor of the assoc AP */
1016 pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), len-sizeof(struct rtw_ieee80211_hdr_3addr));
1018 /* update TSF Value */
1019 update_TSF(pmlmeext, pframe, len);
1022 start_clnt_auth(padapter);
1027 if(((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
1029 if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1031 #ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
1032 /* Merge from 8712 FW code */
1033 if (cmp_pkt_chnl_diff(padapter,pframe,len) != 0)
1034 { /* join wrong channel, deauth and reconnect */
1035 issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
1037 report_del_sta_event(padapter,(&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL);
1038 pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS);
1041 #endif /* CONFIG_PATCH_JOIN_WRONG_CHANNEL */
1043 ret = rtw_check_bcn_info(padapter, pframe, len);
1045 DBG_8723A_LEVEL(_drv_always_, "ap has changed, disconnect now\n ");
1046 receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 65535);
1049 /* update WMM, ERP in the beacon */
1050 /* todo: the timer is used instead of the number of the beacon received */
1051 if ((sta_rx_pkts(psta) & 0xf) == 0)
1053 /* DBG_8723A("update_bcn_info\n"); */
1054 update_beacon_info(padapter, pframe, len, psta);
1058 process_csa_ie(padapter, pframe, len); /* channel switch announcement */
1059 #endif /* CONFIG_DFS */
1061 #ifdef CONFIG_P2P_PS
1062 process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1063 #endif /* CONFIG_P2P_PS */
1067 else if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
1069 if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1071 /* update WMM, ERP in the beacon */
1072 /* todo: the timer is used instead of the number of the beacon received */
1073 if ((sta_rx_pkts(psta) & 0xf) == 0)
1075 /* DBG_8723A("update_bcn_info\n"); */
1076 update_beacon_info(padapter, pframe, len, psta);
1082 /* allocate a new CAM entry for IBSS station */
1083 if ((cam_idx = allocate_fw_sta_entry(padapter)) == NUM_STA)
1085 goto _END_ONBEACON_;
1088 /* get supported rate */
1089 if (update_sta_support_rate(padapter, (pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_), (len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_), cam_idx) == _FAIL)
1091 pmlmeinfo->FW_sta_info[cam_idx].status = 0;
1092 goto _END_ONBEACON_;
1095 /* update TSF Value */
1096 update_TSF(pmlmeext, pframe, len);
1098 /* report sta add event */
1099 report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx);
1109 unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame)
1111 #ifdef CONFIG_AP_MODE
1113 unsigned int auth_mode, seq, ie_len;
1114 unsigned char *sa, *p;
1117 static struct sta_info stat;
1118 struct sta_info *pstat=NULL;
1119 struct sta_priv *pstapriv = &padapter->stapriv;
1120 struct security_priv *psecuritypriv = &padapter->securitypriv;
1121 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1122 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1123 u8 *pframe = precv_frame->u.hdr.rx_data;
1124 uint len = precv_frame->u.hdr.len;
1126 #ifdef CONFIG_CONCURRENT_MODE
1127 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1128 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1130 /* don't process auth request; */
1133 #endif /* CONFIG_CONCURRENT_MODE */
1135 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1138 DBG_8723A("+OnAuth\n");
1140 sa = GetAddr2Ptr(pframe);
1142 auth_mode = psecuritypriv->dot11AuthAlgrthm;
1143 seq = cpu_to_le16(*(u16*)((unsigned long)pframe + WLAN_HDR_A3_LEN + 2));
1144 algorithm = cpu_to_le16(*(u16*)((unsigned long)pframe + WLAN_HDR_A3_LEN));
1146 DBG_8723A("auth alg=%x, seq=%X\n", algorithm, seq);
1148 if (auth_mode == 2 &&
1149 psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
1150 psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
1153 if ((algorithm > 0 && auth_mode == 0) || /* rx a shared-key auth but shared not enabled */
1154 (algorithm == 0 && auth_mode == 1) ) /* rx a open-system auth but shared-key is enabled */
1156 DBG_8723A("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
1157 algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
1159 status = _STATS_NO_SUPP_ALG_;
1164 if(rtw_access_ctrl(padapter, sa) == _FALSE)
1166 status = _STATS_UNABLE_HANDLE_STA_;
1170 pstat = rtw_get_stainfo(pstapriv, sa);
1173 /* allocate a new one */
1174 DBG_8723A("going to alloc stainfo for sa="MAC_FMT"\n", MAC_ARG(sa));
1175 pstat = rtw_alloc_stainfo(pstapriv, sa);
1178 DBG_8723A(" Exceed the upper limit of supported clients...\n");
1179 status = _STATS_UNABLE_HANDLE_STA_;
1183 pstat->state = WIFI_FW_AUTH_NULL;
1184 pstat->auth_seq = 0;
1186 /* pstat->flags = 0; */
1187 /* pstat->capability = 0; */
1191 spin_lock_bh(&pstapriv->asoc_list_lock);
1192 if(rtw_is_list_empty(&pstat->asoc_list)==_FALSE)
1194 rtw_list_delete(&pstat->asoc_list);
1195 pstapriv->asoc_list_cnt--;
1196 if (pstat->expire_to > 0)
1198 /* TODO: STA re_auth within expire_to */
1201 spin_unlock_bh(&pstapriv->asoc_list_lock);
1204 /* TODO: STA re_auth and auth timeout */
1208 spin_lock_bh(&pstapriv->auth_list_lock);
1209 if (rtw_is_list_empty(&pstat->auth_list))
1211 rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list);
1212 pstapriv->auth_list_cnt++;
1214 spin_unlock_bh(&pstapriv->auth_list_lock);
1216 if (pstat->auth_seq == 0)
1217 pstat->expire_to = pstapriv->auth_to;
1219 if ((pstat->auth_seq + 1) != seq)
1221 DBG_8723A("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
1222 seq, pstat->auth_seq+1);
1223 status = _STATS_OUT_OF_AUTH_SEQ_;
1227 if (algorithm==0 && (auth_mode == 0 || auth_mode == 2))
1231 pstat->state &= ~WIFI_FW_AUTH_NULL;
1232 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1233 pstat->expire_to = pstapriv->assoc_to;
1234 pstat->authalg = algorithm;
1238 DBG_8723A("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
1239 seq, pstat->auth_seq+1);
1240 status = _STATS_OUT_OF_AUTH_SEQ_;
1244 else /* shared system or auto authentication */
1248 /* prepare for the challenging txt... */
1249 pstat->state &= ~WIFI_FW_AUTH_NULL;
1250 pstat->state |= WIFI_FW_AUTH_STATE;
1251 pstat->authalg = algorithm;
1252 pstat->auth_seq = 2;
1256 /* checking for challenging txt... */
1257 DBG_8723A("checking for challenging txt...\n");
1259 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len,
1260 len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
1262 if((p==NULL) || (ie_len<=0))
1264 DBG_8723A("auth rejected because challenge failure!(1)\n");
1265 status = _STATS_CHALLENGE_FAIL_;
1269 if (!memcmp((void *)(p + 2), pstat->chg_txt, 128))
1271 pstat->state &= (~WIFI_FW_AUTH_STATE);
1272 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1273 /* challenging txt is correct... */
1274 pstat->expire_to = pstapriv->assoc_to;
1278 DBG_8723A("auth rejected because challenge failure!\n");
1279 status = _STATS_CHALLENGE_FAIL_;
1285 DBG_8723A("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
1286 seq, pstat->auth_seq+1);
1287 status = _STATS_OUT_OF_AUTH_SEQ_;
1292 /* Now, we are going to issue_auth... */
1293 pstat->auth_seq = seq + 1;
1295 #ifdef CONFIG_NATIVEAP_MLME
1296 issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
1299 if (pstat->state & WIFI_FW_AUTH_SUCCESS)
1300 pstat->auth_seq = 0;
1307 rtw_free_stainfo(padapter , pstat);
1310 memset((char *)pstat, '\0', sizeof(stat));
1311 pstat->auth_seq = 2;
1312 memcpy(pstat->hwaddr, sa, 6);
1314 #ifdef CONFIG_NATIVEAP_MLME
1315 issue_auth(padapter, pstat, (unsigned short)status);
1322 unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame)
1324 unsigned int seq, len, status, algthm, offset;
1326 unsigned int go2asoc = 0;
1327 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1328 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1329 u8 *pframe = precv_frame->u.hdr.rx_data;
1330 uint pkt_len = precv_frame->u.hdr.len;
1332 DBG_8723A("%s\n", __FUNCTION__);
1334 /* check A1 matches or not */
1335 if (memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
1338 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
1341 offset = (GetPrivacy(pframe))? 4: 0;
1343 algthm = le16_to_cpu(*(unsigned short *)((unsigned long)pframe + WLAN_HDR_A3_LEN + offset));
1344 seq = le16_to_cpu(*(unsigned short *)((unsigned long)pframe + WLAN_HDR_A3_LEN + offset + 2));
1345 status = le16_to_cpu(*(unsigned short *)((unsigned long)pframe + WLAN_HDR_A3_LEN + offset + 4));
1349 DBG_8723A("clnt auth fail, status: %d\n", status);
1350 if(status == 13)/* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
1352 if(pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1353 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
1355 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
1356 /* pmlmeinfo->reauth_count = 0; */
1359 set_link_timer(pmlmeext, 1);
1365 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1367 /* legendary shared system */
1368 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
1369 pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
1373 /* DBG_8723A("marc: no challenge text?\n"); */
1377 memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
1378 pmlmeinfo->auth_seq = 3;
1379 issue_auth(padapter, NULL, 0);
1380 set_link_timer(pmlmeext, REAUTH_TO);
1392 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1403 /* this is also illegal */
1404 /* DBG_8723A("marc: clnt auth failed due to illegal seq=%x\n", seq); */
1410 DBG_8723A_LEVEL(_drv_always_, "auth success, start assoc\n");
1411 start_clnt_assoc(padapter);
1417 /* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
1422 unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame)
1424 #ifdef CONFIG_AP_MODE
1426 u16 capab_info, listen_interval;
1427 struct rtw_ieee802_11_elems elems;
1428 struct sta_info *pstat;
1429 unsigned char reassoc, *p, *pos, *wpa_ie;
1430 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
1431 int i, ie_len, wpa_ie_len, left;
1432 unsigned char supportRate[16];
1434 unsigned short status = _STATS_SUCCESSFUL_;
1435 unsigned short frame_type, ie_offset=0;
1436 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1437 struct security_priv *psecuritypriv = &padapter->securitypriv;
1438 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1439 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1440 WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
1441 struct sta_priv *pstapriv = &padapter->stapriv;
1442 u8 *pframe = precv_frame->u.hdr.rx_data;
1443 uint pkt_len = precv_frame->u.hdr.len;
1445 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
1446 u8 p2p_status_code = P2P_STATUS_SUCCESS;
1450 u8 wfd_ie[ 128 ] = { 0x00 };
1452 #endif /* CONFIG_WFD */
1453 #endif /* CONFIG_P2P */
1455 #ifdef CONFIG_CONCURRENT_MODE
1456 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1457 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1459 /* don't process assoc request; */
1462 #endif /* CONFIG_CONCURRENT_MODE */
1464 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1467 frame_type = GetFrameSubType(pframe);
1468 if (frame_type == WIFI_ASSOCREQ)
1471 ie_offset = _ASOCREQ_IE_OFFSET_;
1473 else /* WIFI_REASSOCREQ */
1476 ie_offset = _REASOCREQ_IE_OFFSET_;
1479 if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
1480 DBG_8723A("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
1481 "\n", reassoc, (unsigned long)pkt_len);
1485 pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1486 if (pstat == (struct sta_info *)NULL)
1488 status = _RSON_CLS2_;
1489 goto asoc_class2_error;
1492 capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN);
1493 /* capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN)); */
1494 /* listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2)); */
1495 listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN+2);
1497 left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
1498 pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
1500 DBG_8723A("%s\n", __FUNCTION__);
1502 /* check if this stat has been successfully authenticated/assocated */
1503 if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS))
1505 if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS))
1507 status = _RSON_CLS2_;
1508 goto asoc_class2_error;
1512 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
1513 pstat->state |= WIFI_FW_ASSOC_STATE;
1518 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
1519 pstat->state |= WIFI_FW_ASSOC_STATE;
1522 pstat->capability = capab_info;
1524 /* now parse all ieee802_11 ie to point to elems */
1525 if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
1527 DBG_8723A("STA " MAC_FMT " sent invalid association request\n",
1528 MAC_ARG(pstat->hwaddr));
1529 status = _STATS_FAILURE_;
1530 goto OnAssocReqFail;
1533 /* now we should check all the fields... */
1535 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
1536 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1539 status = _STATS_FAILURE_;
1542 if (ie_len == 0) /* broadcast ssid, however it is not allowed in assocreq */
1543 status = _STATS_FAILURE_;
1546 /* check if ssid match */
1547 if (memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
1548 status = _STATS_FAILURE_;
1550 if (ie_len != cur->Ssid.SsidLength)
1551 status = _STATS_FAILURE_;
1554 if(_STATS_SUCCESSFUL_ != status)
1555 goto OnAssocReqFail;
1557 /* check if the supported rate is ok */
1558 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1560 DBG_8723A("Rx a sta assoc-req which supported rate is empty!\n");
1561 /* use our own rate set as statoin used */
1562 /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
1563 /* supportRateNum = AP_BSSRATE_LEN; */
1565 status = _STATS_FAILURE_;
1566 goto OnAssocReqFail;
1569 memcpy(supportRate, p+2, ie_len);
1570 supportRateNum = ie_len;
1572 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_ , &ie_len,
1573 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1576 if(supportRateNum<=sizeof(supportRate))
1578 memcpy(supportRate+supportRateNum, p+2, ie_len);
1579 supportRateNum += ie_len;
1584 /* todo: mask supportRate between AP & STA -> move to update raid */
1585 /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */
1587 /* update station supportRate */
1588 pstat->bssratelen = supportRateNum;
1589 memcpy(pstat->bssrateset, supportRate, supportRateNum);
1590 UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
1592 /* check RSN/WPA/WPS */
1593 pstat->dot8021xalg = 0;
1595 pstat->wpa_group_cipher = 0;
1596 pstat->wpa2_group_cipher = 0;
1597 pstat->wpa_pairwise_cipher = 0;
1598 pstat->wpa2_pairwise_cipher = 0;
1599 memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
1600 if((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
1602 int group_cipher=0, pairwise_cipher=0;
1604 wpa_ie = elems.rsn_ie;
1605 wpa_ie_len = elems.rsn_ie_len;
1607 if(rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1608 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1609 pstat->wpa_psk |= BIT(1);
1611 pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher;
1612 pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher;
1614 if(!pstat->wpa2_group_cipher)
1615 status = WLAN_REASON_INVALID_GROUP_CIPHER;
1617 if(!pstat->wpa2_pairwise_cipher)
1618 status = WLAN_REASON_INVALID_PAIRWISE_CIPHER;
1620 status = WLAN_STATUS_INVALID_IE;
1623 } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
1625 int group_cipher=0, pairwise_cipher=0;
1627 wpa_ie = elems.wpa_ie;
1628 wpa_ie_len = elems.wpa_ie_len;
1630 if(rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1631 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1632 pstat->wpa_psk |= BIT(0);
1634 pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher;
1635 pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher;
1637 if(!pstat->wpa_group_cipher)
1638 status = WLAN_STATUS_INVALID_GROUP_CIPHER;
1640 if(!pstat->wpa_pairwise_cipher)
1641 status = WLAN_STATUS_INVALID_PAIRWISE_CIPHER;
1644 status = WLAN_STATUS_INVALID_IE;
1652 if(_STATS_SUCCESSFUL_ != status)
1653 goto OnAssocReqFail;
1655 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
1656 if(wpa_ie == NULL) {
1658 DBG_8723A("STA included WPS IE in "
1659 "(Re)Association Request - assume WPS is "
1661 pstat->flags |= WLAN_STA_WPS;
1663 DBG_8723A("STA did not include WPA/RSN IE "
1664 "in (Re)Association Request - possible WPS "
1666 pstat->flags |= WLAN_STA_MAYBE_WPS;
1669 /* AP support WPA/RSN, and sta is going to do WPS, but AP is not ready */
1670 /* that the selected registrar of AP is _FLASE */
1671 if ((psecuritypriv->wpa_psk > 0) &&
1672 (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS))) {
1673 if(pmlmepriv->wps_beacon_ie) {
1674 u8 selected_registrar = 0;
1676 rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len,
1677 WPS_ATTR_SELECTED_REGISTRAR , &selected_registrar, NULL);
1679 if(!selected_registrar) {
1680 DBG_8723A("selected_registrar is _FALSE , or AP is not ready to do WPS\n");
1682 status = _STATS_UNABLE_HANDLE_STA_;
1684 goto OnAssocReqFail;
1691 if(psecuritypriv->wpa_psk == 0) {
1692 DBG_8723A("STA " MAC_FMT ": WPA/RSN IE in association "
1693 "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr));
1695 status = WLAN_STATUS_INVALID_IE;
1697 goto OnAssocReqFail;
1701 DBG_8723A("STA included WPS IE in "
1702 "(Re)Association Request - WPS is "
1704 pstat->flags |= WLAN_STA_WPS;
1707 copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2);
1711 memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
1715 /* check if there is WMM IE & support WWM-PS */
1716 pstat->flags &= ~WLAN_STA_WME;
1717 pstat->qos_option = 0;
1718 pstat->qos_info = 0;
1719 pstat->has_legacy_ac = _TRUE;
1720 pstat->uapsd_vo = 0;
1721 pstat->uapsd_vi = 0;
1722 pstat->uapsd_be = 0;
1723 pstat->uapsd_bk = 0;
1724 if (pmlmepriv->qospriv.qos_option)
1726 p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
1729 p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1731 if (!memcmp(p+2, WMM_IE, 6)) {
1733 pstat->flags |= WLAN_STA_WME;
1735 pstat->qos_option = 1;
1736 pstat->qos_info = *(p+8);
1738 pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
1740 if((pstat->qos_info&0xf) !=0xf)
1741 pstat->has_legacy_ac = _TRUE;
1743 pstat->has_legacy_ac = _FALSE;
1745 if(pstat->qos_info&0xf)
1747 if(pstat->qos_info&BIT(0))
1748 pstat->uapsd_vo = BIT(0)|BIT(1);
1750 pstat->uapsd_vo = 0;
1752 if(pstat->qos_info&BIT(1))
1753 pstat->uapsd_vi = BIT(0)|BIT(1);
1755 pstat->uapsd_vi = 0;
1757 if(pstat->qos_info&BIT(2))
1758 pstat->uapsd_bk = BIT(0)|BIT(1);
1760 pstat->uapsd_bk = 0;
1762 if(pstat->qos_info&BIT(3))
1763 pstat->uapsd_be = BIT(0)|BIT(1);
1765 pstat->uapsd_be = 0;
1779 #ifdef CONFIG_80211N_HT
1780 /* save HT capabilities in the sta object */
1781 memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap));
1782 if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct ieee80211_ht_cap))
1784 pstat->flags |= WLAN_STA_HT;
1786 pstat->flags |= WLAN_STA_WME;
1788 memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct ieee80211_ht_cap));
1791 pstat->flags &= ~WLAN_STA_HT;
1793 if((pmlmepriv->htpriv.ht_option == _FALSE) && (pstat->flags&WLAN_STA_HT))
1795 status = _STATS_FAILURE_;
1796 goto OnAssocReqFail;
1799 if ((pstat->flags & WLAN_STA_HT) &&
1800 ((pstat->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||
1801 (pstat->wpa_pairwise_cipher&WPA_CIPHER_TKIP)))
1803 DBG_8723A("HT: " MAC_FMT " tried to "
1804 "use TKIP with HT association\n", MAC_ARG(pstat->hwaddr));
1806 /* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */
1807 /* goto OnAssocReqFail; */
1809 #endif /* CONFIG_80211N_HT */
1812 pstat->flags |= WLAN_STA_NONERP;
1813 for (i = 0; i < pstat->bssratelen; i++) {
1814 if ((pstat->bssrateset[i] & 0x7f) > 22) {
1815 pstat->flags &= ~WLAN_STA_NONERP;
1820 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1821 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
1823 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1825 if (status != _STATS_SUCCESSFUL_)
1826 goto OnAssocReqFail;
1829 pstat->is_p2p_device = _FALSE;
1830 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
1832 if( (p2pie=rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen)))
1834 pstat->is_p2p_device = _TRUE;
1835 if((p2p_status_code=(u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat))>0)
1837 pstat->p2p_status_code = p2p_status_code;
1838 status = _STATS_CAP_FAIL_;
1839 goto OnAssocReqFail;
1843 if(rtw_get_wfd_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , wfd_ie, &wfd_ielen ))
1845 u8 attr_content[ 10 ] = { 0x00 };
1846 u32 attr_contentlen = 0;
1848 DBG_8723A( "[%s] WFD IE Found!!\n", __FUNCTION__ );
1849 rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
1850 if ( attr_contentlen )
1852 pwdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 );
1853 DBG_8723A( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport );
1858 pstat->p2p_status_code = p2p_status_code;
1859 #endif /* CONFIG_P2P */
1861 /* TODO: identify_proprietary_vendor_ie(); */
1862 /* Realtek proprietary IE */
1863 /* identify if this is Broadcom sta */
1864 /* identify if this is ralink sta */
1865 /* Customer proprietary IE */
1867 /* get a unique AID */
1868 if (pstat->aid > 0) {
1869 DBG_8723A(" old AID %d\n", pstat->aid);
1871 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
1872 if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
1875 if (pstat->aid > NUM_STA)
1876 pstat->aid = NUM_STA;
1877 if (pstat->aid > pstapriv->max_num_sta) {
1881 DBG_8723A(" no room for more AIDs\n");
1883 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1885 goto OnAssocReqFail;
1888 pstapriv->sta_aid[pstat->aid - 1] = pstat;
1889 DBG_8723A("allocate new AID = (%d)\n", pstat->aid);
1893 pstat->state &= (~WIFI_FW_ASSOC_STATE);
1894 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
1896 spin_lock_bh(&pstapriv->auth_list_lock);
1897 if (!rtw_is_list_empty(&pstat->auth_list))
1899 rtw_list_delete(&pstat->auth_list);
1900 pstapriv->auth_list_cnt--;
1902 spin_unlock_bh(&pstapriv->auth_list_lock);
1904 spin_lock_bh(&pstapriv->asoc_list_lock);
1905 if (rtw_is_list_empty(&pstat->asoc_list))
1907 pstat->expire_to = pstapriv->expire_to;
1908 rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list);
1909 pstapriv->asoc_list_cnt++;
1911 spin_unlock_bh(&pstapriv->asoc_list_lock);
1913 /* now the station is qualified to join our BSS... */
1914 if(pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_==status))
1916 #ifdef CONFIG_NATIVEAP_MLME
1917 /* 1 bss_cap_update & sta_info_update */
1918 bss_cap_update_on_sta_join(padapter, pstat);
1919 sta_info_update(padapter, pstat);
1921 /* issue assoc rsp before notify station join event. */
1922 if (frame_type == WIFI_ASSOCREQ)
1923 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
1925 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
1927 /* 2 - report to upper layer */
1928 DBG_8723A("indicate_sta_join_event to upper layer - hostapd\n");
1929 #ifdef CONFIG_IOCTL_CFG80211
1931 #ifdef COMPAT_KERNEL_RELEASE
1932 rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
1933 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
1934 rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
1935 #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) */
1936 spin_lock_bh(&pstat->lock);
1937 if(pstat->passoc_req)
1939 rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
1940 pstat->passoc_req = NULL;
1941 pstat->assoc_req_len = 0;
1944 pstat->passoc_req = rtw_zmalloc(pkt_len);
1945 if(pstat->passoc_req)
1947 memcpy(pstat->passoc_req, pframe, pkt_len);
1948 pstat->assoc_req_len = pkt_len;
1950 spin_unlock_bh(&pstat->lock);
1951 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) */
1954 #endif /* CONFIG_IOCTL_CFG80211 */
1956 rtw_indicate_sta_assoc_event(padapter, pstat);
1959 /* 3-(1) report sta add event */
1960 report_add_sta_event(padapter, pstat->hwaddr, pstat->aid);
1968 #ifdef CONFIG_NATIVEAP_MLME
1969 issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
1976 #ifdef CONFIG_NATIVEAP_MLME
1978 if (frame_type == WIFI_ASSOCREQ)
1979 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
1981 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
1984 #endif /* CONFIG_AP_MODE */
1989 unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame)
1993 unsigned short status;
1994 PNDIS_802_11_VARIABLE_IEs pIE;
1995 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1996 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1997 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1998 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
1999 u8 *pframe = precv_frame->u.hdr.rx_data;
2000 uint pkt_len = precv_frame->u.hdr.len;
2001 PNDIS_802_11_VARIABLE_IEs pWapiIE = NULL;
2003 DBG_8723A("%s\n", __FUNCTION__);
2005 /* check A1 matches or not */
2006 if (memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
2009 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
2012 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
2015 _cancel_timer_ex(&pmlmeext->link_timer);
2018 if ((status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2))) > 0)
2020 DBG_8723A("assoc reject, status code: %d\n", status);
2021 pmlmeinfo->state = WIFI_FW_NULL_STATE;
2023 goto report_assoc_result;
2026 /* get capabilities */
2027 pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2030 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
2033 res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff);
2035 /* following are moved to join event callback function */
2036 /* to handle HT, WMM, rate adaptive, update MAC reg */
2037 /* for not to handle the synchronous IO in the tasklet */
2038 for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;)
2040 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
2042 switch (pIE->ElementID)
2044 case _VENDOR_SPECIFIC_IE_:
2045 if (!memcmp(pIE->data, WMM_PARA_OUI, 6))/* WMM */
2047 WMM_param_handler(padapter, pIE);
2049 #if defined(CONFIG_P2P) && defined(CONFIG_WFD)
2050 else if (!memcmp(pIE->data, WFD_OUI, 4))/* WFD */
2052 DBG_8723A( "[%s] Found WFD IE\n", __FUNCTION__ );
2053 WFD_info_handler( padapter, pIE );
2058 #ifdef CONFIG_WAPI_SUPPORT
2064 case _HT_CAPABILITY_IE_: /* HT caps */
2065 HT_caps_handler(padapter, pIE);
2068 case _HT_EXTRA_INFO_IE_: /* HT info */
2069 HT_info_handler(padapter, pIE);
2073 ERP_IE_handler(padapter, pIE);
2079 i += (pIE->Length + 2);
2082 #ifdef CONFIG_WAPI_SUPPORT
2083 rtw_wapi_on_assoc_ok(padapter, pIE);
2086 pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
2087 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
2089 /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
2090 UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
2092 report_assoc_result:
2094 rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
2096 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
2099 report_join_res(padapter, res);
2104 unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame)
2106 unsigned short reason;
2107 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2108 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2109 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2110 u8 *pframe = precv_frame->u.hdr.rx_data;
2112 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
2113 #endif /* CONFIG_P2P */
2116 if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network),
2121 if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
2123 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
2124 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
2126 #endif /* CONFIG_P2P */
2128 reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2130 DBG_8723A("%s Reason code(%d)\n", __FUNCTION__,reason);
2132 #ifdef CONFIG_AP_MODE
2133 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
2136 struct sta_info *psta;
2137 struct sta_priv *pstapriv = &padapter->stapriv;
2139 /* spin_lock_bh(&(pstapriv->sta_hash_lock)); */
2140 /* rtw_free_stainfo(padapter, psta); */
2141 /* spin_unlock_bh(&(pstapriv->sta_hash_lock)); */
2143 DBG_8723A_LEVEL(_drv_always_, "ap recv deauth reason code(%d) sta:%pM\n",
2144 reason, GetAddr2Ptr(pframe));
2146 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2151 spin_lock_bh(&pstapriv->asoc_list_lock);
2152 if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
2154 rtw_list_delete(&psta->asoc_list);
2155 pstapriv->asoc_list_cnt--;
2156 updated = ap_free_sta(padapter, psta, _FALSE, reason);
2159 spin_unlock_bh(&pstapriv->asoc_list_lock);
2161 associated_clients_update(padapter, updated);
2169 DBG_8723A_LEVEL(_drv_always_, "sta recv deauth reason code(%d) sta:%pM\n",
2170 reason, GetAddr3Ptr(pframe));
2172 receive_disconnect(padapter, GetAddr3Ptr(pframe) ,reason);
2174 pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
2178 unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame)
2180 unsigned short reason;
2181 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2182 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2183 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2184 u8 *pframe = precv_frame->u.hdr.rx_data;
2186 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
2187 #endif /* CONFIG_P2P */
2190 if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
2194 if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
2196 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
2197 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
2199 #endif /* CONFIG_P2P */
2201 reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2203 DBG_8723A("%s Reason code(%d)\n", __FUNCTION__,reason);
2205 #ifdef CONFIG_AP_MODE
2206 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
2209 struct sta_info *psta;
2210 struct sta_priv *pstapriv = &padapter->stapriv;
2212 /* spin_lock_bh(&(pstapriv->sta_hash_lock)); */
2213 /* rtw_free_stainfo(padapter, psta); */
2214 /* spin_unlock_bh(&(pstapriv->sta_hash_lock)); */
2216 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n",
2217 reason, GetAddr2Ptr(pframe));
2219 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2224 spin_lock_bh(&pstapriv->asoc_list_lock);
2225 if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
2227 rtw_list_delete(&psta->asoc_list);
2228 pstapriv->asoc_list_cnt--;
2229 updated = ap_free_sta(padapter, psta, _FALSE, reason);
2232 spin_unlock_bh(&pstapriv->asoc_list_lock);
2234 associated_clients_update(padapter, updated);
2242 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n",
2243 reason, GetAddr3Ptr(pframe));
2245 receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
2247 pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
2251 unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame)
2253 DBG_8723A("%s\n", __FUNCTION__);
2257 unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len)
2259 unsigned int ret = _FAIL;
2260 struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
2261 struct mlme_ext_info *pmlmeinfo = &(mlmeext->mlmext_info);
2263 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
2268 if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
2270 int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1;
2273 struct ieee80211_info_element *ie;
2275 DBG_8723A(FUNC_NDEV_FMT" from "MAC_FMT"\n",
2276 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->hwaddr));
2278 for_each_ie(ie, ies, ies_len) {
2279 if (ie->id == WLAN_EID_CHANNEL_SWITCH) {
2280 ch_switch_mode = ie->data[0];
2282 ch_switch_cnt = ie->data[2];
2283 DBG_8723A("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n",
2284 ch_switch_mode, ch, ch_switch_cnt);
2286 else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) {
2287 ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]);
2288 DBG_8723A("ch_offset:%d\n", ch_offset);
2295 if (ch_offset == -1)
2296 bwmode = mlmeext->cur_bwmode;
2298 bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ?
2299 HT_CHANNEL_WIDTH_20 : HT_CHANNEL_WIDTH_40;
2301 ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset;
2304 * 1. the decision of channel switching
2305 * 2. things after channel switching
2308 ret = rtw_set_ch_cmd(padapter, ch, bwmode, ch_offset, _TRUE);
2315 unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame)
2317 unsigned int ret = _FAIL;
2318 struct sta_info *psta = NULL;
2319 struct sta_priv *pstapriv = &padapter->stapriv;
2320 u8 *pframe = precv_frame->u.hdr.rx_data;
2321 uint frame_len = precv_frame->u.hdr.len;
2322 u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
2326 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
2328 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2333 category = frame_body[0];
2334 if(category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
2337 action = frame_body[1];
2339 case RTW_WLAN_ACTION_SPCT_MSR_REQ:
2340 case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
2341 case RTW_WLAN_ACTION_SPCT_TPC_REQ:
2342 case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
2344 case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
2345 #ifdef CONFIG_SPCT_CH_SWITCH
2346 ret = on_action_spct_ch_switch(padapter, psta, &frame_body[2],
2347 frame_len-(frame_body-pframe)-2);
2358 unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame)
2363 unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame)
2368 unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame)
2371 struct sta_info *psta=NULL;
2372 struct recv_reorder_ctrl *preorder_ctrl;
2373 unsigned char *frame_body;
2374 unsigned char category, action;
2375 unsigned short tid, status, reason_code = 0;
2376 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2377 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2378 u8 *pframe = precv_frame->u.hdr.rx_data;
2379 struct sta_priv *pstapriv = &padapter->stapriv;
2380 #ifdef CONFIG_80211N_HT
2381 /* check RA matches or not */
2382 if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))/* for if1, sta/ap mode */
2385 DBG_8723A("%s\n", __FUNCTION__);
2387 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
2388 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
2391 addr = GetAddr2Ptr(pframe);
2392 psta = rtw_get_stainfo(pstapriv, addr);
2397 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
2399 category = frame_body[0];
2400 if (category == RTW_WLAN_CATEGORY_BACK)/* representing Block Ack */
2403 if((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
2404 (psta->htpriv.ht_option==_TRUE) &&
2405 (psta->htpriv.ampdu_enable==_TRUE) )
2407 /* do nothing; just don't want to return _SUCCESS; */
2409 #endif /* CONFIG_TDLS */
2410 if (!pmlmeinfo->HT_enable)
2412 action = frame_body[1];
2413 DBG_8723A("%s, action=%d\n", __FUNCTION__, action);
2415 case RTW_WLAN_ACTION_ADDBA_REQ: /* ADDBA request */
2416 memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
2417 /* process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe)); */
2418 process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), addr);
2420 if(pmlmeinfo->bAcceptAddbaReq == _TRUE)
2421 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 0);
2423 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 37);/* reject ADDBA Req */
2425 case RTW_WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
2426 status = RTW_GET_LE16(&frame_body[3]);
2427 tid = ((frame_body[5] >> 2) & 0x7);
2428 if (status == 0) { /* successful */
2429 DBG_8723A("agg_enable for TID=%d\n", tid);
2430 psta->htpriv.agg_enable_bitmap |= 1 << tid;
2431 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
2433 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
2437 case RTW_WLAN_ACTION_DELBA: /* DELBA */
2438 if ((frame_body[3] & BIT(3)) == 0) {
2439 psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
2440 psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
2442 /* reason_code = frame_body[4] | (frame_body[5] << 8); */
2443 reason_code = RTW_GET_LE16(&frame_body[4]);
2444 } else if((frame_body[3] & BIT(3)) == BIT(3)) {
2445 tid = (frame_body[3] >> 4) & 0x0F;
2447 preorder_ctrl = &psta->recvreorder_ctrl[tid];
2448 preorder_ctrl->enable = _FALSE;
2449 preorder_ctrl->indicate_seq = 0xffff;
2451 DBG_8723A("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
2452 preorder_ctrl->indicate_seq);
2456 DBG_8723A("%s(): DELBA: %x(%x)\n", __FUNCTION__,pmlmeinfo->agg_enable_bitmap, reason_code);
2457 /* todo: how to notify the host while receiving DELETE BA */
2463 #endif /* CONFIG_80211N_HT */
2469 static int get_reg_classes_full_count(struct p2p_channels channel_list) {
2473 for (i = 0; i < channel_list.reg_classes; i++) {
2474 cnt += channel_list.reg_class[i].channels;
2480 static void get_channel_cnt_24g_5gl_5gh( struct mlme_ext_priv *pmlmeext, u8* p24g_cnt, u8* p5gl_cnt, u8* p5gh_cnt )
2488 for( i = 0; i < pmlmeext->max_chan_nums; i++ )
2490 if ( pmlmeext->channel_set[ i ].ChannelNum <= 14 )
2494 else if ( ( pmlmeext->channel_set[ i ].ChannelNum > 14 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 48 ) )
2496 /* Just include the channel 36, 40, 44, 48 channels for 5G low */
2499 else if ( ( pmlmeext->channel_set[ i ].ChannelNum >= 149 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 161 ) )
2501 /* Just include the channel 149, 153, 157, 161 channels for 5G high */
2507 void issue_p2p_GO_request(_adapter *padapter, u8* raddr)
2510 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
2511 u8 action = P2P_PUB_ACTION_ACTION;
2512 u32 p2poui = cpu_to_be32(P2POUI);
2513 u8 oui_subtype = P2P_GO_NEGO_REQ;
2514 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
2515 u8 wpsielen = 0, p2pielen = 0, i;
2516 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
2517 u16 len_channellist_attr = 0;
2520 #endif /* CONFIG_WFD */
2522 struct xmit_frame *pmgntframe;
2523 struct pkt_attrib *pattrib;
2524 unsigned char *pframe;
2525 struct rtw_ieee80211_hdr *pwlanhdr;
2526 unsigned short *fctrl;
2527 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2528 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2529 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2530 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
2532 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
2537 DBG_8723A( "[%s] In\n", __FUNCTION__ );
2538 /* update attribute */
2539 pattrib = &pmgntframe->attrib;
2540 update_mgntframe_attrib(padapter, pattrib);
2542 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2544 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2545 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
2547 fctrl = &(pwlanhdr->frame_ctl);
2550 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
2551 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
2552 memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
2554 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2555 pmlmeext->mgnt_seq++;
2556 SetFrameSubType(pframe, WIFI_ACTION);
2558 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
2559 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
2561 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
2562 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
2563 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
2564 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
2565 pwdinfo->negotiation_dialog_token = 1; /* Initialize the dialog value */
2566 pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen));
2571 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
2576 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
2580 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
2584 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
2586 /* Device Password ID */
2588 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
2592 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
2597 if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN )
2599 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
2601 else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN )
2603 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
2605 else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC )
2607 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
2612 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
2614 /* P2P IE Section. */
2618 p2pie[ p2pielen++ ] = 0x50;
2619 p2pie[ p2pielen++ ] = 0x6F;
2620 p2pie[ p2pielen++ ] = 0x9A;
2621 p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
2623 /* Commented by Albert 20110306 */
2624 /* According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes */
2625 /* 1. P2P Capability */
2626 /* 2. Group Owner Intent */
2627 /* 3. Configuration Timeout */
2628 /* 4. Listen Channel */
2629 /* 5. Extended Listen Timing */
2630 /* 6. Intended P2P Interface Address */
2631 /* 7. Channel List */
2632 /* 8. P2P Device Info */
2633 /* 9. Operating Channel */
2635 /* P2P Capability */
2637 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
2640 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
2644 /* Device Capability Bitmap, 1 byte */
2645 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
2647 /* Group Capability Bitmap, 1 byte */
2648 if ( pwdinfo->persistent_supported )
2650 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
2654 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
2657 /* Group Owner Intent */
2659 p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
2662 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
2666 /* Todo the tie breaker bit. */
2667 p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
2669 /* Configuration Timeout */
2671 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
2674 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
2678 p2pie[ p2pielen++ ] = 200; /* 2 seconds needed to be the P2P GO */
2679 p2pie[ p2pielen++ ] = 200; /* 2 seconds needed to be the P2P Client */
2681 /* Listen Channel */
2683 p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
2686 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
2690 /* Country String */
2691 p2pie[ p2pielen++ ] = 'X';
2692 p2pie[ p2pielen++ ] = 'X';
2694 /* The third byte should be set to 0x04. */
2695 /* Described in the "Operating Channel Attribute" section. */
2696 p2pie[ p2pielen++ ] = 0x04;
2698 /* Operating Class */
2699 p2pie[ p2pielen++ ] = 0x51; /* Copy from SD7 */
2701 /* Channel Number */
2702 p2pie[ p2pielen++ ] = pwdinfo->listen_channel; /* listening channel number */
2704 /* Extended Listen Timing ATTR */
2706 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
2709 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
2713 /* Availability Period */
2714 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
2717 /* Availability Interval */
2718 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
2721 /* Intended P2P Interface Address */
2723 p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
2726 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
2730 memcpy(p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
2731 p2pielen += ETH_ALEN;
2735 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
2738 /* Country String(3) */
2739 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
2740 /* + number of channels in all classes */
2741 len_channellist_attr = 3
2742 + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
2743 + get_reg_classes_full_count(pmlmeext->channel_list);
2745 #ifdef CONFIG_CONCURRENT_MODE
2746 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
2748 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
2752 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
2756 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
2762 /* Country String */
2763 p2pie[ p2pielen++ ] = 'X';
2764 p2pie[ p2pielen++ ] = 'X';
2766 /* The third byte should be set to 0x04. */
2767 /* Described in the "Operating Channel Attribute" section. */
2768 p2pie[ p2pielen++ ] = 0x04;
2770 /* Channel Entry List */
2772 #ifdef CONFIG_CONCURRENT_MODE
2773 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
2775 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
2776 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
2778 /* Operating Class */
2779 if ( pbuddy_mlmeext->cur_channel > 14 )
2781 if ( pbuddy_mlmeext->cur_channel >= 149 )
2783 p2pie[ p2pielen++ ] = 0x7c;
2787 p2pie[ p2pielen++ ] = 0x73;
2792 p2pie[ p2pielen++ ] = 0x51;
2795 /* Number of Channels */
2796 /* Just support 1 channel and this channel is AP's channel */
2797 p2pie[ p2pielen++ ] = 1;
2800 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
2805 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
2806 /* Operating Class */
2807 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
2809 /* Number of Channels */
2810 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
2813 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
2814 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
2818 #else /* CONFIG_CONCURRENT_MODE */
2821 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
2822 /* Operating Class */
2823 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
2825 /* Number of Channels */
2826 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
2829 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
2830 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
2834 #endif /* CONFIG_CONCURRENT_MODE */
2838 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
2841 /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
2842 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
2843 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
2847 /* P2P Device Address */
2848 memcpy(p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
2849 p2pielen += ETH_ALEN;
2852 /* This field should be big endian. Noted by P2P specification. */
2854 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
2858 /* Primary Device Type */
2860 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
2864 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
2867 /* Sub Category ID */
2868 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
2871 /* Number of Secondary Device Types */
2872 p2pie[ p2pielen++ ] = 0x00; /* No Secondary Device Type List */
2876 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
2880 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
2884 memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
2885 p2pielen += pwdinfo->device_name_len;
2887 /* Operating Channel */
2889 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
2892 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
2896 /* Country String */
2897 p2pie[ p2pielen++ ] = 'X';
2898 p2pie[ p2pielen++ ] = 'X';
2900 /* The third byte should be set to 0x04. */
2901 /* Described in the "Operating Channel Attribute" section. */
2902 p2pie[ p2pielen++ ] = 0x04;
2904 /* Operating Class */
2905 if ( pwdinfo->operating_channel <= 14 )
2907 /* Operating Class */
2908 p2pie[ p2pielen++ ] = 0x51;
2910 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
2912 /* Operating Class */
2913 p2pie[ p2pielen++ ] = 0x73;
2917 /* Operating Class */
2918 p2pie[ p2pielen++ ] = 0x7c;
2921 /* Channel Number */
2922 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; /* operating channel number */
2924 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
2927 wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
2929 pattrib->pktlen += wfdielen;
2930 #endif /* CONFIG_WFD */
2932 pattrib->last_txcmdsz = pattrib->pktlen;
2934 dump_mgntframe(padapter, pmgntframe);
2939 void issue_p2p_GO_response(_adapter *padapter, u8* raddr, u8* frame_body,uint len, u8 result)
2942 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
2943 u8 action = P2P_PUB_ACTION_ACTION;
2944 u32 p2poui = cpu_to_be32(P2POUI);
2945 u8 oui_subtype = P2P_GO_NEGO_RESP;
2946 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
2949 u16 wps_devicepassword_id = 0x0000;
2950 uint wps_devicepassword_id_len = 0;
2951 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
2952 u16 len_channellist_attr = 0;
2954 struct xmit_frame *pmgntframe;
2955 struct pkt_attrib *pattrib;
2956 unsigned char *pframe;
2957 struct rtw_ieee80211_hdr *pwlanhdr;
2958 unsigned short *fctrl;
2959 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2960 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2961 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2962 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
2966 #endif /* CONFIG_WFD */
2968 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
2973 DBG_8723A( "[%s] In, result = %d\n", __FUNCTION__, result );
2974 /* update attribute */
2975 pattrib = &pmgntframe->attrib;
2976 update_mgntframe_attrib(padapter, pattrib);
2978 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2980 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2981 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
2983 fctrl = &(pwlanhdr->frame_ctl);
2986 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
2987 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
2988 memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
2990 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2991 pmlmeext->mgnt_seq++;
2992 SetFrameSubType(pframe, WIFI_ACTION);
2994 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
2995 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
2997 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
2998 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
2999 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
3000 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
3001 pwdinfo->negotiation_dialog_token = frame_body[7]; /* The Dialog Token of provisioning discovery request frame. */
3002 pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
3004 /* Commented by Albert 20110328 */
3005 /* Try to get the device password ID from the WPS IE of group negotiation request frame */
3006 /* WiFi Direct test plan 5.1.15 */
3007 rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
3008 rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
3009 wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
3011 memset( wpsie, 0x00, 255 );
3017 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
3022 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
3026 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
3030 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
3032 /* Device Password ID */
3034 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
3038 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
3042 if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
3044 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
3046 else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
3048 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
3052 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
3056 /* Commented by Kurt 20120113 */
3057 /* If some device wants to do p2p handshake without sending prov_disc_req */
3058 /* We have to get peer_req_cm from here. */
3059 if (!memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) )
3061 if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
3063 memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 );
3065 else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
3067 memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 );
3071 memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 );
3075 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
3077 /* P2P IE Section. */
3081 p2pie[ p2pielen++ ] = 0x50;
3082 p2pie[ p2pielen++ ] = 0x6F;
3083 p2pie[ p2pielen++ ] = 0x9A;
3084 p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
3086 /* Commented by Albert 20100908 */
3087 /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
3089 /* 2. P2P Capability */
3090 /* 3. Group Owner Intent */
3091 /* 4. Configuration Timeout */
3092 /* 5. Operating Channel */
3093 /* 6. Intended P2P Interface Address */
3094 /* 7. Channel List */
3095 /* 8. Device Info */
3096 /* 9. Group ID ( Only GO ) */
3102 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
3105 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3109 p2pie[ p2pielen++ ] = result;
3111 /* P2P Capability */
3113 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
3116 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3120 /* Device Capability Bitmap, 1 byte */
3122 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
3124 /* Commented by Albert 2011/03/08 */
3125 /* According to the P2P specification */
3126 /* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
3127 p2pie[ p2pielen++ ] = 0;
3131 /* Be group owner or meet the error case */
3132 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
3135 /* Group Capability Bitmap, 1 byte */
3136 if ( pwdinfo->persistent_supported )
3138 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
3142 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
3145 /* Group Owner Intent */
3147 p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
3150 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3154 if ( pwdinfo->peer_intent & 0x01 )
3156 /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
3157 p2pie[ p2pielen++ ] = ( pwdinfo->intent << 1 );
3161 /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
3162 p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
3165 /* Configuration Timeout */
3167 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
3170 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3174 p2pie[ p2pielen++ ] = 200; /* 2 seconds needed to be the P2P GO */
3175 p2pie[ p2pielen++ ] = 200; /* 2 seconds needed to be the P2P Client */
3177 /* Operating Channel */
3179 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
3182 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
3186 /* Country String */
3187 p2pie[ p2pielen++ ] = 'X';
3188 p2pie[ p2pielen++ ] = 'X';
3190 /* The third byte should be set to 0x04. */
3191 /* Described in the "Operating Channel Attribute" section. */
3192 p2pie[ p2pielen++ ] = 0x04;
3194 /* Operating Class */
3195 if ( pwdinfo->operating_channel <= 14 )
3197 /* Operating Class */
3198 p2pie[ p2pielen++ ] = 0x51;
3200 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
3202 /* Operating Class */
3203 p2pie[ p2pielen++ ] = 0x73;
3207 /* Operating Class */
3208 p2pie[ p2pielen++ ] = 0x7c;
3211 /* Channel Number */
3212 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; /* operating channel number */
3214 /* Intended P2P Interface Address */
3216 p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
3219 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
3223 memcpy(p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
3224 p2pielen += ETH_ALEN;
3228 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
3230 /* Country String(3) */
3231 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
3232 /* + number of channels in all classes */
3233 len_channellist_attr = 3
3234 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
3235 + get_reg_classes_full_count(pmlmeext->channel_list);
3237 #ifdef CONFIG_CONCURRENT_MODE
3238 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3240 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
3244 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3248 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3254 /* Country String */
3255 p2pie[ p2pielen++ ] = 'X';
3256 p2pie[ p2pielen++ ] = 'X';
3258 /* The third byte should be set to 0x04. */
3259 /* Described in the "Operating Channel Attribute" section. */
3260 p2pie[ p2pielen++ ] = 0x04;
3262 /* Channel Entry List */
3264 #ifdef CONFIG_CONCURRENT_MODE
3265 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3267 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
3268 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3270 /* Operating Class */
3271 if ( pbuddy_mlmeext->cur_channel > 14 )
3273 if ( pbuddy_mlmeext->cur_channel >= 149 )
3275 p2pie[ p2pielen++ ] = 0x7c;
3279 p2pie[ p2pielen++ ] = 0x73;
3284 p2pie[ p2pielen++ ] = 0x51;
3287 /* Number of Channels */
3288 /* Just support 1 channel and this channel is AP's channel */
3289 p2pie[ p2pielen++ ] = 1;
3292 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
3297 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
3298 /* Operating Class */
3299 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
3301 /* Number of Channels */
3302 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
3305 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
3306 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
3310 #else /* CONFIG_CONCURRENT_MODE */
3313 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
3314 /* Operating Class */
3315 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
3317 /* Number of Channels */
3318 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
3321 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
3322 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
3326 #endif /* CONFIG_CONCURRENT_MODE */
3330 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
3333 /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
3334 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
3335 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
3339 /* P2P Device Address */
3340 memcpy(p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
3341 p2pielen += ETH_ALEN;
3344 /* This field should be big endian. Noted by P2P specification. */
3346 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
3350 /* Primary Device Type */
3352 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
3356 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
3359 /* Sub Category ID */
3360 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
3363 /* Number of Secondary Device Types */
3364 p2pie[ p2pielen++ ] = 0x00; /* No Secondary Device Type List */
3368 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
3372 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
3376 memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
3377 p2pielen += pwdinfo->device_name_len;
3379 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
3381 /* Group ID Attribute */
3383 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
3386 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
3390 /* p2P Device Address */
3391 memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
3392 p2pielen += ETH_ALEN;
3395 memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
3396 p2pielen += pwdinfo->nego_ssidlen;
3400 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
3403 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
3405 pattrib->pktlen += wfdielen;
3406 #endif /* CONFIG_WFD */
3408 pattrib->last_txcmdsz = pattrib->pktlen;
3410 dump_mgntframe(padapter, pmgntframe);
3415 void issue_p2p_GO_confirm(_adapter *padapter, u8* raddr, u8 result)
3418 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3419 u8 action = P2P_PUB_ACTION_ACTION;
3420 u32 p2poui = cpu_to_be32(P2POUI);
3421 u8 oui_subtype = P2P_GO_NEGO_CONF;
3422 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
3423 u8 wpsielen = 0, p2pielen = 0;
3425 struct xmit_frame *pmgntframe;
3426 struct pkt_attrib *pattrib;
3427 unsigned char *pframe;
3428 struct rtw_ieee80211_hdr *pwlanhdr;
3429 unsigned short *fctrl;
3430 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3431 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3432 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3433 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
3436 #endif /* CONFIG_WFD */
3438 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3443 DBG_8723A( "[%s] In\n", __FUNCTION__ );
3444 /* update attribute */
3445 pattrib = &pmgntframe->attrib;
3446 update_mgntframe_attrib(padapter, pattrib);
3448 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3450 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3451 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3453 fctrl = &(pwlanhdr->frame_ctl);
3456 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3457 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3458 memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
3460 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3461 pmlmeext->mgnt_seq++;
3462 SetFrameSubType(pframe, WIFI_ACTION);
3464 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3465 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3467 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3468 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3469 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
3470 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
3471 pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
3473 /* P2P IE Section. */
3477 p2pie[ p2pielen++ ] = 0x50;
3478 p2pie[ p2pielen++ ] = 0x6F;
3479 p2pie[ p2pielen++ ] = 0x9A;
3480 p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
3482 /* Commented by Albert 20110306 */
3483 /* According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes */
3485 /* 2. P2P Capability */
3486 /* 3. Operating Channel */
3487 /* 4. Channel List */
3488 /* 5. Group ID ( if this WiFi is GO ) */
3492 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
3495 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3499 p2pie[ p2pielen++ ] = result;
3501 /* P2P Capability */
3503 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
3506 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3510 /* Device Capability Bitmap, 1 byte */
3511 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
3513 /* Group Capability Bitmap, 1 byte */
3514 if ( pwdinfo->persistent_supported )
3516 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
3520 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
3523 /* Operating Channel */
3525 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
3528 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
3532 /* Country String */
3533 p2pie[ p2pielen++ ] = 'X';
3534 p2pie[ p2pielen++ ] = 'X';
3536 /* The third byte should be set to 0x04. */
3537 /* Described in the "Operating Channel Attribute" section. */
3538 p2pie[ p2pielen++ ] = 0x04;
3540 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
3542 if ( pwdinfo->peer_operating_ch <= 14 )
3544 /* Operating Class */
3545 p2pie[ p2pielen++ ] = 0x51;
3547 else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
3549 /* Operating Class */
3550 p2pie[ p2pielen++ ] = 0x73;
3554 /* Operating Class */
3555 p2pie[ p2pielen++ ] = 0x7c;
3558 p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
3562 if ( pwdinfo->operating_channel <= 14 )
3564 /* Operating Class */
3565 p2pie[ p2pielen++ ] = 0x51;
3567 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
3569 /* Operating Class */
3570 p2pie[ p2pielen++ ] = 0x73;
3574 /* Operating Class */
3575 p2pie[ p2pielen++ ] = 0x7c;
3578 /* Channel Number */
3579 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; /* Use the listen channel as the operating channel */
3584 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
3587 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( pwdinfo->channel_list_attr_len );
3591 memcpy(p2pie + p2pielen, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len );
3592 p2pielen += pwdinfo->channel_list_attr_len;
3594 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
3596 /* Group ID Attribute */
3598 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
3601 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
3605 /* p2P Device Address */
3606 memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
3607 p2pielen += ETH_ALEN;
3610 memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
3611 p2pielen += pwdinfo->nego_ssidlen;
3614 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
3617 wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
3619 pattrib->pktlen += wfdielen;
3620 #endif /* CONFIG_WFD */
3622 pattrib->last_txcmdsz = pattrib->pktlen;
3624 dump_mgntframe(padapter, pmgntframe);
3629 void issue_p2p_invitation_request(_adapter *padapter, u8* raddr )
3632 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3633 u8 action = P2P_PUB_ACTION_ACTION;
3634 u32 p2poui = cpu_to_be32(P2POUI);
3635 u8 oui_subtype = P2P_INVIT_REQ;
3636 u8 p2pie[ 255 ] = { 0x00 };
3639 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
3640 u16 len_channellist_attr = 0;
3643 #endif /* CONFIG_WFD */
3644 #ifdef CONFIG_CONCURRENT_MODE
3645 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
3646 struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
3647 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
3648 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3651 struct xmit_frame *pmgntframe;
3652 struct pkt_attrib *pattrib;
3653 unsigned char *pframe;
3654 struct rtw_ieee80211_hdr *pwlanhdr;
3655 unsigned short *fctrl;
3656 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3657 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3658 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3659 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
3661 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3666 /* update attribute */
3667 pattrib = &pmgntframe->attrib;
3668 update_mgntframe_attrib(padapter, pattrib);
3670 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3672 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3673 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3675 fctrl = &(pwlanhdr->frame_ctl);
3678 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3679 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3680 memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
3682 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3683 pmlmeext->mgnt_seq++;
3684 SetFrameSubType(pframe, WIFI_ACTION);
3686 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3687 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3689 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3690 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3691 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
3692 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
3693 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
3695 /* P2P IE Section. */
3699 p2pie[ p2pielen++ ] = 0x50;
3700 p2pie[ p2pielen++ ] = 0x6F;
3701 p2pie[ p2pielen++ ] = 0x9A;
3702 p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
3704 /* Commented by Albert 20101011 */
3705 /* According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes */
3706 /* 1. Configuration Timeout */
3707 /* 2. Invitation Flags */
3708 /* 3. Operating Channel ( Only GO ) */
3709 /* 4. P2P Group BSSID ( Should be included if I am the GO ) */
3710 /* 5. Channel List */
3711 /* 6. P2P Group ID */
3712 /* 7. P2P Device Info */
3714 /* Configuration Timeout */
3716 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
3719 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3723 p2pie[ p2pielen++ ] = 200; /* 2 seconds needed to be the P2P GO */
3724 p2pie[ p2pielen++ ] = 200; /* 2 seconds needed to be the P2P Client */
3726 /* Invitation Flags */
3728 p2pie[ p2pielen++ ] = P2P_ATTR_INVITATION_FLAGS;
3731 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3735 p2pie[ p2pielen++ ] = P2P_INVITATION_FLAGS_PERSISTENT;
3737 /* Operating Channel */
3739 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
3742 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
3746 /* Country String */
3747 p2pie[ p2pielen++ ] = 'X';
3748 p2pie[ p2pielen++ ] = 'X';
3750 /* The third byte should be set to 0x04. */
3751 /* Described in the "Operating Channel Attribute" section. */
3752 p2pie[ p2pielen++ ] = 0x04;
3754 /* Operating Class */
3755 if ( pwdinfo->invitereq_info.operating_ch <= 14 )
3756 p2pie[ p2pielen++ ] = 0x51;
3757 else if ( ( pwdinfo->invitereq_info.operating_ch >= 36 ) && ( pwdinfo->invitereq_info.operating_ch <= 48 ) )
3758 p2pie[ p2pielen++ ] = 0x73;
3760 p2pie[ p2pielen++ ] = 0x7c;
3762 /* Channel Number */
3763 p2pie[ p2pielen++ ] = pwdinfo->invitereq_info.operating_ch; /* operating channel number */
3765 if (!memcmp(myid(&padapter->eeprompriv),
3766 pwdinfo->invitereq_info.go_bssid, ETH_ALEN))
3768 /* P2P Group BSSID */
3770 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
3773 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
3777 /* P2P Device Address for GO */
3778 memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
3779 p2pielen += ETH_ALEN;
3784 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
3787 /* Country String(3) */
3788 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
3789 /* + number of channels in all classes */
3790 len_channellist_attr = 3
3791 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
3792 + get_reg_classes_full_count(pmlmeext->channel_list);
3794 #ifdef CONFIG_CONCURRENT_MODE
3795 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3797 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
3801 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3805 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3811 /* Country String */
3812 p2pie[ p2pielen++ ] = 'X';
3813 p2pie[ p2pielen++ ] = 'X';
3815 /* The third byte should be set to 0x04. */
3816 /* Described in the "Operating Channel Attribute" section. */
3817 p2pie[ p2pielen++ ] = 0x04;
3819 /* Channel Entry List */
3820 #ifdef CONFIG_CONCURRENT_MODE
3821 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3823 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
3824 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3826 /* Operating Class */
3827 if ( pbuddy_mlmeext->cur_channel > 14 )
3829 if ( pbuddy_mlmeext->cur_channel >= 149 )
3831 p2pie[ p2pielen++ ] = 0x7c;
3835 p2pie[ p2pielen++ ] = 0x73;
3840 p2pie[ p2pielen++ ] = 0x51;
3843 /* Number of Channels */
3844 /* Just support 1 channel and this channel is AP's channel */
3845 p2pie[ p2pielen++ ] = 1;
3848 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
3853 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
3854 /* Operating Class */
3855 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
3857 /* Number of Channels */
3858 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
3861 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
3862 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
3866 #else /* CONFIG_CONCURRENT_MODE */
3869 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
3870 /* Operating Class */
3871 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
3873 /* Number of Channels */
3874 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
3877 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
3878 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
3882 #endif /* CONFIG_CONCURRENT_MODE */
3886 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
3889 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 6 + pwdinfo->invitereq_info.ssidlen );
3893 /* P2P Device Address for GO */
3894 memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
3895 p2pielen += ETH_ALEN;
3898 memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen );
3899 p2pielen += pwdinfo->invitereq_info.ssidlen;
3903 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
3906 /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
3907 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
3908 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
3912 /* P2P Device Address */
3913 memcpy(p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
3914 p2pielen += ETH_ALEN;
3917 /* This field should be big endian. Noted by P2P specification. */
3918 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
3921 /* Primary Device Type */
3923 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
3927 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
3930 /* Sub Category ID */
3931 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
3934 /* Number of Secondary Device Types */
3935 p2pie[ p2pielen++ ] = 0x00; /* No Secondary Device Type List */
3939 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
3943 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
3947 memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
3948 p2pielen += pwdinfo->device_name_len;
3950 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
3953 wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
3955 pattrib->pktlen += wfdielen;
3956 #endif /* CONFIG_WFD */
3958 pattrib->last_txcmdsz = pattrib->pktlen;
3960 dump_mgntframe(padapter, pmgntframe);
3965 void issue_p2p_invitation_response(_adapter *padapter, u8* raddr, u8 dialogToken, u8 status_code)
3968 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3969 u8 action = P2P_PUB_ACTION_ACTION;
3970 u32 p2poui = cpu_to_be32(P2POUI);
3971 u8 oui_subtype = P2P_INVIT_RESP;
3972 u8 p2pie[ 255 ] = { 0x00 };
3974 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
3975 u16 len_channellist_attr = 0;
3976 #ifdef CONFIG_CONCURRENT_MODE
3977 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
3978 struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
3979 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
3980 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3984 #endif /* CONFIG_WFD */
3986 struct xmit_frame *pmgntframe;
3987 struct pkt_attrib *pattrib;
3988 unsigned char *pframe;
3989 struct rtw_ieee80211_hdr *pwlanhdr;
3990 unsigned short *fctrl;
3991 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3992 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3993 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3994 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
3996 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4001 /* update attribute */
4002 pattrib = &pmgntframe->attrib;
4003 update_mgntframe_attrib(padapter, pattrib);
4005 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4007 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4008 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4010 fctrl = &(pwlanhdr->frame_ctl);
4013 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4014 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
4015 memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
4017 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4018 pmlmeext->mgnt_seq++;
4019 SetFrameSubType(pframe, WIFI_ACTION);
4021 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4022 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4024 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4025 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4026 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4027 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4028 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
4030 /* P2P IE Section. */
4034 p2pie[ p2pielen++ ] = 0x50;
4035 p2pie[ p2pielen++ ] = 0x6F;
4036 p2pie[ p2pielen++ ] = 0x9A;
4037 p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
4039 /* Commented by Albert 20101005 */
4040 /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
4042 /* 2. Configuration Timeout */
4043 /* 3. Operating Channel ( Only GO ) */
4044 /* 4. P2P Group BSSID ( Only GO ) */
4045 /* 5. Channel List */
4049 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
4052 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4056 /* When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE. */
4057 /* Sent the event receiving the P2P Invitation Req frame to DMP UI. */
4058 /* DMP had to compare the MAC address to find out the profile. */
4059 /* So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB. */
4060 /* If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req */
4061 /* to NB to rebuild the persistent group. */
4062 p2pie[ p2pielen++ ] = status_code;
4064 /* Configuration Timeout */
4066 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
4069 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4073 p2pie[ p2pielen++ ] = 200; /* 2 seconds needed to be the P2P GO */
4074 p2pie[ p2pielen++ ] = 200; /* 2 seconds needed to be the P2P Client */
4076 if( status_code == P2P_STATUS_SUCCESS )
4078 if( rtw_p2p_chk_role( pwdinfo, P2P_ROLE_GO ) )
4080 /* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
4081 /* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
4082 /* First one is operating channel attribute. */
4083 /* Second one is P2P Group BSSID attribute. */
4085 /* Operating Channel */
4087 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4090 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4094 /* Country String */
4095 p2pie[ p2pielen++ ] = 'X';
4096 p2pie[ p2pielen++ ] = 'X';
4098 /* The third byte should be set to 0x04. */
4099 /* Described in the "Operating Channel Attribute" section. */
4100 p2pie[ p2pielen++ ] = 0x04;
4102 /* Operating Class */
4103 p2pie[ p2pielen++ ] = 0x51; /* Copy from SD7 */
4105 /* Channel Number */
4106 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; /* operating channel number */
4108 /* P2P Group BSSID */
4110 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
4113 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
4117 /* P2P Device Address for GO */
4118 memcpy(p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
4119 p2pielen += ETH_ALEN;
4125 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4128 /* Country String(3) */
4129 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
4130 /* + number of channels in all classes */
4131 len_channellist_attr = 3
4132 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
4133 + get_reg_classes_full_count(pmlmeext->channel_list);
4135 #ifdef CONFIG_CONCURRENT_MODE
4136 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4138 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
4142 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4146 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4152 /* Country String */
4153 p2pie[ p2pielen++ ] = 'X';
4154 p2pie[ p2pielen++ ] = 'X';
4156 /* The third byte should be set to 0x04. */
4157 /* Described in the "Operating Channel Attribute" section. */
4158 p2pie[ p2pielen++ ] = 0x04;
4160 /* Channel Entry List */
4161 #ifdef CONFIG_CONCURRENT_MODE
4162 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4164 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4165 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4167 /* Operating Class */
4168 if ( pbuddy_mlmeext->cur_channel > 14 )
4170 if ( pbuddy_mlmeext->cur_channel >= 149 )
4172 p2pie[ p2pielen++ ] = 0x7c;
4176 p2pie[ p2pielen++ ] = 0x73;
4181 p2pie[ p2pielen++ ] = 0x51;
4184 /* Number of Channels */
4185 /* Just support 1 channel and this channel is AP's channel */
4186 p2pie[ p2pielen++ ] = 1;
4189 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
4194 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4195 /* Operating Class */
4196 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4198 /* Number of Channels */
4199 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4202 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4203 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4207 #else /* CONFIG_CONCURRENT_MODE */
4210 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4211 /* Operating Class */
4212 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4214 /* Number of Channels */
4215 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4218 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4219 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4223 #endif /* CONFIG_CONCURRENT_MODE */
4226 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4229 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
4231 pattrib->pktlen += wfdielen;
4232 #endif /* CONFIG_WFD */
4234 pattrib->last_txcmdsz = pattrib->pktlen;
4236 dump_mgntframe(padapter, pmgntframe);
4241 void issue_p2p_provision_request(_adapter *padapter, u8* pssid, u8 ussidlen, u8* pdev_raddr )
4243 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4244 u8 action = P2P_PUB_ACTION_ACTION;
4246 u32 p2poui = cpu_to_be32(P2POUI);
4247 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
4248 u8 wpsie[ 100 ] = { 0x00 };
4253 #endif /* CONFIG_WFD */
4255 struct xmit_frame *pmgntframe;
4256 struct pkt_attrib *pattrib;
4257 unsigned char *pframe;
4258 struct rtw_ieee80211_hdr *pwlanhdr;
4259 unsigned short *fctrl;
4260 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4261 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4262 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4263 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4265 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4270 DBG_8723A( "[%s] In\n", __FUNCTION__ );
4271 /* update attribute */
4272 pattrib = &pmgntframe->attrib;
4273 update_mgntframe_attrib(padapter, pattrib);
4275 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4277 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4278 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4280 fctrl = &(pwlanhdr->frame_ctl);
4283 memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
4284 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
4285 memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
4287 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4288 pmlmeext->mgnt_seq++;
4289 SetFrameSubType(pframe, WIFI_ACTION);
4291 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4292 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4294 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4295 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4296 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4297 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4298 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
4300 p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, pssid, ussidlen, pdev_raddr );
4303 pattrib->pktlen += p2pielen;
4307 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
4312 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
4316 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4320 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
4324 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
4328 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4332 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
4335 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
4338 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
4340 pattrib->pktlen += wfdielen;
4341 #endif /* CONFIG_WFD */
4343 pattrib->last_txcmdsz = pattrib->pktlen;
4345 dump_mgntframe(padapter, pmgntframe);
4350 u8 is_matched_in_profilelist( u8* peermacaddr, struct profile_info* profileinfo )
4352 u8 i, match_result = 0;
4354 DBG_8723A( "[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
4355 peermacaddr[0], peermacaddr[1],peermacaddr[2],peermacaddr[3],peermacaddr[4],peermacaddr[5]);
4357 for( i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++ )
4359 DBG_8723A( "[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
4360 profileinfo->peermac[0], profileinfo->peermac[1],profileinfo->peermac[2],profileinfo->peermac[3],profileinfo->peermac[4],profileinfo->peermac[5]);
4361 if (!memcmp(peermacaddr, profileinfo->peermac, ETH_ALEN))
4364 DBG_8723A( "[%s] Match!\n", __FUNCTION__ );
4369 return (match_result );
4372 void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
4374 struct xmit_frame *pmgntframe;
4375 struct pkt_attrib *pattrib;
4376 unsigned char *pframe;
4377 struct rtw_ieee80211_hdr *pwlanhdr;
4378 unsigned short *fctrl;
4380 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4381 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4382 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4383 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4384 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
4385 u16 beacon_interval = 100;
4387 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4388 u8 wpsie[255] = { 0x00 };
4389 u32 wpsielen = 0, p2pielen = 0;
4392 #endif /* CONFIG_WFD */
4393 #ifdef CONFIG_IOCTL_CFG80211
4394 struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
4395 struct ieee80211_channel *ieee_ch = &pcfg80211_wdinfo->remain_on_ch_channel;
4396 u8 listen_channel = (u8) ieee80211_frequency_to_channel(ieee_ch->center_freq);
4397 #endif /* CONFIG_IOCTL_CFG80211 */
4398 #ifdef CONFIG_INTEL_WIDI
4399 u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
4400 #endif /* CONFIG_INTEL_WIDI */
4402 /* DBG_8723A("%s\n", __FUNCTION__); */
4404 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4409 /* update attribute */
4410 pattrib = &pmgntframe->attrib;
4411 update_mgntframe_attrib(padapter, pattrib);
4413 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4415 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4416 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4418 mac = myid(&(padapter->eeprompriv));
4420 fctrl = &(pwlanhdr->frame_ctl);
4422 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
4423 memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
4425 /* Use the device address for BSSID field. */
4426 memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
4428 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4429 pmlmeext->mgnt_seq++;
4430 SetFrameSubType(fctrl, WIFI_PROBERSP);
4432 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4433 pattrib->pktlen = pattrib->hdrlen;
4434 pframe += pattrib->hdrlen;
4436 /* timestamp will be inserted by hardware */
4438 pattrib->pktlen += 8;
4440 /* beacon interval: 2 bytes */
4441 memcpy(pframe, (unsigned char *) &beacon_interval, 2);
4443 pattrib->pktlen += 2;
4445 /* capability info: 2 bytes */
4446 /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
4447 capInfo |= cap_ShortPremble;
4448 capInfo |= cap_ShortSlot;
4450 memcpy(pframe, (unsigned char *) &capInfo, 2);
4452 pattrib->pktlen += 2;
4455 pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
4457 /* supported rates... */
4458 /* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
4459 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
4461 /* DS parameter set */
4462 #ifdef CONFIG_IOCTL_CFG80211
4463 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && listen_channel !=0 )
4465 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&listen_channel, &pattrib->pktlen);
4468 #endif /* CONFIG_IOCTL_CFG80211 */
4470 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
4473 #ifdef CONFIG_IOCTL_CFG80211
4474 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
4476 if( pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL )
4479 memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
4480 pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
4481 pframe += pmlmepriv->wps_probe_resp_ie_len;
4484 memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
4485 pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
4486 pframe += pmlmepriv->p2p_probe_resp_ie_len;
4490 #endif /* CONFIG_IOCTL_CFG80211 */
4494 /* Noted by Albert 20100907 */
4495 /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
4499 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
4504 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
4508 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4512 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
4514 #ifdef CONFIG_INTEL_WIDI
4515 /* Commented by Kurt */
4516 /* Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext. */
4517 if (memcmp(pmlmepriv->sa_ext, zero_array_check,
4518 L2SDTA_SERVICE_VE_LEN))
4521 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SEC_DEV_TYPE_LIST );
4525 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
4530 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_DISPLAYS );
4534 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( INTEL_DEV_TYPE_OUI );
4537 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_WIDI_CONSUMER_SINK );
4540 /* Vendor Extension */
4541 memcpy(wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN );
4542 wpsielen += L2SDTA_SERVICE_VE_LEN;
4544 #endif /* CONFIG_INTEL_WIDI */
4546 /* WiFi Simple Config State */
4548 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SIMPLE_CONF_STATE );
4552 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4556 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
4560 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_RESP_TYPE );
4564 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4568 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
4572 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
4576 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
4580 memcpy(wpsie + wpsielen, myid( &padapter->eeprompriv ), ETH_ALEN );
4585 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MANUFACTURER );
4589 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0007 );
4593 memcpy(wpsie + wpsielen, "Realtek", 7 );
4598 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NAME );
4602 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0006 );
4606 memcpy(wpsie + wpsielen, "8192CU", 6 );
4611 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NUMBER );
4615 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4619 wpsie[ wpsielen++ ] = 0x31; /* character 1 */
4623 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SERIAL_NUMBER );
4627 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( ETH_ALEN );
4631 memcpy(wpsie + wpsielen, "123456" , ETH_ALEN );
4632 wpsielen += ETH_ALEN;
4634 /* Primary Device Type */
4636 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
4640 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
4645 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
4649 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
4652 /* Sub Category ID */
4653 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
4658 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4662 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
4666 if (pwdinfo->device_name_len)
4668 memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
4669 wpsielen += pwdinfo->device_name_len;
4674 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
4678 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4682 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
4685 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
4687 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
4689 pattrib->pktlen += p2pielen;
4693 #ifdef CONFIG_IOCTL_CFG80211
4694 if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
4695 #endif /* CONFIG_IOCTL_CFG80211 */
4697 wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
4699 pattrib->pktlen += wfdielen;
4701 #ifdef CONFIG_IOCTL_CFG80211
4702 else if (pmlmepriv->wfd_probe_resp_ie != NULL && pmlmepriv->wfd_probe_resp_ie_len>0)
4705 memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, pmlmepriv->wfd_probe_resp_ie_len);
4706 pattrib->pktlen += pmlmepriv->wfd_probe_resp_ie_len;
4707 pframe += pmlmepriv->wfd_probe_resp_ie_len;
4709 #endif /* CONFIG_IOCTL_CFG80211 */
4710 #endif /* CONFIG_WFD */
4712 pattrib->last_txcmdsz = pattrib->pktlen;
4714 dump_mgntframe(padapter, pmgntframe);
4719 int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
4722 struct xmit_frame *pmgntframe;
4723 struct pkt_attrib *pattrib;
4724 unsigned char *pframe;
4725 struct rtw_ieee80211_hdr *pwlanhdr;
4726 unsigned short *fctrl;
4728 unsigned char bssrate[NumRates];
4729 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4730 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4731 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4732 int bssrate_len = 0;
4733 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4734 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4735 u8 wpsie[255] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
4736 u16 wpsielen = 0, p2pielen = 0;
4739 #endif /* CONFIG_WFD */
4741 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4743 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4748 /* update attribute */
4749 pattrib = &pmgntframe->attrib;
4750 update_mgntframe_attrib(padapter, pattrib);
4752 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4754 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4755 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4757 mac = myid(&(padapter->eeprompriv));
4759 fctrl = &(pwlanhdr->frame_ctl);
4763 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
4764 memcpy(pwlanhdr->addr3, da, ETH_ALEN);
4766 if ( ( pwdinfo->p2p_info.scan_op_ch_only ) || ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
4768 /* This two flags will be set when this is only the P2P client mode. */
4769 memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
4770 memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
4774 /* broadcast probe request frame */
4775 memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
4776 memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
4779 memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
4781 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4782 pmlmeext->mgnt_seq++;
4783 SetFrameSubType(pframe, WIFI_PROBEREQ);
4785 pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
4786 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
4788 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
4790 pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen));
4794 pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen));
4796 /* Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 ) */
4797 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
4799 #ifdef CONFIG_IOCTL_CFG80211
4800 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
4802 if( pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL )
4805 memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
4806 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
4807 pframe += pmlmepriv->wps_probe_req_ie_len;
4810 memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len);
4811 pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
4812 pframe += pmlmepriv->p2p_probe_req_ie_len;
4816 #endif /* CONFIG_IOCTL_CFG80211 */
4820 /* Noted by Albert 20110221 */
4821 /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
4825 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
4830 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
4834 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4838 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
4840 if( pmlmepriv->wps_probe_req_ie == NULL )
4844 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
4848 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
4852 memcpy(wpsie + wpsielen, myid( &padapter->eeprompriv ), ETH_ALEN );
4857 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
4861 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4865 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
4871 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4875 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
4879 memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
4880 wpsielen += pwdinfo->device_name_len;
4882 /* Primary Device Type */
4884 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
4888 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
4893 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_RTK_WIDI );
4897 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
4900 /* Sub Category ID */
4901 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_RTK_DMP );
4904 /* Device Password ID */
4906 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
4910 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4914 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC ); /* Registrar-specified */
4917 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
4921 p2pie[ p2pielen++ ] = 0x50;
4922 p2pie[ p2pielen++ ] = 0x6F;
4923 p2pie[ p2pielen++ ] = 0x9A;
4924 p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
4926 /* Commented by Albert 20110221 */
4927 /* According to the P2P Specification, the probe request frame should contain 5 P2P attributes */
4928 /* 1. P2P Capability */
4929 /* 2. P2P Device ID if this probe request wants to find the specific P2P device */
4930 /* 3. Listen Channel */
4931 /* 4. Extended Listen Timing */
4932 /* 5. Operating Channel if this WiFi is working as the group owner now */
4934 /* P2P Capability */
4936 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4939 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4943 /* Device Capability Bitmap, 1 byte */
4944 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
4946 /* Group Capability Bitmap, 1 byte */
4947 if ( pwdinfo->persistent_supported )
4948 p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
4950 p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
4952 /* Listen Channel */
4954 p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
4957 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4961 /* Country String */
4962 p2pie[ p2pielen++ ] = 'X';
4963 p2pie[ p2pielen++ ] = 'X';
4965 /* The third byte should be set to 0x04. */
4966 /* Described in the "Operating Channel Attribute" section. */
4967 p2pie[ p2pielen++ ] = 0x04;
4969 /* Operating Class */
4970 p2pie[ p2pielen++ ] = 0x51; /* Copy from SD7 */
4972 /* Channel Number */
4973 p2pie[ p2pielen++ ] = pwdinfo->listen_channel; /* listen channel */
4975 /* Extended Listen Timing */
4977 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
4980 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
4984 /* Availability Period */
4985 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
4988 /* Availability Interval */
4989 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
4992 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
4994 /* Operating Channel (if this WiFi is working as the group owner now) */
4996 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4999 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
5003 /* Country String */
5004 p2pie[ p2pielen++ ] = 'X';
5005 p2pie[ p2pielen++ ] = 'X';
5007 /* The third byte should be set to 0x04. */
5008 /* Described in the "Operating Channel Attribute" section. */
5009 p2pie[ p2pielen++ ] = 0x04;
5011 /* Operating Class */
5012 p2pie[ p2pielen++ ] = 0x51; /* Copy from SD7 */
5014 /* Channel Number */
5015 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; /* operating channel number */
5019 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
5021 if( pmlmepriv->wps_probe_req_ie != NULL )
5024 memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
5025 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
5026 pframe += pmlmepriv->wps_probe_req_ie_len;
5031 #ifdef CONFIG_IOCTL_CFG80211
5032 if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
5035 wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe);
5037 pattrib->pktlen += wfdielen;
5039 #ifdef CONFIG_IOCTL_CFG80211
5040 else if (pmlmepriv->wfd_probe_req_ie != NULL && pmlmepriv->wfd_probe_req_ie_len>0)
5043 memcpy(pframe, pmlmepriv->wfd_probe_req_ie, pmlmepriv->wfd_probe_req_ie_len);
5044 pattrib->pktlen += pmlmepriv->wfd_probe_req_ie_len;
5045 pframe += pmlmepriv->wfd_probe_req_ie_len;
5047 #endif /* CONFIG_IOCTL_CFG80211 */
5048 #endif /* CONFIG_WFD */
5050 pattrib->last_txcmdsz = pattrib->pktlen;
5052 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
5055 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
5057 dump_mgntframe(padapter, pmgntframe);
5065 inline void issue_probereq_p2p(_adapter *adapter, u8 *da)
5067 _issue_probereq_p2p(adapter, da, _FALSE);
5070 int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms)
5074 u32 start = rtw_get_current_time();
5078 ret = _issue_probereq_p2p(adapter, da, wait_ms>0?_TRUE:_FALSE);
5082 if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
5085 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
5086 rtw_msleep_os(wait_ms);
5088 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
5092 #ifndef DBG_XMIT_ACK
5097 if (try_cnt && wait_ms) {
5099 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
5100 FUNC_ADPT_ARG(adapter), MAC_ARG(da), rtw_get_oper_ch(adapter),
5101 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
5103 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
5104 FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
5105 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
5111 #endif /* CONFIG_P2P */
5113 s32 rtw_action_public_decache(union recv_frame *recv_frame, s32 token)
5115 _adapter *adapter = recv_frame->u.hdr.adapter;
5116 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
5117 u8 *frame = recv_frame->u.hdr.rx_data;
5118 u16 seq_ctrl = ( (recv_frame->u.hdr.attrib.seq_num&0xffff) << 4) |
5119 (recv_frame->u.hdr.attrib.frag_num & 0xf);
5121 if (GetRetry(frame)) {
5123 if ((seq_ctrl == mlmeext->action_public_rxseq)
5124 && (token == mlmeext->action_public_dialog_token))
5126 DBG_8723A(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n",
5127 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
5131 if (seq_ctrl == mlmeext->action_public_rxseq) {
5132 DBG_8723A(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x\n",
5133 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq);
5139 mlmeext->action_public_rxseq = seq_ctrl;
5142 mlmeext->action_public_dialog_token = token;
5147 unsigned int on_action_public_p2p(union recv_frame *precv_frame)
5149 _adapter *padapter = precv_frame->u.hdr.adapter;
5150 u8 *pframe = precv_frame->u.hdr.rx_data;
5151 uint len = precv_frame->u.hdr.len;
5156 u32 p2p_ielen, wps_ielen;
5157 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5158 u8 result = P2P_STATUS_SUCCESS;
5159 u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
5160 #endif /* CONFIG_P2P */
5162 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
5164 dialogToken = frame_body[7];
5166 if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
5170 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
5171 #ifdef CONFIG_IOCTL_CFG80211
5172 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
5174 rtw_cfg80211_rx_p2p_action_public(padapter, pframe, len);
5177 #endif /* CONFIG_IOCTL_CFG80211 */
5179 /* Do nothing if the driver doesn't enable the P2P function. */
5180 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
5183 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
5185 switch( frame_body[ 6 ] )/* OUI Subtype */
5187 case P2P_GO_NEGO_REQ:
5189 DBG_8723A( "[%s] Got GO Nego Req Frame\n", __FUNCTION__);
5190 memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
5192 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
5194 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
5197 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
5199 /* Commented by Albert 20110526 */
5200 /* In this case, this means the previous nego fail doesn't be reset yet. */
5201 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
5202 /* Restore the previous p2p state */
5203 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
5204 DBG_8723A( "[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );
5206 #ifdef CONFIG_CONCURRENT_MODE
5207 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
5209 _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
5211 #endif /* CONFIG_CONCURRENT_MODE */
5213 /* Commented by Kurt 20110902 */
5214 /* Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
5215 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
5216 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5218 /* Commented by Kurt 20120113 */
5219 /* Get peer_dev_addr here if peer doesn't issue prov_disc frame. */
5220 if (!memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN))
5221 memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
5223 result = process_p2p_group_negotation_req( pwdinfo, frame_body, len );
5224 issue_p2p_GO_response( padapter, GetAddr2Ptr(pframe), frame_body, len, result );
5225 #ifdef CONFIG_INTEL_WIDI
5226 if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
5228 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
5229 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
5231 #endif /* CONFIG_INTEL_WIDI */
5233 /* Commented by Albert 20110718 */
5234 /* No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer. */
5235 #ifdef CONFIG_CONCURRENT_MODE
5236 /* Commented by Albert 20120107 */
5237 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
5238 #else /* CONFIG_CONCURRENT_MODE */
5239 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
5240 #endif /* CONFIG_CONCURRENT_MODE */
5243 case P2P_GO_NEGO_RESP:
5245 DBG_8723A( "[%s] Got GO Nego Resp Frame\n", __FUNCTION__);
5247 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
5249 /* Commented by Albert 20110425 */
5250 /* The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function. */
5251 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
5252 pwdinfo->nego_req_info.benable = _FALSE;
5253 result = process_p2p_group_negotation_resp( pwdinfo, frame_body, len);
5254 issue_p2p_GO_confirm( pwdinfo->padapter, GetAddr2Ptr(pframe), result);
5255 if ( P2P_STATUS_SUCCESS == result )
5257 if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
5259 pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
5260 pwdinfo->p2p_info.scan_op_ch_only = 1;
5261 _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
5265 /* Reset the dialog token for group negotiation frames. */
5266 pwdinfo->negotiation_dialog_token = 1;
5268 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
5270 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
5275 DBG_8723A( "[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__);
5280 case P2P_GO_NEGO_CONF:
5282 DBG_8723A( "[%s] Got GO Nego Confirm Frame\n", __FUNCTION__);
5283 result = process_p2p_group_negotation_confirm( pwdinfo, frame_body, len);
5284 if ( P2P_STATUS_SUCCESS == result )
5286 if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
5288 pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
5289 pwdinfo->p2p_info.scan_op_ch_only = 1;
5290 _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
5297 /* Added by Albert 2010/10/05 */
5298 /* Received the P2P Invite Request frame. */
5300 DBG_8723A( "[%s] Got invite request frame!\n", __FUNCTION__ );
5301 if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
5303 /* Parse the necessary information from the P2P Invitation Request frame. */
5304 /* For example: The MAC address of sending this P2P Invitation Request frame. */
5305 u32 attr_contentlen = 0;
5306 u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
5307 struct group_id_info group_id;
5308 u8 invitation_flag = 0;
5310 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
5311 if ( attr_contentlen )
5314 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
5315 /* Commented by Albert 20120510 */
5316 /* Copy to the pwdinfo->p2p_peer_interface_addr. */
5317 /* So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command. */
5318 /* #> iwpriv wlan0 p2p_get peer_ifa */
5319 /* After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant. */
5321 if ( attr_contentlen )
5323 DBG_8723A( "[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5324 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
5325 pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
5326 pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5] );
5329 if ( invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT )
5331 /* Re-invoke the persistent group. */
5333 memset( &group_id, 0x00, sizeof( struct group_id_info ) );
5334 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
5335 if ( attr_contentlen )
5337 if (!memcmp(group_id.go_device_addr, myid( &padapter->eeprompriv), ETH_ALEN))
5339 /* The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO. */
5340 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO );
5341 rtw_p2p_set_role( pwdinfo, P2P_ROLE_GO );
5342 status_code = P2P_STATUS_SUCCESS;
5346 /* The p2p device sending this p2p invitation request wants to be the persistent GO. */
5347 if ( is_matched_in_profilelist( pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[ 0 ] ) )
5349 u8 operatingch_info[5] = { 0x00 };
5350 if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
5352 if( rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4] ) )
5354 /* The operating channel is acceptable for this device. */
5355 pwdinfo->rx_invitereq_info.operation_ch[0]= operatingch_info[4];
5356 pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
5357 _set_timer( &pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH );
5358 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
5359 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
5360 status_code = P2P_STATUS_SUCCESS;
5364 /* The operating channel isn't supported by this device. */
5365 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
5366 rtw_p2p_set_role( pwdinfo, P2P_ROLE_DEVICE );
5367 status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
5368 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
5373 /* Commented by Albert 20121130 */
5374 /* Intel will use the different P2P IE to store the operating channel information */
5375 /* Workaround for Intel WiDi 3.5 */
5376 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
5377 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
5378 status_code = P2P_STATUS_SUCCESS;
5383 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
5384 #ifdef CONFIG_INTEL_WIDI
5385 memcpy(pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
5386 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
5387 #endif /* CONFIG_INTEL_WIDI */
5389 status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
5395 DBG_8723A( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
5396 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
5401 /* Received the invitation to join a P2P group. */
5403 memset( &group_id, 0x00, sizeof( struct group_id_info ) );
5404 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
5405 if ( attr_contentlen )
5407 if (!memcmp(group_id.go_device_addr, myid( &padapter->eeprompriv), ETH_ALEN))
5409 /* In this case, the GO can't be myself. */
5410 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
5411 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
5415 /* The p2p device sending this p2p invitation request wants to join an existing P2P group */
5416 /* Commented by Albert 2012/06/28 */
5417 /* In this case, this Wi-Fi device should use the iwpriv command to get the peer device address. */
5418 /* The peer device address should be the destination address for the provisioning discovery request. */
5419 /* Then, this Wi-Fi device should use the iwpriv command to get the peer interface address. */
5420 /* The peer interface address should be the address for WPS mac address */
5421 memcpy(pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
5422 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
5423 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN );
5424 status_code = P2P_STATUS_SUCCESS;
5429 DBG_8723A( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
5430 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
5436 DBG_8723A( "[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__ );
5437 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
5440 DBG_8723A( "[%s] status_code = %d\n", __FUNCTION__, status_code );
5442 pwdinfo->inviteresp_info.token = frame_body[ 7 ];
5443 issue_p2p_invitation_response( padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code );
5445 #ifdef CONFIG_INTEL_WIDI
5446 if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
5448 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
5449 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
5451 #endif /* CONFIG_INTEL_WIDI */
5454 case P2P_INVIT_RESP:
5456 u8 attr_content = 0x00;
5457 u32 attr_contentlen = 0;
5459 DBG_8723A( "[%s] Got invite response frame!\n", __FUNCTION__ );
5460 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
5461 if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
5463 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
5465 if ( attr_contentlen == 1 )
5467 DBG_8723A( "[%s] Status = %d\n", __FUNCTION__, attr_content );
5468 pwdinfo->invitereq_info.benable = _FALSE;
5470 if ( attr_content == P2P_STATUS_SUCCESS )
5472 if (!memcmp(pwdinfo->invitereq_info.go_bssid, myid( &padapter->eeprompriv), ETH_ALEN))
5474 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO );
5478 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
5480 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_OK );
5484 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
5485 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
5490 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
5491 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
5496 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
5497 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
5500 if ( rtw_p2p_chk_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ) )
5502 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
5506 case P2P_DEVDISC_REQ:
5508 process_p2p_devdisc_req(pwdinfo, pframe, len);
5512 case P2P_DEVDISC_RESP:
5514 process_p2p_devdisc_resp(pwdinfo, pframe, len);
5518 case P2P_PROVISION_DISC_REQ:
5519 DBG_8723A( "[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__ );
5520 process_p2p_provdisc_req(pwdinfo, pframe, len);
5521 memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
5524 /* Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
5525 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
5526 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5528 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
5529 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
5530 #ifdef CONFIG_INTEL_WIDI
5531 if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
5533 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
5534 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
5536 #endif /* CONFIG_INTEL_WIDI */
5539 case P2P_PROVISION_DISC_RESP:
5540 /* Commented by Albert 20110707 */
5541 /* Should we check the pwdinfo->tx_prov_disc_info.bsent flag here?? */
5542 DBG_8723A( "[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__ );
5543 /* Commented by Albert 20110426 */
5544 /* The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function. */
5545 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
5546 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
5547 process_p2p_provdisc_resp(pwdinfo, pframe);
5548 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
5553 #endif /* CONFIG_P2P */
5558 unsigned int on_action_public_vendor(union recv_frame *precv_frame)
5560 unsigned int ret = _FAIL;
5561 u8 *pframe = precv_frame->u.hdr.rx_data;
5562 uint frame_len = precv_frame->u.hdr.len;
5563 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
5565 if (!memcmp(frame_body + 2, P2P_OUI, 4)) {
5566 ret = on_action_public_p2p(precv_frame);
5572 unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
5574 unsigned int ret = _FAIL;
5575 u8 *pframe = precv_frame->u.hdr.rx_data;
5576 uint frame_len = precv_frame->u.hdr.len;
5577 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
5579 _adapter *adapter = precv_frame->u.hdr.adapter;
5583 token = frame_body[2];
5585 if (rtw_action_public_decache(precv_frame, token) == _FAIL)
5588 #ifdef CONFIG_IOCTL_CFG80211
5589 cnt += sprintf((msg+cnt), "%s(token:%u)", action_public_str(action), token);
5590 rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
5599 unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame)
5601 unsigned int ret = _FAIL;
5602 u8 *pframe = precv_frame->u.hdr.rx_data;
5603 uint frame_len = precv_frame->u.hdr.len;
5604 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
5605 u8 category, action;
5607 /* check RA matches or not */
5608 if (memcmp(myid(&(padapter->eeprompriv)),
5609 GetAddr1Ptr(pframe), ETH_ALEN))
5612 category = frame_body[0];
5613 if(category != RTW_WLAN_CATEGORY_PUBLIC)
5616 action = frame_body[1];
5618 case ACT_PUBLIC_VENDOR:
5619 ret = on_action_public_vendor(precv_frame);
5622 ret = on_action_public_default(precv_frame, action);
5630 unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame)
5635 unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame)
5640 unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame)
5644 u8 category, OUI_Subtype, dialogToken=0;
5645 u8 *pframe = precv_frame->u.hdr.rx_data;
5646 uint len = precv_frame->u.hdr.len;
5647 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5649 DBG_8723A("%s\n", __FUNCTION__);
5651 /* check RA matches or not */
5652 if (memcmp(myid(&(padapter->eeprompriv)),
5653 GetAddr1Ptr(pframe), ETH_ALEN))/* for if1, sta/ap mode */
5656 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
5658 category = frame_body[0];
5659 if(category != RTW_WLAN_CATEGORY_P2P)
5662 if ( cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ) != P2POUI )
5665 #ifdef CONFIG_IOCTL_CFG80211
5666 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
5668 rtw_cfg80211_rx_action_p2p(padapter, pframe, len);
5672 #endif /* CONFIG_IOCTL_CFG80211 */
5674 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
5675 OUI_Subtype = frame_body[5];
5676 dialogToken = frame_body[6];
5680 case P2P_NOTICE_OF_ABSENCE:
5684 case P2P_PRESENCE_REQUEST:
5686 process_p2p_presence_req(pwdinfo, pframe, len);
5690 case P2P_PRESENCE_RESPONSE:
5694 case P2P_GO_DISC_REQUEST:
5703 #endif /* CONFIG_P2P */
5708 unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame)
5711 unsigned char category;
5712 struct action_handler *ptable;
5713 unsigned char *frame_body;
5714 u8 *pframe = precv_frame->u.hdr.rx_data;
5716 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
5718 category = frame_body[0];
5720 for(i = 0; i < sizeof(OnAction_tbl)/sizeof(struct action_handler); i++)
5722 ptable = &OnAction_tbl[i];
5724 if(category == ptable->num)
5725 ptable->func(padapter, precv_frame);
5732 unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame)
5735 /* DBG_8723A("rcvd mgt frame(%x, %x)\n", (GetFrameSubType(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe)); */
5739 struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
5741 struct xmit_frame *pmgntframe;
5742 struct xmit_buf *pxmitbuf;
5745 pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
5747 pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
5749 if (pmgntframe == NULL) {
5750 DBG_8723A(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
5754 if ((pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv)) == NULL) {
5755 DBG_8723A(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
5756 rtw_free_xmitframe(pxmitpriv, pmgntframe);
5761 pmgntframe->frame_tag = MGNT_FRAMETAG;
5762 pmgntframe->pxmitbuf = pxmitbuf;
5763 pmgntframe->buf_addr = pxmitbuf->pbuf;
5764 pxmitbuf->priv_data = pmgntframe;
5770 inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
5772 return _alloc_mgtxmitframe(pxmitpriv, _FALSE);
5775 inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv)
5777 return _alloc_mgtxmitframe(pxmitpriv, _TRUE);
5780 /****************************************************************************
5782 Following are some TX fuctions for WiFi MLME
5784 *****************************************************************************/
5786 void update_mgnt_tx_rate(_adapter *padapter, u8 rate)
5788 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5790 pmlmeext->tx_rate = rate;
5791 DBG_8723A("%s(): rate = %x\n",__FUNCTION__, rate);
5794 void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
5796 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5798 memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib));
5800 pattrib->hdrlen = 24;
5801 pattrib->nr_frags = 1;
5802 pattrib->priority = 7;
5803 pattrib->mac_id = 0;
5804 pattrib->qsel = 0x12;
5806 pattrib->pktlen = 0;
5808 if(pmlmeext->cur_wireless_mode & WIRELESS_11B)
5809 pattrib->raid = 6;/* b mode */
5811 pattrib->raid = 5;/* a/g mode */
5813 pattrib->encrypt = _NO_PRIVACY_;
5814 pattrib->bswenc = _FALSE;
5816 pattrib->qos_en = _FALSE;
5817 pattrib->ht_en = _FALSE;
5818 pattrib->bwmode = HT_CHANNEL_WIDTH_20;
5819 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5820 pattrib->sgi = _FALSE;
5822 pattrib->seqnum = pmlmeext->mgnt_seq;
5824 pattrib->retry_ctrl = _TRUE;
5827 void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe)
5829 if(padapter->bSurpriseRemoved == _TRUE ||
5830 padapter->bDriverStopped == _TRUE)
5833 rtw_hal_mgnt_xmit(padapter, pmgntframe);
5836 s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
5840 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5841 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
5842 struct submit_ctx sctx;
5844 if(padapter->bSurpriseRemoved == _TRUE ||
5845 padapter->bDriverStopped == _TRUE)
5848 rtw_sctx_init(&sctx, timeout_ms);
5849 pxmitbuf->sctx = &sctx;
5851 ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
5853 if (ret == _SUCCESS)
5854 ret = rtw_sctx_wait(&sctx);
5856 spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL);
5857 pxmitbuf->sctx = NULL;
5858 spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL);
5863 s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe)
5865 #ifdef CONFIG_XMIT_ACK
5867 u32 timeout_ms = 500;/* 500ms */
5868 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5869 #ifdef CONFIG_CONCURRENT_MODE
5870 if (padapter->pbuddy_adapter && !padapter->isprimary)
5871 pxmitpriv = &(padapter->pbuddy_adapter->xmitpriv);
5874 if(padapter->bSurpriseRemoved == _TRUE ||
5875 padapter->bDriverStopped == _TRUE)
5878 _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
5879 pxmitpriv->ack_tx = _TRUE;
5881 pmgntframe->ack_report = 1;
5882 if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
5883 ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms);
5886 pxmitpriv->ack_tx = _FALSE;
5887 _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
5890 #else /* CONFIG_XMIT_ACK */
5891 dump_mgntframe(padapter, pmgntframe);
5894 #endif /* CONFIG_XMIT_ACK */
5897 int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
5903 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
5905 /* DBG_8723A("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
5907 if(ssid_ie && ssid_len_ori>0)
5909 switch(hidden_ssid_mode)
5913 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
5916 remain_len = ies_len -(next_ie-ies);
5919 memcpy(ssid_ie+2, next_ie, remain_len);
5920 len_diff -= ssid_len_ori;
5925 memset(&ssid_ie[2], 0, ssid_len_ori);
5935 void issue_beacon(_adapter *padapter, int timeout_ms)
5937 struct xmit_frame *pmgntframe;
5938 struct pkt_attrib *pattrib;
5939 unsigned char *pframe;
5940 struct rtw_ieee80211_hdr *pwlanhdr;
5941 unsigned short *fctrl;
5942 unsigned int rate_len;
5943 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5944 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
5946 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5947 #endif /* if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
5948 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5949 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5950 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
5951 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
5953 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5954 #endif /* CONFIG_P2P */
5956 /* DBG_8723A("%s\n", __FUNCTION__); */
5958 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5960 DBG_8723A("%s, alloc mgnt frame fail\n", __FUNCTION__);
5963 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
5964 spin_lock_bh(&pmlmepriv->bcn_update_lock);
5965 #endif /* if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
5967 /* update attribute */
5968 pattrib = &pmgntframe->attrib;
5969 update_mgntframe_attrib(padapter, pattrib);
5970 pattrib->qsel = 0x10;
5972 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5974 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5975 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5977 fctrl = &(pwlanhdr->frame_ctl);
5980 memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
5981 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
5982 memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
5984 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
5985 /* pmlmeext->mgnt_seq++; */
5986 SetFrameSubType(pframe, WIFI_BEACON);
5988 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5989 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
5991 if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
5993 /* DBG_8723A("ie len=%d\n", cur_network->IELength); */
5995 /* for P2P : Primary Device Type & Device Name */
5996 u32 wpsielen=0, insert_len=0;
5998 wpsie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
6000 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen>0)
6002 uint wps_offset, remainder_ielen;
6003 u8 *premainder_ie, *pframe_wscie;
6005 wps_offset = (uint)(wpsie - cur_network->IEs);
6007 premainder_ie = wpsie + wpsielen;
6009 remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
6011 #ifdef CONFIG_IOCTL_CFG80211
6012 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
6014 if(pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len>0)
6016 memcpy(pframe, cur_network->IEs, wps_offset);
6017 pframe += wps_offset;
6018 pattrib->pktlen += wps_offset;
6020 memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
6021 pframe += pmlmepriv->wps_beacon_ie_len;
6022 pattrib->pktlen += pmlmepriv->wps_beacon_ie_len;
6024 /* copy remainder_ie to pframe */
6025 memcpy(pframe, premainder_ie, remainder_ielen);
6026 pframe += remainder_ielen;
6027 pattrib->pktlen += remainder_ielen;
6031 memcpy(pframe, cur_network->IEs, cur_network->IELength);
6032 pframe += cur_network->IELength;
6033 pattrib->pktlen += cur_network->IELength;
6037 #endif /* CONFIG_IOCTL_CFG80211 */
6039 pframe_wscie = pframe + wps_offset;
6040 memcpy(pframe, cur_network->IEs, wps_offset+wpsielen);
6041 pframe += (wps_offset + wpsielen);
6042 pattrib->pktlen += (wps_offset + wpsielen);
6044 /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
6045 /* Primary Device Type */
6047 *(u16*) ( pframe + insert_len) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
6051 *(u16*) ( pframe + insert_len ) = cpu_to_be16( 0x0008 );
6056 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
6060 *(u32*) ( pframe + insert_len ) = cpu_to_be32( WPSOUI );
6063 /* Sub Category ID */
6064 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
6069 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
6073 *(u16*) ( pframe + insert_len ) = cpu_to_be16( pwdinfo->device_name_len );
6077 memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len );
6078 insert_len += pwdinfo->device_name_len;
6080 /* update wsc ie length */
6081 *(pframe_wscie+1) = (wpsielen -2) + insert_len;
6083 /* pframe move to end */
6085 pattrib->pktlen += insert_len;
6087 /* copy remainder_ie to pframe */
6088 memcpy(pframe, premainder_ie, remainder_ielen);
6089 pframe += remainder_ielen;
6090 pattrib->pktlen += remainder_ielen;
6094 #endif /* CONFIG_P2P */
6097 memcpy(pframe, cur_network->IEs, cur_network->IELength);
6098 len_diff = update_hidden_ssid(
6099 pframe+_BEACON_IE_OFFSET_
6100 , cur_network->IELength-_BEACON_IE_OFFSET_
6101 , pmlmeinfo->hidden_ssid_mode
6103 pframe += (cur_network->IELength+len_diff);
6104 pattrib->pktlen += (cur_network->IELength+len_diff);
6111 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
6112 pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
6113 if (wps_ie && wps_ielen>0) {
6114 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
6117 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
6119 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
6123 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
6126 #ifdef CONFIG_IOCTL_CFG80211
6127 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
6129 len = pmlmepriv->p2p_beacon_ie_len;
6130 if(pmlmepriv->p2p_beacon_ie && len>0)
6131 memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
6134 #endif /* CONFIG_IOCTL_CFG80211 */
6136 len = build_beacon_p2p_ie(pwdinfo, pframe);
6140 pattrib->pktlen += len;
6142 #ifdef CONFIG_IOCTL_CFG80211
6143 if(_TRUE == pwdinfo->wfd_info->wfd_enable)
6144 #endif /* CONFIG_IOCTL_CFG80211 */
6146 len = build_beacon_wfd_ie( pwdinfo, pframe );
6148 #ifdef CONFIG_IOCTL_CFG80211
6152 if(pmlmepriv->wfd_beacon_ie && pmlmepriv->wfd_beacon_ie_len>0)
6154 len = pmlmepriv->wfd_beacon_ie_len;
6155 memcpy(pframe, pmlmepriv->wfd_beacon_ie, len);
6158 #endif /* CONFIG_IOCTL_CFG80211 */
6160 pattrib->pktlen += len;
6161 #endif /* CONFIG_WFD */
6163 #endif /* CONFIG_P2P */
6169 /* below for ad-hoc mode */
6171 /* timestamp will be inserted by hardware */
6173 pattrib->pktlen += 8;
6175 /* beacon interval: 2 bytes */
6177 memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6180 pattrib->pktlen += 2;
6182 /* capability info: 2 bytes */
6184 memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6187 pattrib->pktlen += 2;
6190 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
6192 /* supported rates... */
6193 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6194 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
6196 /* DS parameter set */
6197 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
6199 /* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
6203 /* IBSS Parameter Set... */
6204 /* ATIMWindow = cur->Configuration.ATIMWindow; */
6206 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
6209 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
6212 /* EXTERNDED SUPPORTED RATE */
6215 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
6218 /* todo:HT for adhoc */
6222 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
6223 pmlmepriv->update_bcn = _FALSE;
6225 spin_unlock_bh(&pmlmepriv->bcn_update_lock);
6226 #endif /* if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6228 if ((pattrib->pktlen + TXDESC_SIZE) > 512)
6230 DBG_8723A("beacon frame too large\n");
6234 pattrib->last_txcmdsz = pattrib->pktlen;
6236 /* DBG_8723A("issue bcn_sz=%d\n", pattrib->last_txcmdsz); */
6238 dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
6240 dump_mgntframe(padapter, pmgntframe);
6243 void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
6245 struct xmit_frame *pmgntframe;
6246 struct pkt_attrib *pattrib;
6247 unsigned char *pframe;
6248 struct rtw_ieee80211_hdr *pwlanhdr;
6249 unsigned short *fctrl;
6250 unsigned char *mac, *bssid;
6251 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6252 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
6255 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6256 #endif /* if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6257 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6258 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6259 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
6260 unsigned int rate_len;
6262 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6265 #endif /* CONFIG_WFD */
6266 #endif /* CONFIG_P2P */
6268 /* DBG_8723A("%s\n", __FUNCTION__); */
6270 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
6272 DBG_8723A("%s, alloc mgnt frame fail\n", __FUNCTION__);
6276 /* update attribute */
6277 pattrib = &pmgntframe->attrib;
6278 update_mgntframe_attrib(padapter, pattrib);
6280 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6282 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6283 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6285 mac = myid(&(padapter->eeprompriv));
6286 bssid = cur_network->MacAddress;
6288 fctrl = &(pwlanhdr->frame_ctl);
6290 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
6291 memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6292 memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
6294 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6295 pmlmeext->mgnt_seq++;
6296 SetFrameSubType(fctrl, WIFI_PROBERSP);
6298 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6299 pattrib->pktlen = pattrib->hdrlen;
6300 pframe += pattrib->hdrlen;
6302 if(cur_network->IELength>MAX_IE_SZ)
6305 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
6306 if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
6308 pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
6310 /* inerset & update wps_probe_resp_ie */
6311 if((pmlmepriv->wps_probe_resp_ie!=NULL) && pwps_ie && (wps_ielen>0))
6313 uint wps_offset, remainder_ielen;
6316 wps_offset = (uint)(pwps_ie - cur_network->IEs);
6318 premainder_ie = pwps_ie + wps_ielen;
6320 remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
6322 memcpy(pframe, cur_network->IEs, wps_offset);
6323 pframe += wps_offset;
6324 pattrib->pktlen += wps_offset;
6326 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];/* to get ie data len */
6327 if((wps_offset+wps_ielen+2)<=MAX_IE_SZ)
6329 memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
6330 pframe += wps_ielen+2;
6331 pattrib->pktlen += wps_ielen+2;
6334 if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)
6336 memcpy(pframe, premainder_ie, remainder_ielen);
6337 pframe += remainder_ielen;
6338 pattrib->pktlen += remainder_ielen;
6343 memcpy(pframe, cur_network->IEs, cur_network->IELength);
6344 pframe += cur_network->IELength;
6345 pattrib->pktlen += cur_network->IELength;
6348 /* retrieve SSID IE from cur_network->Ssid */
6352 int ssid_ielen_diff;
6354 u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct rtw_ieee80211_hdr_3addr);
6356 ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
6357 (pframe-ies)-_FIXED_IE_LENGTH_);
6359 ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
6361 if (ssid_ie && cur_network->Ssid.SsidLength) {
6362 uint remainder_ielen;
6364 remainder_ie = ssid_ie+2;
6365 remainder_ielen = (pframe-remainder_ie);
6367 DBG_8723A_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
6368 if (remainder_ielen > MAX_IE_SZ) {
6369 remainder_ielen = MAX_IE_SZ;
6372 memcpy(buf, remainder_ie, remainder_ielen);
6373 memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen);
6374 *(ssid_ie+1) = cur_network->Ssid.SsidLength;
6375 memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
6377 pframe += ssid_ielen_diff;
6378 pattrib->pktlen += ssid_ielen_diff;
6386 /* timestamp will be inserted by hardware */
6388 pattrib->pktlen += 8;
6390 /* beacon interval: 2 bytes */
6392 memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6395 pattrib->pktlen += 2;
6397 /* capability info: 2 bytes */
6399 memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6402 pattrib->pktlen += 2;
6404 /* below for ad-hoc mode */
6407 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
6409 /* supported rates... */
6410 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6411 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
6413 /* DS parameter set */
6414 pframe =rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
6416 if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
6420 /* IBSS Parameter Set... */
6421 /* ATIMWindow = cur->Configuration.ATIMWindow; */
6423 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
6426 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
6429 /* EXTERNDED SUPPORTED RATE */
6432 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
6435 /* todo:HT for adhoc */
6440 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && is_valid_p2p_probereq)
6443 #ifdef CONFIG_IOCTL_CFG80211
6444 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
6446 /* if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p() */
6447 len = pmlmepriv->p2p_go_probe_resp_ie_len;
6448 if(pmlmepriv->p2p_go_probe_resp_ie && len>0)
6449 memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len);
6452 #endif /* CONFIG_IOCTL_CFG80211 */
6454 len = build_probe_resp_p2p_ie(pwdinfo, pframe);
6458 pattrib->pktlen += len;
6461 #ifdef CONFIG_IOCTL_CFG80211
6462 if(_TRUE == pwdinfo->wfd_info->wfd_enable)
6463 #endif /* CONFIG_IOCTL_CFG80211 */
6465 len = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
6467 #ifdef CONFIG_IOCTL_CFG80211
6471 if(pmlmepriv->wfd_probe_resp_ie && pmlmepriv->wfd_probe_resp_ie_len>0)
6473 len = pmlmepriv->wfd_probe_resp_ie_len;
6474 memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, len);
6477 #endif /* CONFIG_IOCTL_CFG80211 */
6479 pattrib->pktlen += len;
6480 #endif /* CONFIG_WFD */
6483 #endif /* CONFIG_P2P */
6485 pattrib->last_txcmdsz = pattrib->pktlen;
6487 dump_mgntframe(padapter, pmgntframe);
6492 int _issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, int wait_ack)
6495 struct xmit_frame *pmgntframe;
6496 struct pkt_attrib *pattrib;
6497 unsigned char *pframe;
6498 struct rtw_ieee80211_hdr *pwlanhdr;
6499 unsigned short *fctrl;
6501 unsigned char bssrate[NumRates];
6502 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6503 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6504 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6505 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6506 int bssrate_len = 0;
6507 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6509 RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("+issue_probereq\n"));
6511 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
6516 /* update attribute */
6517 pattrib = &pmgntframe->attrib;
6518 update_mgntframe_attrib(padapter, pattrib);
6520 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6522 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6523 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6525 mac = myid(&(padapter->eeprompriv));
6527 fctrl = &(pwlanhdr->frame_ctl);
6532 /* unicast probe request frame */
6533 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
6534 memcpy(pwlanhdr->addr3, da, ETH_ALEN);
6538 /* broadcast probe request frame */
6539 memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6540 memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
6543 memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6545 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6546 pmlmeext->mgnt_seq++;
6547 SetFrameSubType(pframe, WIFI_PROBEREQ);
6549 pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
6550 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
6553 pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
6555 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
6557 get_rate_set(padapter, bssrate, &bssrate_len);
6559 if (bssrate_len > 8)
6561 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
6562 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
6566 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
6569 /* add wps_ie for wps2.0 */
6570 if(pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie)
6572 memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
6573 pframe += pmlmepriv->wps_probe_req_ie_len;
6574 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
6577 pattrib->last_txcmdsz = pattrib->pktlen;
6579 RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
6582 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
6584 dump_mgntframe(padapter, pmgntframe);
6592 inline void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da)
6594 _issue_probereq(padapter, pssid, da, _FALSE);
6597 int issue_probereq_ex(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da,
6598 int try_cnt, int wait_ms)
6602 u32 start = rtw_get_current_time();
6606 ret = _issue_probereq(padapter, pssid, da, wait_ms>0?_TRUE:_FALSE);
6610 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
6613 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
6614 rtw_msleep_os(wait_ms);
6616 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
6620 #ifndef DBG_XMIT_ACK
6625 if (try_cnt && wait_ms) {
6627 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
6628 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
6629 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
6631 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
6632 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
6633 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
6639 /* if psta == NULL, indiate we are station(client) now... */
6640 void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status)
6642 struct xmit_frame *pmgntframe;
6643 struct pkt_attrib *pattrib;
6644 unsigned char *pframe;
6645 struct rtw_ieee80211_hdr *pwlanhdr;
6646 unsigned short *fctrl;
6648 unsigned short val16;
6649 int use_shared_key = 0;
6650 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6651 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6652 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6654 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
6659 /* update attribute */
6660 pattrib = &pmgntframe->attrib;
6661 update_mgntframe_attrib(padapter, pattrib);
6663 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6665 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6666 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6668 fctrl = &(pwlanhdr->frame_ctl);
6671 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6672 pmlmeext->mgnt_seq++;
6673 SetFrameSubType(pframe, WIFI_AUTH);
6675 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6676 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6678 if(psta)/* for AP mode */
6680 #ifdef CONFIG_NATIVEAP_MLME
6682 memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);
6683 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
6684 memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
6686 /* setting auth algo number */
6687 val16 = (u16)psta->authalg;
6689 if(status != _STATS_SUCCESSFUL_)
6693 val16 = cpu_to_le16(val16);
6697 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
6699 /* setting auth seq number */
6700 val16 =(u16)psta->auth_seq;
6701 val16 = cpu_to_le16(val16);
6702 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
6704 /* setting status code... */
6706 val16 = cpu_to_le16(val16);
6707 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
6709 /* added challenging text... */
6710 if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
6712 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
6718 memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
6719 memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
6720 memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
6722 /* setting auth algo number */
6723 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;/* 0:OPEN System, 1:Shared key */
6725 val16 = cpu_to_le16(val16);
6728 /* DBG_8723A("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq); */
6730 /* setting IV for auth seq #3 */
6731 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
6733 /* DBG_8723A("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index); */
6734 val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
6735 val32 = cpu_to_le32(val32);
6736 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen));
6738 pattrib->iv_len = 4;
6741 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
6743 /* setting auth seq number */
6744 val16 = pmlmeinfo->auth_seq;
6745 val16 = cpu_to_le16(val16);
6746 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
6748 /* setting status code... */
6750 val16 = cpu_to_le16(val16);
6751 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
6753 /* then checking to see if sending challenging text... */
6754 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
6756 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
6760 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6762 pattrib->encrypt = _WEP40_;
6764 pattrib->icv_len = 4;
6766 pattrib->pktlen += pattrib->icv_len;
6772 pattrib->last_txcmdsz = pattrib->pktlen;
6774 rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
6775 DBG_8723A("%s\n", __FUNCTION__);
6776 dump_mgntframe(padapter, pmgntframe);
6781 void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
6783 #ifdef CONFIG_AP_MODE
6784 struct xmit_frame *pmgntframe;
6785 struct rtw_ieee80211_hdr *pwlanhdr;
6786 struct pkt_attrib *pattrib;
6787 unsigned char *pbuf, *pframe;
6789 unsigned short *fctrl;
6790 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6791 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6792 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6793 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6794 WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
6795 u8 *ie = pnetwork->IEs;
6797 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6800 #endif /* CONFIG_WFD */
6802 #endif /* CONFIG_P2P */
6804 DBG_8723A("%s\n", __FUNCTION__);
6806 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
6811 /* update attribute */
6812 pattrib = &pmgntframe->attrib;
6813 update_mgntframe_attrib(padapter, pattrib);
6815 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6817 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6818 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6820 fctrl = &(pwlanhdr->frame_ctl);
6823 memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
6824 memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&(padapter->eeprompriv)), ETH_ALEN);
6825 memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6827 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6828 pmlmeext->mgnt_seq++;
6829 if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
6830 SetFrameSubType(pwlanhdr, pkt_type);
6834 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6835 pattrib->pktlen += pattrib->hdrlen;
6836 pframe += pattrib->hdrlen;
6839 val = *(unsigned short *)rtw_get_capability_from_ie(ie);
6841 pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen));
6843 status = cpu_to_le16(status);
6844 pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&status, &(pattrib->pktlen));
6846 val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
6847 pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen));
6849 if (pstat->bssratelen <= 8)
6851 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
6855 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
6856 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen));
6859 #ifdef CONFIG_80211N_HT
6860 if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option))
6864 /* FILL HT CAP INFO IE */
6865 /* p = hostapd_eid_ht_capabilities_info(hapd, p); */
6866 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
6867 if(pbuf && ie_len>0)
6869 memcpy(pframe, pbuf, ie_len+2);
6870 pframe += (ie_len+2);
6871 pattrib->pktlen +=(ie_len+2);
6874 /* FILL HT ADD INFO IE */
6875 /* p = hostapd_eid_ht_operation(hapd, p); */
6876 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
6877 if(pbuf && ie_len>0)
6879 memcpy(pframe, pbuf, ie_len+2);
6880 pframe += (ie_len+2);
6881 pattrib->pktlen +=(ie_len+2);
6888 if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option))
6891 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
6893 for (pbuf = ie + _BEACON_IE_OFFSET_; ;pbuf+= (ie_len + 2))
6895 pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
6896 if (pbuf && !memcmp(pbuf+2, WMM_PARA_IE, 6))
6898 memcpy(pframe, pbuf, ie_len+2);
6899 pframe += (ie_len+2);
6900 pattrib->pktlen +=(ie_len+2);
6905 if ((pbuf == NULL) || (ie_len == 0))
6913 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
6915 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
6918 /* add WPS IE ie for wps 2.0 */
6919 if(pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len>0)
6921 memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
6923 pframe += pmlmepriv->wps_assoc_resp_ie_len;
6924 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
6928 #ifndef CONFIG_IOCTL_CFG80211
6929 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE))
6933 len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
6936 pattrib->pktlen += len;
6938 #endif /* CONFIG_IOCTL_CFG80211 */
6940 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
6941 #ifdef CONFIG_IOCTL_CFG80211
6942 && (_TRUE == pwdinfo->wfd_info->wfd_enable)
6943 #endif /* CONFIG_IOCTL_CFG80211 */
6946 wfdielen = build_assoc_resp_wfd_ie(pwdinfo, pframe);
6948 pattrib->pktlen += wfdielen;
6950 #endif /* CONFIG_WFD */
6951 #endif /* CONFIG_P2P */
6953 pattrib->last_txcmdsz = pattrib->pktlen;
6955 dump_mgntframe(padapter, pmgntframe);
6960 void issue_assocreq(_adapter *padapter)
6963 struct xmit_frame *pmgntframe;
6964 struct pkt_attrib *pattrib;
6965 unsigned char *pframe, *p;
6966 struct rtw_ieee80211_hdr *pwlanhdr;
6967 unsigned short *fctrl;
6968 unsigned short val16;
6969 unsigned int i, j, ie_len, index=0;
6970 unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
6971 PNDIS_802_11_VARIABLE_IEs pIE;
6972 struct registry_priv *pregpriv = &padapter->registrypriv;
6973 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6974 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6975 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6976 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6977 int bssrate_len = 0, sta_bssrate_len = 0;
6979 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6980 u8 p2pie[ 255 ] = { 0x00 };
6984 #endif /* CONFIG_WFD */
6985 #endif /* CONFIG_P2P */
6989 #endif /* CONFIG_DFS */
6991 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
6994 /* update attribute */
6995 pattrib = &pmgntframe->attrib;
6996 update_mgntframe_attrib(padapter, pattrib);
6998 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7000 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7001 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7003 fctrl = &(pwlanhdr->frame_ctl);
7005 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7006 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
7007 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7009 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7010 pmlmeext->mgnt_seq++;
7011 SetFrameSubType(pframe, WIFI_ASSOCREQ);
7013 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7014 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7019 memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
7021 memcpy(pframe, &cap, 2);
7023 memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
7024 #endif /* CONFIG_DFS */
7027 pattrib->pktlen += 2;
7029 /* listen interval */
7030 /* todo: listen interval for power saving */
7031 val16 = cpu_to_le16(3);
7032 memcpy(pframe ,(unsigned char *)&val16, 2);
7034 pattrib->pktlen += 2;
7037 pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
7039 /* supported rate & extended supported rate */
7041 #if 1 /* Check if the AP's supported rates are also supported by STA. */
7042 get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
7043 /* DBG_8723A("sta_bssrate_len=%d\n", sta_bssrate_len); */
7045 if(pmlmeext->cur_channel == 14)/* for JAPAN, channel 14 can only uses B Mode(CCK) */
7047 sta_bssrate_len = 4;
7050 /* for (i = 0; i < sta_bssrate_len; i++) { */
7051 /* DBG_8723A("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
7054 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
7055 if (pmlmeinfo->network.SupportedRates[i] == 0) break;
7056 DBG_8723A("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
7059 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
7060 if (pmlmeinfo->network.SupportedRates[i] == 0) break;
7062 /* Check if the AP's supported rates are also supported by STA. */
7063 for (j=0; j < sta_bssrate_len; j++) {
7064 /* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
7065 if ( (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK)
7066 == (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) {
7067 /* DBG_8723A("match i = %d, j=%d\n", i, j); */
7070 /* DBG_8723A("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)); */
7074 if (j == sta_bssrate_len) {
7075 /* the rate is not supported by STA */
7076 DBG_8723A("%s(): the rate[%d]=%02X is not supported by STA!\n",__FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]);
7078 /* the rate is supported by STA */
7079 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
7083 bssrate_len = index;
7084 DBG_8723A("bssrate_len = %d\n", bssrate_len);
7086 #endif /* Check if the AP's supported rates are also supported by STA. */
7088 if (bssrate_len == 0) {
7089 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
7090 rtw_free_xmitframe(pxmitpriv, pmgntframe);
7091 goto exit; /* don't connect to AP if no joint supported rate */
7094 if (bssrate_len > 8)
7096 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
7097 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
7101 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
7105 p = rtw_get_ie((pmlmeinfo->network.IEs + sizeof(NDIS_802_11_FIXED_IEs)), _RSN_IE_2_, &ie_len, (pmlmeinfo->network.IELength - sizeof(NDIS_802_11_FIXED_IEs)));
7108 pframe = rtw_set_ie(pframe, _RSN_IE_2_, ie_len, (p + 2), &(pattrib->pktlen));
7111 #ifdef CONFIG_80211N_HT
7113 if(padapter->mlmepriv.htpriv.ht_option==_TRUE)
7115 p = rtw_get_ie((pmlmeinfo->network.IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_CAPABILITY_IE_, &ie_len, (pmlmeinfo->network.IELength - sizeof(NDIS_802_11_FIXED_IEs)));
7116 if ((p != NULL) && (!(is_ap_in_tkip(padapter))))
7118 memcpy(&(pmlmeinfo->HT_caps), (p + 2), sizeof(struct HT_caps_element));
7120 /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
7121 if (pregpriv->cbw40_enable == 0)
7123 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &= (~(BIT(6) | BIT(1)));
7127 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= BIT(1);
7130 /* todo: disable SM power save mode */
7131 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= 0x000c;
7133 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
7134 /* switch (pregpriv->rf_config) */
7139 if(pregpriv->rx_stbc)
7140 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);/* RX STBC One spatial stream */
7142 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16);
7149 if((pregpriv->rx_stbc == 0x3) ||/* enable for 2.4/5 GHz */
7150 ((pmlmeext->cur_wireless_mode & WIRELESS_11_24N) && (pregpriv->rx_stbc == 0x1)) || /* enable for 2.4GHz */
7151 ((pmlmeext->cur_wireless_mode & WIRELESS_11_5N) && (pregpriv->rx_stbc == 0x2)) || /* enable for 5GHz */
7152 (pregpriv->wifi_spec==1))
7154 DBG_8723A("declare supporting RX STBC\n");
7155 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0200);/* RX STBC two spatial stream */
7157 #ifdef CONFIG_DISABLE_MCS13TO15
7158 if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40 && (pregpriv->wifi_spec!=1))
7159 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R_MCS13TO15_OFF, 16);
7161 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R, 16);
7162 #else /* CONFIG_DISABLE_MCS13TO15 */
7163 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R, 16);
7164 #endif /* CONFIG_DISABLE_MCS13TO15 */
7167 #ifdef RTL8192C_RECONFIG_TO_1T1R
7169 if(pregpriv->rx_stbc)
7170 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);/* RX STBC One spatial stream */
7172 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16);
7175 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
7177 #ifdef CONFIG_BT_COEXIST
7178 if (BT_1Ant(padapter) == _TRUE)
7181 pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para &= (u8)~IEEE80211_HT_AMPDU_PARM_FACTOR;
7182 /* pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para |= MAX_AMPDU_FACTOR_8K */
7186 pframe = rtw_set_ie(pframe, _HT_CAPABILITY_IE_, ie_len , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
7192 /* vendor specific IE, such as WPA, WMM, WPS */
7193 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;)
7195 pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
7197 switch (pIE->ElementID)
7199 case _VENDOR_SPECIFIC_IE_:
7200 if (!memcmp(pIE->data, RTW_WPA_OUI, 4) ||
7201 !memcmp(pIE->data, WMM_OUI, 4) ||
7202 !memcmp(pIE->data, WPS_OUI, 4)) {
7203 if (!padapter->registrypriv.wifi_spec)
7205 /* Commented by Kurt 20110629 */
7206 /* In some older APs, WPS handshake */
7207 /* would be fail if we append vender extensions informations to AP */
7208 if (!memcmp(pIE->data,
7213 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, pIE->Length, pIE->data, &(pattrib->pktlen));
7221 i += (pIE->Length + 2);
7224 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
7226 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
7229 #ifdef CONFIG_WAPI_SUPPORT
7230 rtw_build_assoc_req_wapi_ie(padapter, pframe, pattrib);
7235 #ifdef CONFIG_IOCTL_CFG80211
7236 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
7238 if(pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len>0)
7240 memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len);
7241 pframe += pmlmepriv->p2p_assoc_req_ie_len;
7242 pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
7246 #endif /* CONFIG_IOCTL_CFG80211 */
7248 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
7250 /* Should add the P2P IE in the association request frame. */
7254 p2pie[ p2pielen++ ] = 0x50;
7255 p2pie[ p2pielen++ ] = 0x6F;
7256 p2pie[ p2pielen++ ] = 0x9A;
7257 p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
7259 /* Commented by Albert 20101109 */
7260 /* According to the P2P Specification, the association request frame should contain 3 P2P attributes */
7261 /* 1. P2P Capability */
7262 /* 2. Extended Listen Timing */
7263 /* 3. Device Info */
7264 /* Commented by Albert 20110516 */
7265 /* 4. P2P Interface */
7267 /* P2P Capability */
7269 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
7272 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
7276 /* Device Capability Bitmap, 1 byte */
7277 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
7279 /* Group Capability Bitmap, 1 byte */
7280 if ( pwdinfo->persistent_supported )
7281 p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
7283 p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
7285 /* Extended Listen Timing */
7287 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
7290 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
7294 /* Availability Period */
7295 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
7298 /* Availability Interval */
7299 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
7304 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
7307 /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
7308 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
7309 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
7313 /* P2P Device Address */
7314 memcpy(p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
7315 p2pielen += ETH_ALEN;
7318 /* This field should be big endian. Noted by P2P specification. */
7319 if ( ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN ) ||
7320 ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN ) )
7322 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
7326 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC );
7331 /* Primary Device Type */
7333 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
7337 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
7340 /* Sub Category ID */
7341 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
7344 /* Number of Secondary Device Types */
7345 p2pie[ p2pielen++ ] = 0x00; /* No Secondary Device Type List */
7349 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
7353 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
7357 memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
7358 p2pielen += pwdinfo->device_name_len;
7362 p2pie[ p2pielen++ ] = P2P_ATTR_INTERFACE;
7365 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x000D );
7369 memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); /* P2P Device Address */
7370 p2pielen += ETH_ALEN;
7372 p2pie[ p2pielen++ ] = 1; /* P2P Interface Address Count */
7374 memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); /* P2P Interface Address List */
7375 p2pielen += ETH_ALEN;
7377 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
7380 /* wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe); */
7381 /* pframe += wfdielen; */
7382 /* pattrib->pktlen += wfdielen; */
7383 #endif /* CONFIG_WFD */
7387 #endif /* CONFIG_P2P */
7390 #ifdef CONFIG_IOCTL_CFG80211
7391 if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
7392 #endif /* CONFIG_IOCTL_CFG80211 */
7394 wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);
7396 pattrib->pktlen += wfdielen;
7398 #ifdef CONFIG_IOCTL_CFG80211
7399 else if (pmlmepriv->wfd_assoc_req_ie != NULL && pmlmepriv->wfd_assoc_req_ie_len>0)
7402 memcpy(pframe, pmlmepriv->wfd_assoc_req_ie, pmlmepriv->wfd_assoc_req_ie_len);
7403 pattrib->pktlen += pmlmepriv->wfd_assoc_req_ie_len;
7404 pframe += pmlmepriv->wfd_assoc_req_ie_len;
7406 #endif /* CONFIG_IOCTL_CFG80211 */
7407 #endif /* CONFIG_WFD */
7409 pattrib->last_txcmdsz = pattrib->pktlen;
7410 dump_mgntframe(padapter, pmgntframe);
7415 if (ret == _SUCCESS)
7416 rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
7418 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
7423 /* when wait_ack is ture, this function shoule be called at process context */
7424 static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
7427 struct xmit_frame *pmgntframe;
7428 struct pkt_attrib *pattrib;
7429 unsigned char *pframe;
7430 struct rtw_ieee80211_hdr *pwlanhdr;
7431 unsigned short *fctrl;
7432 struct xmit_priv *pxmitpriv;
7433 struct mlme_ext_priv *pmlmeext;
7434 struct mlme_ext_info *pmlmeinfo;
7436 /* DBG_8723A("%s:%d\n", __FUNCTION__, power_mode); */
7441 pxmitpriv = &(padapter->xmitpriv);
7442 pmlmeext = &(padapter->mlmeextpriv);
7443 pmlmeinfo = &(pmlmeext->mlmext_info);
7445 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7450 /* update attribute */
7451 pattrib = &pmgntframe->attrib;
7452 update_mgntframe_attrib(padapter, pattrib);
7453 pattrib->retry_ctrl = _FALSE;
7455 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7457 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7458 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7460 fctrl = &(pwlanhdr->frame_ctl);
7463 if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7467 else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
7477 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
7478 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
7479 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7481 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7482 pmlmeext->mgnt_seq++;
7483 SetFrameSubType(pframe, WIFI_DATA_NULL);
7485 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7486 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7488 pattrib->last_txcmdsz = pattrib->pktlen;
7492 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
7496 dump_mgntframe(padapter, pmgntframe);
7504 /* when wait_ms >0 , this function shoule be called at process context */
7505 /* da == NULL for station mode */
7506 int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
7510 u32 start = rtw_get_current_time();
7511 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7512 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7514 /* da == NULL, assum it's null data for sta to ap*/
7516 da = get_my_bssid(&(pmlmeinfo->network));
7520 ret = _issue_nulldata(padapter, da, power_mode, wait_ms>0?_TRUE:_FALSE);
7524 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
7527 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
7528 rtw_msleep_os(wait_ms);
7530 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
7534 #ifndef DBG_XMIT_ACK
7539 if (try_cnt && wait_ms) {
7541 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
7542 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
7543 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
7545 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
7546 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
7547 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
7553 /* when wait_ack is ture, this function shoule be called at process context */
7554 static int _issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int wait_ack)
7557 struct xmit_frame *pmgntframe;
7558 struct pkt_attrib *pattrib;
7559 unsigned char *pframe;
7560 struct rtw_ieee80211_hdr *pwlanhdr;
7561 unsigned short *fctrl, *qc;
7562 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7563 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7564 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7566 DBG_8723A("%s\n", __FUNCTION__);
7568 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7573 /* update attribute */
7574 pattrib = &pmgntframe->attrib;
7575 update_mgntframe_attrib(padapter, pattrib);
7577 pattrib->hdrlen +=2;
7578 pattrib->qos_en = _TRUE;
7580 pattrib->ack_policy = 0;
7583 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7585 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7586 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7588 fctrl = &(pwlanhdr->frame_ctl);
7591 if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7595 else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
7603 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
7605 SetPriority(qc, tid);
7607 SetEOSP(qc, pattrib->eosp);
7609 SetAckpolicy(qc, pattrib->ack_policy);
7611 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
7612 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
7613 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7615 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7616 pmlmeext->mgnt_seq++;
7617 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
7619 pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos);
7620 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
7622 pattrib->last_txcmdsz = pattrib->pktlen;
7626 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
7630 dump_mgntframe(padapter, pmgntframe);
7638 /* when wait_ms >0 , this function shoule be called at process context */
7639 /* da == NULL for station mode */
7640 int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
7644 u32 start = rtw_get_current_time();
7645 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7646 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7648 /* da == NULL, assum it's null data for sta to ap*/
7650 da = get_my_bssid(&(pmlmeinfo->network));
7654 ret = _issue_qos_nulldata(padapter, da, tid, wait_ms>0?_TRUE:_FALSE);
7658 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
7661 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
7662 rtw_msleep_os(wait_ms);
7664 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
7668 #ifndef DBG_XMIT_ACK
7673 if (try_cnt && wait_ms) {
7675 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
7676 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
7677 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
7679 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
7680 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
7681 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
7687 static int _issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack)
7689 struct xmit_frame *pmgntframe;
7690 struct pkt_attrib *pattrib;
7691 unsigned char *pframe;
7692 struct rtw_ieee80211_hdr *pwlanhdr;
7693 unsigned short *fctrl;
7694 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7695 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7696 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7699 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
7700 #endif /* CONFIG_P2P */
7702 /* DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
7705 if ( !( rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) ) && ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
7707 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
7708 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
7710 #endif /* CONFIG_P2P */
7712 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7717 /* update attribute */
7718 pattrib = &pmgntframe->attrib;
7719 update_mgntframe_attrib(padapter, pattrib);
7720 pattrib->retry_ctrl = _FALSE;
7722 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7724 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7725 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7727 fctrl = &(pwlanhdr->frame_ctl);
7730 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
7731 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
7732 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7734 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7735 pmlmeext->mgnt_seq++;
7736 SetFrameSubType(pframe, WIFI_DEAUTH);
7738 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7739 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7741 reason = cpu_to_le16(reason);
7742 pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(pattrib->pktlen));
7744 pattrib->last_txcmdsz = pattrib->pktlen;
7748 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
7752 dump_mgntframe(padapter, pmgntframe);
7760 int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason)
7762 DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
7763 return _issue_deauth(padapter, da, reason, _FALSE);
7766 int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
7771 u32 start = rtw_get_current_time();
7775 ret = _issue_deauth(padapter, da, reason, wait_ms>0?_TRUE:_FALSE);
7779 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
7782 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
7783 rtw_msleep_os(wait_ms);
7785 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
7789 #ifndef DBG_XMIT_ACK
7794 if (try_cnt && wait_ms) {
7796 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
7797 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
7798 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
7800 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
7801 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
7802 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
7808 void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
7811 _list *plist, *phead;
7812 struct xmit_frame *pmgntframe;
7813 struct pkt_attrib *pattrib;
7814 unsigned char *pframe;
7815 struct rtw_ieee80211_hdr *pwlanhdr;
7816 unsigned short *fctrl;
7817 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7818 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7819 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7820 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7822 DBG_8723A(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n",
7823 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset);
7825 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7828 /* update attribute */
7829 pattrib = &pmgntframe->attrib;
7830 update_mgntframe_attrib(padapter, pattrib);
7832 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7834 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7835 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7837 fctrl = &(pwlanhdr->frame_ctl);
7840 memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
7841 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); /* TA */
7842 memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
7844 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7845 pmlmeext->mgnt_seq++;
7846 SetFrameSubType(pframe, WIFI_ACTION);
7848 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7849 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7851 /* category, action */
7853 u8 category, action;
7854 category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
7855 action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
7857 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
7858 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
7861 pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0);
7862 pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen),
7863 hal_ch_offset_to_secondary_ch_offset(ch_offset));
7865 pattrib->last_txcmdsz = pattrib->pktlen;
7867 dump_mgntframe(padapter, pmgntframe);
7870 void issue_action_BA(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short status)
7872 u8 category = RTW_WLAN_CATEGORY_BACK;
7876 u16 BA_timeout_value;
7877 u16 BA_starting_seqctrl;
7878 int max_rx_ampdu_factor;
7879 struct xmit_frame *pmgntframe;
7880 struct pkt_attrib *pattrib;
7882 struct rtw_ieee80211_hdr *pwlanhdr;
7884 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7885 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7886 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7887 struct sta_info *psta;
7888 struct sta_priv *pstapriv = &padapter->stapriv;
7889 struct registry_priv *pregpriv = &padapter->registrypriv;
7890 #ifdef CONFIG_BT_COEXIST
7891 u8 tendaAPMac[] = {0xC8, 0x3A, 0x35};
7894 #ifdef CONFIG_80211N_HT
7895 DBG_8723A("%s, category=%d, action=%d, status=%d\n", __FUNCTION__, category, action, status);
7897 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7902 /* update attribute */
7903 pattrib = &pmgntframe->attrib;
7904 update_mgntframe_attrib(padapter, pattrib);
7906 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7908 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7909 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7911 fctrl = &(pwlanhdr->frame_ctl);
7914 /* memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */
7915 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
7916 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
7917 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7919 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7920 pmlmeext->mgnt_seq++;
7921 SetFrameSubType(pframe, WIFI_ACTION);
7923 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7924 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7926 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
7927 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
7929 status = cpu_to_le16(status);
7935 case 0: /* ADDBA req */
7937 pmlmeinfo->dialogToken++;
7938 } while (pmlmeinfo->dialogToken == 0);
7939 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
7941 #ifdef CONFIG_BT_COEXIST
7942 if ((BT_1Ant(padapter) == _TRUE) &&
7943 ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
7944 memcmp(raddr, tendaAPMac, 3)))
7946 /* A-MSDU NOT Supported */
7948 /* immediate Block Ack */
7949 BA_para_set |= (1 << 1) & IEEE80211_ADDBA_PARAM_POLICY_MASK;
7951 BA_para_set |= (status << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
7952 /* max buffer size is 8 MSDU */
7953 BA_para_set |= (8 << 6) & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
7958 BA_para_set = (0x1002 | ((status & 0xf) << 2)); /* immediate ack & 64 buffer size */
7960 BA_para_set = cpu_to_le16(BA_para_set);
7961 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
7963 BA_timeout_value = 5000;/* 5ms */
7964 BA_timeout_value = cpu_to_le16(BA_timeout_value);
7965 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen));
7967 /* if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL) */
7968 if ((psta = rtw_get_stainfo(pstapriv, raddr)) != NULL)
7970 start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1;
7972 DBG_8723A("BA_starting_seqctrl = %d for TID=%d\n", start_seq, status & 0x07);
7974 psta->BA_starting_seqctrl[status & 0x07] = start_seq;
7976 BA_starting_seqctrl = start_seq << 4;
7979 BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
7980 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen));
7983 case 1: /* ADDBA rsp */
7984 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
7985 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
7986 rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
7987 if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_64K)
7988 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
7989 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_32K)
7990 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800); /* 32 buffer size */
7991 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_16K)
7992 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0400); /* 16 buffer size */
7993 else if (max_rx_ampdu_factor == IEEE80211_HT_MAX_AMPDU_8K)
7994 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0200); /* 8 buffer size */
7996 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
7998 #ifdef CONFIG_BT_COEXIST
7999 if ((BT_1Ant(padapter) == _TRUE) &&
8000 ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
8001 memcmp(raddr, tendaAPMac, 3)))
8003 /* max buffer size is 8 MSDU */
8004 BA_para_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
8005 BA_para_set |= (8 << 6) & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
8009 if(pregpriv->ampdu_amsdu==0)/* disabled */
8010 BA_para_set = cpu_to_le16(BA_para_set & ~BIT(0));
8011 else if(pregpriv->ampdu_amsdu==1)/* enabled */
8012 BA_para_set = cpu_to_le16(BA_para_set | BIT(0));
8014 BA_para_set = cpu_to_le16(BA_para_set);
8016 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
8017 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
8020 BA_para_set = (status & 0x1F) << 3;
8021 BA_para_set = cpu_to_le16(BA_para_set);
8022 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
8024 reason_code = 37;/* Requested from peer STA as it does not want to use the mechanism */
8025 reason_code = cpu_to_le16(reason_code);
8026 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(reason_code)), &(pattrib->pktlen));
8033 pattrib->last_txcmdsz = pattrib->pktlen;
8035 dump_mgntframe(padapter, pmgntframe);
8036 #endif /* CONFIG_80211N_HT */
8039 static void issue_action_BSSCoexistPacket(_adapter *padapter)
8042 _list *plist, *phead;
8043 unsigned char category, action;
8044 struct xmit_frame *pmgntframe;
8045 struct pkt_attrib *pattrib;
8046 unsigned char *pframe;
8047 struct rtw_ieee80211_hdr *pwlanhdr;
8048 unsigned short *fctrl;
8049 struct wlan_network *pnetwork = NULL;
8050 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8051 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8052 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8053 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8054 _queue *queue = &(pmlmepriv->scanned_queue);
8055 u8 InfoContent[16] = {0};
8057 #ifdef CONFIG_80211N_HT
8058 if((pmlmepriv->num_FortyMHzIntolerant==0) || (pmlmepriv->num_sta_no_ht==0))
8061 if(_TRUE == pmlmeinfo->bwmode_updated)
8064 DBG_8723A("%s\n", __FUNCTION__);
8066 category = RTW_WLAN_CATEGORY_PUBLIC;
8067 action = ACT_PUBLIC_BSSCOEXIST;
8069 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8074 /* update attribute */
8075 pattrib = &pmgntframe->attrib;
8076 update_mgntframe_attrib(padapter, pattrib);
8078 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8080 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8081 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8083 fctrl = &(pwlanhdr->frame_ctl);
8086 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8087 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
8088 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8090 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8091 pmlmeext->mgnt_seq++;
8092 SetFrameSubType(pframe, WIFI_ACTION);
8094 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8095 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8097 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
8098 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
8101 if(pmlmepriv->num_FortyMHzIntolerant>0)
8105 iedata |= BIT(2);/* 20 MHz BSS Width Request */
8107 pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
8112 memset(ICS, 0, sizeof(ICS));
8113 if(pmlmepriv->num_sta_no_ht>0)
8117 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
8119 phead = get_list_head(queue);
8120 plist = get_next(phead);
8126 WLAN_BSSID_EX *pbss_network;
8128 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
8131 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
8133 plist = get_next(plist);
8135 pbss_network = (WLAN_BSSID_EX *)&pnetwork->network;
8137 p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
8138 if((p==NULL) || (len==0))/* non-HT */
8140 if((pbss_network->Configuration.DSConfig<=0) || (pbss_network->Configuration.DSConfig>14))
8143 ICS[0][pbss_network->Configuration.DSConfig]=1;
8151 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
8160 /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i); */
8169 InfoContent[k] = j; /* channel number */
8170 /* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */
8176 pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
8184 pattrib->last_txcmdsz = pattrib->pktlen;
8186 dump_mgntframe(padapter, pmgntframe);
8187 #endif /* CONFIG_80211N_HT */
8190 unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr)
8192 struct sta_priv *pstapriv = &padapter->stapriv;
8193 struct sta_info *psta = NULL;
8194 /* struct recv_reorder_ctrl *preorder_ctrl; */
8195 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8196 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8199 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
8200 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
8203 psta = rtw_get_stainfo(pstapriv, addr);
8207 /* DBG_8723A("%s:%s\n", __FUNCTION__, (initiator==0)?"RX_DIR":"TX_DIR"); */
8209 if(initiator==0) /* recipient */
8211 for(tid = 0;tid<MAXTID;tid++)
8213 if(psta->recvreorder_ctrl[tid].enable == _TRUE)
8215 DBG_8723A("rx agg disable tid(%d)\n",tid);
8216 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
8217 psta->recvreorder_ctrl[tid].enable = _FALSE;
8218 psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
8220 DBG_8723A("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
8221 psta->recvreorder_ctrl[tid].indicate_seq);
8226 else if(initiator == 1)/* originator */
8228 #ifdef CONFIG_80211N_HT
8229 /* DBG_8723A("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap); */
8230 for(tid = 0;tid<MAXTID;tid++)
8232 if(psta->htpriv.agg_enable_bitmap & BIT(tid))
8234 DBG_8723A("tx agg disable tid(%d)\n",tid);
8235 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F) );
8236 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
8237 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
8241 #endif /* CONFIG_80211N_HT */
8247 unsigned int send_beacon(_adapter *padapter)
8249 u8 bxmitok = _FALSE;
8252 /* ifdef CONFIG_CONCURRENT_MODE */
8253 /* struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); */
8254 /* struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); */
8255 /* _adapter *pbuddy_adapter = padapter->pbuddy_adapter; */
8256 /* struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); */
8259 u32 start = rtw_get_current_time();
8261 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
8263 issue_beacon(padapter, 100);
8267 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
8269 }while((poll%10)!=0 && _FALSE == bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
8271 }while(_FALSE == bxmitok && issue<100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
8273 if(padapter->bSurpriseRemoved || padapter->bDriverStopped)
8278 if(_FALSE == bxmitok)
8280 DBG_8723A("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
8285 u32 passing_time = rtw_get_passing_time_ms(start);
8287 if(passing_time > 100 || issue > 3)
8288 DBG_8723A("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
8290 /* DBG_8723A("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start)); */
8296 /****************************************************************************
8298 Following are some utitity fuctions for WiFi MLME
8300 *****************************************************************************/
8302 bool IsLegal5GChannel(
8303 IN PADAPTER Adapter,
8308 u8 Channel_5G[45] = {36,38,40,42,44,46,48,50,52,54,56,58,
8309 60,62,64,100,102,104,106,108,110,112,114,116,118,120,122,
8310 124,126,128,130,132,134,136,138,140,149,151,153,155,157,159,
8312 for(i=0;i<sizeof(Channel_5G);i++)
8313 if(channel == Channel_5G[i])
8318 void site_survey(_adapter *padapter)
8320 unsigned char survey_channel = 0, val8;
8321 RT_SCAN_TYPE ScanType = SCAN_PASSIVE;
8322 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8323 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8324 u32 initialgain = 0;
8328 #ifdef CONFIG_CONCURRENT_MODE
8330 #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
8331 u8 stay_buddy_ch = 0;
8332 #endif /* CONFIG_STA_MODE_SCAN_UNDER_AP_MODE */
8334 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8335 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
8336 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
8338 #endif /* CONFIG_CONCURRENT_MODE */
8339 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
8340 static unsigned char prev_survey_channel = 0;
8341 static unsigned int p2p_scan_count = 0;
8343 if ( ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) || ( pwdinfo->p2p_info.scan_op_ch_only ) )
8345 if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
8347 survey_channel = pwdinfo->rx_invitereq_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
8351 survey_channel = pwdinfo->p2p_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
8353 ScanType = SCAN_ACTIVE;
8355 else if(rtw_p2p_findphase_ex_is_social(pwdinfo))
8357 /* Commented by Albert 2011/06/03 */
8358 /* The driver is in the find phase, it should go through the social channel. */
8360 survey_channel = pwdinfo->social_chan[pmlmeext->sitesurvey_res.channel_idx];
8361 ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, survey_channel);
8362 if (ch_set_idx >= 0)
8363 ScanType = pmlmeext->channel_set[ch_set_idx].ScanType;
8365 ScanType = SCAN_ACTIVE;
8368 #endif /* CONFIG_P2P */
8370 struct rtw_ieee80211_channel *ch;
8371 if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) {
8372 ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
8373 survey_channel = ch->hw_value;
8374 ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
8379 DBG_8723A(FUNC_ADPT_FMT" ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c\n"
8380 , FUNC_ADPT_ARG(padapter)
8382 , pwdinfo->find_phase_state_exchange_cnt, pmlmeext->sitesurvey_res.channel_idx
8383 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
8384 , ScanType?'A':'P', pmlmeext->sitesurvey_res.scan_mode?'A':'P'
8385 , pmlmeext->sitesurvey_res.ssid[0].SsidLength?'S':' '
8387 #ifdef DBG_FIXED_CHAN
8388 DBG_8723A(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
8392 if(survey_channel != 0)
8394 /* PAUSE 4-AC Queue when site_survey */
8395 /* rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
8397 /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
8398 #ifdef CONFIG_CONCURRENT_MODE
8399 #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
8400 if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE)
8402 if( pmlmeinfo->scan_cnt == RTW_SCAN_NUM_OF_CH )
8404 pmlmeinfo->scan_cnt = 0;
8405 survey_channel = pbuddy_mlmeext->cur_channel;
8406 ScanType = SCAN_ACTIVE;
8411 if( pmlmeinfo->scan_cnt == 0 )
8413 pmlmeinfo->scan_cnt++;
8416 #endif /* CONFIG_STA_MODE_SCAN_UNDER_AP_MODE */
8417 #endif /* CONFIG_CONCURRENT_MODE */
8418 if(pmlmeext->sitesurvey_res.channel_idx == 0)
8420 #ifdef DBG_FIXED_CHAN
8421 if(pmlmeext->fixed_chan !=0xff)
8422 set_channel_bwmode(padapter, pmlmeext->fixed_chan, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
8425 set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
8429 #ifdef DBG_FIXED_CHAN
8430 if(pmlmeext->fixed_chan!=0xff)
8431 SelectChannel(padapter, pmlmeext->fixed_chan);
8434 SelectChannel(padapter, survey_channel);
8437 #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
8438 if( stay_buddy_ch == 1 )
8440 val8 = 0; /* survey done */
8441 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
8443 if(check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
8444 check_buddy_fwstate(padapter, _FW_LINKED))
8446 update_beacon(padapter->pbuddy_adapter, 0, NULL, _TRUE);
8449 else if( stay_buddy_ch == 2 )
8451 val8 = 1; /* under site survey */
8452 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
8454 #endif /* CONFIG_STA_MODE_SCAN_UNDER_AP_MODE */
8456 if(ScanType == SCAN_ACTIVE) /* obey the channel plan setting... */
8459 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) ||
8460 rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
8463 issue_probereq_p2p(padapter, NULL);
8464 issue_probereq_p2p(padapter, NULL);
8465 issue_probereq_p2p(padapter, NULL);
8468 #endif /* CONFIG_P2P */
8471 for(i=0;i<RTW_SSID_SCAN_AMOUNT;i++){
8472 if(pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
8473 /* todo: to issue two probe req??? */
8474 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
8475 /* rtw_msleep_os(SURVEY_TO>>1); */
8476 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
8480 if(pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
8481 /* todo: to issue two probe req??? */
8482 issue_probereq(padapter, NULL, NULL);
8483 /* rtw_msleep_os(SURVEY_TO>>1); */
8484 issue_probereq(padapter, NULL, NULL);
8489 #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
8490 if( stay_buddy_ch == 1 )
8491 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time * RTW_STAY_AP_CH_MILLISECOND );
8493 #endif /* CONFIG_STA_MODE_SCAN_UNDER_AP_MODE */
8494 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
8500 /* channel number is 0 or this channel is not valid. */
8502 #ifdef CONFIG_CONCURRENT_MODE
8507 if(check_fwstate(pmlmepriv, _FW_LINKED))
8509 cur_channel = pmlmeext->cur_channel;
8510 cur_bwmode = pmlmeext->cur_bwmode;
8511 cur_ch_offset = pmlmeext->cur_ch_offset;
8513 /* else if((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) */
8514 else if(check_buddy_fwstate(padapter, _FW_LINKED)) /* for AP or STA */
8516 cur_channel = pbuddy_mlmeext->cur_channel;
8517 cur_bwmode = pbuddy_mlmeext->cur_bwmode;
8518 cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
8522 cur_channel = pmlmeext->cur_channel;
8523 cur_bwmode = pmlmeext->cur_bwmode;
8524 cur_ch_offset = pmlmeext->cur_ch_offset;
8529 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
8531 if( ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) || ( pwdinfo->p2p_info.scan_op_ch_only ) )
8533 /* Set the find_phase_state_exchange_cnt to P2P_FINDPHASE_EX_CNT. */
8534 /* This will let the following flow to run the scanning end. */
8535 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
8537 #ifdef CONFIG_DBG_P2P
8538 DBG_8723A( "[%s] find phase exchange cnt = %d\n", __FUNCTION__, pwdinfo->find_phase_state_exchange_cnt );
8542 if(rtw_p2p_findphase_ex_is_needed(pwdinfo))
8544 /* Set the P2P State to the listen state of find phase and set the current channel to the listen channel */
8545 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
8546 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
8547 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
8549 initialgain = 0xff; /* restore RX GAIN */
8550 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
8551 /* turn on dynamic functions */
8552 Restore_DM_Func_Flag(padapter);
8553 /* Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, _TRUE); */
8555 _set_timer( &pwdinfo->find_phase_timer, ( u32 ) ( ( u32 ) ( pwdinfo->listen_dwell ) * 100 ) );
8558 #endif /* CONFIG_P2P */
8561 #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
8562 pmlmeinfo->scan_cnt = 0;
8563 #endif /* CONFIG_DMP_STA_NODE_SCAN_UNDER_AP_MODE */
8565 #ifdef CONFIG_ANTENNA_DIVERSITY
8566 /* 20100721:Interrupt scan operation here. */
8567 /* For SW antenna diversity before link, it needs to switch to another antenna and scan again. */
8568 /* It compares the scan result and select beter one to do connection. */
8569 if(rtw_hal_antdiv_before_linked(padapter))
8571 pmlmeext->sitesurvey_res.bss_cnt = 0;
8572 pmlmeext->sitesurvey_res.channel_idx = -1;
8573 pmlmeext->chan_scan_time = SURVEY_TO /2;
8574 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
8580 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
8582 #ifdef CONFIG_CONCURRENT_MODE
8583 #ifndef CONFIG_IOCTL_CFG80211
8584 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
8586 _set_timer( &pwdinfo->ap_p2p_switch_timer, 500 );
8588 #endif /* CONFIG_IOCTL_CFG80211 */
8589 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
8591 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
8594 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
8595 #endif /* CONFIG_P2P */
8597 pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
8599 /* switch back to the original channel */
8600 /* SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
8603 #ifdef CONFIG_DUALMAC_CONCURRENT
8604 dc_set_channel_bwmode_survey_done(padapter);
8606 #ifndef CONFIG_IOCTL_CFG80211
8607 if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) )
8609 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
8612 #endif /* CONFIG_IOCTL_CFG80211 */
8613 #ifdef CONFIG_CONCURRENT_MODE
8614 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
8616 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
8617 #endif /* CONFIG_DUALMAC_CONCURRENT */
8618 #endif /* CONFIG_CONCURRENT_MODE */
8621 /* flush 4-AC Queue after site_survey */
8623 /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
8626 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
8628 initialgain = 0xff; /* restore RX GAIN */
8629 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
8630 /* turn on dynamic functions */
8631 Restore_DM_Func_Flag(padapter);
8632 /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE); */
8634 if (is_client_associated_to_ap(padapter) == _TRUE)
8636 issue_nulldata(padapter, NULL, 0, 3, 500);
8638 #ifdef CONFIG_CONCURRENT_MODE
8639 if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
8641 DBG_8723A("adapter is surveydone(buddy_adapter is linked), issue nulldata(pwrbit=0)\n");
8643 issue_nulldata(padapter->pbuddy_adapter, NULL, 0, 3, 500);
8647 #ifdef CONFIG_CONCURRENT_MODE
8648 else if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
8650 issue_nulldata(padapter->pbuddy_adapter, NULL, 0, 3, 500);
8654 val8 = 0; /* survey done */
8655 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
8657 report_surveydone_event(padapter);
8659 pmlmeext->chan_scan_time = SURVEY_TO;
8660 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
8662 issue_action_BSSCoexistPacket(padapter);
8663 issue_action_BSSCoexistPacket(padapter);
8664 issue_action_BSSCoexistPacket(padapter);
8668 #ifdef CONFIG_CONCURRENT_MODE
8669 if(check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
8670 check_buddy_fwstate(padapter, _FW_LINKED))
8673 DBG_8723A("survey done, current CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
8675 DBG_8723A("restart pbuddy_adapter's beacon\n");
8677 update_beacon(padapter->pbuddy_adapter, 0, NULL, _TRUE);
8686 /* collect bss info from Beacon and Probe request/response frames. */
8687 u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid)
8693 u8 *pframe = precv_frame->u.hdr.rx_data;
8694 u32 packet_len = precv_frame->u.hdr.len;
8696 struct registry_priv *pregistrypriv = &padapter->registrypriv;
8697 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8698 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8700 len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
8702 if (len > MAX_IE_SZ)
8704 /* DBG_8723A("IE too long for survey event\n"); */
8708 memset(bssid, 0, sizeof(WLAN_BSSID_EX));
8710 subtype = GetFrameSubType(pframe);
8712 if(subtype==WIFI_BEACON) {
8713 bssid->Reserved[0] = 1;
8714 ie_offset = _BEACON_IE_OFFSET_;
8716 /* FIXME : more type */
8717 if (subtype == WIFI_PROBEREQ) {
8718 ie_offset = _PROBEREQ_IE_OFFSET_;
8719 bssid->Reserved[0] = 2;
8720 } else if (subtype == WIFI_PROBERSP) {
8721 ie_offset = _PROBERSP_IE_OFFSET_;
8722 bssid->Reserved[0] = 3;
8724 bssid->Reserved[0] = 0;
8725 ie_offset = _FIXED_IE_LENGTH_;
8729 bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
8731 /* below is to copy the information element */
8732 bssid->IELength = len;
8733 memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
8735 /* get the signal strength */
8736 bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; /* in dBM.raw data */
8737 bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;/* in percentage */
8738 bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;/* in percentage */
8739 #ifdef CONFIG_ANTENNA_DIVERSITY
8740 /* rtw_hal_get_hwreg(padapter, HW_VAR_CURRENT_ANTENNA, (u8 *)(&bssid->PhyInfo.Optimum_antenna)); */
8741 rtw_hal_get_def_var(padapter, HAL_DEF_CURRENT_ANTENNA, &bssid->PhyInfo.Optimum_antenna);
8745 if ((p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset)) == NULL)
8747 DBG_8723A("marc: cannot find SSID for survey event\n");
8753 if (len > NDIS_802_11_LENGTH_SSID)
8755 DBG_8723A("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
8758 memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
8759 bssid->Ssid.SsidLength = *(p + 1);
8763 bssid->Ssid.SsidLength = 0;
8766 memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
8768 /* checking rate info... */
8770 p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
8773 if (len > NDIS_802_11_LENGTH_RATES_EX)
8775 DBG_8723A("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
8778 memcpy(bssid->SupportedRates, (p + 2), len);
8782 p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
8785 if (len > (NDIS_802_11_LENGTH_RATES_EX-i))
8787 DBG_8723A("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
8790 memcpy(bssid->SupportedRates + i, (p + 2), len);
8795 bssid->NetworkTypeInUse = Ndis802_11OFDM24;
8798 if (bssid->IELength < 12)
8801 /* Checking for DSConfig */
8802 p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
8804 bssid->Configuration.DSConfig = 0;
8805 bssid->Configuration.Length = 0;
8809 bssid->Configuration.DSConfig = *(p + 2);
8812 {/* In 5G, some ap do not have DSSET IE */
8813 /* checking HT info for channel */
8814 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
8817 struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
8818 bssid->Configuration.DSConfig = HT_info->primary_channel;
8821 { /* use current channel */
8822 bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
8826 if (subtype==WIFI_PROBEREQ)
8829 bssid->InfrastructureMode = Ndis802_11Infrastructure;
8830 memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
8835 memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
8836 bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
8838 val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid);
8842 bssid->InfrastructureMode = Ndis802_11Infrastructure;
8843 memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
8847 bssid->InfrastructureMode = Ndis802_11IBSS;
8848 memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
8856 bssid->Configuration.ATIMWindow = 0;
8858 /* 20/40 BSS Coexistence check */
8859 if((pregistrypriv->wifi_spec==1) && (_FALSE == pmlmeinfo->bwmode_updated))
8861 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8862 #ifdef CONFIG_80211N_HT
8863 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
8866 struct HT_caps_element *pHT_caps;
8867 pHT_caps = (struct HT_caps_element *)(p + 2);
8869 if(pHT_caps->u.HT_cap_element.HT_caps_info&BIT(14))
8871 pmlmepriv->num_FortyMHzIntolerant++;
8876 pmlmepriv->num_sta_no_ht++;
8878 #endif /* CONFIG_80211N_HT */
8882 #ifdef CONFIG_INTEL_WIDI
8883 /* process_intel_widi_query_or_tigger(padapter, bssid); */
8884 if(process_intel_widi_query_or_tigger(padapter, bssid))
8888 #endif /* CONFIG_INTEL_WIDI */
8890 #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) & 1
8891 if(strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
8892 DBG_8723A("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
8893 , bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
8894 , rtw_get_oper_ch(padapter)
8895 , bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
8900 /* mark bss info receving from nearby channel as SignalQuality 101 */
8901 if(bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
8903 bssid->PhyInfo.SignalQuality= 101;
8909 void start_create_ibss(_adapter* padapter)
8911 unsigned short caps;
8914 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8915 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8916 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
8917 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
8918 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
8920 /* update wireless mode */
8921 update_wireless_mode(padapter);
8923 /* udpate capability */
8924 caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
8925 update_capinfo(padapter, caps);
8926 if(caps&cap_IBSS)/* adhoc master */
8929 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
8931 /* switch channel */
8932 /* SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
8933 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
8935 beacon_timing_control(padapter);
8937 /* set msr to WIFI_FW_ADHOC_STATE */
8938 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
8939 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
8942 if(send_beacon(padapter)==_FAIL)
8944 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("issuing beacon frame fail....\n"));
8946 report_join_res(padapter, -1);
8947 pmlmeinfo->state = WIFI_FW_NULL_STATE;
8951 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
8953 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
8955 report_join_res(padapter, 1);
8956 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
8961 DBG_8723A("start_create_ibss, invalid cap:%x\n", caps);
8966 void start_clnt_join(_adapter* padapter)
8968 unsigned short caps;
8970 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8971 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8972 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
8975 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
8976 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
8978 /* update wireless mode */
8979 update_wireless_mode(padapter);
8981 /* udpate capability */
8982 caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
8983 update_capinfo(padapter, caps);
8987 #ifdef CONFIG_DUALMAC_CONCURRENT
8988 if(dc_handle_join_request(padapter) == _FAIL)
8990 DBG_8723A("dc_handle_join_request fail !!!\n");
8993 /* switch channel */
8994 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
8995 #elif defined (CONFIG_CONCURRENT_MODE)
8996 if(concurrent_chk_start_clnt_join(padapter) == _FAIL)
8998 #else /* NON CONCURRENT_MODE */
8999 /* switch channel */
9000 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
9003 Set_MSR(padapter, WIFI_FW_STATION_STATE);
9005 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
9007 #ifdef CONFIG_WAPI_SUPPORT
9008 if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI)
9010 /* Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey. */
9014 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
9016 /* switch channel */
9017 /* set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
9019 /* here wait for receiving the beacon to start auth */
9020 /* and enable a timer */
9021 beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
9022 set_link_timer(pmlmeext, beacon_timeout);
9023 _set_timer( &padapter->mlmepriv.assoc_timer,
9024 (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) +beacon_timeout);
9026 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
9028 else if (caps&cap_IBSS) /* adhoc client */
9030 #ifdef CONFIG_DUALMAC_CONCURRENT
9031 if(dc_handle_join_request(padapter) == _FAIL)
9033 DBG_8723A("dc_handle_join_request for Ad-hoc fail !!!\n");
9038 Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
9041 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
9043 /* switch channel */
9044 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
9046 beacon_timing_control(padapter);
9048 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
9050 report_join_res(padapter, 1);
9054 /* DBG_8723A("marc: invalid cap:%x\n", caps); */
9059 void start_clnt_auth(_adapter* padapter)
9061 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9062 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9064 _cancel_timer_ex(&pmlmeext->link_timer);
9066 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
9067 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
9069 pmlmeinfo->auth_seq = 1;
9070 pmlmeinfo->reauth_count = 0;
9071 pmlmeinfo->reassoc_count = 0;
9072 pmlmeinfo->link_count = 0;
9073 pmlmeext->retry = 0;
9075 /* Because of AP's not receiving deauth before */
9076 /* AP may: 1)not response auth or 2)deauth us after link is complete */
9077 /* issue deauth before issuing auth to deal with the situation */
9078 /* Commented by Albert 2012/07/21 */
9079 /* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
9080 issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
9082 DBG_8723A_LEVEL(_drv_always_, "start auth\n");
9083 issue_auth(padapter, NULL, 0);
9085 set_link_timer(pmlmeext, REAUTH_TO);
9088 void start_clnt_assoc(_adapter* padapter)
9090 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9091 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9093 _cancel_timer_ex(&pmlmeext->link_timer);
9095 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
9096 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
9098 issue_assocreq(padapter);
9100 set_link_timer(pmlmeext, REASSOC_TO);
9103 unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason)
9105 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9106 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9109 if (memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
9112 DBG_8723A("%s\n", __FUNCTION__);
9114 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9116 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
9118 pmlmeinfo->state = WIFI_FW_NULL_STATE;
9119 report_del_sta_event(padapter, MacAddr, reason);
9122 else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
9124 pmlmeinfo->state = WIFI_FW_NULL_STATE;
9125 report_join_res(padapter, -2);
9132 #ifdef CONFIG_80211D
9133 static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid)
9135 struct registry_priv *pregistrypriv;
9136 struct mlme_ext_priv *pmlmeext;
9137 RT_CHANNEL_INFO *chplan_new;
9141 pregistrypriv = &padapter->registrypriv;
9142 pmlmeext = &padapter->mlmeextpriv;
9144 /* Adjust channel plan by AP Country IE */
9145 if (pregistrypriv->enable80211d &&
9146 (!pmlmeext->update_channel_plan_by_ap_done))
9150 RT_CHANNEL_PLAN chplan_ap;
9151 RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM];
9153 u8 fcn; /* first channel number */
9154 u8 noc; /* number of channel */
9157 ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
9159 if (len < 6) return;
9165 memset(country, 0, 4);
9166 memcpy(country, p, 3);
9168 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
9169 ("%s: 802.11d country=%s\n", __FUNCTION__, country));
9172 while ((ie - p) >= 3)
9178 for (j = 0; j < noc; j++)
9180 if (fcn <= 14) channel = fcn + j; /* 2.4 GHz */
9181 else channel = fcn + j*4; /* 5 GHz */
9183 chplan_ap.Channel[i++] = channel;
9188 #ifdef CONFIG_DEBUG_RTL871X
9190 DBG_8723A("%s: AP[%s] channel plan {", __func__, bssid->Ssid.Ssid);
9191 while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0))
9193 DBG_8723A("%02d,", chplan_ap.Channel[i]);
9199 memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
9200 #ifdef CONFIG_DEBUG_RTL871X
9202 DBG_8723A("%s: STA channel plan {", __func__);
9203 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
9205 DBG_8723A("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType==SCAN_PASSIVE?'p':'a');
9211 memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
9212 chplan_new = pmlmeext->channel_set;
9215 if (pregistrypriv->wireless_mode & WIRELESS_11G) {
9217 if ((i == MAX_CHANNEL_NUM) ||
9218 (chplan_sta[i].ChannelNum == 0) ||
9219 (chplan_sta[i].ChannelNum > 14))
9222 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
9225 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
9226 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
9227 chplan_new[k].ScanType = SCAN_ACTIVE;
9231 } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
9232 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
9233 chplan_new[k].ScanType = SCAN_PASSIVE;
9236 } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
9237 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
9238 chplan_new[k].ScanType = SCAN_ACTIVE;
9244 /* change AP not support channel to Passive scan */
9245 while ((i < MAX_CHANNEL_NUM) &&
9246 (chplan_sta[i].ChannelNum != 0) &&
9247 (chplan_sta[i].ChannelNum <= 14)) {
9248 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
9249 chplan_new[k].ScanType = SCAN_PASSIVE;
9254 /* add channel AP supported */
9255 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) {
9256 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
9257 chplan_new[k].ScanType = SCAN_ACTIVE;
9262 /* keep original STA 2.4G channel plan */
9263 while ((i < MAX_CHANNEL_NUM) &&
9264 (chplan_sta[i].ChannelNum != 0) &&
9265 (chplan_sta[i].ChannelNum <= 14)) {
9266 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
9267 chplan_new[k].ScanType = chplan_sta[i].ScanType;
9272 /* skip AP 2.4G channel plan */
9273 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) {
9278 if (pregistrypriv->wireless_mode & WIRELESS_11A) {
9280 if ((i == MAX_CHANNEL_NUM) ||
9281 (chplan_sta[i].ChannelNum == 0))
9284 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
9287 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j])
9289 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
9290 chplan_new[k].ScanType = SCAN_ACTIVE;
9295 else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
9297 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
9298 /* chplan_new[k].ScanType = chplan_sta[i].ScanType; */
9299 chplan_new[k].ScanType = SCAN_PASSIVE;
9303 else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
9305 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
9306 chplan_new[k].ScanType = SCAN_ACTIVE;
9312 /* change AP not support channel to Passive scan */
9313 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
9314 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
9315 chplan_new[k].ScanType = SCAN_PASSIVE;
9320 /* add channel AP supported */
9321 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0)) {
9322 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
9323 chplan_new[k].ScanType = SCAN_ACTIVE;
9328 /* keep original STA 5G channel plan */
9329 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
9330 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
9331 chplan_new[k].ScanType = chplan_sta[i].ScanType;
9337 pmlmeext->update_channel_plan_by_ap_done = 1;
9339 #ifdef CONFIG_DEBUG_RTL871X
9341 DBG_8723A("%s: new STA channel plan {", __func__);
9342 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) {
9343 DBG_8723A("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType==SCAN_PASSIVE?'p':'c');
9350 /* If channel is used by AP, set channel scan type to active */
9351 channel = bssid->Configuration.DSConfig;
9352 chplan_new = pmlmeext->channel_set;
9354 while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) {
9355 if (chplan_new[i].ChannelNum == channel)
9357 if (chplan_new[i].ScanType == SCAN_PASSIVE) {
9358 /* 5G Bnad 2, 3 (DFS) doesn't change to active scan */
9359 if(channel >= 52 && channel <= 144)
9362 chplan_new[i].ScanType = SCAN_ACTIVE;
9363 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
9364 ("%s: change channel %d scan type from passive to active\n",
9365 __FUNCTION__, channel));
9374 /****************************************************************************
9376 Following are the functions to report events
9378 *****************************************************************************/
9380 void report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
9382 struct cmd_obj *pcmd_obj;
9385 struct survey_event *psurvey_evt;
9386 struct C2HEvent_Header *pc2h_evt_hdr;
9387 struct mlme_ext_priv *pmlmeext;
9388 struct cmd_priv *pcmdpriv;
9393 pmlmeext = &padapter->mlmeextpriv;
9394 pcmdpriv = &padapter->cmdpriv;
9396 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
9399 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
9400 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL) {
9401 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
9405 _rtw_init_listhead(&pcmd_obj->list);
9407 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
9408 pcmd_obj->cmdsz = cmdsz;
9409 pcmd_obj->parmbuf = pevtcmd;
9411 pcmd_obj->rsp = NULL;
9412 pcmd_obj->rspsz = 0;
9414 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
9415 pc2h_evt_hdr->len = sizeof(struct survey_event);
9416 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
9417 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
9419 psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
9421 if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL) {
9422 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
9423 rtw_mfree((u8 *)pevtcmd, cmdsz);
9427 #ifdef CONFIG_80211D
9428 process_80211d(padapter, &psurvey_evt->bss);
9431 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
9433 pmlmeext->sitesurvey_res.bss_cnt++;
9438 void report_surveydone_event(_adapter *padapter)
9440 struct cmd_obj *pcmd_obj;
9443 struct surveydone_event *psurveydone_evt;
9444 struct C2HEvent_Header *pc2h_evt_hdr;
9445 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9446 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
9448 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
9453 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
9454 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
9456 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
9460 _rtw_init_listhead(&pcmd_obj->list);
9462 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
9463 pcmd_obj->cmdsz = cmdsz;
9464 pcmd_obj->parmbuf = pevtcmd;
9466 pcmd_obj->rsp = NULL;
9467 pcmd_obj->rspsz = 0;
9469 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
9470 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
9471 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
9472 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
9474 psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
9475 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
9477 DBG_8723A("survey done event(%x)\n", psurveydone_evt->bss_cnt);
9479 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
9484 void report_join_res(_adapter *padapter, int res)
9486 struct cmd_obj *pcmd_obj;
9489 struct joinbss_event *pjoinbss_evt;
9490 struct C2HEvent_Header *pc2h_evt_hdr;
9491 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9492 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9493 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
9495 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
9500 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
9501 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
9503 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
9507 _rtw_init_listhead(&pcmd_obj->list);
9509 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
9510 pcmd_obj->cmdsz = cmdsz;
9511 pcmd_obj->parmbuf = pevtcmd;
9513 pcmd_obj->rsp = NULL;
9514 pcmd_obj->rspsz = 0;
9516 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
9517 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
9518 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
9519 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
9521 pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
9522 memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
9523 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
9525 DBG_8723A("report_join_res(%d)\n", res);
9527 rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
9529 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
9534 void report_del_sta_event(_adapter *padapter, unsigned char* MacAddr, unsigned short reason)
9536 struct cmd_obj *pcmd_obj;
9539 struct sta_info *psta;
9541 struct stadel_event *pdel_sta_evt;
9542 struct C2HEvent_Header *pc2h_evt_hdr;
9543 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9544 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
9546 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
9551 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
9552 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
9554 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
9558 _rtw_init_listhead(&pcmd_obj->list);
9560 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
9561 pcmd_obj->cmdsz = cmdsz;
9562 pcmd_obj->parmbuf = pevtcmd;
9564 pcmd_obj->rsp = NULL;
9565 pcmd_obj->rspsz = 0;
9567 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
9568 pc2h_evt_hdr->len = sizeof(struct stadel_event);
9569 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
9570 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
9572 pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
9573 memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
9574 memcpy((unsigned char *)(pdel_sta_evt->rsvd),(unsigned char *)(&reason),2);
9576 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
9578 mac_id = (int)psta->mac_id;
9582 pdel_sta_evt->mac_id = mac_id;
9584 DBG_8723A("report_del_sta_event: delete STA, mac_id=%d\n", mac_id);
9586 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
9591 void report_add_sta_event(_adapter *padapter, unsigned char* MacAddr, int cam_idx)
9593 struct cmd_obj *pcmd_obj;
9596 struct stassoc_event *padd_sta_evt;
9597 struct C2HEvent_Header *pc2h_evt_hdr;
9598 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9599 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
9601 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
9606 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
9607 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
9609 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
9613 _rtw_init_listhead(&pcmd_obj->list);
9615 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
9616 pcmd_obj->cmdsz = cmdsz;
9617 pcmd_obj->parmbuf = pevtcmd;
9619 pcmd_obj->rsp = NULL;
9620 pcmd_obj->rspsz = 0;
9622 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
9623 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
9624 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
9625 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
9627 padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
9628 memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
9629 padd_sta_evt->cam_id = cam_idx;
9631 DBG_8723A("report_add_sta_event: add STA\n");
9633 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
9638 /****************************************************************************
9640 Following are the event callback functions
9642 *****************************************************************************/
9644 /* for sta/adhoc mode */
9645 void update_sta_info(_adapter *padapter, struct sta_info *psta)
9647 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
9648 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9649 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9652 VCS_update(padapter, psta);
9654 #ifdef CONFIG_80211N_HT
9656 if(pmlmepriv->htpriv.ht_option)
9658 psta->htpriv.ht_option = _TRUE;
9660 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
9662 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps)))
9663 psta->htpriv.sgi = _TRUE;
9665 psta->qos_option = _TRUE;
9669 #endif /* CONFIG_80211N_HT */
9671 #ifdef CONFIG_80211N_HT
9672 psta->htpriv.ht_option = _FALSE;
9674 psta->htpriv.ampdu_enable = _FALSE;
9676 psta->htpriv.sgi = _FALSE;
9677 #endif /* CONFIG_80211N_HT */
9678 psta->qos_option = _FALSE;
9681 #ifdef CONFIG_80211N_HT
9682 psta->htpriv.bwmode = pmlmeext->cur_bwmode;
9683 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
9685 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
9686 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
9687 #endif /* CONFIG_80211N_HT */
9690 if(pmlmepriv->qospriv.qos_option)
9691 psta->qos_option = _TRUE;
9693 psta->state = _FW_LINKED;
9696 void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
9698 struct sta_info *psta, *psta_bmc;
9699 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9700 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9701 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
9702 struct sta_priv *pstapriv = &padapter->stapriv;
9709 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
9710 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
9712 /* restore to initial setting. */
9713 update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
9715 goto exit_mlmeext_joinbss_event_callback;
9718 if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
9721 psta_bmc = rtw_get_bcmc_stainfo(padapter);
9724 pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc;
9725 update_bmc_sta_support_rate(padapter, psta_bmc->mac_id);
9726 Update_RA_Entry(padapter, psta_bmc);
9730 /* turn on dynamic functions */
9731 Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE);
9733 /* update IOT-releated issue */
9734 update_IOT_info(padapter);
9736 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
9739 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
9741 /* udpate capability */
9742 update_capinfo(padapter, pmlmeinfo->capability);
9744 /* WMM, Update EDCA param */
9745 WMMOnAssocRsp(padapter);
9748 HTOnAssocRsp(padapter);
9750 #ifndef CONFIG_CONCURRENT_MODE
9751 /* Call set_channel_bwmode when the CONFIG_CONCURRENT_MODE doesn't be defined. */
9752 /* Set cur_channel&cur_bwmode&cur_ch_offset */
9753 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
9756 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
9757 if (psta) /* only for infra. mode */
9759 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
9761 /* DBG_8723A("set_sta_rate\n"); */
9763 psta->wireless_mode = pmlmeext->cur_wireless_mode;
9765 /* set per sta rate after updating HT cap. */
9766 set_sta_rate(padapter, psta);
9768 #if (RATE_ADAPTIVE_SUPPORT==1) /* for 88E RA */
9769 rtw_hal_set_hwreg(padapter,HW_VAR_TX_RPT_MAX_MACID, (u8*)&psta->mac_id);
9771 media_status = (psta->mac_id<<8)|1; /* MACID|OPMODE: 1 means connect */
9772 rtw_hal_set_hwreg(padapter,HW_VAR_H2C_MEDIA_STATUS_RPT,(u8 *)&media_status);
9776 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
9778 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9780 /* correcting TSF */
9781 correct_TSF(padapter, pmlmeext);
9783 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
9787 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
9790 exit_mlmeext_joinbss_event_callback:
9792 #ifdef CONFIG_DUALMAC_CONCURRENT
9793 dc_handle_join_done(padapter, join_res);
9795 #ifdef CONFIG_CONCURRENT_MODE
9796 concurrent_chk_joinbss_done(padapter, join_res);
9799 DBG_8723A("=>%s\n", __FUNCTION__);
9802 void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta)
9804 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9805 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9808 DBG_8723A("%s\n", __FUNCTION__);
9810 if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
9812 if(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)/* adhoc master or sta_count>1 */
9816 else/* adhoc client */
9818 /* update TSF Value */
9819 /* update_TSF(pmlmeext, pframe, len); */
9821 /* correcting TSF */
9822 correct_TSF(padapter, pmlmeext);
9825 if(send_beacon(padapter)==_FAIL)
9827 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
9829 pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
9834 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
9839 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
9842 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
9844 /* rate radaptive */
9845 Update_RA_Entry(padapter, psta);
9847 /* update adhoc sta_info */
9848 update_sta_info(padapter, psta);
9851 void mlmeext_sta_del_event_callback(_adapter *padapter)
9853 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9854 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9856 if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
9858 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
9860 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
9861 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
9863 /* restore to initial setting. */
9864 update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
9866 #ifdef CONFIG_DUALMAC_CONCURRENT
9867 dc_set_channel_bwmode_disconnect(padapter);
9869 #ifdef CONFIG_CONCURRENT_MODE
9870 if((check_buddy_fwstate(padapter, _FW_LINKED)) != _TRUE)
9872 #endif /* CONFIG_CONCURRENT_MODE */
9874 /* switch to the 20M Hz mode after disconnect */
9875 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
9876 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
9878 /* SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
9879 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
9881 #ifdef CONFIG_CONCURRENT_MODE
9883 #endif /* CONFIG_CONCURRENT_MODE */
9884 #endif /* CONFIG_DUALMAC_CONCURRENT */
9886 flush_all_cam_entry(padapter);
9888 pmlmeinfo->state = WIFI_FW_NULL_STATE;
9890 /* set MSR to no link state -> infra. mode */
9891 Set_MSR(padapter, _HW_STATE_STATION_);
9893 _cancel_timer_ex(&pmlmeext->link_timer);
9898 /****************************************************************************
9900 Following are the functions for the timer handlers
9902 *****************************************************************************/
9903 void _linked_rx_signal_strehgth_display(_adapter *padapter);
9904 void _linked_rx_signal_strehgth_display(_adapter *padapter)
9906 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9907 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9909 int UndecoratedSmoothedPWDB;
9910 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9914 else if((pmlmeinfo->state&0x03) == _HW_STATE_AP_)
9919 rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP,&mac_id);
9921 rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
9922 DBG_8723A("UndecoratedSmoothedPWDB:%d\n",UndecoratedSmoothedPWDB);
9925 u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta)
9928 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9929 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9931 #ifdef DBG_EXPIRATION_CHK
9932 DBG_8723A(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
9933 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
9935 , FUNC_ADPT_ARG(padapter)
9936 , STA_RX_PKTS_DIFF_ARG(psta)
9937 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
9938 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
9939 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
9940 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
9941 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
9942 , pmlmeinfo->bcn_interval*/
9946 DBG_8723A(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter)
9947 , padapter->xmitpriv.tx_pkts
9948 , pmlmeinfo->link_count
9952 if((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
9953 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
9954 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
9964 sta_update_last_rx_pkts(psta);
9969 void linked_status_chk(_adapter *padapter)
9972 struct sta_info *psta;
9973 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9974 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9975 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9976 struct sta_priv *pstapriv = &padapter->stapriv;
9978 if(padapter->bRxRSSIDisplay)
9979 _linked_rx_signal_strehgth_display(padapter);
9981 #ifdef DBG_CONFIG_ERROR_DETECT
9982 rtw_hal_sreset_linked_status_check(padapter);
9985 if (is_client_associated_to_ap(padapter))
9987 /* linked infrastructure client mode */
9989 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
9992 #if defined(DBG_ROAMING_TEST)
9994 #elif defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK)
10000 #ifdef CONFIG_INTEL_WIDI
10001 if (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_NONE)
10005 if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
10007 bool is_p2p_enable = _FALSE;
10009 is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
10012 if (chk_ap_is_alive(padapter, psta) == _FALSE)
10015 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
10018 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
10019 if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
10020 u8 backup_oper_channel=0;
10022 /* switch to correct channel of current network before issue keep-alive frames */
10023 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
10024 backup_oper_channel = rtw_get_oper_ch(padapter);
10025 SelectChannel(padapter, pmlmeext->cur_channel);
10028 if (rx_chk != _SUCCESS)
10029 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1);
10031 if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) {
10032 tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1);
10033 /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
10034 if (tx_chk == _SUCCESS && !is_p2p_enable)
10038 /* back to the original operation channel */
10039 if(backup_oper_channel>0)
10040 SelectChannel(padapter, backup_oper_channel);
10044 #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
10046 if (rx_chk != _SUCCESS) {
10047 if (pmlmeext->retry == 0) {
10048 #ifdef DBG_EXPIRATION_CHK
10049 DBG_8723A("issue_probereq to trigger probersp, retry=%d\n", pmlmeext->retry);
10051 issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
10052 issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
10053 issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
10057 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) {
10058 #ifdef DBG_EXPIRATION_CHK
10059 DBG_8723A("%s issue_nulldata 0\n", __FUNCTION__);
10061 tx_chk = issue_nulldata(padapter, NULL, 0, 1, 0);
10065 if (rx_chk == _FAIL) {
10067 if (pmlmeext->retry > rx_chk_limit) {
10068 DBG_8723A_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
10069 FUNC_ADPT_ARG(padapter));
10070 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
10071 , WLAN_REASON_EXPIRATION_CHK);
10075 pmlmeext->retry = 0;
10078 if (tx_chk == _FAIL) {
10079 pmlmeinfo->link_count &= 0xf;
10081 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
10082 pmlmeinfo->link_count = 0;
10085 } /* end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) */
10087 else if (is_client_associated_to_ibss(padapter))
10089 /* linked IBSS mode */
10090 /* for each assoc list entry to check the rx pkt counter */
10091 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
10093 if (pmlmeinfo->FW_sta_info[i].status == 1)
10095 psta = pmlmeinfo->FW_sta_info[i].psta;
10097 if(NULL==psta) continue;
10099 if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta))
10102 if(pmlmeinfo->FW_sta_info[i].retry<3)
10104 pmlmeinfo->FW_sta_info[i].retry++;
10108 pmlmeinfo->FW_sta_info[i].retry = 0;
10109 pmlmeinfo->FW_sta_info[i].status = 0;
10110 report_del_sta_event(padapter, psta->hwaddr
10111 , 65535/* indicate disconnect caused by no rx */
10117 pmlmeinfo->FW_sta_info[i].retry = 0;
10118 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
10123 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
10128 void survey_timer_hdl(_adapter *padapter)
10130 struct cmd_obj *ph2c;
10131 struct sitesurvey_parm *psurveyPara;
10132 struct cmd_priv *pcmdpriv=&padapter->cmdpriv;
10133 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10135 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
10138 /* DBG_8723A("marc: survey timer\n"); */
10139 /* issue rtw_sitesurvey_cmd */
10140 if (pmlmeext->sitesurvey_res.state > SCAN_START)
10142 if(pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
10144 #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
10145 if( padapter->mlmeextpriv.mlmext_info.scan_cnt != RTW_SCAN_NUM_OF_CH )
10146 #endif /* CONFIG_STA_MODE_SCAN_UNDER_AP_MODE */
10147 pmlmeext->sitesurvey_res.channel_idx++;
10150 if(pmlmeext->scan_abort == _TRUE)
10153 if(!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
10155 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
10156 pmlmeext->sitesurvey_res.channel_idx = 3;
10157 DBG_8723A("%s idx:%d, cnt:%u\n", __FUNCTION__
10158 , pmlmeext->sitesurvey_res.channel_idx
10159 , pwdinfo->find_phase_state_exchange_cnt
10165 pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num;
10166 DBG_8723A("%s idx:%d\n", __FUNCTION__
10167 , pmlmeext->sitesurvey_res.channel_idx
10171 pmlmeext->scan_abort = _FALSE;/* reset */
10174 if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
10176 goto exit_survey_timer_hdl;
10179 if ((psurveyPara = (struct sitesurvey_parm*)rtw_zmalloc(sizeof(struct sitesurvey_parm))) == NULL)
10181 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
10182 goto exit_survey_timer_hdl;
10185 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
10186 rtw_enqueue_cmd(pcmdpriv, ph2c);
10189 exit_survey_timer_hdl:
10193 void link_timer_hdl(_adapter *padapter)
10195 /* static unsigned int rx_pkt = 0; */
10196 /* static u64 tx_cnt = 0; */
10197 /* struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); */
10198 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10199 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10200 /* struct sta_priv *pstapriv = &padapter->stapriv; */
10202 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
10204 DBG_8723A("link_timer_hdl:no beacon while connecting\n");
10205 pmlmeinfo->state = WIFI_FW_NULL_STATE;
10206 report_join_res(padapter, -3);
10208 else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE)
10210 /* re-auth timer */
10211 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT)
10213 /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
10215 pmlmeinfo->state = 0;
10216 report_join_res(padapter, -1);
10221 /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
10222 /* pmlmeinfo->reauth_count = 0; */
10226 DBG_8723A("link_timer_hdl: auth timeout and try again\n");
10227 pmlmeinfo->auth_seq = 1;
10228 issue_auth(padapter, NULL, 0);
10229 set_link_timer(pmlmeext, REAUTH_TO);
10231 else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)
10233 /* re-assoc timer */
10234 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT)
10236 pmlmeinfo->state = WIFI_FW_NULL_STATE;
10237 report_join_res(padapter, -2);
10241 DBG_8723A("link_timer_hdl: assoc timeout and try again\n");
10242 issue_assocreq(padapter);
10243 set_link_timer(pmlmeext, REASSOC_TO);
10249 void addba_timer_hdl(struct sta_info *psta)
10251 #ifdef CONFIG_80211N_HT
10252 struct ht_priv *phtpriv;
10257 phtpriv = &psta->htpriv;
10259 if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE))
10261 if(phtpriv->candidate_tid_bitmap)
10262 phtpriv->candidate_tid_bitmap=0x0;
10265 #endif /* CONFIG_80211N_HT */
10268 u8 NULL_hdl(_adapter *padapter, u8 *pbuf)
10270 return H2C_SUCCESS;
10273 u8 setopmode_hdl(_adapter *padapter, u8 *pbuf)
10276 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10277 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10278 struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
10280 if(psetop->mode == Ndis802_11APMode)
10282 pmlmeinfo->state = WIFI_FW_AP_STATE;
10283 type = _HW_STATE_AP_;
10284 #ifdef CONFIG_NATIVEAP_MLME
10285 /* start_ap_mode(padapter); */
10288 else if(psetop->mode == Ndis802_11Infrastructure)
10290 pmlmeinfo->state &= ~(BIT(0)|BIT(1));/* clear state */
10291 pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */
10292 type = _HW_STATE_STATION_;
10294 else if(psetop->mode == Ndis802_11IBSS)
10296 type = _HW_STATE_ADHOC_;
10300 type = _HW_STATE_NOLINK_;
10303 rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
10304 /* Set_NETYPE0_MSR(padapter, type); */
10306 return H2C_SUCCESS;
10309 u8 createbss_hdl(_adapter *padapter, u8 *pbuf)
10311 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10312 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10313 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10314 struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
10315 /* u32 initialgain; */
10317 if(pparm->network.InfrastructureMode == Ndis802_11APMode)
10319 #ifdef CONFIG_AP_MODE
10321 if(pmlmeinfo->state == WIFI_FW_AP_STATE)
10324 return H2C_SUCCESS;
10329 /* below is for ad-hoc master */
10330 if(pparm->network.InfrastructureMode == Ndis802_11IBSS)
10332 rtw_joinbss_reset(padapter);
10334 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
10335 pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE;
10336 pmlmeinfo->ERP_enable = 0;
10337 pmlmeinfo->WMM_enable = 0;
10338 pmlmeinfo->HT_enable = 0;
10339 pmlmeinfo->HT_caps_enable = 0;
10340 pmlmeinfo->HT_info_enable = 0;
10341 pmlmeinfo->agg_enable_bitmap = 0;
10342 pmlmeinfo->candidate_tid_bitmap = 0;
10344 /* disable dynamic functions, such as high power, DIG */
10345 Save_DM_Func_Flag(padapter);
10346 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
10348 /* config the initial gain under linking, need to write the BB registers */
10349 /* initialgain = 0x1E; */
10350 /* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */
10352 /* cancel link timer */
10353 _cancel_timer_ex(&pmlmeext->link_timer);
10356 flush_all_cam_entry(padapter);
10358 memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
10359 pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
10361 if(pnetwork->IELength>MAX_IE_SZ)/* Check pbuf->IELength */
10362 return H2C_PARAMETERS_ERROR;
10364 memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
10366 start_create_ibss(padapter);
10370 return H2C_SUCCESS;
10373 u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf)
10376 PNDIS_802_11_VARIABLE_IEs pIE;
10377 struct registry_priv *pregpriv = &padapter->registrypriv;
10378 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10379 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10380 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10381 #ifdef CONFIG_ANTENNA_DIVERSITY
10382 struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
10383 #endif /* CONFIG_ANTENNA_DIVERSITY */
10385 /* u32 initialgain; */
10388 /* check already connecting to AP or not */
10389 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
10391 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
10393 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 5, 100);
10396 pmlmeinfo->state = WIFI_FW_NULL_STATE;
10399 flush_all_cam_entry(padapter);
10401 _cancel_timer_ex(&pmlmeext->link_timer);
10403 /* set MSR to nolink -> infra. mode */
10404 /* Set_MSR(padapter, _HW_STATE_NOLINK_); */
10405 Set_MSR(padapter, _HW_STATE_STATION_);
10407 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
10410 #ifdef CONFIG_ANTENNA_DIVERSITY
10411 rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, _FALSE);
10414 #ifdef CONFIG_WAPI_SUPPORT
10415 rtw_wapi_clear_all_cam_entry(padapter);
10418 rtw_joinbss_reset(padapter);
10420 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
10421 pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE;
10422 pmlmeinfo->ERP_enable = 0;
10423 pmlmeinfo->WMM_enable = 0;
10424 pmlmeinfo->HT_enable = 0;
10425 pmlmeinfo->HT_caps_enable = 0;
10426 pmlmeinfo->HT_info_enable = 0;
10427 pmlmeinfo->agg_enable_bitmap = 0;
10428 pmlmeinfo->candidate_tid_bitmap = 0;
10429 pmlmeinfo->bwmode_updated = _FALSE;
10430 /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
10432 memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
10433 pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
10435 if(pnetwork->IELength>MAX_IE_SZ)/* Check pbuf->IELength */
10436 return H2C_PARAMETERS_ERROR;
10438 memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
10440 /* Check AP vendor to move rtw_joinbss_cmd() */
10441 /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength); */
10443 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pnetwork->IELength;)
10445 pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
10447 switch (pIE->ElementID)
10449 case _VENDOR_SPECIFIC_IE_:/* Get WMM IE. */
10450 if (!memcmp(pIE->data, WMM_OUI, 4))
10452 pmlmeinfo->WMM_enable = 1;
10456 case _HT_CAPABILITY_IE_: /* Get HT Cap IE. */
10457 pmlmeinfo->HT_caps_enable = 1;
10460 case _HT_EXTRA_INFO_IE_: /* Get HT Info IE. */
10461 #ifdef CONFIG_80211N_HT
10462 pmlmeinfo->HT_info_enable = 1;
10464 /* spec case only for cisco's ap because cisco's ap issue assoc rsp using mcs rate @40MHz or @20MHz */
10465 /* if !defined(CONFIG_CONCURRENT_MODE) && !defined(CONFIG_DUALMAC_CONCURRENT) */
10466 /* if(pmlmeinfo->assoc_AP_vendor == ciscoAP) */
10469 struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data);
10471 if ((pregpriv->cbw40_enable) && (pht_info->infos[0] & BIT(2)))
10473 /* switch to the 40M Hz mode according to the AP */
10474 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
10475 switch (pht_info->infos[0] & 0x3)
10478 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
10482 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
10486 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
10490 DBG_8723A("set ch/bw before connected\n");
10493 #endif /* CONFIG_80211N_HT */
10500 i += (pIE->Length + 2);
10502 /* disable dynamic functions, such as high power, DIG */
10503 /* Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE); */
10505 /* config the initial gain under linking, need to write the BB registers */
10506 /* initialgain = 0x1E; */
10507 /* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */
10509 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
10511 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
10513 /* cancel link timer */
10514 _cancel_timer_ex(&pmlmeext->link_timer);
10516 start_clnt_join(padapter);
10518 return H2C_SUCCESS;
10521 u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf)
10523 struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
10524 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10525 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10526 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10529 if (is_client_associated_to_ap(padapter))
10531 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
10534 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
10536 /* pmlmeinfo->state = WIFI_FW_NULL_STATE; */
10538 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
10539 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
10541 /* restore to initial setting. */
10542 update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
10544 if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
10548 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
10551 /* set MSR to no link state -> infra. mode */
10552 Set_MSR(padapter, _HW_STATE_STATION_);
10554 pmlmeinfo->state = WIFI_FW_NULL_STATE;
10556 #ifdef CONFIG_DUALMAC_CONCURRENT
10557 dc_set_channel_bwmode_disconnect(padapter);
10559 #ifdef CONFIG_CONCURRENT_MODE
10560 if((check_buddy_fwstate(padapter, _FW_LINKED)) != _TRUE)
10562 #endif /* CONFIG_CONCURRENT_MODE */
10563 /* switch to the 20M Hz mode after disconnect */
10564 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
10565 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
10567 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
10568 #ifdef CONFIG_CONCURRENT_MODE
10570 #endif /* CONFIG_CONCURRENT_MODE */
10571 #endif /* CONFIG_DUALMAC_CONCURRENT */
10573 flush_all_cam_entry(padapter);
10575 _cancel_timer_ex(&pmlmeext->link_timer);
10577 rtw_free_uc_swdec_pending_queue(padapter);
10579 return H2C_SUCCESS;
10582 int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out,
10583 u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
10586 int scan_ch_num = 0;
10588 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10590 /* clear out first */
10591 memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
10593 /* acquire channels from in */
10595 for (i=0;i<in_num;i++) {
10597 DBG_8723A(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
10598 if(in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED)
10599 && (set_idx=rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value)) >=0
10602 memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
10604 if(pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
10605 out[j].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
10613 /* if out is empty, use channel_set as default */
10615 for (i=0;i<pmlmeext->max_chan_nums;i++) {
10616 out[i].hw_value = pmlmeext->channel_set[i].ChannelNum;
10618 if(pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
10619 out[i].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
10625 if (padapter->setband == GHZ_24) { /* 2.4G */
10626 for (i=0; i < j ; i++) {
10627 if (out[i].hw_value > 35)
10628 memset(&out[i], 0 , sizeof(struct rtw_ieee80211_channel));
10633 } else if (padapter->setband == GHZ_50) { /* 5G */
10634 for (i=0; i < j ; i++) {
10635 if (out[i].hw_value > 35) {
10636 memcpy(&out[scan_ch_num++], &out[i], sizeof(struct rtw_ieee80211_channel));
10646 u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
10648 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10649 struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
10650 u8 bdelayscan = _FALSE;
10656 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
10659 if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE)
10661 /* for first time sitesurvey_cmd */
10662 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
10664 pmlmeext->sitesurvey_res.state = SCAN_START;
10665 pmlmeext->sitesurvey_res.bss_cnt = 0;
10666 pmlmeext->sitesurvey_res.channel_idx = 0;
10668 for(i=0;i<RTW_SSID_SCAN_AMOUNT;i++){
10669 if(pparm->ssid[i].SsidLength) {
10670 memcpy(pmlmeext->sitesurvey_res.ssid[i].Ssid, pparm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
10671 pmlmeext->sitesurvey_res.ssid[i].SsidLength= pparm->ssid[i].SsidLength;
10673 pmlmeext->sitesurvey_res.ssid[i].SsidLength= 0;
10677 pmlmeext->sitesurvey_res.ch_num = rtw_scan_ch_decision(padapter
10678 , pmlmeext->sitesurvey_res.ch, RTW_CHANNEL_SCAN_AMOUNT
10679 , pparm->ch, pparm->ch_num
10682 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
10684 #ifdef CONFIG_DUALMAC_CONCURRENT
10685 bdelayscan = dc_handle_site_survey(padapter);
10688 /* issue null data if associating to the AP */
10689 if (is_client_associated_to_ap(padapter) == _TRUE)
10691 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
10693 /* switch to correct channel of current network before issue keep-alive frames */
10694 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
10695 SelectChannel(padapter, pmlmeext->cur_channel);
10698 issue_nulldata(padapter, NULL, 1, 3, 500);
10700 #ifdef CONFIG_CONCURRENT_MODE
10701 if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
10703 DBG_8723A("adapter is scanning(buddy_adapter is linked), issue nulldata(pwrbit=1)\n");
10705 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
10708 bdelayscan = _TRUE;
10710 #ifdef CONFIG_CONCURRENT_MODE
10711 else if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
10714 if(padapter->pbuddy_adapter->wdinfo.wfd_tdls_enable == 1)
10716 issue_tunneled_probe_req(padapter->pbuddy_adapter);
10718 #endif /* CONFIG_TDLS */
10720 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
10722 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
10724 bdelayscan = _TRUE;
10729 /* delay 50ms to protect nulldata(1). */
10730 set_survey_timer(pmlmeext, 50);
10731 return H2C_SUCCESS;
10735 if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL))
10737 /* disable dynamic functions, such as high power, DIG */
10738 Save_DM_Func_Flag(padapter);
10739 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
10741 /* config the initial gain under scaning, need to write the BB registers */
10742 #ifdef CONFIG_IOCTL_CFG80211
10743 if((wdev_to_priv(padapter->rtw_wdev))->p2p_enabled == _TRUE)
10745 initialgain = 0x30;
10748 initialgain = 0x1E;
10749 #else /* go through the WEXT interface CONFIG_IOCTL_CFG80211 */
10751 if ( rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) )
10752 initialgain = 0x1E;
10754 initialgain = 0x28;
10755 #else /* CONFIG_P2P */
10756 initialgain = 0x1E;
10757 #endif /* CONFIG_P2P */
10758 #endif /* CONFIG_IOCTL_CFG80211 */
10760 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
10762 /* set MSR to no link state */
10763 Set_MSR(padapter, _HW_STATE_NOLINK_);
10765 val8 = 1; /* under site survey */
10766 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
10768 pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
10771 site_survey(padapter);
10773 return H2C_SUCCESS;
10776 u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf)
10778 struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
10779 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10780 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10782 if (pparm->mode < 4)
10784 pmlmeinfo->auth_algo = pparm->mode;
10787 return H2C_SUCCESS;
10790 u8 setkey_hdl(_adapter *padapter, u8 *pbuf)
10792 unsigned short ctrl;
10793 struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
10794 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10795 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10796 unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
10798 /* main tx key for wep. */
10800 pmlmeinfo->key_index = pparm->keyid;
10803 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
10805 DBG_8723A_LEVEL(_drv_always_, "set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) "
10806 "keyid:%d\n", pparm->algorithm, pparm->keyid);
10807 write_cam(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
10809 /* allow multicast packets to driver */
10810 padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_ON_RCR_AM, null_addr);
10812 return H2C_SUCCESS;
10815 u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf)
10818 u8 cam_id;/* cam_entry */
10819 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10820 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10821 struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
10823 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
10824 struct sta_priv *pstapriv = &padapter->stapriv;
10825 struct sta_info *psta;
10826 #endif /* CONFIG_TDLS */
10829 /* 0~3 for default key */
10831 /* for concurrent mode (ap+sta): */
10832 /* default key is disable, using sw encrypt/decrypt */
10833 /* cam_entry = 4 for sta mode (macid=0) */
10834 /* cam_entry(macid+3) = 5 ~ N for ap mode (aid=1~N, macid=2 ~N) */
10836 /* for concurrent mode (sta+sta): */
10837 /* default key is disable, using sw encrypt/decrypt */
10838 /* cam_entry = 4 mapping to macid=0 */
10839 /* cam_entry = 5 mapping to macid=2 */
10841 #ifdef CONFIG_CONCURRENT_MODE
10842 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
10844 struct sta_priv *pstapriv = &padapter->stapriv;
10845 struct sta_info *psta;
10847 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
10849 if(psta && psta->mac_id==2)
10858 if(padapter->iface_type > PRIMARY_IFACE)
10872 DBG_8723A_LEVEL(_drv_always_, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) camid:%d\n",
10873 pparm->algorithm, cam_id);
10874 if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
10877 struct sta_info *psta;
10878 struct sta_priv *pstapriv = &padapter->stapriv;
10880 if(pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */
10882 clear_cam_entry(padapter, pparm->id);
10883 return H2C_SUCCESS_RSP;
10886 psta = rtw_get_stainfo(pstapriv, pparm->addr);
10889 ctrl = (BIT(15) | ((pparm->algorithm) << 2));
10891 DBG_8723A("r871x_set_stakey_hdl(): enc_algorithm=%d\n", pparm->algorithm);
10893 if((psta->mac_id<1) || (psta->mac_id>(NUM_STA-4)))
10895 DBG_8723A("r871x_set_stakey_hdl():set_stakey failed, mac_id(aid)=%d\n", psta->mac_id);
10896 return H2C_REJECTED;
10899 cam_id = (psta->mac_id + 3);/* 0~3 for default key, cmd_id=macid + 3, macid=aid+1; */
10901 DBG_8723A("Write CAM, mac_addr=%x:%x:%x:%x:%x:%x, cam_entry=%d\n", pparm->addr[0],
10902 pparm->addr[1], pparm->addr[2], pparm->addr[3], pparm->addr[4],
10903 pparm->addr[5], cam_id);
10905 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
10907 return H2C_SUCCESS_RSP;
10912 DBG_8723A("r871x_set_stakey_hdl(): sta has been free\n");
10913 return H2C_REJECTED;
10918 /* below for sta mode */
10920 if(pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */
10922 clear_cam_entry(padapter, pparm->id);
10923 return H2C_SUCCESS;
10926 ctrl = BIT(15) | ((pparm->algorithm) << 2);
10929 if(ptdlsinfo->clear_cam!=0){
10930 clear_cam_entry(padapter, ptdlsinfo->clear_cam);
10931 ptdlsinfo->clear_cam=0;
10933 return H2C_SUCCESS;
10936 psta = rtw_get_stainfo(pstapriv, pparm->addr);/* Get TDLS Peer STA */
10937 if( psta->tdls_sta_state&TDLS_LINKED_STATE ){
10938 write_cam(padapter, psta->mac_id, ctrl, pparm->addr, pparm->key);
10941 #endif /* CONFIG_TDLS */
10942 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
10944 pmlmeinfo->enc_algo = pparm->algorithm;
10946 return H2C_SUCCESS;
10949 u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf)
10951 struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
10952 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10953 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10955 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
10958 return H2C_SUCCESS;
10960 #ifdef CONFIG_80211N_HT
10961 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
10962 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
10964 /* pmlmeinfo->ADDBA_retry_count = 0; */
10965 /* pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid); */
10966 /* psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid); */
10967 issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
10968 /* _set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO); */
10969 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
10972 else if((psta->tdls_sta_state & TDLS_LINKED_STATE)&&
10973 (psta->htpriv.ht_option==_TRUE) &&
10974 (psta->htpriv.ampdu_enable==_TRUE) )
10976 issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
10977 /* _set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO); */
10978 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
10980 #endif /* CONFIG */
10983 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
10985 #endif /* CONFIG_80211N_HT */
10986 return H2C_SUCCESS;
10989 u8 set_tx_beacon_cmd(_adapter* padapter)
10991 struct cmd_obj *ph2c;
10992 struct Tx_Beacon_param *ptxBeacon_parm;
10993 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
10994 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10995 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11001 if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11007 if ((ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param))) == NULL)
11009 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
11014 memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
11016 len_diff = update_hidden_ssid(
11017 ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_
11018 , ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_
11019 , pmlmeinfo->hidden_ssid_mode
11021 ptxBeacon_parm->network.IELength += len_diff;
11023 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
11025 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
11034 u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf)
11036 u8 evt_code, evt_seq;
11039 void (*event_callback)(_adapter *dev, u8 *pbuf);
11040 struct evt_priv *pevt_priv = &(padapter->evtpriv);
11042 peventbuf = (uint*)pbuf;
11043 evt_sz = (u16)(*peventbuf&0xffff);
11044 evt_seq = (u8)((*peventbuf>>24)&0x7f);
11045 evt_code = (u8)((*peventbuf>>16)&0xff);
11047 #ifdef CHECK_EVENT_SEQ
11048 /* checking event sequence... */
11049 if (evt_seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f) )
11051 RT_TRACE(_module_rtl871x_cmd_c_,_drv_info_,("Evetn Seq Error! %d vs %d\n", (evt_seq & 0x7f), (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f)));
11053 pevt_priv->event_seq = (evt_seq+1)&0x7f;
11055 goto _abort_event_;
11059 /* checking if event code is valid */
11060 if (evt_code >= MAX_C2HEVT) {
11061 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent Code(%d) mismatch!\n", evt_code));
11062 goto _abort_event_;
11065 /* checking if event size match the event parm size */
11066 if ((wlanevents[evt_code].parmsize != 0) &&
11067 (wlanevents[evt_code].parmsize != evt_sz)) {
11068 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
11069 evt_code, wlanevents[evt_code].parmsize, evt_sz));
11070 goto _abort_event_;
11073 ATOMIC_INC(&pevt_priv->event_seq);
11078 event_callback = wlanevents[evt_code].event_callback;
11079 event_callback(padapter, (u8*)peventbuf);
11081 pevt_priv->evt_done_cnt++;
11086 return H2C_SUCCESS;
11089 u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf)
11092 return H2C_PARAMETERS_ERROR;
11094 return H2C_SUCCESS;
11097 u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf)
11099 if(send_beacon(padapter)==_FAIL)
11101 DBG_8723A("issue_beacon, fail!\n");
11102 return H2C_PARAMETERS_ERROR;
11104 #ifdef CONFIG_AP_MODE
11105 else /* tx bc/mc frames after update TIM */
11108 struct sta_info *psta_bmc;
11109 _list *xmitframe_plist, *xmitframe_phead;
11110 struct xmit_frame *pxmitframe=NULL;
11111 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
11112 struct sta_priv *pstapriv = &padapter->stapriv;
11114 /* for BC/MC Frames */
11115 psta_bmc = rtw_get_bcmc_stainfo(padapter);
11117 return H2C_SUCCESS;
11119 if((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0))
11121 rtw_msleep_os(10);/* 10ms, ATIM(HIQ) Windows */
11122 /* spin_lock_bh(&psta_bmc->sleep_q.lock); */
11123 spin_lock_bh(&pxmitpriv->lock);
11125 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
11126 xmitframe_plist = get_next(xmitframe_phead);
11128 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
11130 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
11132 xmitframe_plist = get_next(xmitframe_plist);
11134 rtw_list_delete(&pxmitframe->list);
11136 psta_bmc->sleepq_len--;
11137 if(psta_bmc->sleepq_len>0)
11138 pxmitframe->attrib.mdata = 1;
11140 pxmitframe->attrib.mdata = 0;
11142 pxmitframe->attrib.triggered=1;
11144 pxmitframe->attrib.qsel = 0x11;/* HIQ */
11146 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
11148 /* pstapriv->tim_bitmap &= ~BIT(0); */
11152 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
11153 spin_unlock_bh(&pxmitpriv->lock);
11159 return H2C_SUCCESS;
11162 #ifdef CONFIG_DUALMAC_CONCURRENT
11163 void dc_SelectChannel(_adapter *padapter, unsigned char channel)
11165 PADAPTER ptarget_adapter;
11167 if( (padapter->pbuddy_adapter != NULL) &&
11168 (padapter->DualMacConcurrent == _TRUE) &&
11169 (padapter->adapter_type == SECONDARY_ADAPTER))
11171 /* only mac0 could control BB&RF */
11172 ptarget_adapter = padapter->pbuddy_adapter;
11176 ptarget_adapter = padapter;
11179 _enter_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setch_mutex), NULL);
11181 rtw_hal_set_chan(ptarget_adapter, channel);
11183 _exit_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setch_mutex), NULL);
11186 void dc_SetBWMode(_adapter *padapter, unsigned short bwmode, unsigned char channel_offset)
11188 PADAPTER ptarget_adapter;
11190 if( (padapter->pbuddy_adapter != NULL) &&
11191 (padapter->DualMacConcurrent == _TRUE) &&
11192 (padapter->adapter_type == SECONDARY_ADAPTER))
11194 /* only mac0 could control BB&RF */
11195 ptarget_adapter = padapter->pbuddy_adapter;
11199 ptarget_adapter = padapter;
11202 _enter_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setbw_mutex), NULL);
11204 rtw_hal_set_bwmode(ptarget_adapter, (HT_CHANNEL_WIDTH)bwmode, channel_offset);
11206 _exit_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setbw_mutex), NULL);
11209 static void dc_change_band(_adapter *padapter, WLAN_BSSID_EX *pnetwork)
11211 u8 network_type,rate_len, total_rate_len,remainder_rate_len;
11212 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
11213 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11216 /* DBG_8723A("%s\n", __FUNCTION__); */
11218 if(pmlmeext->cur_channel >= 36)
11220 network_type = WIRELESS_11A;
11221 total_rate_len = IEEE80211_NUM_OFDM_RATESLEN;
11222 DBG_8723A("%s(): change to 5G Band\n",__FUNCTION__);
11223 rtw_remove_bcn_ie(padapter, pnetwork, _ERPINFO_IE_);
11227 network_type = WIRELESS_11BG;
11228 total_rate_len = IEEE80211_CCK_RATE_LEN+IEEE80211_NUM_OFDM_RATESLEN;
11229 DBG_8723A("%s(): change to 2.4G Band\n",__FUNCTION__);
11230 rtw_add_bcn_ie(padapter, pnetwork, _ERPINFO_IE_, &erpinfo, 1);
11233 rtw_set_supported_rate(pnetwork->SupportedRates, network_type);
11235 UpdateBrateTbl(padapter, pnetwork->SupportedRates);
11236 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);
11238 if(total_rate_len > 8)
11241 remainder_rate_len = total_rate_len - 8;
11245 rate_len = total_rate_len;
11246 remainder_rate_len = 0;
11249 rtw_add_bcn_ie(padapter, pnetwork, _SUPPORTEDRATES_IE_, pnetwork->SupportedRates, rate_len);
11251 if(remainder_rate_len)
11253 rtw_add_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_, (pnetwork->SupportedRates+8), remainder_rate_len);
11257 rtw_remove_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_);
11261 void dc_set_channel_bwmode_disconnect(_adapter *padapter)
11263 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11264 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
11265 struct mlme_priv *pbuddy_mlmepriv = NULL;
11267 if(pbuddy_adapter != NULL &&
11268 padapter->DualMacConcurrent == _TRUE)
11270 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11271 if((check_fwstate(pbuddy_mlmepriv, _FW_LINKED)) != _TRUE)
11273 /* switch to the 20M Hz mode after disconnect */
11274 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
11275 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11277 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
11282 /* switch to the 20M Hz mode after disconnect */
11283 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
11284 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11286 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
11290 u8 dc_handle_join_request(_adapter *padapter)
11292 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11293 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11294 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
11295 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
11296 struct mlme_ext_priv *pbuddy_mlmeext = NULL;
11297 struct mlme_priv *pbuddy_mlmepriv = NULL;
11300 if(pbuddy_adapter != NULL &&
11301 padapter->DualMacConcurrent == _TRUE)
11303 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
11304 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11306 if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel ||
11307 pmlmeext->cur_bwmode != pbuddy_mlmeext->cur_bwmode ||
11308 pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset)
11310 if((check_fwstate(pbuddy_mlmepriv, WIFI_AP_STATE)) == _TRUE)
11312 /* issue deauth to all stas if if2 is at ap mode */
11313 rtw_sta_flush(pbuddy_adapter);
11315 /* rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0); */
11316 rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_CHECK_TXBUF, 0);
11318 else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED) == _TRUE)
11320 if(pmlmeext->cur_channel == pbuddy_mlmeext->cur_channel)
11322 /* HT_CHANNEL_WIDTH_40 or HT_CHANNEL_WIDTH_20 but channel offset is different */
11323 if((pmlmeext->cur_bwmode == pbuddy_mlmeext->cur_bwmode) &&
11324 (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset) )
11326 report_join_res(padapter, -4);
11332 report_join_res(padapter, -4);
11337 else if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE)
11339 issue_nulldata(pbuddy_adapter, NULL, 1, 0, 0);
11346 void dc_handle_join_done(_adapter *padapter, u8 join_res)
11348 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11349 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11350 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
11351 struct mlme_priv *pbuddy_mlmepriv = NULL;
11352 struct mlme_ext_priv *pbuddy_mlmeext = NULL;
11353 struct mlme_ext_info *pbuddy_mlmeinfo = NULL;
11354 WLAN_BSSID_EX *pbuddy_network_mlmeext = NULL;
11355 u8 change_band = _FALSE;
11357 if(pbuddy_adapter != NULL &&
11358 padapter->DualMacConcurrent == _TRUE)
11360 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11361 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
11362 pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
11363 pbuddy_network_mlmeext = &(pbuddy_mlmeinfo->network);
11365 if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
11366 check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
11368 /* restart and update beacon */
11369 DBG_8723A("after join, current adapter, CH=%d, BW=%d, offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
11375 struct HT_info_element *pht_info=NULL;
11377 if((pbuddy_mlmeext->cur_channel <= 14 && pmlmeext->cur_channel >= 36) ||
11378 (pbuddy_mlmeext->cur_channel >= 36 && pmlmeext->cur_channel <= 14))
11380 change_band = _TRUE;
11383 /* sync channel/bwmode/ch_offset with another adapter */
11384 pbuddy_mlmeext->cur_channel = pmlmeext->cur_channel;
11386 if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
11388 p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
11391 pht_info = (struct HT_info_element *)(p+2);
11392 pht_info->infos[0] &= ~(BIT(0)|BIT(1)); /* no secondary channel is present */
11395 if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
11397 pbuddy_mlmeext->cur_ch_offset = pmlmeext->cur_ch_offset;
11399 /* to update cur_ch_offset value in beacon */
11402 switch(pmlmeext->cur_ch_offset)
11404 case HAL_PRIME_CHNL_OFFSET_LOWER:
11405 pht_info->infos[0] |= 0x1;
11407 case HAL_PRIME_CHNL_OFFSET_UPPER:
11408 pht_info->infos[0] |= 0x3;
11410 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
11416 else if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20)
11418 pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
11419 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11421 if(pmlmeext->cur_channel>0 && pmlmeext->cur_channel<5)
11424 pht_info->infos[0] |= 0x1;
11426 pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
11427 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
11430 if(pmlmeext->cur_channel>7 && pmlmeext->cur_channel<(14+1))
11433 pht_info->infos[0] |= 0x3;
11435 pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
11436 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
11439 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
11443 /* to update channel value in beacon */
11444 pbuddy_network_mlmeext->Configuration.DSConfig = pmlmeext->cur_channel;
11445 p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
11447 *(p + 2) = pmlmeext->cur_channel;
11449 p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
11452 pht_info = (struct HT_info_element *)(p+2);
11453 pht_info->primary_channel = pmlmeext->cur_channel;
11456 /* update mlmepriv's cur_network */
11457 memcpy(&pbuddy_mlmepriv->cur_network.network, pbuddy_network_mlmeext, pbuddy_network_mlmeext->Length);
11461 /* switch back to original channel/bwmode/ch_offset; */
11462 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
11465 DBG_8723A("after join, another adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
11467 if(change_band == _TRUE)
11468 dc_change_band(pbuddy_adapter, pbuddy_network_mlmeext);
11470 DBG_8723A("update pbuddy_adapter's beacon\n");
11472 update_beacon(pbuddy_adapter, 0, NULL, _TRUE);
11474 else if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE)
11476 if((pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
11477 (pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20))
11479 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
11482 issue_nulldata(pbuddy_adapter, NULL, 0, 0, 0);
11487 int dc_check_fwstate(_adapter *padapter, int fw_state)
11489 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
11490 struct mlme_priv *pbuddy_mlmepriv = NULL;
11492 if(padapter->pbuddy_adapter != NULL &&
11493 padapter->DualMacConcurrent == _TRUE)
11496 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11498 return check_fwstate(pbuddy_mlmepriv, fw_state);
11504 u8 dc_handle_site_survey(_adapter *padapter)
11506 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11507 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11508 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
11510 /* only mac0 can do scan request, help issue nulldata(1) for mac1 */
11511 if(pbuddy_adapter != NULL &&
11512 padapter->DualMacConcurrent == _TRUE)
11514 if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE)
11516 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
11518 issue_nulldata(pbuddy_adapter, NULL, 1, 2, 0);
11527 void dc_report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
11529 if(padapter->pbuddy_adapter != NULL &&
11530 padapter->DualMacConcurrent == _TRUE)
11532 report_survey_event(padapter->pbuddy_adapter, precv_frame);
11536 void dc_set_channel_bwmode_survey_done(_adapter *padapter)
11538 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
11539 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11540 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
11541 struct mlme_priv *pbuddy_mlmepriv = NULL;
11542 struct mlme_ext_priv *pbuddy_mlmeext = NULL;
11543 struct mlme_ext_info *pbuddy_mlmeinfo = NULL;
11548 if(pbuddy_adapter != NULL &&
11549 padapter->DualMacConcurrent == _TRUE)
11551 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11552 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
11553 pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
11555 if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
11557 if(check_fwstate(pmlmepriv, _FW_LINKED) &&
11558 (pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40))
11560 cur_channel = pmlmeext->cur_channel;
11561 cur_bwmode = pmlmeext->cur_bwmode;
11562 cur_ch_offset = pmlmeext->cur_ch_offset;
11566 cur_channel = pbuddy_mlmeext->cur_channel;
11567 cur_bwmode = pbuddy_mlmeext->cur_bwmode;
11568 cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
11573 cur_channel = pmlmeext->cur_channel;
11574 cur_bwmode = pmlmeext->cur_bwmode;
11575 cur_ch_offset = pmlmeext->cur_ch_offset;
11578 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
11580 if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE)
11582 /* issue null data */
11583 issue_nulldata(pbuddy_adapter, NULL, 0, 0, 0);
11586 if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
11587 check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
11590 DBG_8723A("survey done, current CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
11592 DBG_8723A("restart pbuddy_adapter's beacon\n");
11594 update_beacon(pbuddy_adapter, 0, NULL, _TRUE);
11599 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
11603 void dc_set_ap_channel_bandwidth(_adapter *padapter, u8 channel, u8 channel_offset, u8 bwmode)
11606 u8 val8, cur_channel, cur_bwmode, cur_ch_offset, change_band;
11608 struct registry_priv *pregpriv = &padapter->registrypriv;
11609 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
11610 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
11611 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
11612 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11613 struct HT_info_element *pht_info=NULL;
11614 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
11615 struct mlme_priv *pbuddy_mlmepriv = NULL;
11616 struct mlme_ext_priv *pbuddy_mlmeext = NULL;
11618 DBG_8723A("dualmac_concurrent_ap_set_channel_bwmode ==>\n");
11620 cur_channel = channel;
11621 cur_bwmode = bwmode;
11622 cur_ch_offset = channel_offset;
11623 change_band = _FALSE;
11625 p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
11628 pht_info = (struct HT_info_element *)(p+2);
11631 if(pbuddy_adapter != NULL &&
11632 padapter->DualMacConcurrent == _TRUE)
11634 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11635 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
11637 if(!check_fwstate(pbuddy_mlmepriv, _FW_LINKED|_FW_UNDER_LINKING|_FW_UNDER_SURVEY))
11639 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
11641 else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED)==_TRUE)
11643 /* To sync cur_channel/cur_bwmode/cur_ch_offset with another adapter */
11644 DBG_8723A("Another iface is at linked state, sync cur_channel/cur_bwmode/cur_ch_offset\n");
11645 DBG_8723A("Another adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
11646 DBG_8723A("Current adapter, CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
11648 cur_channel = pbuddy_mlmeext->cur_channel;
11649 if(cur_bwmode == HT_CHANNEL_WIDTH_40)
11652 pht_info->infos[0] &= ~(BIT(0)|BIT(1));
11654 if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
11656 cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
11658 /* to update cur_ch_offset value in beacon */
11661 switch(cur_ch_offset)
11663 case HAL_PRIME_CHNL_OFFSET_LOWER:
11664 pht_info->infos[0] |= 0x1;
11666 case HAL_PRIME_CHNL_OFFSET_UPPER:
11667 pht_info->infos[0] |= 0x3;
11669 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
11675 else if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20)
11677 cur_bwmode = HT_CHANNEL_WIDTH_20;
11678 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11680 if(cur_channel>0 && cur_channel<5)
11683 pht_info->infos[0] |= 0x1;
11685 cur_bwmode = HT_CHANNEL_WIDTH_40;
11686 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
11689 if(cur_channel>7 && cur_channel<(14+1))
11692 pht_info->infos[0] |= 0x3;
11694 cur_bwmode = HT_CHANNEL_WIDTH_40;
11695 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
11698 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
11702 /* to update channel value in beacon */
11703 pnetwork->Configuration.DSConfig = cur_channel;
11704 p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
11706 *(p + 2) = cur_channel;
11709 pht_info->primary_channel = cur_channel;
11714 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
11717 DBG_8723A("CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
11719 if((channel <= 14 && cur_channel >= 36) ||
11720 (channel >= 36 && cur_channel <= 14))
11722 change_band = _TRUE;
11725 pmlmeext->cur_channel = cur_channel;
11726 pmlmeext->cur_bwmode = cur_bwmode;
11727 pmlmeext->cur_ch_offset = cur_ch_offset;
11729 if(change_band == _TRUE)
11730 dc_change_band(padapter, pnetwork);
11732 DBG_8723A("dualmac_concurrent_ap_set_channel_bwmode <==\n");
11735 void dc_resume_xmit(_adapter *padapter)
11737 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
11739 if(pbuddy_adapter != NULL &&
11740 padapter->DualMacConcurrent == _TRUE)
11742 DBG_8723A("dc_resume_xmit, resume pbuddy_adapter Tx\n");
11743 rtw_os_xmit_schedule(pbuddy_adapter);
11747 u8 dc_check_xmit(_adapter *padapter)
11749 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
11750 struct mlme_priv *pbuddy_mlmepriv = NULL;
11752 if(pbuddy_adapter != NULL &&
11753 padapter->DualMacConcurrent == _TRUE)
11755 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11756 if (check_fwstate(pbuddy_mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
11758 DBG_8723A("dc_check_xmit pbuddy_adapter is under survey or under linking\n");
11767 #ifdef CONFIG_CONCURRENT_MODE
11768 int check_buddy_mlmeinfo_state(_adapter *padapter, u32 state)
11770 PADAPTER pbuddy_adapter;
11771 struct mlme_ext_priv *pbuddy_mlmeext;
11772 struct mlme_ext_info *pbuddy_mlmeinfo;
11774 if(padapter == NULL)
11777 pbuddy_adapter = padapter->pbuddy_adapter;
11779 if(pbuddy_adapter == NULL)
11782 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
11783 pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
11785 if((pbuddy_mlmeinfo->state&0x03) == state)
11791 int concurrent_chk_start_clnt_join(_adapter *padapter)
11794 PADAPTER pbuddy_adapter;
11795 struct mlme_ext_priv *pbuddy_mlmeext;
11796 struct mlme_ext_info *pbuddy_pmlmeinfo;
11797 struct mlme_priv *pbuddy_mlmepriv;
11798 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11799 unsigned char cur_ch = pmlmeext->cur_channel;
11800 unsigned char cur_bw = pmlmeext->cur_bwmode;
11801 unsigned char cur_ch_offset = pmlmeext->cur_ch_offset;
11803 if(!rtw_buddy_adapter_up(padapter))
11805 goto start_join_set_ch_bw;
11808 pbuddy_adapter = padapter->pbuddy_adapter;
11809 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
11810 pbuddy_pmlmeinfo = &(pbuddy_mlmeext->mlmext_info);
11811 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11813 if((pbuddy_pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)/* for AP MODE */
11815 bool inform_ch_switch = _FALSE;
11816 if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel)
11818 inform_ch_switch = _TRUE;
11820 else if((pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
11821 (pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
11822 (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset))
11824 inform_ch_switch = _TRUE;
11826 else if((pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20) &&
11827 (pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40))
11829 inform_ch_switch = _FALSE;
11830 cur_ch = pmlmeext->cur_channel;
11831 cur_bw = pbuddy_mlmeext->cur_bwmode;
11832 cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
11835 if (inform_ch_switch) {
11836 #ifdef CONFIG_SPCT_CH_SWITCH
11838 rtw_ap_inform_ch_switch(pbuddy_adapter, pmlmeext->cur_channel , pmlmeext->cur_ch_offset);
11842 /* issue deauth to all stas if if2 is at ap mode */
11843 rtw_sta_flush(pbuddy_adapter);
11845 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
11848 else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED) == _TRUE &&
11849 check_fwstate(pbuddy_mlmepriv, WIFI_STATION_STATE) == _TRUE) /* for Client Mode/p2p client */
11851 #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211)
11852 struct wifidirect_info *pbuddy_wdinfo = &(pbuddy_adapter->wdinfo);
11853 if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE))
11855 goto start_join_set_ch_bw;/* wlan0-sta mode has higher priority than p2p0-p2p client */
11857 #endif /* CONFIG_P2P && CONFIG_IOCTL_CFG80211 */
11859 if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel)
11861 DBG_8723A("start_clnt_join(ch=%d), but channel mismatch with buddy(ch=%d) interface\n",
11862 pmlmeext->cur_channel, pbuddy_mlmeext->cur_channel);
11864 report_join_res(padapter, (-4));
11869 if((pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
11870 (pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
11871 (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset))
11873 DBG_8723A("start_clnt_join(bwmode=%d, ch_offset=%d), but bwmode & ch_offset mismatch with buddy(bwmode=%d, ch_offset=%d) interface\n",
11874 pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
11876 report_join_res(padapter, (-4));
11883 start_join_set_ch_bw:
11885 set_channel_bwmode(padapter, cur_ch, cur_ch_offset, cur_bw);
11890 void concurrent_chk_joinbss_done(_adapter *padapter, int join_res)
11892 struct mlme_ext_priv *pmlmeext;
11893 struct mlme_ext_info *pmlmeinfo;
11894 PADAPTER pbuddy_adapter;
11895 struct mlme_priv *pbuddy_mlmepriv;
11896 struct mlme_ext_priv *pbuddy_mlmeext;
11897 struct mlme_ext_info *pbuddy_mlmeinfo;
11898 WLAN_BSSID_EX *pbuddy_network_mlmeext;
11900 if(!rtw_buddy_adapter_up(padapter))
11902 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
11906 pmlmeext = &padapter->mlmeextpriv;
11907 pmlmeinfo = &(pmlmeext->mlmext_info);
11909 pbuddy_adapter = padapter->pbuddy_adapter;
11910 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11911 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
11912 pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
11913 pbuddy_network_mlmeext = &(pbuddy_mlmeinfo->network);
11915 if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
11916 check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
11918 /* restart and update beacon */
11920 DBG_8723A("after join,primary adapter, CH=%d, BW=%d, offset=%d\n"
11921 , pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
11927 struct HT_info_element *pht_info=NULL;
11929 /* sync channel/bwmode/ch_offset with primary adapter */
11930 pbuddy_mlmeext->cur_channel = pmlmeext->cur_channel;
11931 if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
11933 p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
11936 pht_info = (struct HT_info_element *)(p+2);
11937 pht_info->infos[0] &= ~(BIT(0)|BIT(1)); /* no secondary channel is present */
11940 if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
11942 pbuddy_mlmeext->cur_ch_offset = pmlmeext->cur_ch_offset;
11944 /* to update cur_ch_offset value in beacon */
11947 switch(pmlmeext->cur_ch_offset)
11949 case HAL_PRIME_CHNL_OFFSET_LOWER:
11950 pht_info->infos[0] |= 0x1;
11952 case HAL_PRIME_CHNL_OFFSET_UPPER:
11953 pht_info->infos[0] |= 0x3;
11955 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
11963 else if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20)
11965 if(pmlmeext->cur_channel>=1 && pmlmeext->cur_channel<=4)
11968 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
11970 pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
11971 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
11973 else if(pmlmeext->cur_channel>=5 && pmlmeext->cur_channel<=14)
11976 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
11978 pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
11979 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
11983 switch(pmlmeext->cur_channel)
11998 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
11999 pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
12000 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
12016 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
12018 pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
12019 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
12024 pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
12025 pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
12026 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
12035 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
12040 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
12043 /* to update channel value in beacon */
12044 pbuddy_network_mlmeext->Configuration.DSConfig = pmlmeext->cur_channel;
12045 p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
12047 *(p + 2) = pmlmeext->cur_channel;
12049 p = rtw_get_ie((pbuddy_network_mlmeext->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _HT_ADD_INFO_IE_, &ie_len, (pbuddy_network_mlmeext->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
12052 pht_info = (struct HT_info_element *)(p+2);
12053 pht_info->primary_channel = pmlmeext->cur_channel;
12059 /* switch back to original channel/bwmode/ch_offset; */
12060 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
12063 DBG_8723A("after join, second adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
12065 DBG_8723A("update pbuddy_adapter's beacon\n");
12067 update_beacon(pbuddy_adapter, 0, NULL, _TRUE);
12070 else if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) &&
12071 check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
12075 pbuddy_mlmeext->cur_channel = pmlmeext->cur_channel;
12076 if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
12077 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
12078 else if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
12079 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
12081 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
12085 /* switch back to original channel/bwmode/ch_offset; */
12086 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
12091 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
12094 #endif /* CONFIG_CONCURRENT_MODE */
12096 u8 set_ch_hdl(_adapter *padapter, u8 *pbuf)
12098 struct set_ch_parm *set_ch_parm;
12099 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12100 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12103 return H2C_PARAMETERS_ERROR;
12105 set_ch_parm = (struct set_ch_parm *)pbuf;
12107 DBG_8723A(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
12108 FUNC_NDEV_ARG(padapter->pnetdev),
12109 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
12111 pmlmeext->cur_channel = set_ch_parm->ch;
12112 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
12113 pmlmeext->cur_bwmode = set_ch_parm->bw;
12115 set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
12117 return H2C_SUCCESS;
12120 u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf)
12122 struct SetChannelPlan_param *setChannelPlan_param;
12123 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12124 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12127 return H2C_PARAMETERS_ERROR;
12129 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
12131 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
12132 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
12134 return H2C_SUCCESS;
12137 u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf)
12139 struct LedBlink_param *ledBlink_param;
12142 return H2C_PARAMETERS_ERROR;
12144 ledBlink_param = (struct LedBlink_param *)pbuf;
12146 #ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD
12147 BlinkHandler(ledBlink_param->pLed);
12150 return H2C_SUCCESS;
12153 u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf)
12156 struct SetChannelSwitch_param *setChannelSwitch_param;
12157 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12158 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12159 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
12161 u8 gval8 = 0x00, sval8 = 0xff;
12164 return H2C_PARAMETERS_ERROR;
12166 setChannelSwitch_param = (struct SetChannelSwitch_param *)pbuf;
12167 new_ch_no = setChannelSwitch_param->new_ch_no;
12169 rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
12171 rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &sval8);
12173 DBG_8723A("DFS detected! Swiching channel to %d!\n", new_ch_no);
12174 SelectChannel(padapter, new_ch_no);
12176 rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
12178 rtw_free_network_queue(padapter, _TRUE);
12179 rtw_indicate_disconnect(padapter);
12181 if ( ((new_ch_no >= 52) && (new_ch_no <= 64)) ||((new_ch_no >= 100) && (new_ch_no <= 140)) ) {
12182 DBG_8723A("Switched to DFS band (ch %02x) again!!\n", new_ch_no);
12185 return H2C_SUCCESS;
12187 return H2C_REJECTED;
12188 #endif /* CONFIG_DFS */
12191 /* TDLS_WRCR : write RCR DATA BIT */
12192 /* TDLS_SD_PTI : issue peer traffic indication */
12193 /* TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure */
12194 /* TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame */
12195 /* TDLS_DONE_CH_SEN: channel sensing and report candidate channel */
12196 /* TDLS_OFF_CH : first time set channel to off channel */
12197 /* TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel */
12198 /* TDLS_P_OFF_CH : periodically go to off channel */
12199 /* TDLS_P_BASE_CH : periodically go back to base channel */
12200 /* TDLS_RS_RCR : restore RCR */
12201 /* TDLS_CKALV_PH1 : check alive timer phase1 */
12202 /* TDLS_CKALV_PH2 : check alive timer phase2 */
12203 /* TDLS_FREE_STA : free tdls sta */
12204 u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf)
12208 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12209 struct TDLSoption_param *TDLSoption;
12210 struct sta_info *ptdls_sta;
12211 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12212 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
12213 u8 survey_channel, i, min, option;
12216 return H2C_PARAMETERS_ERROR;
12218 TDLSoption = (struct TDLSoption_param *)pbuf;
12220 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), TDLSoption->addr );
12221 option = TDLSoption->option;
12223 if( ptdls_sta == NULL )
12225 if( option != TDLS_RS_RCR )
12226 return H2C_REJECTED;
12229 /* spin_lock_bh(&(ptdlsinfo->hdl_lock)); */
12230 DBG_8723A("[%s] option:%d\n", __FUNCTION__, option);
12234 /* As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0 */
12235 /* such we can receive all kinds of data frames. */
12236 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_WRCR, 0);
12237 DBG_8723A("TDLS with "MAC_FMT"\n", MAC_ARG(ptdls_sta->hwaddr));
12239 pmlmeinfo->FW_sta_info[ptdls_sta->mac_id].psta = ptdls_sta;
12240 /* set TDLS sta rate. */
12241 set_sta_rate(padapter, ptdls_sta);
12244 issue_tdls_peer_traffic_indication(padapter, ptdls_sta);
12247 _cancel_timer_ex(&ptdls_sta->base_ch_timer);
12248 _cancel_timer_ex(&ptdls_sta->off_ch_timer);
12249 SelectChannel(padapter, pmlmeext->cur_channel);
12250 ptdls_sta->tdls_sta_state &= ~(TDLS_CH_SWITCH_ON_STATE |
12251 TDLS_PEER_AT_OFF_STATE |
12252 TDLS_AT_OFF_CH_STATE);
12253 DBG_8723A("go back to base channel\n ");
12254 issue_nulldata(padapter, NULL, 0, 0, 0);
12256 case TDLS_INIT_CH_SEN:
12257 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_INIT_CH_SEN, 0);
12258 pmlmeext->sitesurvey_res.channel_idx = 0;
12259 ptdls_sta->option = TDLS_DONE_CH_SEN;
12260 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_DONE_CH_SEN);
12262 case TDLS_DONE_CH_SEN:
12263 survey_channel = pmlmeext->channel_set[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
12264 if(survey_channel){
12265 SelectChannel(padapter, survey_channel);
12266 ptdlsinfo->cur_channel = survey_channel;
12267 pmlmeext->sitesurvey_res.channel_idx++;
12268 _set_timer(&ptdls_sta->option_timer, SURVEY_TO);
12270 SelectChannel(padapter, pmlmeext->cur_channel);
12272 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_DONE_CH_SEN, 0);
12274 if(ptdlsinfo->ch_sensing==1){
12275 ptdlsinfo->ch_sensing=0;
12276 ptdlsinfo->cur_channel=1;
12277 min=ptdlsinfo->collect_pkt_num[0];
12278 for(i=1; i<MAX_CHANNEL_NUM-1; i++){
12279 if(min > ptdlsinfo->collect_pkt_num[i]){
12280 ptdlsinfo->cur_channel=i+1;
12281 min=ptdlsinfo->collect_pkt_num[i];
12283 ptdlsinfo->collect_pkt_num[i]=0;
12285 ptdlsinfo->collect_pkt_num[0]=0;
12286 ptdlsinfo->candidate_ch=ptdlsinfo->cur_channel;
12287 DBG_8723A("TDLS channel sensing done, candidate channel: %02x\n", ptdlsinfo->candidate_ch);
12288 ptdlsinfo->cur_channel=0;
12292 if(ptdls_sta->tdls_sta_state & TDLS_PEER_SLEEP_STATE){
12293 ptdls_sta->tdls_sta_state |= TDLS_APSD_CHSW_STATE;
12295 /* send null data with pwrbit==1 before send ch_switching_req to peer STA. */
12296 issue_nulldata(padapter, NULL, 1, 0, 0);
12298 ptdls_sta->tdls_sta_state |= TDLS_CH_SW_INITIATOR_STATE;
12300 issue_tdls_ch_switch_req(padapter, ptdls_sta->hwaddr);
12301 DBG_8723A("issue tdls ch switch req\n");
12306 issue_nulldata(padapter, NULL, 1, 0, 0);
12307 SelectChannel(padapter, ptdls_sta->off_ch);
12309 DBG_8723A("change channel to tar ch:%02x\n", ptdls_sta->off_ch);
12310 ptdls_sta->tdls_sta_state |= TDLS_AT_OFF_CH_STATE;
12311 ptdls_sta->tdls_sta_state &= ~(TDLS_PEER_AT_OFF_STATE);
12312 _set_timer(&ptdls_sta->option_timer, (u32)ptdls_sta->ch_switch_time);
12315 _cancel_timer_ex(&ptdls_sta->base_ch_timer);
12316 _cancel_timer_ex(&ptdls_sta->off_ch_timer);
12317 SelectChannel(padapter, pmlmeext->cur_channel);
12318 ptdls_sta->tdls_sta_state &= ~(TDLS_CH_SWITCH_ON_STATE |
12319 TDLS_PEER_AT_OFF_STATE |
12320 TDLS_AT_OFF_CH_STATE);
12321 DBG_8723A("go back to base channel\n ");
12322 issue_nulldata(padapter, NULL, 0, 0, 0);
12323 _set_timer(&ptdls_sta->option_timer, (u32)ptdls_sta->ch_switch_time);
12325 case TDLS_P_OFF_CH:
12326 SelectChannel(padapter, pmlmeext->cur_channel);
12327 issue_nulldata(padapter, NULL, 0, 0, 0);
12328 DBG_8723A("change channel to base ch:%02x\n", pmlmeext->cur_channel);
12329 ptdls_sta->tdls_sta_state &= ~(TDLS_PEER_AT_OFF_STATE| TDLS_AT_OFF_CH_STATE);
12330 _set_timer(&ptdls_sta->off_ch_timer, TDLS_STAY_TIME);
12332 case TDLS_P_BASE_CH:
12333 issue_nulldata(ptdls_sta->padapter, NULL, 1, 0, 0);
12334 SelectChannel(padapter, ptdls_sta->off_ch);
12335 DBG_8723A("change channel to off ch:%02x\n", ptdls_sta->off_ch);
12336 ptdls_sta->tdls_sta_state |= TDLS_AT_OFF_CH_STATE;
12337 if((ptdls_sta->tdls_sta_state & TDLS_PEER_AT_OFF_STATE) != TDLS_PEER_AT_OFF_STATE){
12338 issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta, 0);
12340 _set_timer(&ptdls_sta->base_ch_timer, TDLS_STAY_TIME);
12343 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_RS_RCR, 0);
12344 DBG_8723A("wirte REG_RCR, set bit6 on\n");
12346 case TDLS_CKALV_PH1:
12347 _set_timer(&ptdls_sta->alive_timer2, TDLS_ALIVE_TIMER_PH2);
12349 case TDLS_CKALV_PH2:
12350 _set_timer(&ptdls_sta->alive_timer1, TDLS_ALIVE_TIMER_PH1);
12352 case TDLS_FREE_STA:
12353 free_tdls_sta(padapter, ptdls_sta);
12358 /* spin_unlock_bh(&(ptdlsinfo->hdl_lock)); */
12360 return H2C_SUCCESS;
12362 return H2C_REJECTED;
12363 #endif /* CONFIG_TDLS */