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>
31 #ifdef CONFIG_BT_COEXIST
32 #include <rtl8723a_hal.h>
35 struct mlme_handler mlme_sta_tbl[]={
36 {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
37 {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
38 {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
39 {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
40 {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
41 {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
43 /*----------------------------------------------------------
45 -----------------------------------------------------------*/
46 {0, "DoReserved", &DoReserved},
47 {0, "DoReserved", &DoReserved},
48 {WIFI_BEACON, "OnBeacon", &OnBeacon},
49 {WIFI_ATIM, "OnATIM", &OnAtim},
50 {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
51 {WIFI_AUTH, "OnAuth", &OnAuthClient},
52 {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
53 {WIFI_ACTION, "OnAction", &OnAction},
56 #ifdef _CONFIG_NATIVEAP_MLME_
57 struct mlme_handler mlme_ap_tbl[]={
58 {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
59 {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
60 {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
61 {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
62 {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
63 {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
65 /*----------------------------------------------------------
67 -----------------------------------------------------------*/
68 {0, "DoReserved", &DoReserved},
69 {0, "DoReserved", &DoReserved},
70 {WIFI_BEACON, "OnBeacon", &OnBeacon},
71 {WIFI_ATIM, "OnATIM", &OnAtim},
72 {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
73 {WIFI_AUTH, "OnAuth", &OnAuth},
74 {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
75 {WIFI_ACTION, "OnAction", &OnAction},
79 struct action_handler OnAction_tbl[]={
80 {RTW_WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct},
81 {RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction_qos},
82 {RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction_dls},
83 {RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back},
84 {RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public},
85 {RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved},
86 {RTW_WLAN_CATEGORY_FT, "ACTION_FT", &DoReserved},
87 {RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht},
88 {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved},
89 {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm},
90 {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p},
93 u8 null_addr[ETH_ALEN]= {0,0,0,0,0,0};
95 /**************************************************
96 OUI definitions for the vendor specific IE
97 ***************************************************/
98 unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
99 unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
100 unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
101 unsigned char P2P_OUI[] = {0x50,0x6F,0x9A,0x09};
102 unsigned char WFD_OUI[] = {0x50,0x6F,0x9A,0x0A};
104 unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
105 unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
107 unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
108 unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
110 extern unsigned char REALTEK_96B_IE[];
112 /********************************************************
114 *********************************************************/
115 #ifdef CONFIG_DISABLE_MCS13TO15
116 unsigned char MCS_rate_2R_MCS13TO15_OFF[16] = {0xff, 0x1f, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
117 unsigned char MCS_rate_2R[16] = {0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
118 #else /* CONFIG_DISABLE_MCS13TO15 */
119 unsigned char MCS_rate_2R[16] = {0xff, 0xff, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
120 #endif /* CONFIG_DISABLE_MCS13TO15 */
121 unsigned char MCS_rate_1R[16] = {0xff, 0x00, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
123 /********************************************************
124 ChannelPlan definitions
125 *********************************************************/
127 static RT_CHANNEL_PLAN_2G RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = {
128 {{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 */
129 {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */
130 {{1,2,3,4,5,6,7,8,9,10,11},11}, /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */
131 {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */
132 {{10,11,12,13},4}, /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */
133 {{},0}, /* 0x05, RT_CHANNEL_DOMAIN_2G_NULL */
136 static RT_CHANNEL_PLAN_5G RTW_ChannelPlan5G[RT_CHANNEL_DOMAIN_5G_MAX] = {
137 {{},0}, /* 0x00, RT_CHANNEL_DOMAIN_5G_NULL */
138 {{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 */
139 {{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 */
140 {{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 */
141 {{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 */
142 {{36,40,44,48,149,153,157,161,165},9}, /* 0x05, RT_CHANNEL_DOMAIN_5G_FCC2 */
143 {{36,40,44,48,52,56,60,64,149,153,157,161,165},13}, /* 0x06, RT_CHANNEL_DOMAIN_5G_FCC3 */
144 {{36,40,44,48,52,56,60,64,149,153,157,161},12}, /* 0x07, RT_CHANNEL_DOMAIN_5G_FCC4 */
145 {{149,153,157,161,165},5}, /* 0x08, RT_CHANNEL_DOMAIN_5G_FCC5 */
146 {{36,40,44,48,52,56,60,64},8}, /* 0x09, RT_CHANNEL_DOMAIN_5G_FCC6 */
147 {{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 */
148 {{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 */
149 {{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 */
150 {{36,40,44,48,52,56,60,64},8}, /* 0x0D, RT_CHANNEL_DOMAIN_5G_MKK2 */
151 {{100,104,108,112,116,120,124,128,132,136,140},11}, /* 0x0E, RT_CHANNEL_DOMAIN_5G_MKK3 */
152 {{56,60,64,100,104,108,112,116,136,140,149,153,157,161,165},15}, /* 0x0F, RT_CHANNEL_DOMAIN_5G_NCC1 */
153 {{56,60,64,149,153,157,161,165},8}, /* 0x10, RT_CHANNEL_DOMAIN_5G_NCC2 */
155 /* Driver self defined for old channel plan Compatible ,Remember to modify if have new channel plan definition ===== */
156 {{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 */
157 {{36,40,44,48},4}, /* 0x12, RT_CHANNEL_DOMAIN_5G_JAPAN_NO_DFS */
158 {{36,40,44,48,149,153,157,161},8}, /* 0x13, RT_CHANNEL_DOMAIN_5G_FCC4_NO_DFS */
161 static RT_CHANNEL_PLAN_MAP RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = {
162 /* 0x00 ~ 0x1F , Old Define ===== */
163 {0x02,0x11}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */
164 {0x02,0x0A}, /* 0x01, RT_CHANNEL_DOMAIN_IC */
165 {0x01,0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */
166 {0x01,0x00}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */
167 {0x01,0x00}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */
168 {0x03,0x00}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */
169 {0x03,0x00}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */
170 {0x01,0x09}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */
171 {0x03,0x09}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */
172 {0x03,0x00}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */
173 {0x00,0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */
174 {0x02,0x0F}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */
175 {0x01,0x08}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */
176 {0x02,0x06}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */
177 {0x02,0x0B}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */
178 {0x02,0x09}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */
179 {0x01,0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */
180 {0x02,0x05}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */
181 {0x01,0x12}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
182 {0x00,0x04}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */
183 {0x02,0x10}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */
184 {0x00,0x12}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */
185 {0x00,0x13}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */
186 {0x03,0x12}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */
187 {0x05,0x08}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */
188 {0x02,0x08}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */
189 {0x00,0x00}, /* 0x1A, */
190 {0x00,0x00}, /* 0x1B, */
191 {0x00,0x00}, /* 0x1C, */
192 {0x00,0x00}, /* 0x1D, */
193 {0x00,0x00}, /* 0x1E, */
194 {0x05,0x04}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */
195 /* 0x20 ~ 0x7F ,New Define ===== */
196 {0x00,0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */
197 {0x01,0x00}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */
198 {0x02,0x00}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */
199 {0x03,0x00}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */
200 {0x04,0x00}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */
201 {0x02,0x04}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */
202 {0x00,0x01}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */
203 {0x03,0x0C}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */
204 {0x00,0x0B}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */
205 {0x00,0x05}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */
206 {0x00,0x00}, /* 0x2A, */
207 {0x00,0x00}, /* 0x2B, */
208 {0x00,0x00}, /* 0x2C, */
209 {0x00,0x00}, /* 0x2D, */
210 {0x00,0x00}, /* 0x2E, */
211 {0x00,0x00}, /* 0x2F, */
212 {0x00,0x06}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */
213 {0x00,0x07}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */
214 {0x00,0x08}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */
215 {0x00,0x09}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */
216 {0x02,0x0A}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */
217 {0x00,0x02}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */
218 {0x00,0x03}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */
219 {0x03,0x0D}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */
220 {0x03,0x0E}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */
221 {0x02,0x0F}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */
222 {0x00,0x00}, /* 0x3A, */
223 {0x00,0x00}, /* 0x3B, */
224 {0x00,0x00}, /* 0x3C, */
225 {0x00,0x00}, /* 0x3D, */
226 {0x00,0x00}, /* 0x3E, */
227 {0x00,0x00}, /* 0x3F, */
228 {0x02,0x10}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */
229 {0x03,0x00}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G */
232 static RT_CHANNEL_PLAN_MAP RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03,0x02}; /* use the conbination for max channel numbers */
235 * Search the @param channel_num in given @param channel_set
236 * @ch_set: the given channel set
237 * @ch: the given channel number
239 * return the index of channel_num in channel_set, -1 if not found
241 int rtw_ch_set_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch)
244 for(i=0;ch_set[i].ChannelNum!=0;i++){
245 if(ch == ch_set[i].ChannelNum)
249 if(i >= ch_set[i].ChannelNum)
254 /****************************************************************************
256 Following are the initialization functions for WiFi MLME
258 *****************************************************************************/
260 int init_hw_mlme_ext(_adapter *padapter)
262 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
264 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
268 static void init_mlme_ext_priv_value(_adapter* padapter)
270 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
271 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
277 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};
278 unsigned char mixed_basicrate[NumRates] ={_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _12M_RATE_, _24M_RATE_, 0xff,};
280 ATOMIC_SET(&pmlmeext->event_seq, 0);
281 pmlmeext->mgnt_seq = 0;/* reset to zero when disconnect at client mode */
283 pmlmeext->cur_channel = padapter->registrypriv.channel;
284 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
285 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
289 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
291 /* memcpy(pmlmeext->channel_set, DefaultChannelPlan[padapter->mlmepriv.ChannelPlan].Channel, DefaultChannelPlan[padapter->mlmepriv.ChannelPlan].Len); */
292 /* memcpy(pmlmeext->channel_set, default_channel_set, MAX_CHANNEL_NUM); */
293 memcpy(pmlmeext->datarate, mixed_datarate, NumRates);
294 memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates);
296 if(pmlmeext->cur_channel > 14)
297 pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
299 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
301 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
302 pmlmeext->sitesurvey_res.channel_idx = 0;
303 pmlmeext->sitesurvey_res.bss_cnt = 0;
304 pmlmeext->scan_abort = _FALSE;
306 pmlmeinfo->state = WIFI_FW_NULL_STATE;
307 pmlmeinfo->reauth_count = 0;
308 pmlmeinfo->reassoc_count = 0;
309 pmlmeinfo->link_count = 0;
310 pmlmeinfo->auth_seq = 0;
311 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
312 pmlmeinfo->key_index = 0;
315 pmlmeinfo->enc_algo = _NO_PRIVACY_;
316 pmlmeinfo->authModeToggle = 0;
318 memset(pmlmeinfo->chg_txt, 0, 128);
320 pmlmeinfo->slotTime = SHORT_SLOT_TIME;
321 pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
323 pmlmeinfo->dialogToken = 0;
325 pmlmeext->action_public_rxseq = 0xffff;
326 pmlmeext->action_public_dialog_token = 0xff;
329 static int has_channel(RT_CHANNEL_INFO *channel_set,
334 for (i = 0; i < chanset_size; i++) {
335 if (channel_set[i].ChannelNum == chan) {
343 static void init_channel_list(_adapter *padapter, RT_CHANNEL_INFO *channel_set,
345 struct p2p_channels *channel_list) {
347 struct p2p_oper_class_map op_class[] = {
348 { IEEE80211G, 81, 1, 13, 1, BW20 },
349 { IEEE80211G, 82, 14, 14, 1, BW20 },
350 { IEEE80211A, 115, 36, 48, 4, BW20 },
351 { IEEE80211A, 116, 36, 44, 8, BW40PLUS },
352 { IEEE80211A, 117, 40, 48, 8, BW40MINUS },
353 { IEEE80211A, 124, 149, 161, 4, BW20 },
354 { IEEE80211A, 125, 149, 169, 4, BW20 },
355 { IEEE80211A, 126, 149, 157, 8, BW40PLUS },
356 { IEEE80211A, 127, 153, 161, 8, BW40MINUS },
357 { -1, 0, 0, 0, 0, BW20 }
364 for (op = 0; op_class[op].op_class; op++) {
366 struct p2p_oper_class_map *o = &op_class[op];
367 struct p2p_reg_class *reg = NULL;
369 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
370 if (!has_channel(channel_set, chanset_size, ch)) {
374 if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc))
377 if ((0 == (padapter->registrypriv.cbw40_enable & BIT(1))) &&
378 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw)))
382 reg = &channel_list->reg_class[cla];
384 reg->reg_class = o->op_class;
387 reg->channel[reg->channels] = ch;
391 channel_list->reg_classes = cla;
394 static u8 init_channel_set(_adapter* padapter, u8 ChannelPlan, RT_CHANNEL_INFO *channel_set)
396 u8 index,chanset_size = 0;
397 u8 b5GBand = _FALSE, b2_4GBand = _FALSE;
398 u8 Index2G = 0, Index5G=0;
400 memset(channel_set, 0, sizeof(RT_CHANNEL_INFO)*MAX_CHANNEL_NUM);
402 if(ChannelPlan >= RT_CHANNEL_DOMAIN_MAX && ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE)
404 DBG_8723A("ChannelPlan ID %x error !!!!!\n",ChannelPlan);
408 if(padapter->registrypriv.wireless_mode & WIRELESS_11G)
411 if(RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
412 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G;
414 Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G;
417 if(padapter->registrypriv.wireless_mode & WIRELESS_11A)
420 if(RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan)
421 Index5G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index5G;
423 Index5G = RTW_ChannelPlanMap[ChannelPlan].Index5G;
428 for(index=0;index<RTW_ChannelPlan2G[Index2G].Len;index++)
430 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index];
432 if( (RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == ChannelPlan) ||/* Channel 1~11 is active, and 12~14 is passive */
433 (RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN_2G == ChannelPlan) )
435 if(channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11)
436 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
437 else if((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14))
438 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
440 else if(RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan ||
441 RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan ||
442 RT_CHANNEL_DOMAIN_2G_WORLD == Index2G)/* channel 12~13, passive scan */
444 if(channel_set[chanset_size].ChannelNum <= 11)
445 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
447 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
451 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
460 for(index=0;index<RTW_ChannelPlan5G[Index5G].Len;index++)
463 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
464 if ( channel_set[chanset_size].ChannelNum <= 48
465 || channel_set[chanset_size].ChannelNum >= 149 )
467 if(RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)/* passive scan for all 5G channels */
468 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
470 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
474 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
477 #else /* CONFIG_DFS */
478 if ( RTW_ChannelPlan5G[Index5G].Channel[index] <= 48
479 || RTW_ChannelPlan5G[Index5G].Channel[index] >= 149 ) {
480 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan5G[Index5G].Channel[index];
481 if(RT_CHANNEL_DOMAIN_WORLD_WIDE_5G == ChannelPlan)/* passive scan for all 5G channels */
482 channel_set[chanset_size].ScanType = SCAN_PASSIVE;
484 channel_set[chanset_size].ScanType = SCAN_ACTIVE;
485 DBG_8723A("%s(): channel_set[%d].ChannelNum = %d\n", __FUNCTION__, chanset_size, channel_set[chanset_size].ChannelNum);
488 #endif /* CONFIG_DFS */
495 int init_mlme_ext_priv(_adapter* padapter)
498 struct registry_priv* pregistrypriv = &padapter->registrypriv;
499 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
500 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
501 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
503 /* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
504 /* memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv)); */
506 pmlmeext->padapter = padapter;
508 /* fill_fwpriv(padapter, &(pmlmeext->fwpriv)); */
510 init_mlme_ext_priv_value(padapter);
511 pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
513 init_mlme_ext_timer(padapter);
515 #ifdef CONFIG_AP_MODE
516 init_mlme_ap_info(padapter);
519 pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan,pmlmeext->channel_set);
520 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
522 pmlmeext->chan_scan_time = SURVEY_TO;
523 pmlmeext->mlmeext_init = _TRUE;
525 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
526 pmlmeext->active_keep_alive_check = _TRUE;
529 #ifdef DBG_FIXED_CHAN
530 pmlmeext->fixed_chan = 0xFF;
536 void free_mlme_ext_priv (struct mlme_ext_priv *pmlmeext)
538 _adapter *padapter = pmlmeext->padapter;
543 if (padapter->bDriverStopped == _TRUE)
545 _cancel_timer_ex(&pmlmeext->survey_timer);
546 _cancel_timer_ex(&pmlmeext->link_timer);
547 /* _cancel_timer_ex(&pmlmeext->ADDBA_timer); */
551 static u8 cmp_pkt_chnl_diff(_adapter *padapter,u8* pframe,uint packet_len)
552 { /* if the channel is same, return 0. else return channel differential */
556 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, _DSSET_IE_, &len, packet_len - _BEACON_IE_OFFSET_);
560 if(padapter->mlmeextpriv.cur_channel >= channel)
562 return (padapter->mlmeextpriv.cur_channel - channel);
566 return (channel-padapter->mlmeextpriv.cur_channel);
575 static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
577 u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
578 u8 *pframe = precv_frame->u.hdr.rx_data;
582 /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
583 if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv),
585 memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
590 ptable->func(padapter, precv_frame);
594 void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame)
597 struct mlme_handler *ptable;
598 #ifdef CONFIG_AP_MODE
599 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
600 #endif /* CONFIG_AP_MODE */
601 u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
602 u8 *pframe = precv_frame->u.hdr.rx_data;
603 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe));
605 RT_TRACE(_module_rtl871x_mlme_c_, _drv_info_,
606 ("+mgt_dispatcher: type(0x%x) subtype(0x%x)\n",
607 GetFrameType(pframe), GetFrameSubType(pframe)));
609 if (GetFrameType(pframe) != WIFI_MGT_TYPE)
611 RT_TRACE(_module_rtl871x_mlme_c_, _drv_err_, ("mgt_dispatcher: type(0x%x) error!\n", GetFrameType(pframe)));
615 /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
616 if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv),
618 memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
623 ptable = mlme_sta_tbl;
625 index = GetFrameSubType(pframe) >> 4;
628 if((index << 4)==WIFI_ACTION){
629 /* category==public (4), action==TDLS_DISCOVERY_RESPONSE */
630 if(*(pframe+24)==0x04 && *(pframe+25)==TDLS_DISCOVERY_RESPONSE){
631 DBG_8723A("recv tdls discovery response frame\n");
632 On_TDLS_Dis_Rsp(padapter, precv_frame);
635 #endif /* CONFIG_TDLS */
639 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("Currently we do not support reserved sub-fr-type=%d\n", index));
647 if (GetRetry(pframe))
649 if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum)
651 /* drop the duplicate management frame */
652 DBG_8723A("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num);
656 psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
662 /* RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("drop due to decache!\n")); */
667 #ifdef CONFIG_AP_MODE
668 switch (GetFrameSubType(pframe))
671 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
672 ptable->func = &OnAuth;
674 ptable->func = &OnAuthClient;
677 case WIFI_REASSOCREQ:
678 _mgt_dispatcher(padapter, ptable, precv_frame);
679 #ifdef CONFIG_HOSTAPD_MLME
680 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
681 rtw_hostapd_mlme_rx(padapter, precv_frame);
685 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
687 #ifdef CONFIG_HOSTAPD_MLME
688 rtw_hostapd_mlme_rx(padapter, precv_frame);
690 _mgt_dispatcher(padapter, ptable, precv_frame);
694 _mgt_dispatcher(padapter, ptable, precv_frame);
697 _mgt_dispatcher(padapter, ptable, precv_frame);
700 /* if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) */
701 _mgt_dispatcher(padapter, ptable, precv_frame);
704 _mgt_dispatcher(padapter, ptable, precv_frame);
705 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
706 rtw_hostapd_mlme_rx(padapter, precv_frame);
711 _mgt_dispatcher(padapter, ptable, precv_frame);
717 u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da)
719 bool response = _TRUE;
721 #ifdef CONFIG_IOCTL_CFG80211
722 if (wdev_to_priv(padapter->rtw_wdev)->p2p_enabled == _FALSE
723 || padapter->mlmepriv.wps_probe_resp_ie == NULL
724 || padapter->mlmepriv.p2p_probe_resp_ie == NULL
727 DBG_8723A("DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p\n",
728 wdev_to_priv(padapter->rtw_wdev)->p2p_enabled,
729 padapter->mlmepriv.wps_probe_resp_ie,
730 padapter->mlmepriv.p2p_probe_resp_ie);
735 /* do nothing if the device name is empty */
736 if ( !padapter->wdinfo.device_name_len )
742 if (response == _TRUE)
743 issue_probersp_p2p( padapter, da);
747 #endif /* CONFIG_P2P */
749 /****************************************************************************
751 Following are the callback functions for each subtype of the management frames
753 *****************************************************************************/
755 unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame)
759 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
760 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
761 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
762 WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
763 u8 *pframe = precv_frame->u.hdr.rx_data;
764 uint len = precv_frame->u.hdr.len;
765 u8 is_valid_p2p_probereq = _FALSE;
768 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
769 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
770 u8 wifi_test_chk_rate = 1;
772 if ( !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
773 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
774 !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
775 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
776 !rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
779 /* Commented by Albert 2011/03/17 */
780 /* mcs_rate = 0 -> CCK 1M rate */
781 /* mcs_rate = 1 -> CCK 2M rate */
782 /* mcs_rate = 2 -> CCK 5.5M rate */
783 /* mcs_rate = 3 -> CCK 11M rate */
784 /* In the P2P mode, the driver should not support the CCK rate */
786 /* Commented by Kurt 2012/10/16 */
787 /* IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client */
788 #ifdef CONFIG_WIFI_TEST
789 if ( pattrib->mcs_rate <= 3 )
791 wifi_test_chk_rate = 0;
793 #endif /* CONFIG_WIFI_TEST */
795 if( wifi_test_chk_rate == 1 )
797 if((is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len)) == _TRUE)
799 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE))
801 #ifndef CONFIG_IOCTL_CFG80211
803 report_survey_event(padapter, precv_frame);
805 p2p_listen_state_process( padapter, get_sa(pframe));
810 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
819 #endif /* CONFIG_P2P */
821 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE))
826 if(check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE &&
827 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE)==_FALSE)
832 /* DBG_8723A("+OnProbeReq\n"); */
834 #ifdef CONFIG_CONCURRENT_MODE
835 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
836 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
838 /* don't process probe req */
843 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
844 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
846 /* check (wildcard) SSID */
849 if(is_valid_p2p_probereq == _TRUE)
851 goto _issue_probersp;
855 memcmp((void *)(p+2), cur->Ssid.Ssid,
856 cur->Ssid.SsidLength)) ||
857 (ielen == 0 && pmlmeinfo->hidden_ssid_mode))
864 if(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
865 pmlmepriv->cur_network.join_res == _TRUE)
867 /* DBG_8723A("+issue_probersp during ap mode\n"); */
868 issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
876 unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
878 struct sta_info *psta;
879 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
880 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
881 struct sta_priv *pstapriv = &padapter->stapriv;
882 u8 *pframe = precv_frame->u.hdr.rx_data;
884 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
888 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
890 if ( _TRUE == pwdinfo->tx_prov_disc_info.benable )
892 if (!memcmp(pwdinfo->tx_prov_disc_info.peerIFAddr,
893 GetAddr2Ptr(pframe), ETH_ALEN))
895 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
897 pwdinfo->tx_prov_disc_info.benable = _FALSE;
898 issue_p2p_provision_request( padapter,
899 pwdinfo->tx_prov_disc_info.ssid.Ssid,
900 pwdinfo->tx_prov_disc_info.ssid.SsidLength,
901 pwdinfo->tx_prov_disc_info.peerDevAddr );
903 else if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
905 pwdinfo->tx_prov_disc_info.benable = _FALSE;
906 issue_p2p_provision_request( padapter,
909 pwdinfo->tx_prov_disc_info.peerDevAddr );
915 else if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
917 if ( _TRUE == pwdinfo->nego_req_info.benable )
919 DBG_8723A( "[%s] P2P State is GONEGO ING!\n", __FUNCTION__ );
920 if (!memcmp(pwdinfo->nego_req_info.peerDevAddr,
921 GetAddr2Ptr(pframe), ETH_ALEN))
923 pwdinfo->nego_req_info.benable = _FALSE;
924 issue_p2p_GO_request( padapter, pwdinfo->nego_req_info.peerDevAddr);
928 else if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ ) )
930 if ( _TRUE == pwdinfo->invitereq_info.benable )
932 DBG_8723A( "[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__ );
933 if (!memcmp( pwdinfo->invitereq_info.peer_macaddr,
934 GetAddr2Ptr(pframe), ETH_ALEN))
936 pwdinfo->invitereq_info.benable = _FALSE;
937 issue_p2p_invitation_request( padapter, pwdinfo->invitereq_info.peer_macaddr );
943 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
945 report_survey_event(padapter, precv_frame);
946 #ifdef CONFIG_CONCURRENT_MODE
947 report_survey_event(padapter->pbuddy_adapter, precv_frame);
949 #ifdef CONFIG_DUALMAC_CONCURRENT
950 dc_report_survey_event(padapter, precv_frame);
958 unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
961 struct sta_info *psta;
962 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
963 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
964 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
965 struct sta_priv *pstapriv = &padapter->stapriv;
966 u8 *pframe = precv_frame->u.hdr.rx_data;
967 uint len = precv_frame->u.hdr.len;
973 #ifdef CONFIG_ATTEMPT_TO_FIX_AP_BEACON_ERROR
974 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_);
975 if ((p != NULL) && (ielen > 0))
977 if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D))
979 /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */
980 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)));
981 *(p + 1) = ielen - 1;
986 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
988 report_survey_event(padapter, precv_frame);
989 #ifdef CONFIG_CONCURRENT_MODE
990 report_survey_event(padapter->pbuddy_adapter, precv_frame);
993 #ifdef CONFIG_DUALMAC_CONCURRENT
994 dc_report_survey_event(padapter, precv_frame);
1000 if (!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network),
1002 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
1004 /* we should update current network before auth, or some IE is wrong */
1005 pbss = (WLAN_BSSID_EX*)rtw_malloc(sizeof(WLAN_BSSID_EX));
1007 if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
1008 update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
1009 rtw_get_bcn_info(&(pmlmepriv->cur_network));
1011 rtw_mfree((u8*)pbss, sizeof(WLAN_BSSID_EX));
1014 /* check the vendor of the assoc AP */
1015 pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr), len-sizeof(struct rtw_ieee80211_hdr_3addr));
1017 /* update TSF Value */
1018 update_TSF(pmlmeext, pframe, len);
1021 start_clnt_auth(padapter);
1026 if(((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
1028 if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1030 #ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
1031 /* Merge from 8712 FW code */
1032 if (cmp_pkt_chnl_diff(padapter,pframe,len) != 0)
1033 { /* join wrong channel, deauth and reconnect */
1034 issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
1036 report_del_sta_event(padapter,(&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL);
1037 pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS);
1040 #endif /* CONFIG_PATCH_JOIN_WRONG_CHANNEL */
1042 ret = rtw_check_bcn_info(padapter, pframe, len);
1044 DBG_8723A_LEVEL(_drv_always_, "ap has changed, disconnect now\n ");
1045 receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 65535);
1048 /* update WMM, ERP in the beacon */
1049 /* todo: the timer is used instead of the number of the beacon received */
1050 if ((sta_rx_pkts(psta) & 0xf) == 0)
1052 /* DBG_8723A("update_bcn_info\n"); */
1053 update_beacon_info(padapter, pframe, len, psta);
1057 process_csa_ie(padapter, pframe, len); /* channel switch announcement */
1058 #endif /* CONFIG_DFS */
1060 #ifdef CONFIG_P2P_PS
1061 process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1062 #endif /* CONFIG_P2P_PS */
1066 else if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
1068 if ((psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe))) != NULL)
1070 /* update WMM, ERP in the beacon */
1071 /* todo: the timer is used instead of the number of the beacon received */
1072 if ((sta_rx_pkts(psta) & 0xf) == 0)
1074 /* DBG_8723A("update_bcn_info\n"); */
1075 update_beacon_info(padapter, pframe, len, psta);
1081 /* allocate a new CAM entry for IBSS station */
1082 if ((cam_idx = allocate_fw_sta_entry(padapter)) == NUM_STA)
1084 goto _END_ONBEACON_;
1087 /* get supported rate */
1088 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)
1090 pmlmeinfo->FW_sta_info[cam_idx].status = 0;
1091 goto _END_ONBEACON_;
1094 /* update TSF Value */
1095 update_TSF(pmlmeext, pframe, len);
1097 /* report sta add event */
1098 report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx);
1108 unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame)
1110 #ifdef CONFIG_AP_MODE
1112 unsigned int auth_mode, seq, ie_len;
1113 unsigned char *sa, *p;
1116 static struct sta_info stat;
1117 struct sta_info *pstat=NULL;
1118 struct sta_priv *pstapriv = &padapter->stapriv;
1119 struct security_priv *psecuritypriv = &padapter->securitypriv;
1120 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1121 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1122 u8 *pframe = precv_frame->u.hdr.rx_data;
1123 uint len = precv_frame->u.hdr.len;
1125 #ifdef CONFIG_CONCURRENT_MODE
1126 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1127 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1129 /* don't process auth request; */
1132 #endif /* CONFIG_CONCURRENT_MODE */
1134 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1137 DBG_8723A("+OnAuth\n");
1139 sa = GetAddr2Ptr(pframe);
1141 auth_mode = psecuritypriv->dot11AuthAlgrthm;
1142 seq = cpu_to_le16(*(u16*)((unsigned long)pframe + WLAN_HDR_A3_LEN + 2));
1143 algorithm = cpu_to_le16(*(u16*)((unsigned long)pframe + WLAN_HDR_A3_LEN));
1145 DBG_8723A("auth alg=%x, seq=%X\n", algorithm, seq);
1147 if (auth_mode == 2 &&
1148 psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ &&
1149 psecuritypriv->dot11PrivacyAlgrthm != _WEP104_)
1152 if ((algorithm > 0 && auth_mode == 0) || /* rx a shared-key auth but shared not enabled */
1153 (algorithm == 0 && auth_mode == 1) ) /* rx a open-system auth but shared-key is enabled */
1155 DBG_8723A("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
1156 algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
1158 status = _STATS_NO_SUPP_ALG_;
1163 if(rtw_access_ctrl(padapter, sa) == _FALSE)
1165 status = _STATS_UNABLE_HANDLE_STA_;
1169 pstat = rtw_get_stainfo(pstapriv, sa);
1172 /* allocate a new one */
1173 DBG_8723A("going to alloc stainfo for sa="MAC_FMT"\n", MAC_ARG(sa));
1174 pstat = rtw_alloc_stainfo(pstapriv, sa);
1177 DBG_8723A(" Exceed the upper limit of supported clients...\n");
1178 status = _STATS_UNABLE_HANDLE_STA_;
1182 pstat->state = WIFI_FW_AUTH_NULL;
1183 pstat->auth_seq = 0;
1185 /* pstat->flags = 0; */
1186 /* pstat->capability = 0; */
1190 spin_lock_bh(&pstapriv->asoc_list_lock);
1191 if(rtw_is_list_empty(&pstat->asoc_list)==_FALSE)
1193 rtw_list_delete(&pstat->asoc_list);
1194 pstapriv->asoc_list_cnt--;
1195 if (pstat->expire_to > 0)
1197 /* TODO: STA re_auth within expire_to */
1200 spin_unlock_bh(&pstapriv->asoc_list_lock);
1203 /* TODO: STA re_auth and auth timeout */
1207 spin_lock_bh(&pstapriv->auth_list_lock);
1208 if (rtw_is_list_empty(&pstat->auth_list))
1210 rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list);
1211 pstapriv->auth_list_cnt++;
1213 spin_unlock_bh(&pstapriv->auth_list_lock);
1215 if (pstat->auth_seq == 0)
1216 pstat->expire_to = pstapriv->auth_to;
1218 if ((pstat->auth_seq + 1) != seq)
1220 DBG_8723A("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
1221 seq, pstat->auth_seq+1);
1222 status = _STATS_OUT_OF_AUTH_SEQ_;
1226 if (algorithm==0 && (auth_mode == 0 || auth_mode == 2))
1230 pstat->state &= ~WIFI_FW_AUTH_NULL;
1231 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1232 pstat->expire_to = pstapriv->assoc_to;
1233 pstat->authalg = algorithm;
1237 DBG_8723A("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
1238 seq, pstat->auth_seq+1);
1239 status = _STATS_OUT_OF_AUTH_SEQ_;
1243 else /* shared system or auto authentication */
1247 /* prepare for the challenging txt... */
1248 pstat->state &= ~WIFI_FW_AUTH_NULL;
1249 pstat->state |= WIFI_FW_AUTH_STATE;
1250 pstat->authalg = algorithm;
1251 pstat->auth_seq = 2;
1255 /* checking for challenging txt... */
1256 DBG_8723A("checking for challenging txt...\n");
1258 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len,
1259 len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
1261 if((p==NULL) || (ie_len<=0))
1263 DBG_8723A("auth rejected because challenge failure!(1)\n");
1264 status = _STATS_CHALLENGE_FAIL_;
1268 if (!memcmp((void *)(p + 2), pstat->chg_txt, 128))
1270 pstat->state &= (~WIFI_FW_AUTH_STATE);
1271 pstat->state |= WIFI_FW_AUTH_SUCCESS;
1272 /* challenging txt is correct... */
1273 pstat->expire_to = pstapriv->assoc_to;
1277 DBG_8723A("auth rejected because challenge failure!\n");
1278 status = _STATS_CHALLENGE_FAIL_;
1284 DBG_8723A("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
1285 seq, pstat->auth_seq+1);
1286 status = _STATS_OUT_OF_AUTH_SEQ_;
1291 /* Now, we are going to issue_auth... */
1292 pstat->auth_seq = seq + 1;
1294 #ifdef CONFIG_NATIVEAP_MLME
1295 issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
1298 if (pstat->state & WIFI_FW_AUTH_SUCCESS)
1299 pstat->auth_seq = 0;
1306 rtw_free_stainfo(padapter , pstat);
1309 memset((char *)pstat, '\0', sizeof(stat));
1310 pstat->auth_seq = 2;
1311 memcpy(pstat->hwaddr, sa, 6);
1313 #ifdef CONFIG_NATIVEAP_MLME
1314 issue_auth(padapter, pstat, (unsigned short)status);
1321 unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame)
1323 unsigned int seq, len, status, algthm, offset;
1325 unsigned int go2asoc = 0;
1326 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1327 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1328 u8 *pframe = precv_frame->u.hdr.rx_data;
1329 uint pkt_len = precv_frame->u.hdr.len;
1331 DBG_8723A("%s\n", __FUNCTION__);
1333 /* check A1 matches or not */
1334 if (memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
1337 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE))
1340 offset = (GetPrivacy(pframe))? 4: 0;
1342 algthm = le16_to_cpu(*(unsigned short *)((unsigned long)pframe + WLAN_HDR_A3_LEN + offset));
1343 seq = le16_to_cpu(*(unsigned short *)((unsigned long)pframe + WLAN_HDR_A3_LEN + offset + 2));
1344 status = le16_to_cpu(*(unsigned short *)((unsigned long)pframe + WLAN_HDR_A3_LEN + offset + 4));
1348 DBG_8723A("clnt auth fail, status: %d\n", status);
1349 if(status == 13)/* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
1351 if(pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1352 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
1354 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
1355 /* pmlmeinfo->reauth_count = 0; */
1358 set_link_timer(pmlmeext, 1);
1364 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1366 /* legendary shared system */
1367 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
1368 pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
1372 /* DBG_8723A("marc: no challenge text?\n"); */
1376 memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
1377 pmlmeinfo->auth_seq = 3;
1378 issue_auth(padapter, NULL, 0);
1379 set_link_timer(pmlmeext, REAUTH_TO);
1391 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
1402 /* this is also illegal */
1403 /* DBG_8723A("marc: clnt auth failed due to illegal seq=%x\n", seq); */
1409 DBG_8723A_LEVEL(_drv_always_, "auth success, start assoc\n");
1410 start_clnt_assoc(padapter);
1416 /* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
1421 unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame)
1423 #ifdef CONFIG_AP_MODE
1425 u16 capab_info, listen_interval;
1426 struct rtw_ieee802_11_elems elems;
1427 struct sta_info *pstat;
1428 unsigned char reassoc, *p, *pos, *wpa_ie;
1429 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
1430 int i, ie_len, wpa_ie_len, left;
1431 unsigned char supportRate[16];
1433 unsigned short status = _STATS_SUCCESSFUL_;
1434 unsigned short frame_type, ie_offset=0;
1435 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1436 struct security_priv *psecuritypriv = &padapter->securitypriv;
1437 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1438 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1439 WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
1440 struct sta_priv *pstapriv = &padapter->stapriv;
1441 u8 *pframe = precv_frame->u.hdr.rx_data;
1442 uint pkt_len = precv_frame->u.hdr.len;
1444 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
1445 u8 p2p_status_code = P2P_STATUS_SUCCESS;
1449 u8 wfd_ie[ 128 ] = { 0x00 };
1451 #endif /* CONFIG_WFD */
1452 #endif /* CONFIG_P2P */
1454 #ifdef CONFIG_CONCURRENT_MODE
1455 if(((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
1456 check_buddy_fwstate(padapter, _FW_UNDER_LINKING|_FW_UNDER_SURVEY))
1458 /* don't process assoc request; */
1461 #endif /* CONFIG_CONCURRENT_MODE */
1463 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
1466 frame_type = GetFrameSubType(pframe);
1467 if (frame_type == WIFI_ASSOCREQ)
1470 ie_offset = _ASOCREQ_IE_OFFSET_;
1472 else /* WIFI_REASSOCREQ */
1475 ie_offset = _REASOCREQ_IE_OFFSET_;
1478 if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
1479 DBG_8723A("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
1480 "\n", reassoc, (unsigned long)pkt_len);
1484 pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1485 if (pstat == (struct sta_info *)NULL)
1487 status = _RSON_CLS2_;
1488 goto asoc_class2_error;
1491 capab_info = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN);
1492 /* capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN)); */
1493 /* listen_interval = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN+2)); */
1494 listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN+2);
1496 left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
1497 pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
1499 DBG_8723A("%s\n", __FUNCTION__);
1501 /* check if this stat has been successfully authenticated/assocated */
1502 if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS))
1504 if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS))
1506 status = _RSON_CLS2_;
1507 goto asoc_class2_error;
1511 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
1512 pstat->state |= WIFI_FW_ASSOC_STATE;
1517 pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
1518 pstat->state |= WIFI_FW_ASSOC_STATE;
1521 pstat->capability = capab_info;
1523 /* now parse all ieee802_11 ie to point to elems */
1524 if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed ||
1526 DBG_8723A("STA " MAC_FMT " sent invalid association request\n",
1527 MAC_ARG(pstat->hwaddr));
1528 status = _STATS_FAILURE_;
1529 goto OnAssocReqFail;
1532 /* now we should check all the fields... */
1534 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SSID_IE_, &ie_len,
1535 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1538 status = _STATS_FAILURE_;
1541 if (ie_len == 0) /* broadcast ssid, however it is not allowed in assocreq */
1542 status = _STATS_FAILURE_;
1545 /* check if ssid match */
1546 if (memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength))
1547 status = _STATS_FAILURE_;
1549 if (ie_len != cur->Ssid.SsidLength)
1550 status = _STATS_FAILURE_;
1553 if(_STATS_SUCCESSFUL_ != status)
1554 goto OnAssocReqFail;
1556 /* check if the supported rate is ok */
1557 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _SUPPORTEDRATES_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1559 DBG_8723A("Rx a sta assoc-req which supported rate is empty!\n");
1560 /* use our own rate set as statoin used */
1561 /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */
1562 /* supportRateNum = AP_BSSRATE_LEN; */
1564 status = _STATS_FAILURE_;
1565 goto OnAssocReqFail;
1568 memcpy(supportRate, p+2, ie_len);
1569 supportRateNum = ie_len;
1571 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, _EXT_SUPPORTEDRATES_IE_ , &ie_len,
1572 pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1575 if(supportRateNum<=sizeof(supportRate))
1577 memcpy(supportRate+supportRateNum, p+2, ie_len);
1578 supportRateNum += ie_len;
1583 /* todo: mask supportRate between AP & STA -> move to update raid */
1584 /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */
1586 /* update station supportRate */
1587 pstat->bssratelen = supportRateNum;
1588 memcpy(pstat->bssrateset, supportRate, supportRateNum);
1589 UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen);
1591 /* check RSN/WPA/WPS */
1592 pstat->dot8021xalg = 0;
1594 pstat->wpa_group_cipher = 0;
1595 pstat->wpa2_group_cipher = 0;
1596 pstat->wpa_pairwise_cipher = 0;
1597 pstat->wpa2_pairwise_cipher = 0;
1598 memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie));
1599 if((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) {
1601 int group_cipher=0, pairwise_cipher=0;
1603 wpa_ie = elems.rsn_ie;
1604 wpa_ie_len = elems.rsn_ie_len;
1606 if(rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1607 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1608 pstat->wpa_psk |= BIT(1);
1610 pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher;
1611 pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher;
1613 if(!pstat->wpa2_group_cipher)
1614 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
1616 if(!pstat->wpa2_pairwise_cipher)
1617 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1619 status = WLAN_STATUS_INVALID_IE;
1622 } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) {
1624 int group_cipher=0, pairwise_cipher=0;
1626 wpa_ie = elems.wpa_ie;
1627 wpa_ie_len = elems.wpa_ie_len;
1629 if(rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1630 pstat->dot8021xalg = 1;/* psk, todo:802.1x */
1631 pstat->wpa_psk |= BIT(0);
1633 pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher;
1634 pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher;
1636 if(!pstat->wpa_group_cipher)
1637 status = WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
1639 if(!pstat->wpa_pairwise_cipher)
1640 status = WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1643 status = WLAN_STATUS_INVALID_IE;
1651 if(_STATS_SUCCESSFUL_ != status)
1652 goto OnAssocReqFail;
1654 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS);
1655 if(wpa_ie == NULL) {
1657 DBG_8723A("STA included WPS IE in "
1658 "(Re)Association Request - assume WPS is "
1660 pstat->flags |= WLAN_STA_WPS;
1662 DBG_8723A("STA did not include WPA/RSN IE "
1663 "in (Re)Association Request - possible WPS "
1665 pstat->flags |= WLAN_STA_MAYBE_WPS;
1668 /* AP support WPA/RSN, and sta is going to do WPS, but AP is not ready */
1669 /* that the selected registrar of AP is _FLASE */
1670 if ((psecuritypriv->wpa_psk > 0) &&
1671 (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS))) {
1672 if(pmlmepriv->wps_beacon_ie) {
1673 u8 selected_registrar = 0;
1675 rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len,
1676 WPS_ATTR_SELECTED_REGISTRAR , &selected_registrar, NULL);
1678 if(!selected_registrar) {
1679 DBG_8723A("selected_registrar is _FALSE , or AP is not ready to do WPS\n");
1681 status = _STATS_UNABLE_HANDLE_STA_;
1683 goto OnAssocReqFail;
1690 if(psecuritypriv->wpa_psk == 0) {
1691 DBG_8723A("STA " MAC_FMT ": WPA/RSN IE in association "
1692 "request, but AP don't support WPA/RSN\n", MAC_ARG(pstat->hwaddr));
1694 status = WLAN_STATUS_INVALID_IE;
1696 goto OnAssocReqFail;
1700 DBG_8723A("STA included WPS IE in "
1701 "(Re)Association Request - WPS is "
1703 pstat->flags |= WLAN_STA_WPS;
1706 copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2);
1710 memcpy(pstat->wpa_ie, wpa_ie-2, copy_len);
1714 /* check if there is WMM IE & support WWM-PS */
1715 pstat->flags &= ~WLAN_STA_WME;
1716 pstat->qos_option = 0;
1717 pstat->qos_info = 0;
1718 pstat->has_legacy_ac = _TRUE;
1719 pstat->uapsd_vo = 0;
1720 pstat->uapsd_vi = 0;
1721 pstat->uapsd_be = 0;
1722 pstat->uapsd_bk = 0;
1723 if (pmlmepriv->qospriv.qos_option)
1725 p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0;
1728 p = rtw_get_ie(p, _VENDOR_SPECIFIC_IE_, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
1730 if (!memcmp(p+2, WMM_IE, 6)) {
1732 pstat->flags |= WLAN_STA_WME;
1734 pstat->qos_option = 1;
1735 pstat->qos_info = *(p+8);
1737 pstat->max_sp_len = (pstat->qos_info>>5)&0x3;
1739 if((pstat->qos_info&0xf) !=0xf)
1740 pstat->has_legacy_ac = _TRUE;
1742 pstat->has_legacy_ac = _FALSE;
1744 if(pstat->qos_info&0xf)
1746 if(pstat->qos_info&BIT(0))
1747 pstat->uapsd_vo = BIT(0)|BIT(1);
1749 pstat->uapsd_vo = 0;
1751 if(pstat->qos_info&BIT(1))
1752 pstat->uapsd_vi = BIT(0)|BIT(1);
1754 pstat->uapsd_vi = 0;
1756 if(pstat->qos_info&BIT(2))
1757 pstat->uapsd_bk = BIT(0)|BIT(1);
1759 pstat->uapsd_bk = 0;
1761 if(pstat->qos_info&BIT(3))
1762 pstat->uapsd_be = BIT(0)|BIT(1);
1764 pstat->uapsd_be = 0;
1778 #ifdef CONFIG_80211N_HT
1779 /* save HT capabilities in the sta object */
1780 memset(&pstat->htpriv.ht_cap, 0, sizeof(struct rtw_ieee80211_ht_cap));
1781 if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct rtw_ieee80211_ht_cap))
1783 pstat->flags |= WLAN_STA_HT;
1785 pstat->flags |= WLAN_STA_WME;
1787 memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct rtw_ieee80211_ht_cap));
1790 pstat->flags &= ~WLAN_STA_HT;
1792 if((pmlmepriv->htpriv.ht_option == _FALSE) && (pstat->flags&WLAN_STA_HT))
1794 status = _STATS_FAILURE_;
1795 goto OnAssocReqFail;
1798 if ((pstat->flags & WLAN_STA_HT) &&
1799 ((pstat->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) ||
1800 (pstat->wpa_pairwise_cipher&WPA_CIPHER_TKIP)))
1802 DBG_8723A("HT: " MAC_FMT " tried to "
1803 "use TKIP with HT association\n", MAC_ARG(pstat->hwaddr));
1805 /* status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY; */
1806 /* goto OnAssocReqFail; */
1808 #endif /* CONFIG_80211N_HT */
1811 pstat->flags |= WLAN_STA_NONERP;
1812 for (i = 0; i < pstat->bssratelen; i++) {
1813 if ((pstat->bssrateset[i] & 0x7f) > 22) {
1814 pstat->flags &= ~WLAN_STA_NONERP;
1819 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
1820 pstat->flags |= WLAN_STA_SHORT_PREAMBLE;
1822 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE;
1824 if (status != _STATS_SUCCESSFUL_)
1825 goto OnAssocReqFail;
1828 pstat->is_p2p_device = _FALSE;
1829 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
1831 if( (p2pie=rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen)))
1833 pstat->is_p2p_device = _TRUE;
1834 if((p2p_status_code=(u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat))>0)
1836 pstat->p2p_status_code = p2p_status_code;
1837 status = _STATS_CAP_FAIL_;
1838 goto OnAssocReqFail;
1842 if(rtw_get_wfd_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , wfd_ie, &wfd_ielen ))
1844 u8 attr_content[ 10 ] = { 0x00 };
1845 u32 attr_contentlen = 0;
1847 DBG_8723A( "[%s] WFD IE Found!!\n", __FUNCTION__ );
1848 rtw_get_wfd_attr_content( wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, attr_content, &attr_contentlen);
1849 if ( attr_contentlen )
1851 pwdinfo->wfd_info->peer_rtsp_ctrlport = RTW_GET_BE16( attr_content + 2 );
1852 DBG_8723A( "[%s] Peer PORT NUM = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport );
1857 pstat->p2p_status_code = p2p_status_code;
1858 #endif /* CONFIG_P2P */
1860 /* TODO: identify_proprietary_vendor_ie(); */
1861 /* Realtek proprietary IE */
1862 /* identify if this is Broadcom sta */
1863 /* identify if this is ralink sta */
1864 /* Customer proprietary IE */
1866 /* get a unique AID */
1867 if (pstat->aid > 0) {
1868 DBG_8723A(" old AID %d\n", pstat->aid);
1870 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++)
1871 if (pstapriv->sta_aid[pstat->aid - 1] == NULL)
1874 if (pstat->aid > NUM_STA)
1875 pstat->aid = NUM_STA;
1876 if (pstat->aid > pstapriv->max_num_sta) {
1880 DBG_8723A(" no room for more AIDs\n");
1882 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
1884 goto OnAssocReqFail;
1887 pstapriv->sta_aid[pstat->aid - 1] = pstat;
1888 DBG_8723A("allocate new AID = (%d)\n", pstat->aid);
1892 pstat->state &= (~WIFI_FW_ASSOC_STATE);
1893 pstat->state |= WIFI_FW_ASSOC_SUCCESS;
1895 spin_lock_bh(&pstapriv->auth_list_lock);
1896 if (!rtw_is_list_empty(&pstat->auth_list))
1898 rtw_list_delete(&pstat->auth_list);
1899 pstapriv->auth_list_cnt--;
1901 spin_unlock_bh(&pstapriv->auth_list_lock);
1903 spin_lock_bh(&pstapriv->asoc_list_lock);
1904 if (rtw_is_list_empty(&pstat->asoc_list))
1906 pstat->expire_to = pstapriv->expire_to;
1907 rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list);
1908 pstapriv->asoc_list_cnt++;
1910 spin_unlock_bh(&pstapriv->asoc_list_lock);
1912 /* now the station is qualified to join our BSS... */
1913 if(pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_==status))
1915 #ifdef CONFIG_NATIVEAP_MLME
1916 /* 1 bss_cap_update & sta_info_update */
1917 bss_cap_update_on_sta_join(padapter, pstat);
1918 sta_info_update(padapter, pstat);
1920 /* issue assoc rsp before notify station join event. */
1921 if (frame_type == WIFI_ASSOCREQ)
1922 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
1924 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
1926 /* 2 - report to upper layer */
1927 DBG_8723A("indicate_sta_join_event to upper layer - hostapd\n");
1928 #ifdef CONFIG_IOCTL_CFG80211
1930 #ifdef COMPAT_KERNEL_RELEASE
1931 rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
1932 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
1933 rtw_cfg80211_indicate_sta_assoc(padapter, pframe, pkt_len);
1934 #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) */
1935 spin_lock_bh(&pstat->lock);
1936 if(pstat->passoc_req)
1938 rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
1939 pstat->passoc_req = NULL;
1940 pstat->assoc_req_len = 0;
1943 pstat->passoc_req = rtw_zmalloc(pkt_len);
1944 if(pstat->passoc_req)
1946 memcpy(pstat->passoc_req, pframe, pkt_len);
1947 pstat->assoc_req_len = pkt_len;
1949 spin_unlock_bh(&pstat->lock);
1950 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER) */
1953 #endif /* CONFIG_IOCTL_CFG80211 */
1955 rtw_indicate_sta_assoc_event(padapter, pstat);
1958 /* 3-(1) report sta add event */
1959 report_add_sta_event(padapter, pstat->hwaddr, pstat->aid);
1967 #ifdef CONFIG_NATIVEAP_MLME
1968 issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status);
1975 #ifdef CONFIG_NATIVEAP_MLME
1977 if (frame_type == WIFI_ASSOCREQ)
1978 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
1980 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
1983 #endif /* CONFIG_AP_MODE */
1988 unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame)
1992 unsigned short status;
1993 PNDIS_802_11_VARIABLE_IEs pIE;
1994 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1995 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1996 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1997 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
1998 u8 *pframe = precv_frame->u.hdr.rx_data;
1999 uint pkt_len = precv_frame->u.hdr.len;
2000 PNDIS_802_11_VARIABLE_IEs pWapiIE = NULL;
2002 DBG_8723A("%s\n", __FUNCTION__);
2004 /* check A1 matches or not */
2005 if (memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN))
2008 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)))
2011 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
2014 _cancel_timer_ex(&pmlmeext->link_timer);
2017 if ((status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2))) > 0)
2019 DBG_8723A("assoc reject, status code: %d\n", status);
2020 pmlmeinfo->state = WIFI_FW_NULL_STATE;
2022 goto report_assoc_result;
2025 /* get capabilities */
2026 pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2029 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10))? 9: 20;
2032 res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff);
2034 /* following are moved to join event callback function */
2035 /* to handle HT, WMM, rate adaptive, update MAC reg */
2036 /* for not to handle the synchronous IO in the tasklet */
2037 for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;)
2039 pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
2041 switch (pIE->ElementID)
2043 case _VENDOR_SPECIFIC_IE_:
2044 if (!memcmp(pIE->data, WMM_PARA_OUI, 6))/* WMM */
2046 WMM_param_handler(padapter, pIE);
2048 #if defined(CONFIG_P2P) && defined(CONFIG_WFD)
2049 else if (!memcmp(pIE->data, WFD_OUI, 4))/* WFD */
2051 DBG_8723A( "[%s] Found WFD IE\n", __FUNCTION__ );
2052 WFD_info_handler( padapter, pIE );
2057 #ifdef CONFIG_WAPI_SUPPORT
2063 case _HT_CAPABILITY_IE_: /* HT caps */
2064 HT_caps_handler(padapter, pIE);
2067 case _HT_EXTRA_INFO_IE_: /* HT info */
2068 HT_info_handler(padapter, pIE);
2072 ERP_IE_handler(padapter, pIE);
2078 i += (pIE->Length + 2);
2081 #ifdef CONFIG_WAPI_SUPPORT
2082 rtw_wapi_on_assoc_ok(padapter, pIE);
2085 pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
2086 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
2088 /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
2089 UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
2091 report_assoc_result:
2093 rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
2095 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
2098 report_join_res(padapter, res);
2103 unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame)
2105 unsigned short reason;
2106 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2107 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2108 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2109 u8 *pframe = precv_frame->u.hdr.rx_data;
2111 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
2112 #endif /* CONFIG_P2P */
2115 if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network),
2120 if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
2122 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
2123 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
2125 #endif /* CONFIG_P2P */
2127 reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2129 DBG_8723A("%s Reason code(%d)\n", __FUNCTION__,reason);
2131 #ifdef CONFIG_AP_MODE
2132 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
2135 struct sta_info *psta;
2136 struct sta_priv *pstapriv = &padapter->stapriv;
2138 /* spin_lock_bh(&(pstapriv->sta_hash_lock)); */
2139 /* rtw_free_stainfo(padapter, psta); */
2140 /* spin_unlock_bh(&(pstapriv->sta_hash_lock)); */
2142 DBG_8723A_LEVEL(_drv_always_, "ap recv deauth reason code(%d) sta:%pM\n",
2143 reason, GetAddr2Ptr(pframe));
2145 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2150 spin_lock_bh(&pstapriv->asoc_list_lock);
2151 if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
2153 rtw_list_delete(&psta->asoc_list);
2154 pstapriv->asoc_list_cnt--;
2155 updated = ap_free_sta(padapter, psta, _FALSE, reason);
2158 spin_unlock_bh(&pstapriv->asoc_list_lock);
2160 associated_clients_update(padapter, updated);
2168 DBG_8723A_LEVEL(_drv_always_, "sta recv deauth reason code(%d) sta:%pM\n",
2169 reason, GetAddr3Ptr(pframe));
2171 receive_disconnect(padapter, GetAddr3Ptr(pframe) ,reason);
2173 pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
2177 unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame)
2179 unsigned short reason;
2180 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2181 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2182 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2183 u8 *pframe = precv_frame->u.hdr.rx_data;
2185 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
2186 #endif /* CONFIG_P2P */
2189 if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
2193 if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
2195 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
2196 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
2198 #endif /* CONFIG_P2P */
2200 reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2202 DBG_8723A("%s Reason code(%d)\n", __FUNCTION__,reason);
2204 #ifdef CONFIG_AP_MODE
2205 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
2208 struct sta_info *psta;
2209 struct sta_priv *pstapriv = &padapter->stapriv;
2211 /* spin_lock_bh(&(pstapriv->sta_hash_lock)); */
2212 /* rtw_free_stainfo(padapter, psta); */
2213 /* spin_unlock_bh(&(pstapriv->sta_hash_lock)); */
2215 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n",
2216 reason, GetAddr2Ptr(pframe));
2218 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2223 spin_lock_bh(&pstapriv->asoc_list_lock);
2224 if(rtw_is_list_empty(&psta->asoc_list)==_FALSE)
2226 rtw_list_delete(&psta->asoc_list);
2227 pstapriv->asoc_list_cnt--;
2228 updated = ap_free_sta(padapter, psta, _FALSE, reason);
2231 spin_unlock_bh(&pstapriv->asoc_list_lock);
2233 associated_clients_update(padapter, updated);
2241 DBG_8723A_LEVEL(_drv_always_, "ap recv disassoc reason code(%d) sta:%pM\n",
2242 reason, GetAddr3Ptr(pframe));
2244 receive_disconnect(padapter, GetAddr3Ptr(pframe), reason);
2246 pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
2250 unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame)
2252 DBG_8723A("%s\n", __FUNCTION__);
2256 unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len)
2258 unsigned int ret = _FAIL;
2259 struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
2260 struct mlme_ext_info *pmlmeinfo = &(mlmeext->mlmext_info);
2262 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
2267 if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
2269 int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1;
2272 struct ieee80211_info_element *ie;
2274 DBG_8723A(FUNC_NDEV_FMT" from "MAC_FMT"\n",
2275 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->hwaddr));
2277 for_each_ie(ie, ies, ies_len) {
2278 if (ie->id == WLAN_EID_CHANNEL_SWITCH) {
2279 ch_switch_mode = ie->data[0];
2281 ch_switch_cnt = ie->data[2];
2282 DBG_8723A("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n",
2283 ch_switch_mode, ch, ch_switch_cnt);
2285 else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) {
2286 ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]);
2287 DBG_8723A("ch_offset:%d\n", ch_offset);
2294 if (ch_offset == -1)
2295 bwmode = mlmeext->cur_bwmode;
2297 bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ?
2298 HT_CHANNEL_WIDTH_20 : HT_CHANNEL_WIDTH_40;
2300 ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset;
2303 * 1. the decision of channel switching
2304 * 2. things after channel switching
2307 ret = rtw_set_ch_cmd(padapter, ch, bwmode, ch_offset, _TRUE);
2314 unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame)
2316 unsigned int ret = _FAIL;
2317 struct sta_info *psta = NULL;
2318 struct sta_priv *pstapriv = &padapter->stapriv;
2319 u8 *pframe = precv_frame->u.hdr.rx_data;
2320 uint frame_len = precv_frame->u.hdr.len;
2321 u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
2325 DBG_8723A(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(padapter->pnetdev));
2327 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
2332 category = frame_body[0];
2333 if(category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
2336 action = frame_body[1];
2338 case RTW_WLAN_ACTION_SPCT_MSR_REQ:
2339 case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
2340 case RTW_WLAN_ACTION_SPCT_TPC_REQ:
2341 case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
2343 case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
2344 #ifdef CONFIG_SPCT_CH_SWITCH
2345 ret = on_action_spct_ch_switch(padapter, psta, &frame_body[2],
2346 frame_len-(frame_body-pframe)-2);
2357 unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame)
2362 unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame)
2367 unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame)
2370 struct sta_info *psta=NULL;
2371 struct recv_reorder_ctrl *preorder_ctrl;
2372 unsigned char *frame_body;
2373 unsigned char category, action;
2374 unsigned short tid, status, reason_code = 0;
2375 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2376 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2377 u8 *pframe = precv_frame->u.hdr.rx_data;
2378 struct sta_priv *pstapriv = &padapter->stapriv;
2379 #ifdef CONFIG_80211N_HT
2380 /* check RA matches or not */
2381 if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))/* for if1, sta/ap mode */
2384 DBG_8723A("%s\n", __FUNCTION__);
2386 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
2387 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
2390 addr = GetAddr2Ptr(pframe);
2391 psta = rtw_get_stainfo(pstapriv, addr);
2396 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
2398 category = frame_body[0];
2399 if (category == RTW_WLAN_CATEGORY_BACK)/* representing Block Ack */
2402 if((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
2403 (psta->htpriv.ht_option==_TRUE) &&
2404 (psta->htpriv.ampdu_enable==_TRUE) )
2406 /* do nothing; just don't want to return _SUCCESS; */
2408 #endif /* CONFIG_TDLS */
2409 if (!pmlmeinfo->HT_enable)
2411 action = frame_body[1];
2412 DBG_8723A("%s, action=%d\n", __FUNCTION__, action);
2414 case RTW_WLAN_ACTION_ADDBA_REQ: /* ADDBA request */
2415 memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
2416 /* process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe)); */
2417 process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), addr);
2419 if(pmlmeinfo->bAcceptAddbaReq == _TRUE)
2420 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 0);
2422 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_ADDBA_RESP, 37);/* reject ADDBA Req */
2424 case RTW_WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
2425 status = RTW_GET_LE16(&frame_body[3]);
2426 tid = ((frame_body[5] >> 2) & 0x7);
2427 if (status == 0) { /* successful */
2428 DBG_8723A("agg_enable for TID=%d\n", tid);
2429 psta->htpriv.agg_enable_bitmap |= 1 << tid;
2430 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
2432 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
2436 case RTW_WLAN_ACTION_DELBA: /* DELBA */
2437 if ((frame_body[3] & BIT(3)) == 0) {
2438 psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
2439 psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
2441 /* reason_code = frame_body[4] | (frame_body[5] << 8); */
2442 reason_code = RTW_GET_LE16(&frame_body[4]);
2443 } else if((frame_body[3] & BIT(3)) == BIT(3)) {
2444 tid = (frame_body[3] >> 4) & 0x0F;
2446 preorder_ctrl = &psta->recvreorder_ctrl[tid];
2447 preorder_ctrl->enable = _FALSE;
2448 preorder_ctrl->indicate_seq = 0xffff;
2450 DBG_8723A("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
2451 preorder_ctrl->indicate_seq);
2455 DBG_8723A("%s(): DELBA: %x(%x)\n", __FUNCTION__,pmlmeinfo->agg_enable_bitmap, reason_code);
2456 /* todo: how to notify the host while receiving DELETE BA */
2462 #endif /* CONFIG_80211N_HT */
2468 static int get_reg_classes_full_count(struct p2p_channels channel_list) {
2472 for (i = 0; i < channel_list.reg_classes; i++) {
2473 cnt += channel_list.reg_class[i].channels;
2479 static void get_channel_cnt_24g_5gl_5gh( struct mlme_ext_priv *pmlmeext, u8* p24g_cnt, u8* p5gl_cnt, u8* p5gh_cnt )
2487 for( i = 0; i < pmlmeext->max_chan_nums; i++ )
2489 if ( pmlmeext->channel_set[ i ].ChannelNum <= 14 )
2493 else if ( ( pmlmeext->channel_set[ i ].ChannelNum > 14 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 48 ) )
2495 /* Just include the channel 36, 40, 44, 48 channels for 5G low */
2498 else if ( ( pmlmeext->channel_set[ i ].ChannelNum >= 149 ) && ( pmlmeext->channel_set[ i ].ChannelNum <= 161 ) )
2500 /* Just include the channel 149, 153, 157, 161 channels for 5G high */
2506 void issue_p2p_GO_request(_adapter *padapter, u8* raddr)
2509 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
2510 u8 action = P2P_PUB_ACTION_ACTION;
2511 u32 p2poui = cpu_to_be32(P2POUI);
2512 u8 oui_subtype = P2P_GO_NEGO_REQ;
2513 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
2514 u8 wpsielen = 0, p2pielen = 0, i;
2515 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
2516 u16 len_channellist_attr = 0;
2519 #endif /* CONFIG_WFD */
2521 struct xmit_frame *pmgntframe;
2522 struct pkt_attrib *pattrib;
2523 unsigned char *pframe;
2524 struct rtw_ieee80211_hdr *pwlanhdr;
2525 unsigned short *fctrl;
2526 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2527 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2528 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2529 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
2531 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
2536 DBG_8723A( "[%s] In\n", __FUNCTION__ );
2537 /* update attribute */
2538 pattrib = &pmgntframe->attrib;
2539 update_mgntframe_attrib(padapter, pattrib);
2541 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2543 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2544 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
2546 fctrl = &(pwlanhdr->frame_ctl);
2549 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
2550 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
2551 memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
2553 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2554 pmlmeext->mgnt_seq++;
2555 SetFrameSubType(pframe, WIFI_ACTION);
2557 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
2558 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
2560 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
2561 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
2562 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
2563 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
2564 pwdinfo->negotiation_dialog_token = 1; /* Initialize the dialog value */
2565 pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen));
2570 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
2575 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
2579 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
2583 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
2585 /* Device Password ID */
2587 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
2591 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
2596 if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN )
2598 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
2600 else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN )
2602 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
2604 else if ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC )
2606 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
2611 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
2613 /* P2P IE Section. */
2617 p2pie[ p2pielen++ ] = 0x50;
2618 p2pie[ p2pielen++ ] = 0x6F;
2619 p2pie[ p2pielen++ ] = 0x9A;
2620 p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
2622 /* Commented by Albert 20110306 */
2623 /* According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes */
2624 /* 1. P2P Capability */
2625 /* 2. Group Owner Intent */
2626 /* 3. Configuration Timeout */
2627 /* 4. Listen Channel */
2628 /* 5. Extended Listen Timing */
2629 /* 6. Intended P2P Interface Address */
2630 /* 7. Channel List */
2631 /* 8. P2P Device Info */
2632 /* 9. Operating Channel */
2634 /* P2P Capability */
2636 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
2639 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
2643 /* Device Capability Bitmap, 1 byte */
2644 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
2646 /* Group Capability Bitmap, 1 byte */
2647 if ( pwdinfo->persistent_supported )
2649 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
2653 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
2656 /* Group Owner Intent */
2658 p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
2661 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
2665 /* Todo the tie breaker bit. */
2666 p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
2668 /* Configuration Timeout */
2670 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
2673 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
2677 p2pie[ p2pielen++ ] = 200; /* 2 seconds needed to be the P2P GO */
2678 p2pie[ p2pielen++ ] = 200; /* 2 seconds needed to be the P2P Client */
2680 /* Listen Channel */
2682 p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
2685 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
2689 /* Country String */
2690 p2pie[ p2pielen++ ] = 'X';
2691 p2pie[ p2pielen++ ] = 'X';
2693 /* The third byte should be set to 0x04. */
2694 /* Described in the "Operating Channel Attribute" section. */
2695 p2pie[ p2pielen++ ] = 0x04;
2697 /* Operating Class */
2698 p2pie[ p2pielen++ ] = 0x51; /* Copy from SD7 */
2700 /* Channel Number */
2701 p2pie[ p2pielen++ ] = pwdinfo->listen_channel; /* listening channel number */
2703 /* Extended Listen Timing ATTR */
2705 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
2708 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
2712 /* Availability Period */
2713 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
2716 /* Availability Interval */
2717 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
2720 /* Intended P2P Interface Address */
2722 p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
2725 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
2729 memcpy(p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
2730 p2pielen += ETH_ALEN;
2734 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
2737 /* Country String(3) */
2738 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
2739 /* + number of channels in all classes */
2740 len_channellist_attr = 3
2741 + (1 + 1) * (u16)(pmlmeext->channel_list.reg_classes)
2742 + get_reg_classes_full_count(pmlmeext->channel_list);
2744 #ifdef CONFIG_CONCURRENT_MODE
2745 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
2747 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
2751 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
2755 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
2761 /* Country String */
2762 p2pie[ p2pielen++ ] = 'X';
2763 p2pie[ p2pielen++ ] = 'X';
2765 /* The third byte should be set to 0x04. */
2766 /* Described in the "Operating Channel Attribute" section. */
2767 p2pie[ p2pielen++ ] = 0x04;
2769 /* Channel Entry List */
2771 #ifdef CONFIG_CONCURRENT_MODE
2772 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
2774 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
2775 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
2777 /* Operating Class */
2778 if ( pbuddy_mlmeext->cur_channel > 14 )
2780 if ( pbuddy_mlmeext->cur_channel >= 149 )
2782 p2pie[ p2pielen++ ] = 0x7c;
2786 p2pie[ p2pielen++ ] = 0x73;
2791 p2pie[ p2pielen++ ] = 0x51;
2794 /* Number of Channels */
2795 /* Just support 1 channel and this channel is AP's channel */
2796 p2pie[ p2pielen++ ] = 1;
2799 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
2804 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
2805 /* Operating Class */
2806 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
2808 /* Number of Channels */
2809 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
2812 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
2813 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
2817 #else /* CONFIG_CONCURRENT_MODE */
2820 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
2821 /* Operating Class */
2822 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
2824 /* Number of Channels */
2825 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
2828 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
2829 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
2833 #endif /* CONFIG_CONCURRENT_MODE */
2837 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
2840 /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
2841 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
2842 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
2846 /* P2P Device Address */
2847 memcpy(p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
2848 p2pielen += ETH_ALEN;
2851 /* This field should be big endian. Noted by P2P specification. */
2853 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
2857 /* Primary Device Type */
2859 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
2863 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
2866 /* Sub Category ID */
2867 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
2870 /* Number of Secondary Device Types */
2871 p2pie[ p2pielen++ ] = 0x00; /* No Secondary Device Type List */
2875 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
2879 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
2883 memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
2884 p2pielen += pwdinfo->device_name_len;
2886 /* Operating Channel */
2888 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
2891 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
2895 /* Country String */
2896 p2pie[ p2pielen++ ] = 'X';
2897 p2pie[ p2pielen++ ] = 'X';
2899 /* The third byte should be set to 0x04. */
2900 /* Described in the "Operating Channel Attribute" section. */
2901 p2pie[ p2pielen++ ] = 0x04;
2903 /* Operating Class */
2904 if ( pwdinfo->operating_channel <= 14 )
2906 /* Operating Class */
2907 p2pie[ p2pielen++ ] = 0x51;
2909 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
2911 /* Operating Class */
2912 p2pie[ p2pielen++ ] = 0x73;
2916 /* Operating Class */
2917 p2pie[ p2pielen++ ] = 0x7c;
2920 /* Channel Number */
2921 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; /* operating channel number */
2923 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
2926 wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
2928 pattrib->pktlen += wfdielen;
2929 #endif /* CONFIG_WFD */
2931 pattrib->last_txcmdsz = pattrib->pktlen;
2933 dump_mgntframe(padapter, pmgntframe);
2938 void issue_p2p_GO_response(_adapter *padapter, u8* raddr, u8* frame_body,uint len, u8 result)
2941 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
2942 u8 action = P2P_PUB_ACTION_ACTION;
2943 u32 p2poui = cpu_to_be32(P2POUI);
2944 u8 oui_subtype = P2P_GO_NEGO_RESP;
2945 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
2948 u16 wps_devicepassword_id = 0x0000;
2949 uint wps_devicepassword_id_len = 0;
2950 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh;
2951 u16 len_channellist_attr = 0;
2953 struct xmit_frame *pmgntframe;
2954 struct pkt_attrib *pattrib;
2955 unsigned char *pframe;
2956 struct rtw_ieee80211_hdr *pwlanhdr;
2957 unsigned short *fctrl;
2958 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
2959 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2960 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2961 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
2965 #endif /* CONFIG_WFD */
2967 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
2972 DBG_8723A( "[%s] In, result = %d\n", __FUNCTION__, result );
2973 /* update attribute */
2974 pattrib = &pmgntframe->attrib;
2975 update_mgntframe_attrib(padapter, pattrib);
2977 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
2979 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
2980 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
2982 fctrl = &(pwlanhdr->frame_ctl);
2985 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
2986 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
2987 memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
2989 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
2990 pmlmeext->mgnt_seq++;
2991 SetFrameSubType(pframe, WIFI_ACTION);
2993 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
2994 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
2996 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
2997 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
2998 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
2999 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
3000 pwdinfo->negotiation_dialog_token = frame_body[7]; /* The Dialog Token of provisioning discovery request frame. */
3001 pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
3003 /* Commented by Albert 20110328 */
3004 /* Try to get the device password ID from the WPS IE of group negotiation request frame */
3005 /* WiFi Direct test plan 5.1.15 */
3006 rtw_get_wps_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
3007 rtw_get_wps_attr_content( wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8*) &wps_devicepassword_id, &wps_devicepassword_id_len);
3008 wps_devicepassword_id = be16_to_cpu( wps_devicepassword_id );
3010 memset( wpsie, 0x00, 255 );
3016 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
3021 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
3025 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
3029 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
3031 /* Device Password ID */
3033 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
3037 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
3041 if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
3043 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC );
3045 else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
3047 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_USER_SPEC );
3051 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_PBC );
3055 /* Commented by Kurt 20120113 */
3056 /* If some device wants to do p2p handshake without sending prov_disc_req */
3057 /* We have to get peer_req_cm from here. */
3058 if (!memcmp( pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3) )
3060 if ( wps_devicepassword_id == WPS_DPID_USER_SPEC )
3062 memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3 );
3064 else if ( wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC )
3066 memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3 );
3070 memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3 );
3074 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
3076 /* P2P IE Section. */
3080 p2pie[ p2pielen++ ] = 0x50;
3081 p2pie[ p2pielen++ ] = 0x6F;
3082 p2pie[ p2pielen++ ] = 0x9A;
3083 p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
3085 /* Commented by Albert 20100908 */
3086 /* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
3088 /* 2. P2P Capability */
3089 /* 3. Group Owner Intent */
3090 /* 4. Configuration Timeout */
3091 /* 5. Operating Channel */
3092 /* 6. Intended P2P Interface Address */
3093 /* 7. Channel List */
3094 /* 8. Device Info */
3095 /* 9. Group ID ( Only GO ) */
3101 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
3104 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3108 p2pie[ p2pielen++ ] = result;
3110 /* P2P Capability */
3112 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
3115 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3119 /* Device Capability Bitmap, 1 byte */
3121 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
3123 /* Commented by Albert 2011/03/08 */
3124 /* According to the P2P specification */
3125 /* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
3126 p2pie[ p2pielen++ ] = 0;
3130 /* Be group owner or meet the error case */
3131 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
3134 /* Group Capability Bitmap, 1 byte */
3135 if ( pwdinfo->persistent_supported )
3137 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
3141 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
3144 /* Group Owner Intent */
3146 p2pie[ p2pielen++ ] = P2P_ATTR_GO_INTENT;
3149 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3153 if ( pwdinfo->peer_intent & 0x01 )
3155 /* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
3156 p2pie[ p2pielen++ ] = ( pwdinfo->intent << 1 );
3160 /* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
3161 p2pie[ p2pielen++ ] = ( ( pwdinfo->intent << 1 ) | BIT(0) );
3164 /* Configuration Timeout */
3166 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
3169 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3173 p2pie[ p2pielen++ ] = 200; /* 2 seconds needed to be the P2P GO */
3174 p2pie[ p2pielen++ ] = 200; /* 2 seconds needed to be the P2P Client */
3176 /* Operating Channel */
3178 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
3181 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
3185 /* Country String */
3186 p2pie[ p2pielen++ ] = 'X';
3187 p2pie[ p2pielen++ ] = 'X';
3189 /* The third byte should be set to 0x04. */
3190 /* Described in the "Operating Channel Attribute" section. */
3191 p2pie[ p2pielen++ ] = 0x04;
3193 /* Operating Class */
3194 if ( pwdinfo->operating_channel <= 14 )
3196 /* Operating Class */
3197 p2pie[ p2pielen++ ] = 0x51;
3199 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
3201 /* Operating Class */
3202 p2pie[ p2pielen++ ] = 0x73;
3206 /* Operating Class */
3207 p2pie[ p2pielen++ ] = 0x7c;
3210 /* Channel Number */
3211 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; /* operating channel number */
3213 /* Intended P2P Interface Address */
3215 p2pie[ p2pielen++ ] = P2P_ATTR_INTENTED_IF_ADDR;
3218 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
3222 memcpy(p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
3223 p2pielen += ETH_ALEN;
3227 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
3229 /* Country String(3) */
3230 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
3231 /* + number of channels in all classes */
3232 len_channellist_attr = 3
3233 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
3234 + get_reg_classes_full_count(pmlmeext->channel_list);
3236 #ifdef CONFIG_CONCURRENT_MODE
3237 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3239 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
3243 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3247 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3253 /* Country String */
3254 p2pie[ p2pielen++ ] = 'X';
3255 p2pie[ p2pielen++ ] = 'X';
3257 /* The third byte should be set to 0x04. */
3258 /* Described in the "Operating Channel Attribute" section. */
3259 p2pie[ p2pielen++ ] = 0x04;
3261 /* Channel Entry List */
3263 #ifdef CONFIG_CONCURRENT_MODE
3264 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3266 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
3267 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3269 /* Operating Class */
3270 if ( pbuddy_mlmeext->cur_channel > 14 )
3272 if ( pbuddy_mlmeext->cur_channel >= 149 )
3274 p2pie[ p2pielen++ ] = 0x7c;
3278 p2pie[ p2pielen++ ] = 0x73;
3283 p2pie[ p2pielen++ ] = 0x51;
3286 /* Number of Channels */
3287 /* Just support 1 channel and this channel is AP's channel */
3288 p2pie[ p2pielen++ ] = 1;
3291 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
3296 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
3297 /* Operating Class */
3298 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
3300 /* Number of Channels */
3301 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
3304 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
3305 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
3309 #else /* CONFIG_CONCURRENT_MODE */
3312 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
3313 /* Operating Class */
3314 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
3316 /* Number of Channels */
3317 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
3320 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
3321 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
3325 #endif /* CONFIG_CONCURRENT_MODE */
3329 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
3332 /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
3333 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
3334 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
3338 /* P2P Device Address */
3339 memcpy(p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
3340 p2pielen += ETH_ALEN;
3343 /* This field should be big endian. Noted by P2P specification. */
3345 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
3349 /* Primary Device Type */
3351 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
3355 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
3358 /* Sub Category ID */
3359 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
3362 /* Number of Secondary Device Types */
3363 p2pie[ p2pielen++ ] = 0x00; /* No Secondary Device Type List */
3367 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
3371 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
3375 memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len );
3376 p2pielen += pwdinfo->device_name_len;
3378 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
3380 /* Group ID Attribute */
3382 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
3385 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
3389 /* p2P Device Address */
3390 memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
3391 p2pielen += ETH_ALEN;
3394 memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
3395 p2pielen += pwdinfo->nego_ssidlen;
3399 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
3402 wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
3404 pattrib->pktlen += wfdielen;
3405 #endif /* CONFIG_WFD */
3407 pattrib->last_txcmdsz = pattrib->pktlen;
3409 dump_mgntframe(padapter, pmgntframe);
3414 void issue_p2p_GO_confirm(_adapter *padapter, u8* raddr, u8 result)
3417 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3418 u8 action = P2P_PUB_ACTION_ACTION;
3419 u32 p2poui = cpu_to_be32(P2POUI);
3420 u8 oui_subtype = P2P_GO_NEGO_CONF;
3421 u8 wpsie[ 255 ] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
3422 u8 wpsielen = 0, p2pielen = 0;
3424 struct xmit_frame *pmgntframe;
3425 struct pkt_attrib *pattrib;
3426 unsigned char *pframe;
3427 struct rtw_ieee80211_hdr *pwlanhdr;
3428 unsigned short *fctrl;
3429 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3430 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3431 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3432 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
3435 #endif /* CONFIG_WFD */
3437 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3442 DBG_8723A( "[%s] In\n", __FUNCTION__ );
3443 /* update attribute */
3444 pattrib = &pmgntframe->attrib;
3445 update_mgntframe_attrib(padapter, pattrib);
3447 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3449 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3450 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3452 fctrl = &(pwlanhdr->frame_ctl);
3455 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3456 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3457 memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
3459 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3460 pmlmeext->mgnt_seq++;
3461 SetFrameSubType(pframe, WIFI_ACTION);
3463 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3464 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3466 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3467 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3468 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
3469 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
3470 pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
3472 /* P2P IE Section. */
3476 p2pie[ p2pielen++ ] = 0x50;
3477 p2pie[ p2pielen++ ] = 0x6F;
3478 p2pie[ p2pielen++ ] = 0x9A;
3479 p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
3481 /* Commented by Albert 20110306 */
3482 /* According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes */
3484 /* 2. P2P Capability */
3485 /* 3. Operating Channel */
3486 /* 4. Channel List */
3487 /* 5. Group ID ( if this WiFi is GO ) */
3491 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
3494 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3498 p2pie[ p2pielen++ ] = result;
3500 /* P2P Capability */
3502 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
3505 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3509 /* Device Capability Bitmap, 1 byte */
3510 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
3512 /* Group Capability Bitmap, 1 byte */
3513 if ( pwdinfo->persistent_supported )
3515 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
3519 p2pie[ p2pielen++ ] = P2P_GRPCAP_CROSS_CONN;
3522 /* Operating Channel */
3524 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
3527 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
3531 /* Country String */
3532 p2pie[ p2pielen++ ] = 'X';
3533 p2pie[ p2pielen++ ] = 'X';
3535 /* The third byte should be set to 0x04. */
3536 /* Described in the "Operating Channel Attribute" section. */
3537 p2pie[ p2pielen++ ] = 0x04;
3539 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) )
3541 if ( pwdinfo->peer_operating_ch <= 14 )
3543 /* Operating Class */
3544 p2pie[ p2pielen++ ] = 0x51;
3546 else if ( ( pwdinfo->peer_operating_ch >= 36 ) && ( pwdinfo->peer_operating_ch <= 48 ) )
3548 /* Operating Class */
3549 p2pie[ p2pielen++ ] = 0x73;
3553 /* Operating Class */
3554 p2pie[ p2pielen++ ] = 0x7c;
3557 p2pie[ p2pielen++ ] = pwdinfo->peer_operating_ch;
3561 if ( pwdinfo->operating_channel <= 14 )
3563 /* Operating Class */
3564 p2pie[ p2pielen++ ] = 0x51;
3566 else if ( ( pwdinfo->operating_channel >= 36 ) && ( pwdinfo->operating_channel <= 48 ) )
3568 /* Operating Class */
3569 p2pie[ p2pielen++ ] = 0x73;
3573 /* Operating Class */
3574 p2pie[ p2pielen++ ] = 0x7c;
3577 /* Channel Number */
3578 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; /* Use the listen channel as the operating channel */
3583 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
3586 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( pwdinfo->channel_list_attr_len );
3590 memcpy(p2pie + p2pielen, pwdinfo->channel_list_attr, pwdinfo->channel_list_attr_len );
3591 p2pielen += pwdinfo->channel_list_attr_len;
3593 if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
3595 /* Group ID Attribute */
3597 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
3600 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN + pwdinfo->nego_ssidlen );
3604 /* p2P Device Address */
3605 memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN );
3606 p2pielen += ETH_ALEN;
3609 memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen );
3610 p2pielen += pwdinfo->nego_ssidlen;
3613 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
3616 wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
3618 pattrib->pktlen += wfdielen;
3619 #endif /* CONFIG_WFD */
3621 pattrib->last_txcmdsz = pattrib->pktlen;
3623 dump_mgntframe(padapter, pmgntframe);
3628 void issue_p2p_invitation_request(_adapter *padapter, u8* raddr )
3631 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3632 u8 action = P2P_PUB_ACTION_ACTION;
3633 u32 p2poui = cpu_to_be32(P2POUI);
3634 u8 oui_subtype = P2P_INVIT_REQ;
3635 u8 p2pie[ 255 ] = { 0x00 };
3638 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
3639 u16 len_channellist_attr = 0;
3642 #endif /* CONFIG_WFD */
3643 #ifdef CONFIG_CONCURRENT_MODE
3644 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
3645 struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
3646 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
3647 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3650 struct xmit_frame *pmgntframe;
3651 struct pkt_attrib *pattrib;
3652 unsigned char *pframe;
3653 struct rtw_ieee80211_hdr *pwlanhdr;
3654 unsigned short *fctrl;
3655 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3656 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3657 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3658 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
3660 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
3665 /* update attribute */
3666 pattrib = &pmgntframe->attrib;
3667 update_mgntframe_attrib(padapter, pattrib);
3669 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3671 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3672 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3674 fctrl = &(pwlanhdr->frame_ctl);
3677 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3678 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
3679 memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
3681 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3682 pmlmeext->mgnt_seq++;
3683 SetFrameSubType(pframe, WIFI_ACTION);
3685 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3686 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3688 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3689 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3690 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
3691 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
3692 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
3694 /* P2P IE Section. */
3698 p2pie[ p2pielen++ ] = 0x50;
3699 p2pie[ p2pielen++ ] = 0x6F;
3700 p2pie[ p2pielen++ ] = 0x9A;
3701 p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
3703 /* Commented by Albert 20101011 */
3704 /* According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes */
3705 /* 1. Configuration Timeout */
3706 /* 2. Invitation Flags */
3707 /* 3. Operating Channel ( Only GO ) */
3708 /* 4. P2P Group BSSID ( Should be included if I am the GO ) */
3709 /* 5. Channel List */
3710 /* 6. P2P Group ID */
3711 /* 7. P2P Device Info */
3713 /* Configuration Timeout */
3715 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
3718 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
3722 p2pie[ p2pielen++ ] = 200; /* 2 seconds needed to be the P2P GO */
3723 p2pie[ p2pielen++ ] = 200; /* 2 seconds needed to be the P2P Client */
3725 /* Invitation Flags */
3727 p2pie[ p2pielen++ ] = P2P_ATTR_INVITATION_FLAGS;
3730 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
3734 p2pie[ p2pielen++ ] = P2P_INVITATION_FLAGS_PERSISTENT;
3736 /* Operating Channel */
3738 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
3741 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
3745 /* Country String */
3746 p2pie[ p2pielen++ ] = 'X';
3747 p2pie[ p2pielen++ ] = 'X';
3749 /* The third byte should be set to 0x04. */
3750 /* Described in the "Operating Channel Attribute" section. */
3751 p2pie[ p2pielen++ ] = 0x04;
3753 /* Operating Class */
3754 if ( pwdinfo->invitereq_info.operating_ch <= 14 )
3755 p2pie[ p2pielen++ ] = 0x51;
3756 else if ( ( pwdinfo->invitereq_info.operating_ch >= 36 ) && ( pwdinfo->invitereq_info.operating_ch <= 48 ) )
3757 p2pie[ p2pielen++ ] = 0x73;
3759 p2pie[ p2pielen++ ] = 0x7c;
3761 /* Channel Number */
3762 p2pie[ p2pielen++ ] = pwdinfo->invitereq_info.operating_ch; /* operating channel number */
3764 if (!memcmp(myid(&padapter->eeprompriv),
3765 pwdinfo->invitereq_info.go_bssid, ETH_ALEN))
3767 /* P2P Group BSSID */
3769 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
3772 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
3776 /* P2P Device Address for GO */
3777 memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
3778 p2pielen += ETH_ALEN;
3783 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
3786 /* Country String(3) */
3787 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
3788 /* + number of channels in all classes */
3789 len_channellist_attr = 3
3790 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
3791 + get_reg_classes_full_count(pmlmeext->channel_list);
3793 #ifdef CONFIG_CONCURRENT_MODE
3794 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3796 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
3800 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3804 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
3810 /* Country String */
3811 p2pie[ p2pielen++ ] = 'X';
3812 p2pie[ p2pielen++ ] = 'X';
3814 /* The third byte should be set to 0x04. */
3815 /* Described in the "Operating Channel Attribute" section. */
3816 p2pie[ p2pielen++ ] = 0x04;
3818 /* Channel Entry List */
3819 #ifdef CONFIG_CONCURRENT_MODE
3820 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
3822 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
3823 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3825 /* Operating Class */
3826 if ( pbuddy_mlmeext->cur_channel > 14 )
3828 if ( pbuddy_mlmeext->cur_channel >= 149 )
3830 p2pie[ p2pielen++ ] = 0x7c;
3834 p2pie[ p2pielen++ ] = 0x73;
3839 p2pie[ p2pielen++ ] = 0x51;
3842 /* Number of Channels */
3843 /* Just support 1 channel and this channel is AP's channel */
3844 p2pie[ p2pielen++ ] = 1;
3847 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
3852 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
3853 /* Operating Class */
3854 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
3856 /* Number of Channels */
3857 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
3860 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
3861 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
3865 #else /* CONFIG_CONCURRENT_MODE */
3868 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
3869 /* Operating Class */
3870 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
3872 /* Number of Channels */
3873 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
3876 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
3877 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
3881 #endif /* CONFIG_CONCURRENT_MODE */
3885 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_ID;
3888 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 6 + pwdinfo->invitereq_info.ssidlen );
3892 /* P2P Device Address for GO */
3893 memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN );
3894 p2pielen += ETH_ALEN;
3897 memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen );
3898 p2pielen += pwdinfo->invitereq_info.ssidlen;
3902 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
3905 /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
3906 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
3907 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
3911 /* P2P Device Address */
3912 memcpy(p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
3913 p2pielen += ETH_ALEN;
3916 /* This field should be big endian. Noted by P2P specification. */
3917 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
3920 /* Primary Device Type */
3922 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
3926 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
3929 /* Sub Category ID */
3930 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
3933 /* Number of Secondary Device Types */
3934 p2pie[ p2pielen++ ] = 0x00; /* No Secondary Device Type List */
3938 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
3942 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
3946 memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
3947 p2pielen += pwdinfo->device_name_len;
3949 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
3952 wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
3954 pattrib->pktlen += wfdielen;
3955 #endif /* CONFIG_WFD */
3957 pattrib->last_txcmdsz = pattrib->pktlen;
3959 dump_mgntframe(padapter, pmgntframe);
3964 void issue_p2p_invitation_response(_adapter *padapter, u8* raddr, u8 dialogToken, u8 status_code)
3967 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3968 u8 action = P2P_PUB_ACTION_ACTION;
3969 u32 p2poui = cpu_to_be32(P2POUI);
3970 u8 oui_subtype = P2P_INVIT_RESP;
3971 u8 p2pie[ 255 ] = { 0x00 };
3973 u8 channel_cnt_24g = 0, channel_cnt_5gl = 0, channel_cnt_5gh = 0;
3974 u16 len_channellist_attr = 0;
3975 #ifdef CONFIG_CONCURRENT_MODE
3976 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
3977 struct wifidirect_info *pbuddy_wdinfo = &pbuddy_adapter->wdinfo;
3978 struct mlme_priv *pbuddy_mlmepriv = &pbuddy_adapter->mlmepriv;
3979 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
3983 #endif /* CONFIG_WFD */
3985 struct xmit_frame *pmgntframe;
3986 struct pkt_attrib *pattrib;
3987 unsigned char *pframe;
3988 struct rtw_ieee80211_hdr *pwlanhdr;
3989 unsigned short *fctrl;
3990 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3991 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3992 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3993 struct wifidirect_info *pwdinfo = &( padapter->wdinfo);
3995 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4000 /* update attribute */
4001 pattrib = &pmgntframe->attrib;
4002 update_mgntframe_attrib(padapter, pattrib);
4004 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4006 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4007 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4009 fctrl = &(pwlanhdr->frame_ctl);
4012 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4013 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
4014 memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
4016 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4017 pmlmeext->mgnt_seq++;
4018 SetFrameSubType(pframe, WIFI_ACTION);
4020 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4021 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4023 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4024 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4025 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4026 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4027 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
4029 /* P2P IE Section. */
4033 p2pie[ p2pielen++ ] = 0x50;
4034 p2pie[ p2pielen++ ] = 0x6F;
4035 p2pie[ p2pielen++ ] = 0x9A;
4036 p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
4038 /* Commented by Albert 20101005 */
4039 /* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
4041 /* 2. Configuration Timeout */
4042 /* 3. Operating Channel ( Only GO ) */
4043 /* 4. P2P Group BSSID ( Only GO ) */
4044 /* 5. Channel List */
4048 p2pie[ p2pielen++ ] = P2P_ATTR_STATUS;
4051 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0001 );
4055 /* When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE. */
4056 /* Sent the event receiving the P2P Invitation Req frame to DMP UI. */
4057 /* DMP had to compare the MAC address to find out the profile. */
4058 /* So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB. */
4059 /* If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req */
4060 /* to NB to rebuild the persistent group. */
4061 p2pie[ p2pielen++ ] = status_code;
4063 /* Configuration Timeout */
4065 p2pie[ p2pielen++ ] = P2P_ATTR_CONF_TIMEOUT;
4068 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4072 p2pie[ p2pielen++ ] = 200; /* 2 seconds needed to be the P2P GO */
4073 p2pie[ p2pielen++ ] = 200; /* 2 seconds needed to be the P2P Client */
4075 if( status_code == P2P_STATUS_SUCCESS )
4077 if( rtw_p2p_chk_role( pwdinfo, P2P_ROLE_GO ) )
4079 /* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
4080 /* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
4081 /* First one is operating channel attribute. */
4082 /* Second one is P2P Group BSSID attribute. */
4084 /* Operating Channel */
4086 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4089 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4093 /* Country String */
4094 p2pie[ p2pielen++ ] = 'X';
4095 p2pie[ p2pielen++ ] = 'X';
4097 /* The third byte should be set to 0x04. */
4098 /* Described in the "Operating Channel Attribute" section. */
4099 p2pie[ p2pielen++ ] = 0x04;
4101 /* Operating Class */
4102 p2pie[ p2pielen++ ] = 0x51; /* Copy from SD7 */
4104 /* Channel Number */
4105 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; /* operating channel number */
4107 /* P2P Group BSSID */
4109 p2pie[ p2pielen++ ] = P2P_ATTR_GROUP_BSSID;
4112 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( ETH_ALEN );
4116 /* P2P Device Address for GO */
4117 memcpy(p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
4118 p2pielen += ETH_ALEN;
4124 p2pie[ p2pielen++ ] = P2P_ATTR_CH_LIST;
4127 /* Country String(3) */
4128 /* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
4129 /* + number of channels in all classes */
4130 len_channellist_attr = 3
4131 + (1 + 1) * (u16)pmlmeext->channel_list.reg_classes
4132 + get_reg_classes_full_count(pmlmeext->channel_list);
4134 #ifdef CONFIG_CONCURRENT_MODE
4135 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4137 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 5 + 1 );
4141 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4145 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( len_channellist_attr );
4151 /* Country String */
4152 p2pie[ p2pielen++ ] = 'X';
4153 p2pie[ p2pielen++ ] = 'X';
4155 /* The third byte should be set to 0x04. */
4156 /* Described in the "Operating Channel Attribute" section. */
4157 p2pie[ p2pielen++ ] = 0x04;
4159 /* Channel Entry List */
4160 #ifdef CONFIG_CONCURRENT_MODE
4161 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
4163 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
4164 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
4166 /* Operating Class */
4167 if ( pbuddy_mlmeext->cur_channel > 14 )
4169 if ( pbuddy_mlmeext->cur_channel >= 149 )
4171 p2pie[ p2pielen++ ] = 0x7c;
4175 p2pie[ p2pielen++ ] = 0x73;
4180 p2pie[ p2pielen++ ] = 0x51;
4183 /* Number of Channels */
4184 /* Just support 1 channel and this channel is AP's channel */
4185 p2pie[ p2pielen++ ] = 1;
4188 p2pie[ p2pielen++ ] = pbuddy_mlmeext->cur_channel;
4193 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4194 /* Operating Class */
4195 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4197 /* Number of Channels */
4198 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4201 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4202 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4206 #else /* CONFIG_CONCURRENT_MODE */
4209 for (j = 0; j < pmlmeext->channel_list.reg_classes; j++) {
4210 /* Operating Class */
4211 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].reg_class;
4213 /* Number of Channels */
4214 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channels;
4217 for (i = 0; i < pmlmeext->channel_list.reg_class[j].channels; i++) {
4218 p2pie[p2pielen++] = pmlmeext->channel_list.reg_class[j].channel[i];
4222 #endif /* CONFIG_CONCURRENT_MODE */
4225 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
4228 wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
4230 pattrib->pktlen += wfdielen;
4231 #endif /* CONFIG_WFD */
4233 pattrib->last_txcmdsz = pattrib->pktlen;
4235 dump_mgntframe(padapter, pmgntframe);
4240 void issue_p2p_provision_request(_adapter *padapter, u8* pssid, u8 ussidlen, u8* pdev_raddr )
4242 unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4243 u8 action = P2P_PUB_ACTION_ACTION;
4245 u32 p2poui = cpu_to_be32(P2POUI);
4246 u8 oui_subtype = P2P_PROVISION_DISC_REQ;
4247 u8 wpsie[ 100 ] = { 0x00 };
4252 #endif /* CONFIG_WFD */
4254 struct xmit_frame *pmgntframe;
4255 struct pkt_attrib *pattrib;
4256 unsigned char *pframe;
4257 struct rtw_ieee80211_hdr *pwlanhdr;
4258 unsigned short *fctrl;
4259 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4260 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4261 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4262 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4264 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4269 DBG_8723A( "[%s] In\n", __FUNCTION__ );
4270 /* update attribute */
4271 pattrib = &pmgntframe->attrib;
4272 update_mgntframe_attrib(padapter, pattrib);
4274 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4276 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4277 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4279 fctrl = &(pwlanhdr->frame_ctl);
4282 memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
4283 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
4284 memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
4286 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4287 pmlmeext->mgnt_seq++;
4288 SetFrameSubType(pframe, WIFI_ACTION);
4290 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4291 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4293 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4294 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4295 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4296 pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4297 pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
4299 p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, pssid, ussidlen, pdev_raddr );
4302 pattrib->pktlen += p2pielen;
4306 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
4311 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
4315 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4319 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
4323 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
4327 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4331 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->tx_prov_disc_info.wps_config_method_request );
4334 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
4337 wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
4339 pattrib->pktlen += wfdielen;
4340 #endif /* CONFIG_WFD */
4342 pattrib->last_txcmdsz = pattrib->pktlen;
4344 dump_mgntframe(padapter, pmgntframe);
4349 u8 is_matched_in_profilelist( u8* peermacaddr, struct profile_info* profileinfo )
4351 u8 i, match_result = 0;
4353 DBG_8723A( "[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
4354 peermacaddr[0], peermacaddr[1],peermacaddr[2],peermacaddr[3],peermacaddr[4],peermacaddr[5]);
4356 for( i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++ )
4358 DBG_8723A( "[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
4359 profileinfo->peermac[0], profileinfo->peermac[1],profileinfo->peermac[2],profileinfo->peermac[3],profileinfo->peermac[4],profileinfo->peermac[5]);
4360 if (!memcmp(peermacaddr, profileinfo->peermac, ETH_ALEN))
4363 DBG_8723A( "[%s] Match!\n", __FUNCTION__ );
4368 return (match_result );
4371 void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
4373 struct xmit_frame *pmgntframe;
4374 struct pkt_attrib *pattrib;
4375 unsigned char *pframe;
4376 struct rtw_ieee80211_hdr *pwlanhdr;
4377 unsigned short *fctrl;
4379 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4380 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4381 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4382 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4383 /* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
4384 u16 beacon_interval = 100;
4386 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4387 u8 wpsie[255] = { 0x00 };
4388 u32 wpsielen = 0, p2pielen = 0;
4391 #endif /* CONFIG_WFD */
4392 #ifdef CONFIG_IOCTL_CFG80211
4393 struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
4394 struct ieee80211_channel *ieee_ch = &pcfg80211_wdinfo->remain_on_ch_channel;
4395 u8 listen_channel = (u8) ieee80211_frequency_to_channel(ieee_ch->center_freq);
4396 #endif /* CONFIG_IOCTL_CFG80211 */
4397 #ifdef CONFIG_INTEL_WIDI
4398 u8 zero_array_check[L2SDTA_SERVICE_VE_LEN] = { 0x00 };
4399 #endif /* CONFIG_INTEL_WIDI */
4401 /* DBG_8723A("%s\n", __FUNCTION__); */
4403 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4408 /* update attribute */
4409 pattrib = &pmgntframe->attrib;
4410 update_mgntframe_attrib(padapter, pattrib);
4412 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4414 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4415 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4417 mac = myid(&(padapter->eeprompriv));
4419 fctrl = &(pwlanhdr->frame_ctl);
4421 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
4422 memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
4424 /* Use the device address for BSSID field. */
4425 memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
4427 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4428 pmlmeext->mgnt_seq++;
4429 SetFrameSubType(fctrl, WIFI_PROBERSP);
4431 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4432 pattrib->pktlen = pattrib->hdrlen;
4433 pframe += pattrib->hdrlen;
4435 /* timestamp will be inserted by hardware */
4437 pattrib->pktlen += 8;
4439 /* beacon interval: 2 bytes */
4440 memcpy(pframe, (unsigned char *) &beacon_interval, 2);
4442 pattrib->pktlen += 2;
4444 /* capability info: 2 bytes */
4445 /* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
4446 capInfo |= cap_ShortPremble;
4447 capInfo |= cap_ShortSlot;
4449 memcpy(pframe, (unsigned char *) &capInfo, 2);
4451 pattrib->pktlen += 2;
4454 pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
4456 /* supported rates... */
4457 /* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
4458 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
4460 /* DS parameter set */
4461 #ifdef CONFIG_IOCTL_CFG80211
4462 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled && listen_channel !=0 )
4464 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&listen_channel, &pattrib->pktlen);
4467 #endif /* CONFIG_IOCTL_CFG80211 */
4469 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
4472 #ifdef CONFIG_IOCTL_CFG80211
4473 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
4475 if( pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL )
4478 memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
4479 pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
4480 pframe += pmlmepriv->wps_probe_resp_ie_len;
4483 memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
4484 pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
4485 pframe += pmlmepriv->p2p_probe_resp_ie_len;
4489 #endif /* CONFIG_IOCTL_CFG80211 */
4493 /* Noted by Albert 20100907 */
4494 /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
4498 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
4503 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
4507 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4511 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
4513 #ifdef CONFIG_INTEL_WIDI
4514 /* Commented by Kurt */
4515 /* Appended WiDi info. only if we did issued_probereq_widi(), and then we saved ven. ext. in pmlmepriv->sa_ext. */
4516 if (memcmp(pmlmepriv->sa_ext, zero_array_check,
4517 L2SDTA_SERVICE_VE_LEN))
4520 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SEC_DEV_TYPE_LIST );
4524 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
4529 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_DISPLAYS );
4533 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( INTEL_DEV_TYPE_OUI );
4536 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_WIDI_CONSUMER_SINK );
4539 /* Vendor Extension */
4540 memcpy(wpsie + wpsielen, pmlmepriv->sa_ext, L2SDTA_SERVICE_VE_LEN );
4541 wpsielen += L2SDTA_SERVICE_VE_LEN;
4543 #endif /* CONFIG_INTEL_WIDI */
4545 /* WiFi Simple Config State */
4547 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SIMPLE_CONF_STATE );
4551 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4555 wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
4559 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_RESP_TYPE );
4563 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4567 wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
4571 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
4575 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
4579 memcpy(wpsie + wpsielen, myid( &padapter->eeprompriv ), ETH_ALEN );
4584 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MANUFACTURER );
4588 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0007 );
4592 memcpy(wpsie + wpsielen, "Realtek", 7 );
4597 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NAME );
4601 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0006 );
4605 memcpy(wpsie + wpsielen, "8192CU", 6 );
4610 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_MODEL_NUMBER );
4614 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4618 wpsie[ wpsielen++ ] = 0x31; /* character 1 */
4622 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_SERIAL_NUMBER );
4626 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( ETH_ALEN );
4630 memcpy(wpsie + wpsielen, "123456" , ETH_ALEN );
4631 wpsielen += ETH_ALEN;
4633 /* Primary Device Type */
4635 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
4639 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
4644 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
4648 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
4651 /* Sub Category ID */
4652 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
4657 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4661 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
4665 if (pwdinfo->device_name_len)
4667 memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
4668 wpsielen += pwdinfo->device_name_len;
4673 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
4677 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4681 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
4684 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
4686 p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
4688 pattrib->pktlen += p2pielen;
4692 #ifdef CONFIG_IOCTL_CFG80211
4693 if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
4694 #endif /* CONFIG_IOCTL_CFG80211 */
4696 wfdielen = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
4698 pattrib->pktlen += wfdielen;
4700 #ifdef CONFIG_IOCTL_CFG80211
4701 else if (pmlmepriv->wfd_probe_resp_ie != NULL && pmlmepriv->wfd_probe_resp_ie_len>0)
4704 memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, pmlmepriv->wfd_probe_resp_ie_len);
4705 pattrib->pktlen += pmlmepriv->wfd_probe_resp_ie_len;
4706 pframe += pmlmepriv->wfd_probe_resp_ie_len;
4708 #endif /* CONFIG_IOCTL_CFG80211 */
4709 #endif /* CONFIG_WFD */
4711 pattrib->last_txcmdsz = pattrib->pktlen;
4713 dump_mgntframe(padapter, pmgntframe);
4718 int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
4721 struct xmit_frame *pmgntframe;
4722 struct pkt_attrib *pattrib;
4723 unsigned char *pframe;
4724 struct rtw_ieee80211_hdr *pwlanhdr;
4725 unsigned short *fctrl;
4727 unsigned char bssrate[NumRates];
4728 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4729 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4730 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4731 int bssrate_len = 0;
4732 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
4733 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4734 u8 wpsie[255] = { 0x00 }, p2pie[ 255 ] = { 0x00 };
4735 u16 wpsielen = 0, p2pielen = 0;
4738 #endif /* CONFIG_WFD */
4740 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
4742 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
4747 /* update attribute */
4748 pattrib = &pmgntframe->attrib;
4749 update_mgntframe_attrib(padapter, pattrib);
4751 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4753 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4754 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4756 mac = myid(&(padapter->eeprompriv));
4758 fctrl = &(pwlanhdr->frame_ctl);
4762 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
4763 memcpy(pwlanhdr->addr3, da, ETH_ALEN);
4765 if ( ( pwdinfo->p2p_info.scan_op_ch_only ) || ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
4767 /* This two flags will be set when this is only the P2P client mode. */
4768 memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
4769 memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
4773 /* broadcast probe request frame */
4774 memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
4775 memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
4778 memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
4780 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4781 pmlmeext->mgnt_seq++;
4782 SetFrameSubType(pframe, WIFI_PROBEREQ);
4784 pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
4785 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
4787 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
4789 pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen));
4793 pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen));
4795 /* Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 ) */
4796 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
4798 #ifdef CONFIG_IOCTL_CFG80211
4799 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
4801 if( pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL )
4804 memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
4805 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
4806 pframe += pmlmepriv->wps_probe_req_ie_len;
4809 memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len);
4810 pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
4811 pframe += pmlmepriv->p2p_probe_req_ie_len;
4815 #endif /* CONFIG_IOCTL_CFG80211 */
4819 /* Noted by Albert 20110221 */
4820 /* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
4824 *(u32*) ( wpsie ) = cpu_to_be32( WPSOUI );
4829 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_VER1 );
4833 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0001 );
4837 wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
4839 if( pmlmepriv->wps_probe_req_ie == NULL )
4843 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_UUID_E );
4847 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0010 );
4851 memcpy(wpsie + wpsielen, myid( &padapter->eeprompriv ), ETH_ALEN );
4856 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_CONF_METHOD );
4860 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4864 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->supported_wps_cm );
4870 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
4874 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( pwdinfo->device_name_len );
4878 memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len );
4879 wpsielen += pwdinfo->device_name_len;
4881 /* Primary Device Type */
4883 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
4887 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0008 );
4892 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_CID_RTK_WIDI );
4896 *(u32*) ( wpsie + wpsielen ) = cpu_to_be32( WPSOUI );
4899 /* Sub Category ID */
4900 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_PDT_SCID_RTK_DMP );
4903 /* Device Password ID */
4905 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_ATTR_DEVICE_PWID );
4909 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( 0x0002 );
4913 *(u16*) ( wpsie + wpsielen ) = cpu_to_be16( WPS_DPID_REGISTRAR_SPEC ); /* Registrar-specified */
4916 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen );
4920 p2pie[ p2pielen++ ] = 0x50;
4921 p2pie[ p2pielen++ ] = 0x6F;
4922 p2pie[ p2pielen++ ] = 0x9A;
4923 p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
4925 /* Commented by Albert 20110221 */
4926 /* According to the P2P Specification, the probe request frame should contain 5 P2P attributes */
4927 /* 1. P2P Capability */
4928 /* 2. P2P Device ID if this probe request wants to find the specific P2P device */
4929 /* 3. Listen Channel */
4930 /* 4. Extended Listen Timing */
4931 /* 5. Operating Channel if this WiFi is working as the group owner now */
4933 /* P2P Capability */
4935 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
4938 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
4942 /* Device Capability Bitmap, 1 byte */
4943 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
4945 /* Group Capability Bitmap, 1 byte */
4946 if ( pwdinfo->persistent_supported )
4947 p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
4949 p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
4951 /* Listen Channel */
4953 p2pie[ p2pielen++ ] = P2P_ATTR_LISTEN_CH;
4956 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
4960 /* Country String */
4961 p2pie[ p2pielen++ ] = 'X';
4962 p2pie[ p2pielen++ ] = 'X';
4964 /* The third byte should be set to 0x04. */
4965 /* Described in the "Operating Channel Attribute" section. */
4966 p2pie[ p2pielen++ ] = 0x04;
4968 /* Operating Class */
4969 p2pie[ p2pielen++ ] = 0x51; /* Copy from SD7 */
4971 /* Channel Number */
4972 p2pie[ p2pielen++ ] = pwdinfo->listen_channel; /* listen channel */
4974 /* Extended Listen Timing */
4976 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
4979 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
4983 /* Availability Period */
4984 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
4987 /* Availability Interval */
4988 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
4991 if ( rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) )
4993 /* Operating Channel (if this WiFi is working as the group owner now) */
4995 p2pie[ p2pielen++ ] = P2P_ATTR_OPERATING_CH;
4998 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0005 );
5002 /* Country String */
5003 p2pie[ p2pielen++ ] = 'X';
5004 p2pie[ p2pielen++ ] = 'X';
5006 /* The third byte should be set to 0x04. */
5007 /* Described in the "Operating Channel Attribute" section. */
5008 p2pie[ p2pielen++ ] = 0x04;
5010 /* Operating Class */
5011 p2pie[ p2pielen++ ] = 0x51; /* Copy from SD7 */
5013 /* Channel Number */
5014 p2pie[ p2pielen++ ] = pwdinfo->operating_channel; /* operating channel number */
5018 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
5020 if( pmlmepriv->wps_probe_req_ie != NULL )
5023 memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
5024 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
5025 pframe += pmlmepriv->wps_probe_req_ie_len;
5030 #ifdef CONFIG_IOCTL_CFG80211
5031 if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
5034 wfdielen = build_probe_req_wfd_ie(pwdinfo, pframe);
5036 pattrib->pktlen += wfdielen;
5038 #ifdef CONFIG_IOCTL_CFG80211
5039 else if (pmlmepriv->wfd_probe_req_ie != NULL && pmlmepriv->wfd_probe_req_ie_len>0)
5042 memcpy(pframe, pmlmepriv->wfd_probe_req_ie, pmlmepriv->wfd_probe_req_ie_len);
5043 pattrib->pktlen += pmlmepriv->wfd_probe_req_ie_len;
5044 pframe += pmlmepriv->wfd_probe_req_ie_len;
5046 #endif /* CONFIG_IOCTL_CFG80211 */
5047 #endif /* CONFIG_WFD */
5049 pattrib->last_txcmdsz = pattrib->pktlen;
5051 RT_TRACE(_module_rtl871x_mlme_c_,_drv_info_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
5054 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
5056 dump_mgntframe(padapter, pmgntframe);
5064 inline void issue_probereq_p2p(_adapter *adapter, u8 *da)
5066 _issue_probereq_p2p(adapter, da, _FALSE);
5069 int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms)
5073 u32 start = rtw_get_current_time();
5077 ret = _issue_probereq_p2p(adapter, da, wait_ms>0?_TRUE:_FALSE);
5081 if (adapter->bDriverStopped || adapter->bSurpriseRemoved)
5084 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
5085 rtw_msleep_os(wait_ms);
5087 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
5091 #ifndef DBG_XMIT_ACK
5096 if (try_cnt && wait_ms) {
5098 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
5099 FUNC_ADPT_ARG(adapter), MAC_ARG(da), rtw_get_oper_ch(adapter),
5100 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
5102 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
5103 FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
5104 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
5110 #endif /* CONFIG_P2P */
5112 s32 rtw_action_public_decache(union recv_frame *recv_frame, s32 token)
5114 _adapter *adapter = recv_frame->u.hdr.adapter;
5115 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
5116 u8 *frame = recv_frame->u.hdr.rx_data;
5117 u16 seq_ctrl = ( (recv_frame->u.hdr.attrib.seq_num&0xffff) << 4) |
5118 (recv_frame->u.hdr.attrib.frag_num & 0xf);
5120 if (GetRetry(frame)) {
5122 if ((seq_ctrl == mlmeext->action_public_rxseq)
5123 && (token == mlmeext->action_public_dialog_token))
5125 DBG_8723A(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n",
5126 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
5130 if (seq_ctrl == mlmeext->action_public_rxseq) {
5131 DBG_8723A(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x\n",
5132 FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq);
5138 mlmeext->action_public_rxseq = seq_ctrl;
5141 mlmeext->action_public_dialog_token = token;
5146 unsigned int on_action_public_p2p(union recv_frame *precv_frame)
5148 _adapter *padapter = precv_frame->u.hdr.adapter;
5149 u8 *pframe = precv_frame->u.hdr.rx_data;
5150 uint len = precv_frame->u.hdr.len;
5155 u32 p2p_ielen, wps_ielen;
5156 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5157 u8 result = P2P_STATUS_SUCCESS;
5158 u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
5159 #endif /* CONFIG_P2P */
5161 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
5163 dialogToken = frame_body[7];
5165 if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL)
5169 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
5170 #ifdef CONFIG_IOCTL_CFG80211
5171 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
5173 rtw_cfg80211_rx_p2p_action_public(padapter, pframe, len);
5176 #endif /* CONFIG_IOCTL_CFG80211 */
5178 /* Do nothing if the driver doesn't enable the P2P function. */
5179 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
5182 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
5184 switch( frame_body[ 6 ] )/* OUI Subtype */
5186 case P2P_GO_NEGO_REQ:
5188 DBG_8723A( "[%s] Got GO Nego Req Frame\n", __FUNCTION__);
5189 memset( &pwdinfo->groupid_info, 0x00, sizeof( struct group_id_info ) );
5191 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
5193 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
5196 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
5198 /* Commented by Albert 20110526 */
5199 /* In this case, this means the previous nego fail doesn't be reset yet. */
5200 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
5201 /* Restore the previous p2p state */
5202 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
5203 DBG_8723A( "[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo) );
5205 #ifdef CONFIG_CONCURRENT_MODE
5206 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
5208 _cancel_timer_ex( &pwdinfo->ap_p2p_switch_timer );
5210 #endif /* CONFIG_CONCURRENT_MODE */
5212 /* Commented by Kurt 20110902 */
5213 /* Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
5214 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
5215 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5217 /* Commented by Kurt 20120113 */
5218 /* Get peer_dev_addr here if peer doesn't issue prov_disc frame. */
5219 if (!memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN))
5220 memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
5222 result = process_p2p_group_negotation_req( pwdinfo, frame_body, len );
5223 issue_p2p_GO_response( padapter, GetAddr2Ptr(pframe), frame_body, len, result );
5224 #ifdef CONFIG_INTEL_WIDI
5225 if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
5227 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
5228 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
5230 #endif /* CONFIG_INTEL_WIDI */
5232 /* Commented by Albert 20110718 */
5233 /* No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer. */
5234 #ifdef CONFIG_CONCURRENT_MODE
5235 /* Commented by Albert 20120107 */
5236 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
5237 #else /* CONFIG_CONCURRENT_MODE */
5238 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
5239 #endif /* CONFIG_CONCURRENT_MODE */
5242 case P2P_GO_NEGO_RESP:
5244 DBG_8723A( "[%s] Got GO Nego Resp Frame\n", __FUNCTION__);
5246 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
5248 /* Commented by Albert 20110425 */
5249 /* The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function. */
5250 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
5251 pwdinfo->nego_req_info.benable = _FALSE;
5252 result = process_p2p_group_negotation_resp( pwdinfo, frame_body, len);
5253 issue_p2p_GO_confirm( pwdinfo->padapter, GetAddr2Ptr(pframe), result);
5254 if ( P2P_STATUS_SUCCESS == result )
5256 if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
5258 pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
5259 pwdinfo->p2p_info.scan_op_ch_only = 1;
5260 _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
5264 /* Reset the dialog token for group negotiation frames. */
5265 pwdinfo->negotiation_dialog_token = 1;
5267 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
5269 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
5274 DBG_8723A( "[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__);
5279 case P2P_GO_NEGO_CONF:
5281 DBG_8723A( "[%s] Got GO Nego Confirm Frame\n", __FUNCTION__);
5282 result = process_p2p_group_negotation_confirm( pwdinfo, frame_body, len);
5283 if ( P2P_STATUS_SUCCESS == result )
5285 if ( rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT )
5287 pwdinfo->p2p_info.operation_ch[ 0 ] = pwdinfo->peer_operating_ch;
5288 pwdinfo->p2p_info.scan_op_ch_only = 1;
5289 _set_timer( &pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH );
5296 /* Added by Albert 2010/10/05 */
5297 /* Received the P2P Invite Request frame. */
5299 DBG_8723A( "[%s] Got invite request frame!\n", __FUNCTION__ );
5300 if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
5302 /* Parse the necessary information from the P2P Invitation Request frame. */
5303 /* For example: The MAC address of sending this P2P Invitation Request frame. */
5304 u32 attr_contentlen = 0;
5305 u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
5306 struct group_id_info group_id;
5307 u8 invitation_flag = 0;
5309 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
5310 if ( attr_contentlen )
5313 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
5314 /* Commented by Albert 20120510 */
5315 /* Copy to the pwdinfo->p2p_peer_interface_addr. */
5316 /* So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command. */
5317 /* #> iwpriv wlan0 p2p_get peer_ifa */
5318 /* After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant. */
5320 if ( attr_contentlen )
5322 DBG_8723A( "[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5323 pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
5324 pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
5325 pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5] );
5328 if ( invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT )
5330 /* Re-invoke the persistent group. */
5332 memset( &group_id, 0x00, sizeof( struct group_id_info ) );
5333 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
5334 if ( attr_contentlen )
5336 if (!memcmp(group_id.go_device_addr, myid( &padapter->eeprompriv), ETH_ALEN))
5338 /* The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO. */
5339 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO );
5340 rtw_p2p_set_role( pwdinfo, P2P_ROLE_GO );
5341 status_code = P2P_STATUS_SUCCESS;
5345 /* The p2p device sending this p2p invitation request wants to be the persistent GO. */
5346 if ( is_matched_in_profilelist( pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[ 0 ] ) )
5348 u8 operatingch_info[5] = { 0x00 };
5349 if ( rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info, &attr_contentlen) )
5351 if( rtw_ch_set_search_ch(padapter->mlmeextpriv.channel_set, (u32)operatingch_info[4] ) )
5353 /* The operating channel is acceptable for this device. */
5354 pwdinfo->rx_invitereq_info.operation_ch[0]= operatingch_info[4];
5355 pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
5356 _set_timer( &pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH );
5357 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
5358 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
5359 status_code = P2P_STATUS_SUCCESS;
5363 /* The operating channel isn't supported by this device. */
5364 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
5365 rtw_p2p_set_role( pwdinfo, P2P_ROLE_DEVICE );
5366 status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
5367 _set_timer( &pwdinfo->restore_p2p_state_timer, 3000 );
5372 /* Commented by Albert 20121130 */
5373 /* Intel will use the different P2P IE to store the operating channel information */
5374 /* Workaround for Intel WiDi 3.5 */
5375 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH );
5376 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
5377 status_code = P2P_STATUS_SUCCESS;
5382 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
5383 #ifdef CONFIG_INTEL_WIDI
5384 memcpy(pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
5385 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
5386 #endif /* CONFIG_INTEL_WIDI */
5388 status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
5394 DBG_8723A( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
5395 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
5400 /* Received the invitation to join a P2P group. */
5402 memset( &group_id, 0x00, sizeof( struct group_id_info ) );
5403 rtw_get_p2p_attr_content( p2p_ie, p2p_ielen, P2P_ATTR_GROUP_ID, ( u8* ) &group_id, &attr_contentlen);
5404 if ( attr_contentlen )
5406 if (!memcmp(group_id.go_device_addr, myid( &padapter->eeprompriv), ETH_ALEN))
5408 /* In this case, the GO can't be myself. */
5409 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH );
5410 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
5414 /* The p2p device sending this p2p invitation request wants to join an existing P2P group */
5415 /* Commented by Albert 2012/06/28 */
5416 /* In this case, this Wi-Fi device should use the iwpriv command to get the peer device address. */
5417 /* The peer device address should be the destination address for the provisioning discovery request. */
5418 /* Then, this Wi-Fi device should use the iwpriv command to get the peer interface address. */
5419 /* The peer interface address should be the address for WPS mac address */
5420 memcpy(pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN );
5421 rtw_p2p_set_role( pwdinfo, P2P_ROLE_CLIENT );
5422 rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN );
5423 status_code = P2P_STATUS_SUCCESS;
5428 DBG_8723A( "[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__ );
5429 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
5435 DBG_8723A( "[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__ );
5436 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
5439 DBG_8723A( "[%s] status_code = %d\n", __FUNCTION__, status_code );
5441 pwdinfo->inviteresp_info.token = frame_body[ 7 ];
5442 issue_p2p_invitation_response( padapter, GetAddr2Ptr(pframe), pwdinfo->inviteresp_info.token, status_code );
5444 #ifdef CONFIG_INTEL_WIDI
5445 if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
5447 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
5448 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
5450 #endif /* CONFIG_INTEL_WIDI */
5453 case P2P_INVIT_RESP:
5455 u8 attr_content = 0x00;
5456 u32 attr_contentlen = 0;
5458 DBG_8723A( "[%s] Got invite response frame!\n", __FUNCTION__ );
5459 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
5460 if ( (p2p_ie=rtw_get_p2p_ie( frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen)) )
5462 rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
5464 if ( attr_contentlen == 1 )
5466 DBG_8723A( "[%s] Status = %d\n", __FUNCTION__, attr_content );
5467 pwdinfo->invitereq_info.benable = _FALSE;
5469 if ( attr_content == P2P_STATUS_SUCCESS )
5471 if (!memcmp(pwdinfo->invitereq_info.go_bssid, myid( &padapter->eeprompriv), ETH_ALEN))
5473 rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO );
5477 rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
5479 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_OK );
5483 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
5484 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
5489 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
5490 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
5495 rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
5496 rtw_p2p_set_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL );
5499 if ( rtw_p2p_chk_state( pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL ) )
5501 _set_timer( &pwdinfo->restore_p2p_state_timer, 5000 );
5505 case P2P_DEVDISC_REQ:
5507 process_p2p_devdisc_req(pwdinfo, pframe, len);
5511 case P2P_DEVDISC_RESP:
5513 process_p2p_devdisc_resp(pwdinfo, pframe, len);
5517 case P2P_PROVISION_DISC_REQ:
5518 DBG_8723A( "[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__ );
5519 process_p2p_provdisc_req(pwdinfo, pframe, len);
5520 memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, GetAddr2Ptr(pframe), ETH_ALEN);
5523 /* Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
5524 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
5525 rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5527 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
5528 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
5529 #ifdef CONFIG_INTEL_WIDI
5530 if( (padapter->mlmepriv.widi_state == INTEL_WIDI_STATE_LISTEN) && (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_WFD_CONNECTION) )
5532 padapter->mlmepriv.widi_state = INTEL_WIDI_STATE_WFD_CONNECTION;
5533 intel_widi_wk_cmd(padapter, INTEL_WIDI_LISTEN_STOP_WK, NULL);
5535 #endif /* CONFIG_INTEL_WIDI */
5538 case P2P_PROVISION_DISC_RESP:
5539 /* Commented by Albert 20110707 */
5540 /* Should we check the pwdinfo->tx_prov_disc_info.bsent flag here?? */
5541 DBG_8723A( "[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__ );
5542 /* Commented by Albert 20110426 */
5543 /* The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function. */
5544 _cancel_timer_ex( &pwdinfo->restore_p2p_state_timer );
5545 rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
5546 process_p2p_provdisc_resp(pwdinfo, pframe);
5547 _set_timer( &pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT );
5552 #endif /* CONFIG_P2P */
5557 unsigned int on_action_public_vendor(union recv_frame *precv_frame)
5559 unsigned int ret = _FAIL;
5560 u8 *pframe = precv_frame->u.hdr.rx_data;
5561 uint frame_len = precv_frame->u.hdr.len;
5562 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
5564 if (!memcmp(frame_body + 2, P2P_OUI, 4)) {
5565 ret = on_action_public_p2p(precv_frame);
5571 unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
5573 unsigned int ret = _FAIL;
5574 u8 *pframe = precv_frame->u.hdr.rx_data;
5575 uint frame_len = precv_frame->u.hdr.len;
5576 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
5578 _adapter *adapter = precv_frame->u.hdr.adapter;
5582 token = frame_body[2];
5584 if (rtw_action_public_decache(precv_frame, token) == _FAIL)
5587 #ifdef CONFIG_IOCTL_CFG80211
5588 cnt += sprintf((msg+cnt), "%s(token:%u)", action_public_str(action), token);
5589 rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg);
5598 unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame)
5600 unsigned int ret = _FAIL;
5601 u8 *pframe = precv_frame->u.hdr.rx_data;
5602 uint frame_len = precv_frame->u.hdr.len;
5603 u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
5604 u8 category, action;
5606 /* check RA matches or not */
5607 if (memcmp(myid(&(padapter->eeprompriv)),
5608 GetAddr1Ptr(pframe), ETH_ALEN))
5611 category = frame_body[0];
5612 if(category != RTW_WLAN_CATEGORY_PUBLIC)
5615 action = frame_body[1];
5617 case ACT_PUBLIC_VENDOR:
5618 ret = on_action_public_vendor(precv_frame);
5621 ret = on_action_public_default(precv_frame, action);
5629 unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame)
5634 unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame)
5639 unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame)
5643 u8 category, OUI_Subtype, dialogToken=0;
5644 u8 *pframe = precv_frame->u.hdr.rx_data;
5645 uint len = precv_frame->u.hdr.len;
5646 struct wifidirect_info *pwdinfo = &( padapter->wdinfo );
5648 DBG_8723A("%s\n", __FUNCTION__);
5650 /* check RA matches or not */
5651 if (memcmp(myid(&(padapter->eeprompriv)),
5652 GetAddr1Ptr(pframe), ETH_ALEN))/* for if1, sta/ap mode */
5655 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
5657 category = frame_body[0];
5658 if(category != RTW_WLAN_CATEGORY_P2P)
5661 if ( cpu_to_be32( *( ( u32* ) ( frame_body + 1 ) ) ) != P2POUI )
5664 #ifdef CONFIG_IOCTL_CFG80211
5665 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
5667 rtw_cfg80211_rx_action_p2p(padapter, pframe, len);
5671 #endif /* CONFIG_IOCTL_CFG80211 */
5673 len -= sizeof(struct rtw_ieee80211_hdr_3addr);
5674 OUI_Subtype = frame_body[5];
5675 dialogToken = frame_body[6];
5679 case P2P_NOTICE_OF_ABSENCE:
5683 case P2P_PRESENCE_REQUEST:
5685 process_p2p_presence_req(pwdinfo, pframe, len);
5689 case P2P_PRESENCE_RESPONSE:
5693 case P2P_GO_DISC_REQUEST:
5702 #endif /* CONFIG_P2P */
5707 unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame)
5710 unsigned char category;
5711 struct action_handler *ptable;
5712 unsigned char *frame_body;
5713 u8 *pframe = precv_frame->u.hdr.rx_data;
5715 frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
5717 category = frame_body[0];
5719 for(i = 0; i < sizeof(OnAction_tbl)/sizeof(struct action_handler); i++)
5721 ptable = &OnAction_tbl[i];
5723 if(category == ptable->num)
5724 ptable->func(padapter, precv_frame);
5731 unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame)
5734 /* DBG_8723A("rcvd mgt frame(%x, %x)\n", (GetFrameSubType(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe)); */
5738 struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
5740 struct xmit_frame *pmgntframe;
5741 struct xmit_buf *pxmitbuf;
5744 pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
5746 pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
5748 if (pmgntframe == NULL) {
5749 DBG_8723A(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
5753 if ((pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv)) == NULL) {
5754 DBG_8723A(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
5755 rtw_free_xmitframe(pxmitpriv, pmgntframe);
5760 pmgntframe->frame_tag = MGNT_FRAMETAG;
5761 pmgntframe->pxmitbuf = pxmitbuf;
5762 pmgntframe->buf_addr = pxmitbuf->pbuf;
5763 pxmitbuf->priv_data = pmgntframe;
5769 inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
5771 return _alloc_mgtxmitframe(pxmitpriv, _FALSE);
5774 inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv)
5776 return _alloc_mgtxmitframe(pxmitpriv, _TRUE);
5779 /****************************************************************************
5781 Following are some TX fuctions for WiFi MLME
5783 *****************************************************************************/
5785 void update_mgnt_tx_rate(_adapter *padapter, u8 rate)
5787 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5789 pmlmeext->tx_rate = rate;
5790 DBG_8723A("%s(): rate = %x\n",__FUNCTION__, rate);
5793 void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
5795 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5797 memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib));
5799 pattrib->hdrlen = 24;
5800 pattrib->nr_frags = 1;
5801 pattrib->priority = 7;
5802 pattrib->mac_id = 0;
5803 pattrib->qsel = 0x12;
5805 pattrib->pktlen = 0;
5807 if(pmlmeext->cur_wireless_mode & WIRELESS_11B)
5808 pattrib->raid = 6;/* b mode */
5810 pattrib->raid = 5;/* a/g mode */
5812 pattrib->encrypt = _NO_PRIVACY_;
5813 pattrib->bswenc = _FALSE;
5815 pattrib->qos_en = _FALSE;
5816 pattrib->ht_en = _FALSE;
5817 pattrib->bwmode = HT_CHANNEL_WIDTH_20;
5818 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
5819 pattrib->sgi = _FALSE;
5821 pattrib->seqnum = pmlmeext->mgnt_seq;
5823 pattrib->retry_ctrl = _TRUE;
5826 void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe)
5828 if(padapter->bSurpriseRemoved == _TRUE ||
5829 padapter->bDriverStopped == _TRUE)
5832 rtw_hal_mgnt_xmit(padapter, pmgntframe);
5835 s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
5839 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5840 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
5841 struct submit_ctx sctx;
5843 if(padapter->bSurpriseRemoved == _TRUE ||
5844 padapter->bDriverStopped == _TRUE)
5847 rtw_sctx_init(&sctx, timeout_ms);
5848 pxmitbuf->sctx = &sctx;
5850 ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
5852 if (ret == _SUCCESS)
5853 ret = rtw_sctx_wait(&sctx);
5855 spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL);
5856 pxmitbuf->sctx = NULL;
5857 spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL);
5862 s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe)
5864 #ifdef CONFIG_XMIT_ACK
5866 u32 timeout_ms = 500;/* 500ms */
5867 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
5868 #ifdef CONFIG_CONCURRENT_MODE
5869 if (padapter->pbuddy_adapter && !padapter->isprimary)
5870 pxmitpriv = &(padapter->pbuddy_adapter->xmitpriv);
5873 if(padapter->bSurpriseRemoved == _TRUE ||
5874 padapter->bDriverStopped == _TRUE)
5877 _enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
5878 pxmitpriv->ack_tx = _TRUE;
5880 pmgntframe->ack_report = 1;
5881 if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) {
5882 ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms);
5885 pxmitpriv->ack_tx = _FALSE;
5886 _exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
5889 #else /* CONFIG_XMIT_ACK */
5890 dump_mgntframe(padapter, pmgntframe);
5893 #endif /* CONFIG_XMIT_ACK */
5896 int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
5902 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
5904 /* DBG_8723A("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
5906 if(ssid_ie && ssid_len_ori>0)
5908 switch(hidden_ssid_mode)
5912 u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
5915 remain_len = ies_len -(next_ie-ies);
5918 memcpy(ssid_ie+2, next_ie, remain_len);
5919 len_diff -= ssid_len_ori;
5924 memset(&ssid_ie[2], 0, ssid_len_ori);
5934 void issue_beacon(_adapter *padapter, int timeout_ms)
5936 struct xmit_frame *pmgntframe;
5937 struct pkt_attrib *pattrib;
5938 unsigned char *pframe;
5939 struct rtw_ieee80211_hdr *pwlanhdr;
5940 unsigned short *fctrl;
5941 unsigned int rate_len;
5942 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5943 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
5945 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5946 #endif /* if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
5947 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5948 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5949 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
5950 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
5952 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5953 #endif /* CONFIG_P2P */
5955 /* DBG_8723A("%s\n", __FUNCTION__); */
5957 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
5959 DBG_8723A("%s, alloc mgnt frame fail\n", __FUNCTION__);
5962 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
5963 spin_lock_bh(&pmlmepriv->bcn_update_lock);
5964 #endif /* if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
5966 /* update attribute */
5967 pattrib = &pmgntframe->attrib;
5968 update_mgntframe_attrib(padapter, pattrib);
5969 pattrib->qsel = 0x10;
5971 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5973 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5974 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5976 fctrl = &(pwlanhdr->frame_ctl);
5979 memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
5980 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
5981 memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
5983 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
5984 /* pmlmeext->mgnt_seq++; */
5985 SetFrameSubType(pframe, WIFI_BEACON);
5987 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5988 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
5990 if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
5992 /* DBG_8723A("ie len=%d\n", cur_network->IELength); */
5994 /* for P2P : Primary Device Type & Device Name */
5995 u32 wpsielen=0, insert_len=0;
5997 wpsie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wpsielen);
5999 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen>0)
6001 uint wps_offset, remainder_ielen;
6002 u8 *premainder_ie, *pframe_wscie;
6004 wps_offset = (uint)(wpsie - cur_network->IEs);
6006 premainder_ie = wpsie + wpsielen;
6008 remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
6010 #ifdef CONFIG_IOCTL_CFG80211
6011 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
6013 if(pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len>0)
6015 memcpy(pframe, cur_network->IEs, wps_offset);
6016 pframe += wps_offset;
6017 pattrib->pktlen += wps_offset;
6019 memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
6020 pframe += pmlmepriv->wps_beacon_ie_len;
6021 pattrib->pktlen += pmlmepriv->wps_beacon_ie_len;
6023 /* copy remainder_ie to pframe */
6024 memcpy(pframe, premainder_ie, remainder_ielen);
6025 pframe += remainder_ielen;
6026 pattrib->pktlen += remainder_ielen;
6030 memcpy(pframe, cur_network->IEs, cur_network->IELength);
6031 pframe += cur_network->IELength;
6032 pattrib->pktlen += cur_network->IELength;
6036 #endif /* CONFIG_IOCTL_CFG80211 */
6038 pframe_wscie = pframe + wps_offset;
6039 memcpy(pframe, cur_network->IEs, wps_offset+wpsielen);
6040 pframe += (wps_offset + wpsielen);
6041 pattrib->pktlen += (wps_offset + wpsielen);
6043 /* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
6044 /* Primary Device Type */
6046 *(u16*) ( pframe + insert_len) = cpu_to_be16( WPS_ATTR_PRIMARY_DEV_TYPE );
6050 *(u16*) ( pframe + insert_len ) = cpu_to_be16( 0x0008 );
6055 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
6059 *(u32*) ( pframe + insert_len ) = cpu_to_be32( WPSOUI );
6062 /* Sub Category ID */
6063 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
6068 *(u16*) ( pframe + insert_len ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
6072 *(u16*) ( pframe + insert_len ) = cpu_to_be16( pwdinfo->device_name_len );
6076 memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len );
6077 insert_len += pwdinfo->device_name_len;
6079 /* update wsc ie length */
6080 *(pframe_wscie+1) = (wpsielen -2) + insert_len;
6082 /* pframe move to end */
6084 pattrib->pktlen += insert_len;
6086 /* copy remainder_ie to pframe */
6087 memcpy(pframe, premainder_ie, remainder_ielen);
6088 pframe += remainder_ielen;
6089 pattrib->pktlen += remainder_ielen;
6093 #endif /* CONFIG_P2P */
6096 memcpy(pframe, cur_network->IEs, cur_network->IELength);
6097 len_diff = update_hidden_ssid(
6098 pframe+_BEACON_IE_OFFSET_
6099 , cur_network->IELength-_BEACON_IE_OFFSET_
6100 , pmlmeinfo->hidden_ssid_mode
6102 pframe += (cur_network->IELength+len_diff);
6103 pattrib->pktlen += (cur_network->IELength+len_diff);
6110 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof (struct rtw_ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_,
6111 pattrib->pktlen-sizeof (struct rtw_ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen);
6112 if (wps_ie && wps_ielen>0) {
6113 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8*)(&sr), NULL);
6116 set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
6118 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
6122 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
6125 #ifdef CONFIG_IOCTL_CFG80211
6126 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
6128 len = pmlmepriv->p2p_beacon_ie_len;
6129 if(pmlmepriv->p2p_beacon_ie && len>0)
6130 memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
6133 #endif /* CONFIG_IOCTL_CFG80211 */
6135 len = build_beacon_p2p_ie(pwdinfo, pframe);
6139 pattrib->pktlen += len;
6141 #ifdef CONFIG_IOCTL_CFG80211
6142 if(_TRUE == pwdinfo->wfd_info->wfd_enable)
6143 #endif /* CONFIG_IOCTL_CFG80211 */
6145 len = build_beacon_wfd_ie( pwdinfo, pframe );
6147 #ifdef CONFIG_IOCTL_CFG80211
6151 if(pmlmepriv->wfd_beacon_ie && pmlmepriv->wfd_beacon_ie_len>0)
6153 len = pmlmepriv->wfd_beacon_ie_len;
6154 memcpy(pframe, pmlmepriv->wfd_beacon_ie, len);
6157 #endif /* CONFIG_IOCTL_CFG80211 */
6159 pattrib->pktlen += len;
6160 #endif /* CONFIG_WFD */
6162 #endif /* CONFIG_P2P */
6168 /* below for ad-hoc mode */
6170 /* timestamp will be inserted by hardware */
6172 pattrib->pktlen += 8;
6174 /* beacon interval: 2 bytes */
6176 memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6179 pattrib->pktlen += 2;
6181 /* capability info: 2 bytes */
6183 memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6186 pattrib->pktlen += 2;
6189 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
6191 /* supported rates... */
6192 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6193 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
6195 /* DS parameter set */
6196 pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
6198 /* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
6202 /* IBSS Parameter Set... */
6203 /* ATIMWindow = cur->Configuration.ATIMWindow; */
6205 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
6208 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
6211 /* EXTERNDED SUPPORTED RATE */
6214 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
6217 /* todo:HT for adhoc */
6221 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
6222 pmlmepriv->update_bcn = _FALSE;
6224 spin_unlock_bh(&pmlmepriv->bcn_update_lock);
6225 #endif /* if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6227 if ((pattrib->pktlen + TXDESC_SIZE) > 512)
6229 DBG_8723A("beacon frame too large\n");
6233 pattrib->last_txcmdsz = pattrib->pktlen;
6235 /* DBG_8723A("issue bcn_sz=%d\n", pattrib->last_txcmdsz); */
6237 dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
6239 dump_mgntframe(padapter, pmgntframe);
6242 void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
6244 struct xmit_frame *pmgntframe;
6245 struct pkt_attrib *pattrib;
6246 unsigned char *pframe;
6247 struct rtw_ieee80211_hdr *pwlanhdr;
6248 unsigned short *fctrl;
6249 unsigned char *mac, *bssid;
6250 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6251 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
6254 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6255 #endif /* if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
6256 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6257 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6258 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
6259 unsigned int rate_len;
6261 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6264 #endif /* CONFIG_WFD */
6265 #endif /* CONFIG_P2P */
6267 /* DBG_8723A("%s\n", __FUNCTION__); */
6269 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
6271 DBG_8723A("%s, alloc mgnt frame fail\n", __FUNCTION__);
6275 /* update attribute */
6276 pattrib = &pmgntframe->attrib;
6277 update_mgntframe_attrib(padapter, pattrib);
6279 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6281 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6282 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6284 mac = myid(&(padapter->eeprompriv));
6285 bssid = cur_network->MacAddress;
6287 fctrl = &(pwlanhdr->frame_ctl);
6289 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
6290 memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6291 memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
6293 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6294 pmlmeext->mgnt_seq++;
6295 SetFrameSubType(fctrl, WIFI_PROBERSP);
6297 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6298 pattrib->pktlen = pattrib->hdrlen;
6299 pframe += pattrib->hdrlen;
6301 if(cur_network->IELength>MAX_IE_SZ)
6304 #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
6305 if( (pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
6307 pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen);
6309 /* inerset & update wps_probe_resp_ie */
6310 if((pmlmepriv->wps_probe_resp_ie!=NULL) && pwps_ie && (wps_ielen>0))
6312 uint wps_offset, remainder_ielen;
6315 wps_offset = (uint)(pwps_ie - cur_network->IEs);
6317 premainder_ie = pwps_ie + wps_ielen;
6319 remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
6321 memcpy(pframe, cur_network->IEs, wps_offset);
6322 pframe += wps_offset;
6323 pattrib->pktlen += wps_offset;
6325 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];/* to get ie data len */
6326 if((wps_offset+wps_ielen+2)<=MAX_IE_SZ)
6328 memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2);
6329 pframe += wps_ielen+2;
6330 pattrib->pktlen += wps_ielen+2;
6333 if((wps_offset+wps_ielen+2+remainder_ielen)<=MAX_IE_SZ)
6335 memcpy(pframe, premainder_ie, remainder_ielen);
6336 pframe += remainder_ielen;
6337 pattrib->pktlen += remainder_ielen;
6342 memcpy(pframe, cur_network->IEs, cur_network->IELength);
6343 pframe += cur_network->IELength;
6344 pattrib->pktlen += cur_network->IELength;
6347 /* retrieve SSID IE from cur_network->Ssid */
6351 int ssid_ielen_diff;
6353 u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct rtw_ieee80211_hdr_3addr);
6355 ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
6356 (pframe-ies)-_FIXED_IE_LENGTH_);
6358 ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
6360 if (ssid_ie && cur_network->Ssid.SsidLength) {
6361 uint remainder_ielen;
6363 remainder_ie = ssid_ie+2;
6364 remainder_ielen = (pframe-remainder_ie);
6366 DBG_8723A_LEVEL(_drv_warning_, FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
6367 if (remainder_ielen > MAX_IE_SZ) {
6368 remainder_ielen = MAX_IE_SZ;
6371 memcpy(buf, remainder_ie, remainder_ielen);
6372 memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen);
6373 *(ssid_ie+1) = cur_network->Ssid.SsidLength;
6374 memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
6376 pframe += ssid_ielen_diff;
6377 pattrib->pktlen += ssid_ielen_diff;
6385 /* timestamp will be inserted by hardware */
6387 pattrib->pktlen += 8;
6389 /* beacon interval: 2 bytes */
6391 memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
6394 pattrib->pktlen += 2;
6396 /* capability info: 2 bytes */
6398 memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
6401 pattrib->pktlen += 2;
6403 /* below for ad-hoc mode */
6406 pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
6408 /* supported rates... */
6409 rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
6410 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8)? 8: rate_len), cur_network->SupportedRates, &pattrib->pktlen);
6412 /* DS parameter set */
6413 pframe =rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
6415 if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
6419 /* IBSS Parameter Set... */
6420 /* ATIMWindow = cur->Configuration.ATIMWindow; */
6422 pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
6425 pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
6428 /* EXTERNDED SUPPORTED RATE */
6431 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
6434 /* todo:HT for adhoc */
6439 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && is_valid_p2p_probereq)
6442 #ifdef CONFIG_IOCTL_CFG80211
6443 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
6445 /* if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p() */
6446 len = pmlmepriv->p2p_go_probe_resp_ie_len;
6447 if(pmlmepriv->p2p_go_probe_resp_ie && len>0)
6448 memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len);
6451 #endif /* CONFIG_IOCTL_CFG80211 */
6453 len = build_probe_resp_p2p_ie(pwdinfo, pframe);
6457 pattrib->pktlen += len;
6460 #ifdef CONFIG_IOCTL_CFG80211
6461 if(_TRUE == pwdinfo->wfd_info->wfd_enable)
6462 #endif /* CONFIG_IOCTL_CFG80211 */
6464 len = build_probe_resp_wfd_ie(pwdinfo, pframe, 0);
6466 #ifdef CONFIG_IOCTL_CFG80211
6470 if(pmlmepriv->wfd_probe_resp_ie && pmlmepriv->wfd_probe_resp_ie_len>0)
6472 len = pmlmepriv->wfd_probe_resp_ie_len;
6473 memcpy(pframe, pmlmepriv->wfd_probe_resp_ie, len);
6476 #endif /* CONFIG_IOCTL_CFG80211 */
6478 pattrib->pktlen += len;
6479 #endif /* CONFIG_WFD */
6482 #endif /* CONFIG_P2P */
6484 pattrib->last_txcmdsz = pattrib->pktlen;
6486 dump_mgntframe(padapter, pmgntframe);
6491 int _issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da, int wait_ack)
6494 struct xmit_frame *pmgntframe;
6495 struct pkt_attrib *pattrib;
6496 unsigned char *pframe;
6497 struct rtw_ieee80211_hdr *pwlanhdr;
6498 unsigned short *fctrl;
6500 unsigned char bssrate[NumRates];
6501 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6502 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6503 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6504 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6505 int bssrate_len = 0;
6506 u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
6508 RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("+issue_probereq\n"));
6510 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
6515 /* update attribute */
6516 pattrib = &pmgntframe->attrib;
6517 update_mgntframe_attrib(padapter, pattrib);
6519 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6521 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6522 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6524 mac = myid(&(padapter->eeprompriv));
6526 fctrl = &(pwlanhdr->frame_ctl);
6531 /* unicast probe request frame */
6532 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
6533 memcpy(pwlanhdr->addr3, da, ETH_ALEN);
6537 /* broadcast probe request frame */
6538 memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
6539 memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
6542 memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
6544 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6545 pmlmeext->mgnt_seq++;
6546 SetFrameSubType(pframe, WIFI_PROBEREQ);
6548 pframe += sizeof (struct rtw_ieee80211_hdr_3addr);
6549 pattrib->pktlen = sizeof (struct rtw_ieee80211_hdr_3addr);
6552 pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
6554 pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
6556 get_rate_set(padapter, bssrate, &bssrate_len);
6558 if (bssrate_len > 8)
6560 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
6561 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
6565 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
6568 /* add wps_ie for wps2.0 */
6569 if(pmlmepriv->wps_probe_req_ie_len>0 && pmlmepriv->wps_probe_req_ie)
6571 memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
6572 pframe += pmlmepriv->wps_probe_req_ie_len;
6573 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
6576 pattrib->last_txcmdsz = pattrib->pktlen;
6578 RT_TRACE(_module_rtl871x_mlme_c_,_drv_notice_,("issuing probe_req, tx_len=%d\n", pattrib->last_txcmdsz));
6581 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
6583 dump_mgntframe(padapter, pmgntframe);
6591 inline void issue_probereq(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da)
6593 _issue_probereq(padapter, pssid, da, _FALSE);
6596 int issue_probereq_ex(_adapter *padapter, NDIS_802_11_SSID *pssid, u8 *da,
6597 int try_cnt, int wait_ms)
6601 u32 start = rtw_get_current_time();
6605 ret = _issue_probereq(padapter, pssid, da, wait_ms>0?_TRUE:_FALSE);
6609 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
6612 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
6613 rtw_msleep_os(wait_ms);
6615 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
6619 #ifndef DBG_XMIT_ACK
6624 if (try_cnt && wait_ms) {
6626 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
6627 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
6628 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
6630 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
6631 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
6632 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
6638 /* if psta == NULL, indiate we are station(client) now... */
6639 void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status)
6641 struct xmit_frame *pmgntframe;
6642 struct pkt_attrib *pattrib;
6643 unsigned char *pframe;
6644 struct rtw_ieee80211_hdr *pwlanhdr;
6645 unsigned short *fctrl;
6647 unsigned short val16;
6648 int use_shared_key = 0;
6649 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6650 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6651 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6653 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
6658 /* update attribute */
6659 pattrib = &pmgntframe->attrib;
6660 update_mgntframe_attrib(padapter, pattrib);
6662 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6664 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6665 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6667 fctrl = &(pwlanhdr->frame_ctl);
6670 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6671 pmlmeext->mgnt_seq++;
6672 SetFrameSubType(pframe, WIFI_AUTH);
6674 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6675 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6677 if(psta)/* for AP mode */
6679 #ifdef CONFIG_NATIVEAP_MLME
6681 memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN);
6682 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
6683 memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN);
6685 /* setting auth algo number */
6686 val16 = (u16)psta->authalg;
6688 if(status != _STATS_SUCCESSFUL_)
6692 val16 = cpu_to_le16(val16);
6696 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
6698 /* setting auth seq number */
6699 val16 =(u16)psta->auth_seq;
6700 val16 = cpu_to_le16(val16);
6701 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
6703 /* setting status code... */
6705 val16 = cpu_to_le16(val16);
6706 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
6708 /* added challenging text... */
6709 if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
6711 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
6717 memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
6718 memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN);
6719 memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
6721 /* setting auth algo number */
6722 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)? 1: 0;/* 0:OPEN System, 1:Shared key */
6724 val16 = cpu_to_le16(val16);
6727 /* DBG_8723A("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq); */
6729 /* setting IV for auth seq #3 */
6730 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
6732 /* DBG_8723A("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index); */
6733 val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
6734 val32 = cpu_to_le32(val32);
6735 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen));
6737 pattrib->iv_len = 4;
6740 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
6742 /* setting auth seq number */
6743 val16 = pmlmeinfo->auth_seq;
6744 val16 = cpu_to_le16(val16);
6745 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
6747 /* setting status code... */
6749 val16 = cpu_to_le16(val16);
6750 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
6752 /* then checking to see if sending challenging text... */
6753 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key==1))
6755 pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
6759 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6761 pattrib->encrypt = _WEP40_;
6763 pattrib->icv_len = 4;
6765 pattrib->pktlen += pattrib->icv_len;
6771 pattrib->last_txcmdsz = pattrib->pktlen;
6773 rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
6774 DBG_8723A("%s\n", __FUNCTION__);
6775 dump_mgntframe(padapter, pmgntframe);
6780 void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
6782 #ifdef CONFIG_AP_MODE
6783 struct xmit_frame *pmgntframe;
6784 struct rtw_ieee80211_hdr *pwlanhdr;
6785 struct pkt_attrib *pattrib;
6786 unsigned char *pbuf, *pframe;
6788 unsigned short *fctrl;
6789 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6790 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6791 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6792 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6793 WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
6794 u8 *ie = pnetwork->IEs;
6796 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6799 #endif /* CONFIG_WFD */
6801 #endif /* CONFIG_P2P */
6803 DBG_8723A("%s\n", __FUNCTION__);
6805 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
6810 /* update attribute */
6811 pattrib = &pmgntframe->attrib;
6812 update_mgntframe_attrib(padapter, pattrib);
6814 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6816 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6817 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6819 fctrl = &(pwlanhdr->frame_ctl);
6822 memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN);
6823 memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&(padapter->eeprompriv)), ETH_ALEN);
6824 memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
6826 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6827 pmlmeext->mgnt_seq++;
6828 if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
6829 SetFrameSubType(pwlanhdr, pkt_type);
6833 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6834 pattrib->pktlen += pattrib->hdrlen;
6835 pframe += pattrib->hdrlen;
6838 val = *(unsigned short *)rtw_get_capability_from_ie(ie);
6840 pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen));
6842 status = cpu_to_le16(status);
6843 pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&status, &(pattrib->pktlen));
6845 val = cpu_to_le16(pstat->aid | BIT(14) | BIT(15));
6846 pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen));
6848 if (pstat->bssratelen <= 8)
6850 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
6854 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
6855 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen));
6858 #ifdef CONFIG_80211N_HT
6859 if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option))
6863 /* FILL HT CAP INFO IE */
6864 /* p = hostapd_eid_ht_capabilities_info(hapd, p); */
6865 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
6866 if(pbuf && ie_len>0)
6868 memcpy(pframe, pbuf, ie_len+2);
6869 pframe += (ie_len+2);
6870 pattrib->pktlen +=(ie_len+2);
6873 /* FILL HT ADD INFO IE */
6874 /* p = hostapd_eid_ht_operation(hapd, p); */
6875 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
6876 if(pbuf && ie_len>0)
6878 memcpy(pframe, pbuf, ie_len+2);
6879 pframe += (ie_len+2);
6880 pattrib->pktlen +=(ie_len+2);
6887 if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option))
6890 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
6892 for (pbuf = ie + _BEACON_IE_OFFSET_; ;pbuf+= (ie_len + 2))
6894 pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
6895 if (pbuf && !memcmp(pbuf+2, WMM_PARA_IE, 6))
6897 memcpy(pframe, pbuf, ie_len+2);
6898 pframe += (ie_len+2);
6899 pattrib->pktlen +=(ie_len+2);
6904 if ((pbuf == NULL) || (ie_len == 0))
6912 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
6914 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
6917 /* add WPS IE ie for wps 2.0 */
6918 if(pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len>0)
6920 memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
6922 pframe += pmlmepriv->wps_assoc_resp_ie_len;
6923 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
6927 #ifndef CONFIG_IOCTL_CFG80211
6928 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE))
6932 len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
6935 pattrib->pktlen += len;
6937 #endif /* CONFIG_IOCTL_CFG80211 */
6939 if(rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
6940 #ifdef CONFIG_IOCTL_CFG80211
6941 && (_TRUE == pwdinfo->wfd_info->wfd_enable)
6942 #endif /* CONFIG_IOCTL_CFG80211 */
6945 wfdielen = build_assoc_resp_wfd_ie(pwdinfo, pframe);
6947 pattrib->pktlen += wfdielen;
6949 #endif /* CONFIG_WFD */
6950 #endif /* CONFIG_P2P */
6952 pattrib->last_txcmdsz = pattrib->pktlen;
6954 dump_mgntframe(padapter, pmgntframe);
6959 void issue_assocreq(_adapter *padapter)
6962 struct xmit_frame *pmgntframe;
6963 struct pkt_attrib *pattrib;
6964 unsigned char *pframe, *p;
6965 struct rtw_ieee80211_hdr *pwlanhdr;
6966 unsigned short *fctrl;
6967 unsigned short val16;
6968 unsigned int i, j, ie_len, index=0;
6969 unsigned char rf_type, bssrate[NumRates], sta_bssrate[NumRates];
6970 PNDIS_802_11_VARIABLE_IEs pIE;
6971 struct registry_priv *pregpriv = &padapter->registrypriv;
6972 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6973 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6974 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6975 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6976 int bssrate_len = 0, sta_bssrate_len = 0;
6978 struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6979 u8 p2pie[ 255 ] = { 0x00 };
6983 #endif /* CONFIG_WFD */
6984 #endif /* CONFIG_P2P */
6988 #endif /* CONFIG_DFS */
6990 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
6993 /* update attribute */
6994 pattrib = &pmgntframe->attrib;
6995 update_mgntframe_attrib(padapter, pattrib);
6997 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6999 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7000 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7002 fctrl = &(pwlanhdr->frame_ctl);
7004 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7005 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
7006 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7008 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7009 pmlmeext->mgnt_seq++;
7010 SetFrameSubType(pframe, WIFI_ASSOCREQ);
7012 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7013 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7018 memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
7020 memcpy(pframe, &cap, 2);
7022 memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
7023 #endif /* CONFIG_DFS */
7026 pattrib->pktlen += 2;
7028 /* listen interval */
7029 /* todo: listen interval for power saving */
7030 val16 = cpu_to_le16(3);
7031 memcpy(pframe ,(unsigned char *)&val16, 2);
7033 pattrib->pktlen += 2;
7036 pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
7038 /* supported rate & extended supported rate */
7040 #if 1 /* Check if the AP's supported rates are also supported by STA. */
7041 get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
7042 /* DBG_8723A("sta_bssrate_len=%d\n", sta_bssrate_len); */
7044 if(pmlmeext->cur_channel == 14)/* for JAPAN, channel 14 can only uses B Mode(CCK) */
7046 sta_bssrate_len = 4;
7049 /* for (i = 0; i < sta_bssrate_len; i++) { */
7050 /* DBG_8723A("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
7053 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
7054 if (pmlmeinfo->network.SupportedRates[i] == 0) break;
7055 DBG_8723A("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
7058 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
7059 if (pmlmeinfo->network.SupportedRates[i] == 0) break;
7061 /* Check if the AP's supported rates are also supported by STA. */
7062 for (j=0; j < sta_bssrate_len; j++) {
7063 /* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
7064 if ( (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK)
7065 == (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)) {
7066 /* DBG_8723A("match i = %d, j=%d\n", i, j); */
7069 /* DBG_8723A("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)); */
7073 if (j == sta_bssrate_len) {
7074 /* the rate is not supported by STA */
7075 DBG_8723A("%s(): the rate[%d]=%02X is not supported by STA!\n",__FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]);
7077 /* the rate is supported by STA */
7078 bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
7082 bssrate_len = index;
7083 DBG_8723A("bssrate_len = %d\n", bssrate_len);
7085 #endif /* Check if the AP's supported rates are also supported by STA. */
7087 if (bssrate_len == 0) {
7088 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
7089 rtw_free_xmitframe(pxmitpriv, pmgntframe);
7090 goto exit; /* don't connect to AP if no joint supported rate */
7093 if (bssrate_len > 8)
7095 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
7096 pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
7100 pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
7104 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)));
7107 pframe = rtw_set_ie(pframe, _RSN_IE_2_, ie_len, (p + 2), &(pattrib->pktlen));
7110 #ifdef CONFIG_80211N_HT
7112 if(padapter->mlmepriv.htpriv.ht_option==_TRUE)
7114 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)));
7115 if ((p != NULL) && (!(is_ap_in_tkip(padapter))))
7117 memcpy(&(pmlmeinfo->HT_caps), (p + 2), sizeof(struct HT_caps_element));
7119 /* to disable 40M Hz support while gd_bw_40MHz_en = 0 */
7120 if (pregpriv->cbw40_enable == 0)
7122 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info &= (~(BIT(6) | BIT(1)));
7126 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= BIT(1);
7129 /* todo: disable SM power save mode */
7130 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= 0x000c;
7132 rtw_hal_get_hwreg(padapter, HW_VAR_RF_TYPE, (u8 *)(&rf_type));
7133 /* switch (pregpriv->rf_config) */
7138 if(pregpriv->rx_stbc)
7139 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);/* RX STBC One spatial stream */
7141 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16);
7148 if((pregpriv->rx_stbc == 0x3) ||/* enable for 2.4/5 GHz */
7149 ((pmlmeext->cur_wireless_mode & WIRELESS_11_24N) && (pregpriv->rx_stbc == 0x1)) || /* enable for 2.4GHz */
7150 ((pmlmeext->cur_wireless_mode & WIRELESS_11_5N) && (pregpriv->rx_stbc == 0x2)) || /* enable for 5GHz */
7151 (pregpriv->wifi_spec==1))
7153 DBG_8723A("declare supporting RX STBC\n");
7154 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0200);/* RX STBC two spatial stream */
7156 #ifdef CONFIG_DISABLE_MCS13TO15
7157 if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40 && (pregpriv->wifi_spec!=1))
7158 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R_MCS13TO15_OFF, 16);
7160 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R, 16);
7161 #else /* CONFIG_DISABLE_MCS13TO15 */
7162 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_2R, 16);
7163 #endif /* CONFIG_DISABLE_MCS13TO15 */
7166 #ifdef RTL8192C_RECONFIG_TO_1T1R
7168 if(pregpriv->rx_stbc)
7169 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info |= cpu_to_le16(0x0100);/* RX STBC One spatial stream */
7171 memcpy(pmlmeinfo->HT_caps.u.HT_cap_element.MCS_rate, MCS_rate_1R, 16);
7174 pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
7176 #ifdef CONFIG_BT_COEXIST
7177 if (BT_1Ant(padapter) == _TRUE)
7180 pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para &= (u8)~IEEE80211_HT_CAP_AMPDU_FACTOR;
7181 /* pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para |= MAX_AMPDU_FACTOR_8K */
7185 pframe = rtw_set_ie(pframe, _HT_CAPABILITY_IE_, ie_len , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
7191 /* vendor specific IE, such as WPA, WMM, WPS */
7192 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;)
7194 pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
7196 switch (pIE->ElementID)
7198 case _VENDOR_SPECIFIC_IE_:
7199 if (!memcmp(pIE->data, RTW_WPA_OUI, 4) ||
7200 !memcmp(pIE->data, WMM_OUI, 4) ||
7201 !memcmp(pIE->data, WPS_OUI, 4)) {
7202 if (!padapter->registrypriv.wifi_spec)
7204 /* Commented by Kurt 20110629 */
7205 /* In some older APs, WPS handshake */
7206 /* would be fail if we append vender extensions informations to AP */
7207 if (!memcmp(pIE->data,
7212 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, pIE->Length, pIE->data, &(pattrib->pktlen));
7220 i += (pIE->Length + 2);
7223 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
7225 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
7228 #ifdef CONFIG_WAPI_SUPPORT
7229 rtw_build_assoc_req_wapi_ie(padapter, pframe, pattrib);
7234 #ifdef CONFIG_IOCTL_CFG80211
7235 if(wdev_to_priv(padapter->rtw_wdev)->p2p_enabled)
7237 if(pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len>0)
7239 memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len);
7240 pframe += pmlmepriv->p2p_assoc_req_ie_len;
7241 pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
7245 #endif /* CONFIG_IOCTL_CFG80211 */
7247 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
7249 /* Should add the P2P IE in the association request frame. */
7253 p2pie[ p2pielen++ ] = 0x50;
7254 p2pie[ p2pielen++ ] = 0x6F;
7255 p2pie[ p2pielen++ ] = 0x9A;
7256 p2pie[ p2pielen++ ] = 0x09; /* WFA P2P v1.0 */
7258 /* Commented by Albert 20101109 */
7259 /* According to the P2P Specification, the association request frame should contain 3 P2P attributes */
7260 /* 1. P2P Capability */
7261 /* 2. Extended Listen Timing */
7262 /* 3. Device Info */
7263 /* Commented by Albert 20110516 */
7264 /* 4. P2P Interface */
7266 /* P2P Capability */
7268 p2pie[ p2pielen++ ] = P2P_ATTR_CAPABILITY;
7271 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 );
7275 /* Device Capability Bitmap, 1 byte */
7276 p2pie[ p2pielen++ ] = DMP_P2P_DEVCAP_SUPPORT;
7278 /* Group Capability Bitmap, 1 byte */
7279 if ( pwdinfo->persistent_supported )
7280 p2pie[ p2pielen++ ] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
7282 p2pie[ p2pielen++ ] = DMP_P2P_GRPCAP_SUPPORT;
7284 /* Extended Listen Timing */
7286 p2pie[ p2pielen++ ] = P2P_ATTR_EX_LISTEN_TIMING;
7289 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0004 );
7293 /* Availability Period */
7294 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
7297 /* Availability Interval */
7298 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0xFFFF );
7303 p2pie[ p2pielen++ ] = P2P_ATTR_DEVICE_INFO;
7306 /* 21 -> P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
7307 /* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
7308 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len );
7312 /* P2P Device Address */
7313 memcpy(p2pie + p2pielen, myid( &padapter->eeprompriv ), ETH_ALEN );
7314 p2pielen += ETH_ALEN;
7317 /* This field should be big endian. Noted by P2P specification. */
7318 if ( ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN ) ||
7319 ( pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN ) )
7321 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_DISPLAY );
7325 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_CONFIG_METHOD_PBC );
7330 /* Primary Device Type */
7332 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_CID_MULIT_MEDIA );
7336 *(u32*) ( p2pie + p2pielen ) = cpu_to_be32( WPSOUI );
7339 /* Sub Category ID */
7340 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_PDT_SCID_MEDIA_SERVER );
7343 /* Number of Secondary Device Types */
7344 p2pie[ p2pielen++ ] = 0x00; /* No Secondary Device Type List */
7348 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( WPS_ATTR_DEVICE_NAME );
7352 *(u16*) ( p2pie + p2pielen ) = cpu_to_be16( pwdinfo->device_name_len );
7356 memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len );
7357 p2pielen += pwdinfo->device_name_len;
7361 p2pie[ p2pielen++ ] = P2P_ATTR_INTERFACE;
7364 *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x000D );
7368 memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); /* P2P Device Address */
7369 p2pielen += ETH_ALEN;
7371 p2pie[ p2pielen++ ] = 1; /* P2P Interface Address Count */
7373 memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN ); /* P2P Interface Address List */
7374 p2pielen += ETH_ALEN;
7376 pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen );
7379 /* wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe); */
7380 /* pframe += wfdielen; */
7381 /* pattrib->pktlen += wfdielen; */
7382 #endif /* CONFIG_WFD */
7386 #endif /* CONFIG_P2P */
7389 #ifdef CONFIG_IOCTL_CFG80211
7390 if ( _TRUE == pwdinfo->wfd_info->wfd_enable )
7391 #endif /* CONFIG_IOCTL_CFG80211 */
7393 wfdielen = build_assoc_req_wfd_ie(pwdinfo, pframe);
7395 pattrib->pktlen += wfdielen;
7397 #ifdef CONFIG_IOCTL_CFG80211
7398 else if (pmlmepriv->wfd_assoc_req_ie != NULL && pmlmepriv->wfd_assoc_req_ie_len>0)
7401 memcpy(pframe, pmlmepriv->wfd_assoc_req_ie, pmlmepriv->wfd_assoc_req_ie_len);
7402 pattrib->pktlen += pmlmepriv->wfd_assoc_req_ie_len;
7403 pframe += pmlmepriv->wfd_assoc_req_ie_len;
7405 #endif /* CONFIG_IOCTL_CFG80211 */
7406 #endif /* CONFIG_WFD */
7408 pattrib->last_txcmdsz = pattrib->pktlen;
7409 dump_mgntframe(padapter, pmgntframe);
7414 if (ret == _SUCCESS)
7415 rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
7417 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
7422 /* when wait_ack is ture, this function shoule be called at process context */
7423 static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
7426 struct xmit_frame *pmgntframe;
7427 struct pkt_attrib *pattrib;
7428 unsigned char *pframe;
7429 struct rtw_ieee80211_hdr *pwlanhdr;
7430 unsigned short *fctrl;
7431 struct xmit_priv *pxmitpriv;
7432 struct mlme_ext_priv *pmlmeext;
7433 struct mlme_ext_info *pmlmeinfo;
7435 /* DBG_8723A("%s:%d\n", __FUNCTION__, power_mode); */
7440 pxmitpriv = &(padapter->xmitpriv);
7441 pmlmeext = &(padapter->mlmeextpriv);
7442 pmlmeinfo = &(pmlmeext->mlmext_info);
7444 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7449 /* update attribute */
7450 pattrib = &pmgntframe->attrib;
7451 update_mgntframe_attrib(padapter, pattrib);
7452 pattrib->retry_ctrl = _FALSE;
7454 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7456 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7457 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7459 fctrl = &(pwlanhdr->frame_ctl);
7462 if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7466 else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
7476 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
7477 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
7478 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7480 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7481 pmlmeext->mgnt_seq++;
7482 SetFrameSubType(pframe, WIFI_DATA_NULL);
7484 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7485 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7487 pattrib->last_txcmdsz = pattrib->pktlen;
7491 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
7495 dump_mgntframe(padapter, pmgntframe);
7503 /* when wait_ms >0 , this function shoule be called at process context */
7504 /* da == NULL for station mode */
7505 int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
7509 u32 start = rtw_get_current_time();
7510 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7511 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7513 /* da == NULL, assum it's null data for sta to ap*/
7515 da = get_my_bssid(&(pmlmeinfo->network));
7519 ret = _issue_nulldata(padapter, da, power_mode, wait_ms>0?_TRUE:_FALSE);
7523 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
7526 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
7527 rtw_msleep_os(wait_ms);
7529 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
7533 #ifndef DBG_XMIT_ACK
7538 if (try_cnt && wait_ms) {
7540 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
7541 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
7542 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
7544 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
7545 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
7546 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
7552 /* when wait_ack is ture, this function shoule be called at process context */
7553 static int _issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int wait_ack)
7556 struct xmit_frame *pmgntframe;
7557 struct pkt_attrib *pattrib;
7558 unsigned char *pframe;
7559 struct rtw_ieee80211_hdr *pwlanhdr;
7560 unsigned short *fctrl, *qc;
7561 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7562 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7563 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7565 DBG_8723A("%s\n", __FUNCTION__);
7567 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7572 /* update attribute */
7573 pattrib = &pmgntframe->attrib;
7574 update_mgntframe_attrib(padapter, pattrib);
7576 pattrib->hdrlen +=2;
7577 pattrib->qos_en = _TRUE;
7579 pattrib->ack_policy = 0;
7582 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7584 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7585 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7587 fctrl = &(pwlanhdr->frame_ctl);
7590 if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
7594 else if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
7602 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
7604 SetPriority(qc, tid);
7606 SetEOSP(qc, pattrib->eosp);
7608 SetAckpolicy(qc, pattrib->ack_policy);
7610 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
7611 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
7612 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7614 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7615 pmlmeext->mgnt_seq++;
7616 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL);
7618 pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos);
7619 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos);
7621 pattrib->last_txcmdsz = pattrib->pktlen;
7625 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
7629 dump_mgntframe(padapter, pmgntframe);
7637 /* when wait_ms >0 , this function shoule be called at process context */
7638 /* da == NULL for station mode */
7639 int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms)
7643 u32 start = rtw_get_current_time();
7644 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7645 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7647 /* da == NULL, assum it's null data for sta to ap*/
7649 da = get_my_bssid(&(pmlmeinfo->network));
7653 ret = _issue_qos_nulldata(padapter, da, tid, wait_ms>0?_TRUE:_FALSE);
7657 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
7660 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
7661 rtw_msleep_os(wait_ms);
7663 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
7667 #ifndef DBG_XMIT_ACK
7672 if (try_cnt && wait_ms) {
7674 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
7675 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
7676 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
7678 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
7679 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
7680 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
7686 static int _issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack)
7688 struct xmit_frame *pmgntframe;
7689 struct pkt_attrib *pattrib;
7690 unsigned char *pframe;
7691 struct rtw_ieee80211_hdr *pwlanhdr;
7692 unsigned short *fctrl;
7693 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7694 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7695 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7698 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
7699 #endif /* CONFIG_P2P */
7701 /* DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
7704 if ( !( rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) ) && ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) )
7706 _cancel_timer_ex( &pwdinfo->reset_ch_sitesurvey );
7707 _set_timer( &pwdinfo->reset_ch_sitesurvey, 10 );
7709 #endif /* CONFIG_P2P */
7711 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7716 /* update attribute */
7717 pattrib = &pmgntframe->attrib;
7718 update_mgntframe_attrib(padapter, pattrib);
7719 pattrib->retry_ctrl = _FALSE;
7721 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7723 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7724 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7726 fctrl = &(pwlanhdr->frame_ctl);
7729 memcpy(pwlanhdr->addr1, da, ETH_ALEN);
7730 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
7731 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7733 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7734 pmlmeext->mgnt_seq++;
7735 SetFrameSubType(pframe, WIFI_DEAUTH);
7737 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7738 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7740 reason = cpu_to_le16(reason);
7741 pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(pattrib->pktlen));
7743 pattrib->last_txcmdsz = pattrib->pktlen;
7747 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
7751 dump_mgntframe(padapter, pmgntframe);
7759 int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason)
7761 DBG_8723A("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
7762 return _issue_deauth(padapter, da, reason, _FALSE);
7765 int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
7770 u32 start = rtw_get_current_time();
7774 ret = _issue_deauth(padapter, da, reason, wait_ms>0?_TRUE:_FALSE);
7778 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
7781 if(i < try_cnt && wait_ms > 0 && ret==_FAIL)
7782 rtw_msleep_os(wait_ms);
7784 }while((i<try_cnt) && ((ret==_FAIL)||(wait_ms==0)));
7788 #ifndef DBG_XMIT_ACK
7793 if (try_cnt && wait_ms) {
7795 DBG_8723A(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
7796 FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
7797 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
7799 DBG_8723A(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
7800 FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
7801 ret==_SUCCESS?", acked":"", i, try_cnt, rtw_get_passing_time_ms(start));
7807 void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
7810 _list *plist, *phead;
7811 struct xmit_frame *pmgntframe;
7812 struct pkt_attrib *pattrib;
7813 unsigned char *pframe;
7814 struct rtw_ieee80211_hdr *pwlanhdr;
7815 unsigned short *fctrl;
7816 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7817 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7818 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7819 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7821 DBG_8723A(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n",
7822 FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset);
7824 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7827 /* update attribute */
7828 pattrib = &pmgntframe->attrib;
7829 update_mgntframe_attrib(padapter, pattrib);
7831 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7833 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7834 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7836 fctrl = &(pwlanhdr->frame_ctl);
7839 memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
7840 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); /* TA */
7841 memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
7843 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7844 pmlmeext->mgnt_seq++;
7845 SetFrameSubType(pframe, WIFI_ACTION);
7847 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7848 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7850 /* category, action */
7852 u8 category, action;
7853 category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
7854 action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
7856 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
7857 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
7860 pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0);
7861 pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen),
7862 hal_ch_offset_to_secondary_ch_offset(ch_offset));
7864 pattrib->last_txcmdsz = pattrib->pktlen;
7866 dump_mgntframe(padapter, pmgntframe);
7869 void issue_action_BA(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short status)
7871 u8 category = RTW_WLAN_CATEGORY_BACK;
7875 u16 BA_timeout_value;
7876 u16 BA_starting_seqctrl;
7877 HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
7878 struct xmit_frame *pmgntframe;
7879 struct pkt_attrib *pattrib;
7881 struct rtw_ieee80211_hdr *pwlanhdr;
7883 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7884 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7885 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7886 struct sta_info *psta;
7887 struct sta_priv *pstapriv = &padapter->stapriv;
7888 struct registry_priv *pregpriv = &padapter->registrypriv;
7889 #ifdef CONFIG_BT_COEXIST
7890 u8 tendaAPMac[] = {0xC8, 0x3A, 0x35};
7893 #ifdef CONFIG_80211N_HT
7894 DBG_8723A("%s, category=%d, action=%d, status=%d\n", __FUNCTION__, category, action, status);
7896 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7901 /* update attribute */
7902 pattrib = &pmgntframe->attrib;
7903 update_mgntframe_attrib(padapter, pattrib);
7905 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7907 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7908 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7910 fctrl = &(pwlanhdr->frame_ctl);
7913 /* memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */
7914 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
7915 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
7916 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
7918 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7919 pmlmeext->mgnt_seq++;
7920 SetFrameSubType(pframe, WIFI_ACTION);
7922 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7923 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7925 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
7926 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
7928 status = cpu_to_le16(status);
7934 case 0: /* ADDBA req */
7936 pmlmeinfo->dialogToken++;
7937 } while (pmlmeinfo->dialogToken == 0);
7938 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
7940 #ifdef CONFIG_BT_COEXIST
7941 if ((BT_1Ant(padapter) == _TRUE) &&
7942 ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
7943 memcmp(raddr, tendaAPMac, 3)))
7945 /* A-MSDU NOT Supported */
7947 /* immediate Block Ack */
7948 BA_para_set |= (1 << 1) & IEEE80211_ADDBA_PARAM_POLICY_MASK;
7950 BA_para_set |= (status << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
7951 /* max buffer size is 8 MSDU */
7952 BA_para_set |= (8 << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
7957 #if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI)
7958 BA_para_set = (0x0802 | ((status & 0xf) << 2)); /* immediate ack & 16 buffer size */
7960 BA_para_set = (0x1002 | ((status & 0xf) << 2)); /* immediate ack & 64 buffer size */
7963 BA_para_set = cpu_to_le16(BA_para_set);
7964 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
7966 BA_timeout_value = 5000;/* 5ms */
7967 BA_timeout_value = cpu_to_le16(BA_timeout_value);
7968 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen));
7970 /* if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL) */
7971 if ((psta = rtw_get_stainfo(pstapriv, raddr)) != NULL)
7973 start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1;
7975 DBG_8723A("BA_starting_seqctrl = %d for TID=%d\n", start_seq, status & 0x07);
7977 psta->BA_starting_seqctrl[status & 0x07] = start_seq;
7979 BA_starting_seqctrl = start_seq << 4;
7982 BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
7983 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen));
7986 case 1: /* ADDBA rsp */
7987 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
7988 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
7989 rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
7990 if(MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor)
7991 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
7992 else if(MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor)
7993 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800); /* 32 buffer size */
7994 else if(MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor)
7995 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0400); /* 16 buffer size */
7996 else if(MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor)
7997 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0200); /* 8 buffer size */
7999 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */
8001 #ifdef CONFIG_BT_COEXIST
8002 if ((BT_1Ant(padapter) == _TRUE) &&
8003 ((pmlmeinfo->assoc_AP_vendor != broadcomAP) ||
8004 memcmp(raddr, tendaAPMac, 3)))
8006 /* max buffer size is 8 MSDU */
8007 BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
8008 BA_para_set |= (8 << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
8012 if(pregpriv->ampdu_amsdu==0)/* disabled */
8013 BA_para_set = cpu_to_le16(BA_para_set & ~BIT(0));
8014 else if(pregpriv->ampdu_amsdu==1)/* enabled */
8015 BA_para_set = cpu_to_le16(BA_para_set | BIT(0));
8017 BA_para_set = cpu_to_le16(BA_para_set);
8019 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
8020 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
8023 BA_para_set = (status & 0x1F) << 3;
8024 BA_para_set = cpu_to_le16(BA_para_set);
8025 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
8027 reason_code = 37;/* Requested from peer STA as it does not want to use the mechanism */
8028 reason_code = cpu_to_le16(reason_code);
8029 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(reason_code)), &(pattrib->pktlen));
8036 pattrib->last_txcmdsz = pattrib->pktlen;
8038 dump_mgntframe(padapter, pmgntframe);
8039 #endif /* CONFIG_80211N_HT */
8042 static void issue_action_BSSCoexistPacket(_adapter *padapter)
8045 _list *plist, *phead;
8046 unsigned char category, action;
8047 struct xmit_frame *pmgntframe;
8048 struct pkt_attrib *pattrib;
8049 unsigned char *pframe;
8050 struct rtw_ieee80211_hdr *pwlanhdr;
8051 unsigned short *fctrl;
8052 struct wlan_network *pnetwork = NULL;
8053 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8054 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8055 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8056 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8057 _queue *queue = &(pmlmepriv->scanned_queue);
8058 u8 InfoContent[16] = {0};
8060 #ifdef CONFIG_80211N_HT
8061 if((pmlmepriv->num_FortyMHzIntolerant==0) || (pmlmepriv->num_sta_no_ht==0))
8064 if(_TRUE == pmlmeinfo->bwmode_updated)
8067 DBG_8723A("%s\n", __FUNCTION__);
8069 category = RTW_WLAN_CATEGORY_PUBLIC;
8070 action = ACT_PUBLIC_BSSCOEXIST;
8072 if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
8077 /* update attribute */
8078 pattrib = &pmgntframe->attrib;
8079 update_mgntframe_attrib(padapter, pattrib);
8081 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8083 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8084 pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8086 fctrl = &(pwlanhdr->frame_ctl);
8089 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8090 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN);
8091 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8093 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8094 pmlmeext->mgnt_seq++;
8095 SetFrameSubType(pframe, WIFI_ACTION);
8097 pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8098 pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8100 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
8101 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
8104 if(pmlmepriv->num_FortyMHzIntolerant>0)
8108 iedata |= BIT(2);/* 20 MHz BSS Width Request */
8110 pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
8115 memset(ICS, 0, sizeof(ICS));
8116 if(pmlmepriv->num_sta_no_ht>0)
8120 spin_lock_bh(&(pmlmepriv->scanned_queue.lock));
8122 phead = get_list_head(queue);
8123 plist = get_next(phead);
8129 WLAN_BSSID_EX *pbss_network;
8131 if (rtw_end_of_queue_search(phead,plist)== _TRUE)
8134 pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
8136 plist = get_next(plist);
8138 pbss_network = (WLAN_BSSID_EX *)&pnetwork->network;
8140 p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
8141 if((p==NULL) || (len==0))/* non-HT */
8143 if((pbss_network->Configuration.DSConfig<=0) || (pbss_network->Configuration.DSConfig>14))
8146 ICS[0][pbss_network->Configuration.DSConfig]=1;
8154 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock));
8163 /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i); */
8172 InfoContent[k] = j; /* channel number */
8173 /* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */
8179 pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
8187 pattrib->last_txcmdsz = pattrib->pktlen;
8189 dump_mgntframe(padapter, pmgntframe);
8190 #endif /* CONFIG_80211N_HT */
8193 unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr)
8195 struct sta_priv *pstapriv = &padapter->stapriv;
8196 struct sta_info *psta = NULL;
8197 /* struct recv_reorder_ctrl *preorder_ctrl; */
8198 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8199 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8202 if((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE)
8203 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
8206 psta = rtw_get_stainfo(pstapriv, addr);
8210 /* DBG_8723A("%s:%s\n", __FUNCTION__, (initiator==0)?"RX_DIR":"TX_DIR"); */
8212 if(initiator==0) /* recipient */
8214 for(tid = 0;tid<MAXTID;tid++)
8216 if(psta->recvreorder_ctrl[tid].enable == _TRUE)
8218 DBG_8723A("rx agg disable tid(%d)\n",tid);
8219 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F));
8220 psta->recvreorder_ctrl[tid].enable = _FALSE;
8221 psta->recvreorder_ctrl[tid].indicate_seq = 0xffff;
8223 DBG_8723A("DBG_RX_SEQ %s:%d indicate_seq:%u \n", __FUNCTION__, __LINE__,
8224 psta->recvreorder_ctrl[tid].indicate_seq);
8229 else if(initiator == 1)/* originator */
8231 #ifdef CONFIG_80211N_HT
8232 /* DBG_8723A("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap); */
8233 for(tid = 0;tid<MAXTID;tid++)
8235 if(psta->htpriv.agg_enable_bitmap & BIT(tid))
8237 DBG_8723A("tx agg disable tid(%d)\n",tid);
8238 issue_action_BA(padapter, addr, RTW_WLAN_ACTION_DELBA, (((tid <<1) |initiator)&0x1F) );
8239 psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
8240 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
8244 #endif /* CONFIG_80211N_HT */
8250 unsigned int send_beacon(_adapter *padapter)
8252 u8 bxmitok = _FALSE;
8255 /* ifdef CONFIG_CONCURRENT_MODE */
8256 /* struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); */
8257 /* struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); */
8258 /* _adapter *pbuddy_adapter = padapter->pbuddy_adapter; */
8259 /* struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv); */
8262 #ifdef CONFIG_PCI_HCI
8264 /* DBG_8723A("%s\n", __FUNCTION__); */
8266 issue_beacon(padapter, 0);
8272 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
8273 u32 start = rtw_get_current_time();
8275 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
8277 issue_beacon(padapter, 100);
8281 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
8283 }while((poll%10)!=0 && _FALSE == bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
8285 }while(_FALSE == bxmitok && issue<100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped);
8287 if(padapter->bSurpriseRemoved || padapter->bDriverStopped)
8292 if(_FALSE == bxmitok)
8294 DBG_8723A("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
8299 u32 passing_time = rtw_get_passing_time_ms(start);
8301 if(passing_time > 100 || issue > 3)
8302 DBG_8723A("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
8304 /* DBG_8723A("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start)); */
8312 /****************************************************************************
8314 Following are some utitity fuctions for WiFi MLME
8316 *****************************************************************************/
8318 bool IsLegal5GChannel(
8319 IN PADAPTER Adapter,
8324 u8 Channel_5G[45] = {36,38,40,42,44,46,48,50,52,54,56,58,
8325 60,62,64,100,102,104,106,108,110,112,114,116,118,120,122,
8326 124,126,128,130,132,134,136,138,140,149,151,153,155,157,159,
8328 for(i=0;i<sizeof(Channel_5G);i++)
8329 if(channel == Channel_5G[i])
8334 void site_survey(_adapter *padapter)
8336 unsigned char survey_channel = 0, val8;
8337 RT_SCAN_TYPE ScanType = SCAN_PASSIVE;
8338 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8339 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8340 u32 initialgain = 0;
8344 #ifdef CONFIG_CONCURRENT_MODE
8346 #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
8347 u8 stay_buddy_ch = 0;
8348 #endif /* CONFIG_STA_MODE_SCAN_UNDER_AP_MODE */
8350 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8351 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
8352 struct mlme_ext_priv *pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
8354 #endif /* CONFIG_CONCURRENT_MODE */
8355 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
8356 static unsigned char prev_survey_channel = 0;
8357 static unsigned int p2p_scan_count = 0;
8359 if ( ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) || ( pwdinfo->p2p_info.scan_op_ch_only ) )
8361 if ( pwdinfo->rx_invitereq_info.scan_op_ch_only )
8363 survey_channel = pwdinfo->rx_invitereq_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
8367 survey_channel = pwdinfo->p2p_info.operation_ch[pmlmeext->sitesurvey_res.channel_idx];
8369 ScanType = SCAN_ACTIVE;
8371 else if(rtw_p2p_findphase_ex_is_social(pwdinfo))
8373 /* Commented by Albert 2011/06/03 */
8374 /* The driver is in the find phase, it should go through the social channel. */
8376 survey_channel = pwdinfo->social_chan[pmlmeext->sitesurvey_res.channel_idx];
8377 ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, survey_channel);
8378 if (ch_set_idx >= 0)
8379 ScanType = pmlmeext->channel_set[ch_set_idx].ScanType;
8381 ScanType = SCAN_ACTIVE;
8384 #endif /* CONFIG_P2P */
8386 struct rtw_ieee80211_channel *ch;
8387 if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) {
8388 ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx];
8389 survey_channel = ch->hw_value;
8390 ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
8395 DBG_8723A(FUNC_ADPT_FMT" ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c\n"
8396 , FUNC_ADPT_ARG(padapter)
8398 , pwdinfo->find_phase_state_exchange_cnt, pmlmeext->sitesurvey_res.channel_idx
8399 , rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
8400 , ScanType?'A':'P', pmlmeext->sitesurvey_res.scan_mode?'A':'P'
8401 , pmlmeext->sitesurvey_res.ssid[0].SsidLength?'S':' '
8403 #ifdef DBG_FIXED_CHAN
8404 DBG_8723A(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
8408 if(survey_channel != 0)
8410 /* PAUSE 4-AC Queue when site_survey */
8411 /* rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
8413 /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
8414 #ifdef CONFIG_CONCURRENT_MODE
8415 #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
8416 if((padapter->pbuddy_adapter->mlmeextpriv.mlmext_info.state&0x03) == WIFI_FW_AP_STATE)
8418 if( pmlmeinfo->scan_cnt == RTW_SCAN_NUM_OF_CH )
8420 pmlmeinfo->scan_cnt = 0;
8421 survey_channel = pbuddy_mlmeext->cur_channel;
8422 ScanType = SCAN_ACTIVE;
8427 if( pmlmeinfo->scan_cnt == 0 )
8429 pmlmeinfo->scan_cnt++;
8432 #endif /* CONFIG_STA_MODE_SCAN_UNDER_AP_MODE */
8433 #endif /* CONFIG_CONCURRENT_MODE */
8434 if(pmlmeext->sitesurvey_res.channel_idx == 0)
8436 #ifdef DBG_FIXED_CHAN
8437 if(pmlmeext->fixed_chan !=0xff)
8438 set_channel_bwmode(padapter, pmlmeext->fixed_chan, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
8441 set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
8445 #ifdef DBG_FIXED_CHAN
8446 if(pmlmeext->fixed_chan!=0xff)
8447 SelectChannel(padapter, pmlmeext->fixed_chan);
8450 SelectChannel(padapter, survey_channel);
8453 #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
8454 if( stay_buddy_ch == 1 )
8456 val8 = 0; /* survey done */
8457 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
8459 if(check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
8460 check_buddy_fwstate(padapter, _FW_LINKED))
8462 update_beacon(padapter->pbuddy_adapter, 0, NULL, _TRUE);
8465 else if( stay_buddy_ch == 2 )
8467 val8 = 1; /* under site survey */
8468 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
8470 #endif /* CONFIG_STA_MODE_SCAN_UNDER_AP_MODE */
8472 if(ScanType == SCAN_ACTIVE) /* obey the channel plan setting... */
8475 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) ||
8476 rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
8479 issue_probereq_p2p(padapter, NULL);
8480 issue_probereq_p2p(padapter, NULL);
8481 issue_probereq_p2p(padapter, NULL);
8484 #endif /* CONFIG_P2P */
8487 for(i=0;i<RTW_SSID_SCAN_AMOUNT;i++){
8488 if(pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
8489 /* todo: to issue two probe req??? */
8490 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
8491 /* rtw_msleep_os(SURVEY_TO>>1); */
8492 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
8496 if(pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
8497 /* todo: to issue two probe req??? */
8498 issue_probereq(padapter, NULL, NULL);
8499 /* rtw_msleep_os(SURVEY_TO>>1); */
8500 issue_probereq(padapter, NULL, NULL);
8505 #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
8506 if( stay_buddy_ch == 1 )
8507 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time * RTW_STAY_AP_CH_MILLISECOND );
8509 #endif /* CONFIG_STA_MODE_SCAN_UNDER_AP_MODE */
8510 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
8516 /* channel number is 0 or this channel is not valid. */
8518 #ifdef CONFIG_CONCURRENT_MODE
8523 if(check_fwstate(pmlmepriv, _FW_LINKED))
8525 cur_channel = pmlmeext->cur_channel;
8526 cur_bwmode = pmlmeext->cur_bwmode;
8527 cur_ch_offset = pmlmeext->cur_ch_offset;
8529 /* else if((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) */
8530 else if(check_buddy_fwstate(padapter, _FW_LINKED)) /* for AP or STA */
8532 cur_channel = pbuddy_mlmeext->cur_channel;
8533 cur_bwmode = pbuddy_mlmeext->cur_bwmode;
8534 cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
8538 cur_channel = pmlmeext->cur_channel;
8539 cur_bwmode = pmlmeext->cur_bwmode;
8540 cur_ch_offset = pmlmeext->cur_ch_offset;
8545 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
8547 if( ( pwdinfo->rx_invitereq_info.scan_op_ch_only ) || ( pwdinfo->p2p_info.scan_op_ch_only ) )
8549 /* Set the find_phase_state_exchange_cnt to P2P_FINDPHASE_EX_CNT. */
8550 /* This will let the following flow to run the scanning end. */
8551 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
8553 #ifdef CONFIG_DBG_P2P
8554 DBG_8723A( "[%s] find phase exchange cnt = %d\n", __FUNCTION__, pwdinfo->find_phase_state_exchange_cnt );
8558 if(rtw_p2p_findphase_ex_is_needed(pwdinfo))
8560 /* Set the P2P State to the listen state of find phase and set the current channel to the listen channel */
8561 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
8562 rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
8563 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
8565 initialgain = 0xff; /* restore RX GAIN */
8566 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
8567 /* turn on dynamic functions */
8568 Restore_DM_Func_Flag(padapter);
8569 /* Switch_DM_Func(padapter, DYNAMIC_FUNC_DIG|DYNAMIC_FUNC_HP|DYNAMIC_FUNC_SS, _TRUE); */
8571 _set_timer( &pwdinfo->find_phase_timer, ( u32 ) ( ( u32 ) ( pwdinfo->listen_dwell ) * 100 ) );
8574 #endif /* CONFIG_P2P */
8577 #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
8578 pmlmeinfo->scan_cnt = 0;
8579 #endif /* CONFIG_DMP_STA_NODE_SCAN_UNDER_AP_MODE */
8581 #ifdef CONFIG_ANTENNA_DIVERSITY
8582 /* 20100721:Interrupt scan operation here. */
8583 /* For SW antenna diversity before link, it needs to switch to another antenna and scan again. */
8584 /* It compares the scan result and select beter one to do connection. */
8585 if(rtw_hal_antdiv_before_linked(padapter))
8587 pmlmeext->sitesurvey_res.bss_cnt = 0;
8588 pmlmeext->sitesurvey_res.channel_idx = -1;
8589 pmlmeext->chan_scan_time = SURVEY_TO /2;
8590 set_survey_timer(pmlmeext, pmlmeext->chan_scan_time);
8596 if(rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
8598 #ifdef CONFIG_CONCURRENT_MODE
8599 #ifndef CONFIG_IOCTL_CFG80211
8600 if ( check_buddy_fwstate(padapter, _FW_LINKED ) )
8602 _set_timer( &pwdinfo->ap_p2p_switch_timer, 500 );
8604 #endif /* CONFIG_IOCTL_CFG80211 */
8605 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
8607 rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
8610 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
8611 #endif /* CONFIG_P2P */
8613 pmlmeext->sitesurvey_res.state = SCAN_COMPLETE;
8615 /* switch back to the original channel */
8616 /* SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
8619 #ifdef CONFIG_DUALMAC_CONCURRENT
8620 dc_set_channel_bwmode_survey_done(padapter);
8622 #ifndef CONFIG_IOCTL_CFG80211
8623 if( rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN) )
8625 set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
8628 #endif /* CONFIG_IOCTL_CFG80211 */
8629 #ifdef CONFIG_CONCURRENT_MODE
8630 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
8632 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
8633 #endif /* CONFIG_DUALMAC_CONCURRENT */
8634 #endif /* CONFIG_CONCURRENT_MODE */
8637 /* flush 4-AC Queue after site_survey */
8639 /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */
8642 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
8644 initialgain = 0xff; /* restore RX GAIN */
8645 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
8646 /* turn on dynamic functions */
8647 Restore_DM_Func_Flag(padapter);
8648 /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE); */
8650 if (is_client_associated_to_ap(padapter) == _TRUE)
8652 issue_nulldata(padapter, NULL, 0, 3, 500);
8654 #ifdef CONFIG_CONCURRENT_MODE
8655 if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
8657 DBG_8723A("adapter is surveydone(buddy_adapter is linked), issue nulldata(pwrbit=0)\n");
8659 issue_nulldata(padapter->pbuddy_adapter, NULL, 0, 3, 500);
8663 #ifdef CONFIG_CONCURRENT_MODE
8664 else if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
8666 issue_nulldata(padapter->pbuddy_adapter, NULL, 0, 3, 500);
8670 val8 = 0; /* survey done */
8671 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
8673 report_surveydone_event(padapter);
8675 pmlmeext->chan_scan_time = SURVEY_TO;
8676 pmlmeext->sitesurvey_res.state = SCAN_DISABLE;
8678 issue_action_BSSCoexistPacket(padapter);
8679 issue_action_BSSCoexistPacket(padapter);
8680 issue_action_BSSCoexistPacket(padapter);
8684 #ifdef CONFIG_CONCURRENT_MODE
8685 if(check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
8686 check_buddy_fwstate(padapter, _FW_LINKED))
8689 DBG_8723A("survey done, current CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
8691 DBG_8723A("restart pbuddy_adapter's beacon\n");
8693 update_beacon(padapter->pbuddy_adapter, 0, NULL, _TRUE);
8702 /* collect bss info from Beacon and Probe request/response frames. */
8703 u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid)
8709 u8 *pframe = precv_frame->u.hdr.rx_data;
8710 u32 packet_len = precv_frame->u.hdr.len;
8712 struct registry_priv *pregistrypriv = &padapter->registrypriv;
8713 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8714 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8716 len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
8718 if (len > MAX_IE_SZ)
8720 /* DBG_8723A("IE too long for survey event\n"); */
8724 memset(bssid, 0, sizeof(WLAN_BSSID_EX));
8726 subtype = GetFrameSubType(pframe);
8728 if(subtype==WIFI_BEACON) {
8729 bssid->Reserved[0] = 1;
8730 ie_offset = _BEACON_IE_OFFSET_;
8732 /* FIXME : more type */
8733 if (subtype == WIFI_PROBEREQ) {
8734 ie_offset = _PROBEREQ_IE_OFFSET_;
8735 bssid->Reserved[0] = 2;
8736 } else if (subtype == WIFI_PROBERSP) {
8737 ie_offset = _PROBERSP_IE_OFFSET_;
8738 bssid->Reserved[0] = 3;
8740 bssid->Reserved[0] = 0;
8741 ie_offset = _FIXED_IE_LENGTH_;
8745 bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
8747 /* below is to copy the information element */
8748 bssid->IELength = len;
8749 memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
8751 /* get the signal strength */
8752 bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; /* in dBM.raw data */
8753 bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;/* in percentage */
8754 bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;/* in percentage */
8755 #ifdef CONFIG_ANTENNA_DIVERSITY
8756 /* rtw_hal_get_hwreg(padapter, HW_VAR_CURRENT_ANTENNA, (u8 *)(&bssid->PhyInfo.Optimum_antenna)); */
8757 rtw_hal_get_def_var(padapter, HAL_DEF_CURRENT_ANTENNA, &bssid->PhyInfo.Optimum_antenna);
8761 if ((p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset)) == NULL)
8763 DBG_8723A("marc: cannot find SSID for survey event\n");
8769 if (len > NDIS_802_11_LENGTH_SSID)
8771 DBG_8723A("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
8774 memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
8775 bssid->Ssid.SsidLength = *(p + 1);
8779 bssid->Ssid.SsidLength = 0;
8782 memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
8784 /* checking rate info... */
8786 p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
8789 if (len > NDIS_802_11_LENGTH_RATES_EX)
8791 DBG_8723A("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
8794 memcpy(bssid->SupportedRates, (p + 2), len);
8798 p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
8801 if (len > (NDIS_802_11_LENGTH_RATES_EX-i))
8803 DBG_8723A("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
8806 memcpy(bssid->SupportedRates + i, (p + 2), len);
8811 bssid->NetworkTypeInUse = Ndis802_11OFDM24;
8814 if (bssid->IELength < 12)
8817 /* Checking for DSConfig */
8818 p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
8820 bssid->Configuration.DSConfig = 0;
8821 bssid->Configuration.Length = 0;
8825 bssid->Configuration.DSConfig = *(p + 2);
8828 {/* In 5G, some ap do not have DSSET IE */
8829 /* checking HT info for channel */
8830 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
8833 struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
8834 bssid->Configuration.DSConfig = HT_info->primary_channel;
8837 { /* use current channel */
8838 bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
8842 if (subtype==WIFI_PROBEREQ)
8845 bssid->InfrastructureMode = Ndis802_11Infrastructure;
8846 memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
8851 memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
8852 bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
8854 val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid);
8858 bssid->InfrastructureMode = Ndis802_11Infrastructure;
8859 memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN);
8863 bssid->InfrastructureMode = Ndis802_11IBSS;
8864 memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
8872 bssid->Configuration.ATIMWindow = 0;
8874 /* 20/40 BSS Coexistence check */
8875 if((pregistrypriv->wifi_spec==1) && (_FALSE == pmlmeinfo->bwmode_updated))
8877 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8878 #ifdef CONFIG_80211N_HT
8879 p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
8882 struct HT_caps_element *pHT_caps;
8883 pHT_caps = (struct HT_caps_element *)(p + 2);
8885 if(pHT_caps->u.HT_cap_element.HT_caps_info&BIT(14))
8887 pmlmepriv->num_FortyMHzIntolerant++;
8892 pmlmepriv->num_sta_no_ht++;
8894 #endif /* CONFIG_80211N_HT */
8898 #ifdef CONFIG_INTEL_WIDI
8899 /* process_intel_widi_query_or_tigger(padapter, bssid); */
8900 if(process_intel_widi_query_or_tigger(padapter, bssid))
8904 #endif /* CONFIG_INTEL_WIDI */
8906 #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) & 1
8907 if(strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
8908 DBG_8723A("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
8909 , bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
8910 , rtw_get_oper_ch(padapter)
8911 , bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
8916 /* mark bss info receving from nearby channel as SignalQuality 101 */
8917 if(bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
8919 bssid->PhyInfo.SignalQuality= 101;
8925 void start_create_ibss(_adapter* padapter)
8927 unsigned short caps;
8930 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8931 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8932 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
8933 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
8934 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
8936 /* update wireless mode */
8937 update_wireless_mode(padapter);
8939 /* udpate capability */
8940 caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
8941 update_capinfo(padapter, caps);
8942 if(caps&cap_IBSS)/* adhoc master */
8945 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
8947 /* switch channel */
8948 /* SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */
8949 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
8951 beacon_timing_control(padapter);
8953 /* set msr to WIFI_FW_ADHOC_STATE */
8954 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
8955 Set_MSR(padapter, (pmlmeinfo->state & 0x3));
8958 if(send_beacon(padapter)==_FAIL)
8960 RT_TRACE(_module_rtl871x_mlme_c_,_drv_err_,("issuing beacon frame fail....\n"));
8962 report_join_res(padapter, -1);
8963 pmlmeinfo->state = WIFI_FW_NULL_STATE;
8967 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
8969 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
8971 report_join_res(padapter, 1);
8972 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
8977 DBG_8723A("start_create_ibss, invalid cap:%x\n", caps);
8982 void start_clnt_join(_adapter* padapter)
8984 unsigned short caps;
8986 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8987 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8988 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
8991 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
8992 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
8994 /* update wireless mode */
8995 update_wireless_mode(padapter);
8997 /* udpate capability */
8998 caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
8999 update_capinfo(padapter, caps);
9003 #ifdef CONFIG_DUALMAC_CONCURRENT
9004 if(dc_handle_join_request(padapter) == _FAIL)
9006 DBG_8723A("dc_handle_join_request fail !!!\n");
9009 /* switch channel */
9010 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
9011 #elif defined (CONFIG_CONCURRENT_MODE)
9012 if(concurrent_chk_start_clnt_join(padapter) == _FAIL)
9014 #else /* NON CONCURRENT_MODE */
9015 /* switch channel */
9016 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
9019 Set_MSR(padapter, WIFI_FW_STATION_STATE);
9021 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X)? 0xcc: 0xcf;
9023 #ifdef CONFIG_WAPI_SUPPORT
9024 if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI)
9026 /* Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey. */
9030 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
9032 /* switch channel */
9033 /* set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); */
9035 /* here wait for receiving the beacon to start auth */
9036 /* and enable a timer */
9037 beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
9038 set_link_timer(pmlmeext, beacon_timeout);
9039 _set_timer( &padapter->mlmepriv.assoc_timer,
9040 (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) +beacon_timeout);
9042 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
9044 else if (caps&cap_IBSS) /* adhoc client */
9046 #ifdef CONFIG_DUALMAC_CONCURRENT
9047 if(dc_handle_join_request(padapter) == _FAIL)
9049 DBG_8723A("dc_handle_join_request for Ad-hoc fail !!!\n");
9054 Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
9057 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
9059 /* switch channel */
9060 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
9062 beacon_timing_control(padapter);
9064 pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
9066 report_join_res(padapter, 1);
9070 /* DBG_8723A("marc: invalid cap:%x\n", caps); */
9075 void start_clnt_auth(_adapter* padapter)
9077 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9078 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9080 _cancel_timer_ex(&pmlmeext->link_timer);
9082 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
9083 pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
9085 pmlmeinfo->auth_seq = 1;
9086 pmlmeinfo->reauth_count = 0;
9087 pmlmeinfo->reassoc_count = 0;
9088 pmlmeinfo->link_count = 0;
9089 pmlmeext->retry = 0;
9091 /* Because of AP's not receiving deauth before */
9092 /* AP may: 1)not response auth or 2)deauth us after link is complete */
9093 /* issue deauth before issuing auth to deal with the situation */
9094 /* Commented by Albert 2012/07/21 */
9095 /* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
9096 issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
9098 DBG_8723A_LEVEL(_drv_always_, "start auth\n");
9099 issue_auth(padapter, NULL, 0);
9101 set_link_timer(pmlmeext, REAUTH_TO);
9104 void start_clnt_assoc(_adapter* padapter)
9106 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9107 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9109 _cancel_timer_ex(&pmlmeext->link_timer);
9111 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
9112 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
9114 issue_assocreq(padapter);
9116 set_link_timer(pmlmeext, REASSOC_TO);
9119 unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason)
9121 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9122 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9125 if (memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN))
9128 DBG_8723A("%s\n", __FUNCTION__);
9130 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9132 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
9134 pmlmeinfo->state = WIFI_FW_NULL_STATE;
9135 report_del_sta_event(padapter, MacAddr, reason);
9138 else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE)
9140 pmlmeinfo->state = WIFI_FW_NULL_STATE;
9141 report_join_res(padapter, -2);
9148 #ifdef CONFIG_80211D
9149 static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid)
9151 struct registry_priv *pregistrypriv;
9152 struct mlme_ext_priv *pmlmeext;
9153 RT_CHANNEL_INFO *chplan_new;
9157 pregistrypriv = &padapter->registrypriv;
9158 pmlmeext = &padapter->mlmeextpriv;
9160 /* Adjust channel plan by AP Country IE */
9161 if (pregistrypriv->enable80211d &&
9162 (!pmlmeext->update_channel_plan_by_ap_done))
9166 RT_CHANNEL_PLAN chplan_ap;
9167 RT_CHANNEL_INFO chplan_sta[MAX_CHANNEL_NUM];
9169 u8 fcn; /* first channel number */
9170 u8 noc; /* number of channel */
9173 ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
9175 if (len < 6) return;
9181 memset(country, 0, 4);
9182 memcpy(country, p, 3);
9184 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
9185 ("%s: 802.11d country=%s\n", __FUNCTION__, country));
9188 while ((ie - p) >= 3)
9194 for (j = 0; j < noc; j++)
9196 if (fcn <= 14) channel = fcn + j; /* 2.4 GHz */
9197 else channel = fcn + j*4; /* 5 GHz */
9199 chplan_ap.Channel[i++] = channel;
9204 #ifdef CONFIG_DEBUG_RTL871X
9206 DBG_8723A("%s: AP[%s] channel plan {", __func__, bssid->Ssid.Ssid);
9207 while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0))
9209 DBG_8723A("%02d,", chplan_ap.Channel[i]);
9215 memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta));
9216 #ifdef CONFIG_DEBUG_RTL871X
9218 DBG_8723A("%s: STA channel plan {", __func__);
9219 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0))
9221 DBG_8723A("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType==SCAN_PASSIVE?'p':'a');
9227 memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set));
9228 chplan_new = pmlmeext->channel_set;
9231 if (pregistrypriv->wireless_mode & WIRELESS_11G) {
9233 if ((i == MAX_CHANNEL_NUM) ||
9234 (chplan_sta[i].ChannelNum == 0) ||
9235 (chplan_sta[i].ChannelNum > 14))
9238 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
9241 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
9242 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
9243 chplan_new[k].ScanType = SCAN_ACTIVE;
9247 } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
9248 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
9249 chplan_new[k].ScanType = SCAN_PASSIVE;
9252 } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
9253 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
9254 chplan_new[k].ScanType = SCAN_ACTIVE;
9260 /* change AP not support channel to Passive scan */
9261 while ((i < MAX_CHANNEL_NUM) &&
9262 (chplan_sta[i].ChannelNum != 0) &&
9263 (chplan_sta[i].ChannelNum <= 14)) {
9264 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
9265 chplan_new[k].ScanType = SCAN_PASSIVE;
9270 /* add channel AP supported */
9271 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) {
9272 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
9273 chplan_new[k].ScanType = SCAN_ACTIVE;
9278 /* keep original STA 2.4G channel plan */
9279 while ((i < MAX_CHANNEL_NUM) &&
9280 (chplan_sta[i].ChannelNum != 0) &&
9281 (chplan_sta[i].ChannelNum <= 14)) {
9282 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
9283 chplan_new[k].ScanType = chplan_sta[i].ScanType;
9288 /* skip AP 2.4G channel plan */
9289 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) {
9294 if (pregistrypriv->wireless_mode & WIRELESS_11A) {
9296 if ((i == MAX_CHANNEL_NUM) ||
9297 (chplan_sta[i].ChannelNum == 0))
9300 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
9303 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;
9311 else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j])
9313 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
9314 /* chplan_new[k].ScanType = chplan_sta[i].ScanType; */
9315 chplan_new[k].ScanType = SCAN_PASSIVE;
9319 else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j])
9321 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
9322 chplan_new[k].ScanType = SCAN_ACTIVE;
9328 /* change AP not support channel to Passive scan */
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 = SCAN_PASSIVE;
9336 /* add channel AP supported */
9337 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0)) {
9338 chplan_new[k].ChannelNum = chplan_ap.Channel[j];
9339 chplan_new[k].ScanType = SCAN_ACTIVE;
9344 /* keep original STA 5G channel plan */
9345 while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
9346 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
9347 chplan_new[k].ScanType = chplan_sta[i].ScanType;
9353 pmlmeext->update_channel_plan_by_ap_done = 1;
9355 #ifdef CONFIG_DEBUG_RTL871X
9357 DBG_8723A("%s: new STA channel plan {", __func__);
9358 while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) {
9359 DBG_8723A("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType==SCAN_PASSIVE?'p':'c');
9366 /* If channel is used by AP, set channel scan type to active */
9367 channel = bssid->Configuration.DSConfig;
9368 chplan_new = pmlmeext->channel_set;
9370 while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) {
9371 if (chplan_new[i].ChannelNum == channel)
9373 if (chplan_new[i].ScanType == SCAN_PASSIVE) {
9374 /* 5G Bnad 2, 3 (DFS) doesn't change to active scan */
9375 if(channel >= 52 && channel <= 144)
9378 chplan_new[i].ScanType = SCAN_ACTIVE;
9379 RT_TRACE(_module_rtl871x_mlme_c_, _drv_notice_,
9380 ("%s: change channel %d scan type from passive to active\n",
9381 __FUNCTION__, channel));
9390 /****************************************************************************
9392 Following are the functions to report events
9394 *****************************************************************************/
9396 void report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
9398 struct cmd_obj *pcmd_obj;
9401 struct survey_event *psurvey_evt;
9402 struct C2HEvent_Header *pc2h_evt_hdr;
9403 struct mlme_ext_priv *pmlmeext;
9404 struct cmd_priv *pcmdpriv;
9409 pmlmeext = &padapter->mlmeextpriv;
9410 pcmdpriv = &padapter->cmdpriv;
9412 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
9415 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
9416 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL) {
9417 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
9421 _rtw_init_listhead(&pcmd_obj->list);
9423 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
9424 pcmd_obj->cmdsz = cmdsz;
9425 pcmd_obj->parmbuf = pevtcmd;
9427 pcmd_obj->rsp = NULL;
9428 pcmd_obj->rspsz = 0;
9430 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
9431 pc2h_evt_hdr->len = sizeof(struct survey_event);
9432 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
9433 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
9435 psurvey_evt = (struct survey_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
9437 if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL) {
9438 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
9439 rtw_mfree((u8 *)pevtcmd, cmdsz);
9443 #ifdef CONFIG_80211D
9444 process_80211d(padapter, &psurvey_evt->bss);
9447 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
9449 pmlmeext->sitesurvey_res.bss_cnt++;
9454 void report_surveydone_event(_adapter *padapter)
9456 struct cmd_obj *pcmd_obj;
9459 struct surveydone_event *psurveydone_evt;
9460 struct C2HEvent_Header *pc2h_evt_hdr;
9461 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9462 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
9464 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
9469 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
9470 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
9472 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
9476 _rtw_init_listhead(&pcmd_obj->list);
9478 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
9479 pcmd_obj->cmdsz = cmdsz;
9480 pcmd_obj->parmbuf = pevtcmd;
9482 pcmd_obj->rsp = NULL;
9483 pcmd_obj->rspsz = 0;
9485 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
9486 pc2h_evt_hdr->len = sizeof(struct surveydone_event);
9487 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
9488 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
9490 psurveydone_evt = (struct surveydone_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
9491 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
9493 DBG_8723A("survey done event(%x)\n", psurveydone_evt->bss_cnt);
9495 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
9500 void report_join_res(_adapter *padapter, int res)
9502 struct cmd_obj *pcmd_obj;
9505 struct joinbss_event *pjoinbss_evt;
9506 struct C2HEvent_Header *pc2h_evt_hdr;
9507 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9508 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9509 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
9511 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
9516 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
9517 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
9519 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
9523 _rtw_init_listhead(&pcmd_obj->list);
9525 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
9526 pcmd_obj->cmdsz = cmdsz;
9527 pcmd_obj->parmbuf = pevtcmd;
9529 pcmd_obj->rsp = NULL;
9530 pcmd_obj->rspsz = 0;
9532 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
9533 pc2h_evt_hdr->len = sizeof(struct joinbss_event);
9534 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
9535 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
9537 pjoinbss_evt = (struct joinbss_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
9538 memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
9539 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res;
9541 DBG_8723A("report_join_res(%d)\n", res);
9543 rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network);
9545 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
9550 void report_del_sta_event(_adapter *padapter, unsigned char* MacAddr, unsigned short reason)
9552 struct cmd_obj *pcmd_obj;
9555 struct sta_info *psta;
9557 struct stadel_event *pdel_sta_evt;
9558 struct C2HEvent_Header *pc2h_evt_hdr;
9559 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9560 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
9562 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
9567 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
9568 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
9570 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
9574 _rtw_init_listhead(&pcmd_obj->list);
9576 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
9577 pcmd_obj->cmdsz = cmdsz;
9578 pcmd_obj->parmbuf = pevtcmd;
9580 pcmd_obj->rsp = NULL;
9581 pcmd_obj->rspsz = 0;
9583 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
9584 pc2h_evt_hdr->len = sizeof(struct stadel_event);
9585 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
9586 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
9588 pdel_sta_evt = (struct stadel_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
9589 memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
9590 memcpy((unsigned char *)(pdel_sta_evt->rsvd),(unsigned char *)(&reason),2);
9592 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
9594 mac_id = (int)psta->mac_id;
9598 pdel_sta_evt->mac_id = mac_id;
9600 DBG_8723A("report_del_sta_event: delete STA, mac_id=%d\n", mac_id);
9602 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
9607 void report_add_sta_event(_adapter *padapter, unsigned char* MacAddr, int cam_idx)
9609 struct cmd_obj *pcmd_obj;
9612 struct stassoc_event *padd_sta_evt;
9613 struct C2HEvent_Header *pc2h_evt_hdr;
9614 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9615 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
9617 if ((pcmd_obj = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
9622 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
9623 if ((pevtcmd = (u8*)rtw_zmalloc(cmdsz)) == NULL)
9625 rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
9629 _rtw_init_listhead(&pcmd_obj->list);
9631 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
9632 pcmd_obj->cmdsz = cmdsz;
9633 pcmd_obj->parmbuf = pevtcmd;
9635 pcmd_obj->rsp = NULL;
9636 pcmd_obj->rspsz = 0;
9638 pc2h_evt_hdr = (struct C2HEvent_Header*)(pevtcmd);
9639 pc2h_evt_hdr->len = sizeof(struct stassoc_event);
9640 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
9641 pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
9643 padd_sta_evt = (struct stassoc_event*)(pevtcmd + sizeof(struct C2HEvent_Header));
9644 memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
9645 padd_sta_evt->cam_id = cam_idx;
9647 DBG_8723A("report_add_sta_event: add STA\n");
9649 rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
9654 /****************************************************************************
9656 Following are the event callback functions
9658 *****************************************************************************/
9660 /* for sta/adhoc mode */
9661 void update_sta_info(_adapter *padapter, struct sta_info *psta)
9663 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
9664 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9665 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9668 VCS_update(padapter, psta);
9670 #ifdef CONFIG_80211N_HT
9672 if(pmlmepriv->htpriv.ht_option)
9674 psta->htpriv.ht_option = _TRUE;
9676 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
9678 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps)))
9679 psta->htpriv.sgi = _TRUE;
9681 psta->qos_option = _TRUE;
9685 #endif /* CONFIG_80211N_HT */
9687 #ifdef CONFIG_80211N_HT
9688 psta->htpriv.ht_option = _FALSE;
9690 psta->htpriv.ampdu_enable = _FALSE;
9692 psta->htpriv.sgi = _FALSE;
9693 #endif /* CONFIG_80211N_HT */
9694 psta->qos_option = _FALSE;
9697 #ifdef CONFIG_80211N_HT
9698 psta->htpriv.bwmode = pmlmeext->cur_bwmode;
9699 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
9701 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
9702 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
9703 #endif /* CONFIG_80211N_HT */
9706 if(pmlmepriv->qospriv.qos_option)
9707 psta->qos_option = _TRUE;
9709 psta->state = _FW_LINKED;
9712 void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
9714 struct sta_info *psta, *psta_bmc;
9715 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9716 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9717 WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
9718 struct sta_priv *pstapriv = &padapter->stapriv;
9725 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
9726 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
9728 /* restore to initial setting. */
9729 update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
9731 goto exit_mlmeext_joinbss_event_callback;
9734 if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
9737 psta_bmc = rtw_get_bcmc_stainfo(padapter);
9740 pmlmeinfo->FW_sta_info[psta_bmc->mac_id].psta = psta_bmc;
9741 update_bmc_sta_support_rate(padapter, psta_bmc->mac_id);
9742 Update_RA_Entry(padapter, psta_bmc);
9746 /* turn on dynamic functions */
9747 Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE);
9749 /* update IOT-releated issue */
9750 update_IOT_info(padapter);
9752 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
9755 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
9757 /* udpate capability */
9758 update_capinfo(padapter, pmlmeinfo->capability);
9760 /* WMM, Update EDCA param */
9761 WMMOnAssocRsp(padapter);
9764 HTOnAssocRsp(padapter);
9766 #ifndef CONFIG_CONCURRENT_MODE
9767 /* Call set_channel_bwmode when the CONFIG_CONCURRENT_MODE doesn't be defined. */
9768 /* Set cur_channel&cur_bwmode&cur_ch_offset */
9769 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
9772 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
9773 if (psta) /* only for infra. mode */
9775 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
9777 /* DBG_8723A("set_sta_rate\n"); */
9779 psta->wireless_mode = pmlmeext->cur_wireless_mode;
9781 /* set per sta rate after updating HT cap. */
9782 set_sta_rate(padapter, psta);
9784 #if (RATE_ADAPTIVE_SUPPORT==1) /* for 88E RA */
9785 rtw_hal_set_hwreg(padapter,HW_VAR_TX_RPT_MAX_MACID, (u8*)&psta->mac_id);
9787 media_status = (psta->mac_id<<8)|1; /* MACID|OPMODE: 1 means connect */
9788 rtw_hal_set_hwreg(padapter,HW_VAR_H2C_MEDIA_STATUS_RPT,(u8 *)&media_status);
9792 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
9794 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9796 /* correcting TSF */
9797 correct_TSF(padapter, pmlmeext);
9799 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
9803 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0);
9806 exit_mlmeext_joinbss_event_callback:
9808 #ifdef CONFIG_DUALMAC_CONCURRENT
9809 dc_handle_join_done(padapter, join_res);
9811 #ifdef CONFIG_CONCURRENT_MODE
9812 concurrent_chk_joinbss_done(padapter, join_res);
9815 DBG_8723A("=>%s\n", __FUNCTION__);
9818 void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta)
9820 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9821 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9824 DBG_8723A("%s\n", __FUNCTION__);
9826 if((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
9828 if(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)/* adhoc master or sta_count>1 */
9832 else/* adhoc client */
9834 /* update TSF Value */
9835 /* update_TSF(pmlmeext, pframe, len); */
9837 /* correcting TSF */
9838 correct_TSF(padapter, pmlmeext);
9841 if(send_beacon(padapter)==_FAIL)
9843 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0;
9845 pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE;
9850 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
9855 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
9858 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta;
9860 /* rate radaptive */
9861 Update_RA_Entry(padapter, psta);
9863 /* update adhoc sta_info */
9864 update_sta_info(padapter, psta);
9867 void mlmeext_sta_del_event_callback(_adapter *padapter)
9869 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9870 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9872 if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
9874 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
9876 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
9877 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
9879 /* restore to initial setting. */
9880 update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
9882 #ifdef CONFIG_DUALMAC_CONCURRENT
9883 dc_set_channel_bwmode_disconnect(padapter);
9885 #ifdef CONFIG_CONCURRENT_MODE
9886 if((check_buddy_fwstate(padapter, _FW_LINKED)) != _TRUE)
9888 #endif /* CONFIG_CONCURRENT_MODE */
9890 /* switch to the 20M Hz mode after disconnect */
9891 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
9892 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
9894 /* SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */
9895 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
9897 #ifdef CONFIG_CONCURRENT_MODE
9899 #endif /* CONFIG_CONCURRENT_MODE */
9900 #endif /* CONFIG_DUALMAC_CONCURRENT */
9902 flush_all_cam_entry(padapter);
9904 pmlmeinfo->state = WIFI_FW_NULL_STATE;
9906 /* set MSR to no link state -> infra. mode */
9907 Set_MSR(padapter, _HW_STATE_STATION_);
9909 _cancel_timer_ex(&pmlmeext->link_timer);
9914 /****************************************************************************
9916 Following are the functions for the timer handlers
9918 *****************************************************************************/
9919 void _linked_rx_signal_strehgth_display(_adapter *padapter);
9920 void _linked_rx_signal_strehgth_display(_adapter *padapter)
9922 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9923 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9925 int UndecoratedSmoothedPWDB;
9926 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
9930 else if((pmlmeinfo->state&0x03) == _HW_STATE_AP_)
9935 rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP,&mac_id);
9937 rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB);
9938 DBG_8723A("UndecoratedSmoothedPWDB:%d\n",UndecoratedSmoothedPWDB);
9941 u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta)
9944 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9945 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9947 #ifdef DBG_EXPIRATION_CHK
9948 DBG_8723A(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
9949 /*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
9951 , FUNC_ADPT_ARG(padapter)
9952 , STA_RX_PKTS_DIFF_ARG(psta)
9953 , psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
9954 , psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
9955 /*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
9956 , psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
9957 , psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
9958 , pmlmeinfo->bcn_interval*/
9962 DBG_8723A(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter)
9963 , padapter->xmitpriv.tx_pkts
9964 , pmlmeinfo->link_count
9968 if((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
9969 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
9970 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
9980 sta_update_last_rx_pkts(psta);
9985 void linked_status_chk(_adapter *padapter)
9988 struct sta_info *psta;
9989 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9990 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9991 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9992 struct sta_priv *pstapriv = &padapter->stapriv;
9994 if(padapter->bRxRSSIDisplay)
9995 _linked_rx_signal_strehgth_display(padapter);
9997 #ifdef DBG_CONFIG_ERROR_DETECT
9998 rtw_hal_sreset_linked_status_check(padapter);
10001 if (is_client_associated_to_ap(padapter))
10003 /* linked infrastructure client mode */
10005 int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
10008 #if defined(DBG_ROAMING_TEST)
10010 #elif defined(CONFIG_ACTIVE_KEEP_ALIVE_CHECK)
10016 #ifdef CONFIG_INTEL_WIDI
10017 if (padapter->mlmepriv.widi_state != INTEL_WIDI_STATE_NONE)
10021 if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL)
10023 bool is_p2p_enable = _FALSE;
10025 is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
10028 if (chk_ap_is_alive(padapter, psta) == _FALSE)
10031 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts)
10034 #ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
10035 if (pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)) {
10036 u8 backup_oper_channel=0;
10038 /* switch to correct channel of current network before issue keep-alive frames */
10039 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
10040 backup_oper_channel = rtw_get_oper_ch(padapter);
10041 SelectChannel(padapter, pmlmeext->cur_channel);
10044 if (rx_chk != _SUCCESS)
10045 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->hwaddr, 3, 1);
10047 if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) || rx_chk != _SUCCESS) {
10048 tx_chk = issue_nulldata(padapter, psta->hwaddr, 0, 3, 1);
10049 /* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
10050 if (tx_chk == _SUCCESS && !is_p2p_enable)
10054 /* back to the original operation channel */
10055 if(backup_oper_channel>0)
10056 SelectChannel(padapter, backup_oper_channel);
10060 #endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
10062 if (rx_chk != _SUCCESS) {
10063 if (pmlmeext->retry == 0) {
10064 #ifdef DBG_EXPIRATION_CHK
10065 DBG_8723A("issue_probereq to trigger probersp, retry=%d\n", pmlmeext->retry);
10067 issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
10068 issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
10069 issue_probereq(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress);
10073 if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == 0xf) {
10074 #ifdef DBG_EXPIRATION_CHK
10075 DBG_8723A("%s issue_nulldata 0\n", __FUNCTION__);
10077 tx_chk = issue_nulldata(padapter, NULL, 0, 1, 0);
10081 if (rx_chk == _FAIL) {
10083 if (pmlmeext->retry > rx_chk_limit) {
10084 DBG_8723A_LEVEL(_drv_always_, FUNC_ADPT_FMT" disconnect or roaming\n",
10085 FUNC_ADPT_ARG(padapter));
10086 receive_disconnect(padapter, pmlmeinfo->network.MacAddress
10087 , WLAN_REASON_EXPIRATION_CHK);
10091 pmlmeext->retry = 0;
10094 if (tx_chk == _FAIL) {
10095 pmlmeinfo->link_count &= 0xf;
10097 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts;
10098 pmlmeinfo->link_count = 0;
10101 } /* end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) */
10103 else if (is_client_associated_to_ibss(padapter))
10105 /* linked IBSS mode */
10106 /* for each assoc list entry to check the rx pkt counter */
10107 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++)
10109 if (pmlmeinfo->FW_sta_info[i].status == 1)
10111 psta = pmlmeinfo->FW_sta_info[i].psta;
10113 if(NULL==psta) continue;
10115 if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta))
10118 if(pmlmeinfo->FW_sta_info[i].retry<3)
10120 pmlmeinfo->FW_sta_info[i].retry++;
10124 pmlmeinfo->FW_sta_info[i].retry = 0;
10125 pmlmeinfo->FW_sta_info[i].status = 0;
10126 report_del_sta_event(padapter, psta->hwaddr
10127 , 65535/* indicate disconnect caused by no rx */
10133 pmlmeinfo->FW_sta_info[i].retry = 0;
10134 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta);
10139 /* set_link_timer(pmlmeext, DISCONNECT_TO); */
10144 void survey_timer_hdl(_adapter *padapter)
10146 struct cmd_obj *ph2c;
10147 struct sitesurvey_parm *psurveyPara;
10148 struct cmd_priv *pcmdpriv=&padapter->cmdpriv;
10149 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10151 struct wifidirect_info *pwdinfo= &(padapter->wdinfo);
10154 /* DBG_8723A("marc: survey timer\n"); */
10155 /* issue rtw_sitesurvey_cmd */
10156 if (pmlmeext->sitesurvey_res.state > SCAN_START)
10158 if(pmlmeext->sitesurvey_res.state == SCAN_PROCESS)
10160 #ifdef CONFIG_STA_MODE_SCAN_UNDER_AP_MODE
10161 if( padapter->mlmeextpriv.mlmext_info.scan_cnt != RTW_SCAN_NUM_OF_CH )
10162 #endif /* CONFIG_STA_MODE_SCAN_UNDER_AP_MODE */
10163 pmlmeext->sitesurvey_res.channel_idx++;
10166 if(pmlmeext->scan_abort == _TRUE)
10169 if(!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE))
10171 rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
10172 pmlmeext->sitesurvey_res.channel_idx = 3;
10173 DBG_8723A("%s idx:%d, cnt:%u\n", __FUNCTION__
10174 , pmlmeext->sitesurvey_res.channel_idx
10175 , pwdinfo->find_phase_state_exchange_cnt
10181 pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num;
10182 DBG_8723A("%s idx:%d\n", __FUNCTION__
10183 , pmlmeext->sitesurvey_res.channel_idx
10187 pmlmeext->scan_abort = _FALSE;/* reset */
10190 if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
10192 goto exit_survey_timer_hdl;
10195 if ((psurveyPara = (struct sitesurvey_parm*)rtw_zmalloc(sizeof(struct sitesurvey_parm))) == NULL)
10197 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
10198 goto exit_survey_timer_hdl;
10201 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
10202 rtw_enqueue_cmd(pcmdpriv, ph2c);
10205 exit_survey_timer_hdl:
10209 void link_timer_hdl(_adapter *padapter)
10211 /* static unsigned int rx_pkt = 0; */
10212 /* static u64 tx_cnt = 0; */
10213 /* struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); */
10214 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10215 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10216 /* struct sta_priv *pstapriv = &padapter->stapriv; */
10218 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL)
10220 DBG_8723A("link_timer_hdl:no beacon while connecting\n");
10221 pmlmeinfo->state = WIFI_FW_NULL_STATE;
10222 report_join_res(padapter, -3);
10224 else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE)
10226 /* re-auth timer */
10227 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT)
10229 /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
10231 pmlmeinfo->state = 0;
10232 report_join_res(padapter, -1);
10237 /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
10238 /* pmlmeinfo->reauth_count = 0; */
10242 DBG_8723A("link_timer_hdl: auth timeout and try again\n");
10243 pmlmeinfo->auth_seq = 1;
10244 issue_auth(padapter, NULL, 0);
10245 set_link_timer(pmlmeext, REAUTH_TO);
10247 else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)
10249 /* re-assoc timer */
10250 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT)
10252 pmlmeinfo->state = WIFI_FW_NULL_STATE;
10253 report_join_res(padapter, -2);
10257 DBG_8723A("link_timer_hdl: assoc timeout and try again\n");
10258 issue_assocreq(padapter);
10259 set_link_timer(pmlmeext, REASSOC_TO);
10265 void addba_timer_hdl(struct sta_info *psta)
10267 #ifdef CONFIG_80211N_HT
10268 struct ht_priv *phtpriv;
10273 phtpriv = &psta->htpriv;
10275 if((phtpriv->ht_option==_TRUE) && (phtpriv->ampdu_enable==_TRUE))
10277 if(phtpriv->candidate_tid_bitmap)
10278 phtpriv->candidate_tid_bitmap=0x0;
10281 #endif /* CONFIG_80211N_HT */
10284 u8 NULL_hdl(_adapter *padapter, u8 *pbuf)
10286 return H2C_SUCCESS;
10289 u8 setopmode_hdl(_adapter *padapter, u8 *pbuf)
10292 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10293 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10294 struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
10296 if(psetop->mode == Ndis802_11APMode)
10298 pmlmeinfo->state = WIFI_FW_AP_STATE;
10299 type = _HW_STATE_AP_;
10300 #ifdef CONFIG_NATIVEAP_MLME
10301 /* start_ap_mode(padapter); */
10304 else if(psetop->mode == Ndis802_11Infrastructure)
10306 pmlmeinfo->state &= ~(BIT(0)|BIT(1));/* clear state */
10307 pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */
10308 type = _HW_STATE_STATION_;
10310 else if(psetop->mode == Ndis802_11IBSS)
10312 type = _HW_STATE_ADHOC_;
10316 type = _HW_STATE_NOLINK_;
10319 rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
10320 /* Set_NETYPE0_MSR(padapter, type); */
10322 return H2C_SUCCESS;
10325 u8 createbss_hdl(_adapter *padapter, u8 *pbuf)
10327 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10328 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10329 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10330 struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
10331 /* u32 initialgain; */
10333 if(pparm->network.InfrastructureMode == Ndis802_11APMode)
10335 #ifdef CONFIG_AP_MODE
10337 if(pmlmeinfo->state == WIFI_FW_AP_STATE)
10340 return H2C_SUCCESS;
10345 /* below is for ad-hoc master */
10346 if(pparm->network.InfrastructureMode == Ndis802_11IBSS)
10348 rtw_joinbss_reset(padapter);
10350 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
10351 pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE;
10352 pmlmeinfo->ERP_enable = 0;
10353 pmlmeinfo->WMM_enable = 0;
10354 pmlmeinfo->HT_enable = 0;
10355 pmlmeinfo->HT_caps_enable = 0;
10356 pmlmeinfo->HT_info_enable = 0;
10357 pmlmeinfo->agg_enable_bitmap = 0;
10358 pmlmeinfo->candidate_tid_bitmap = 0;
10360 /* disable dynamic functions, such as high power, DIG */
10361 Save_DM_Func_Flag(padapter);
10362 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
10364 /* config the initial gain under linking, need to write the BB registers */
10365 /* initialgain = 0x1E; */
10366 /* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */
10368 /* cancel link timer */
10369 _cancel_timer_ex(&pmlmeext->link_timer);
10372 flush_all_cam_entry(padapter);
10374 memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
10375 pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
10377 if(pnetwork->IELength>MAX_IE_SZ)/* Check pbuf->IELength */
10378 return H2C_PARAMETERS_ERROR;
10380 memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
10382 start_create_ibss(padapter);
10386 return H2C_SUCCESS;
10389 u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf)
10392 PNDIS_802_11_VARIABLE_IEs pIE;
10393 struct registry_priv *pregpriv = &padapter->registrypriv;
10394 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10395 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10396 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10397 #ifdef CONFIG_ANTENNA_DIVERSITY
10398 struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
10399 #endif /* CONFIG_ANTENNA_DIVERSITY */
10401 /* u32 initialgain; */
10404 /* check already connecting to AP or not */
10405 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
10407 if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
10409 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 5, 100);
10412 pmlmeinfo->state = WIFI_FW_NULL_STATE;
10415 flush_all_cam_entry(padapter);
10417 _cancel_timer_ex(&pmlmeext->link_timer);
10419 /* set MSR to nolink -> infra. mode */
10420 /* Set_MSR(padapter, _HW_STATE_NOLINK_); */
10421 Set_MSR(padapter, _HW_STATE_STATION_);
10423 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
10426 #ifdef CONFIG_ANTENNA_DIVERSITY
10427 rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, _FALSE);
10430 #ifdef CONFIG_WAPI_SUPPORT
10431 rtw_wapi_clear_all_cam_entry(padapter);
10434 rtw_joinbss_reset(padapter);
10436 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
10437 pmlmeext->cur_ch_offset= HAL_PRIME_CHNL_OFFSET_DONT_CARE;
10438 pmlmeinfo->ERP_enable = 0;
10439 pmlmeinfo->WMM_enable = 0;
10440 pmlmeinfo->HT_enable = 0;
10441 pmlmeinfo->HT_caps_enable = 0;
10442 pmlmeinfo->HT_info_enable = 0;
10443 pmlmeinfo->agg_enable_bitmap = 0;
10444 pmlmeinfo->candidate_tid_bitmap = 0;
10445 pmlmeinfo->bwmode_updated = _FALSE;
10446 /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
10448 memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
10449 pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
10451 if(pnetwork->IELength>MAX_IE_SZ)/* Check pbuf->IELength */
10452 return H2C_PARAMETERS_ERROR;
10454 memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
10456 /* Check AP vendor to move rtw_joinbss_cmd() */
10457 /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength); */
10459 for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pnetwork->IELength;)
10461 pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
10463 switch (pIE->ElementID)
10465 case _VENDOR_SPECIFIC_IE_:/* Get WMM IE. */
10466 if (!memcmp(pIE->data, WMM_OUI, 4))
10468 pmlmeinfo->WMM_enable = 1;
10472 case _HT_CAPABILITY_IE_: /* Get HT Cap IE. */
10473 pmlmeinfo->HT_caps_enable = 1;
10476 case _HT_EXTRA_INFO_IE_: /* Get HT Info IE. */
10477 #ifdef CONFIG_80211N_HT
10478 pmlmeinfo->HT_info_enable = 1;
10480 /* spec case only for cisco's ap because cisco's ap issue assoc rsp using mcs rate @40MHz or @20MHz */
10481 /* if !defined(CONFIG_CONCURRENT_MODE) && !defined(CONFIG_DUALMAC_CONCURRENT) */
10482 /* if(pmlmeinfo->assoc_AP_vendor == ciscoAP) */
10485 struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data);
10487 if ((pregpriv->cbw40_enable) && (pht_info->infos[0] & BIT(2)))
10489 /* switch to the 40M Hz mode according to the AP */
10490 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
10491 switch (pht_info->infos[0] & 0x3)
10494 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
10498 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
10502 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
10506 DBG_8723A("set ch/bw before connected\n");
10509 #endif /* CONFIG_80211N_HT */
10516 i += (pIE->Length + 2);
10518 /* disable dynamic functions, such as high power, DIG */
10519 /* Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE); */
10521 /* config the initial gain under linking, need to write the BB registers */
10522 /* initialgain = 0x1E; */
10523 /* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */
10525 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
10527 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
10529 /* cancel link timer */
10530 _cancel_timer_ex(&pmlmeext->link_timer);
10532 start_clnt_join(padapter);
10534 return H2C_SUCCESS;
10537 u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf)
10539 struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
10540 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10541 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10542 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
10545 if (is_client_associated_to_ap(padapter))
10547 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100);
10550 /* set_opmode_cmd(padapter, infra_client_with_mlme); */
10552 /* pmlmeinfo->state = WIFI_FW_NULL_STATE; */
10554 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
10555 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
10557 /* restore to initial setting. */
10558 update_tx_basic_rate(padapter, padapter->registrypriv.wireless_mode);
10560 if(((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
10564 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
10567 /* set MSR to no link state -> infra. mode */
10568 Set_MSR(padapter, _HW_STATE_STATION_);
10570 pmlmeinfo->state = WIFI_FW_NULL_STATE;
10572 #ifdef CONFIG_DUALMAC_CONCURRENT
10573 dc_set_channel_bwmode_disconnect(padapter);
10575 #ifdef CONFIG_CONCURRENT_MODE
10576 if((check_buddy_fwstate(padapter, _FW_LINKED)) != _TRUE)
10578 #endif /* CONFIG_CONCURRENT_MODE */
10579 /* switch to the 20M Hz mode after disconnect */
10580 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
10581 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
10583 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
10584 #ifdef CONFIG_CONCURRENT_MODE
10586 #endif /* CONFIG_CONCURRENT_MODE */
10587 #endif /* CONFIG_DUALMAC_CONCURRENT */
10589 flush_all_cam_entry(padapter);
10591 _cancel_timer_ex(&pmlmeext->link_timer);
10593 rtw_free_uc_swdec_pending_queue(padapter);
10595 return H2C_SUCCESS;
10598 int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out,
10599 u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
10602 int scan_ch_num = 0;
10604 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10606 /* clear out first */
10607 memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num);
10609 /* acquire channels from in */
10611 for (i=0;i<in_num;i++) {
10613 DBG_8723A(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
10614 if(in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED)
10615 && (set_idx=rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value)) >=0
10618 memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
10620 if(pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE)
10621 out[j].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
10629 /* if out is empty, use channel_set as default */
10631 for (i=0;i<pmlmeext->max_chan_nums;i++) {
10632 out[i].hw_value = pmlmeext->channel_set[i].ChannelNum;
10634 if(pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE)
10635 out[i].flags &= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
10641 if (padapter->setband == GHZ_24) { /* 2.4G */
10642 for (i=0; i < j ; i++) {
10643 if (out[i].hw_value > 35)
10644 memset(&out[i], 0 , sizeof(struct rtw_ieee80211_channel));
10649 } else if (padapter->setband == GHZ_50) { /* 5G */
10650 for (i=0; i < j ; i++) {
10651 if (out[i].hw_value > 35) {
10652 memcpy(&out[scan_ch_num++], &out[i], sizeof(struct rtw_ieee80211_channel));
10662 u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
10664 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10665 struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
10666 u8 bdelayscan = _FALSE;
10672 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
10675 if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE)
10677 /* for first time sitesurvey_cmd */
10678 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
10680 pmlmeext->sitesurvey_res.state = SCAN_START;
10681 pmlmeext->sitesurvey_res.bss_cnt = 0;
10682 pmlmeext->sitesurvey_res.channel_idx = 0;
10684 for(i=0;i<RTW_SSID_SCAN_AMOUNT;i++){
10685 if(pparm->ssid[i].SsidLength) {
10686 memcpy(pmlmeext->sitesurvey_res.ssid[i].Ssid, pparm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
10687 pmlmeext->sitesurvey_res.ssid[i].SsidLength= pparm->ssid[i].SsidLength;
10689 pmlmeext->sitesurvey_res.ssid[i].SsidLength= 0;
10693 pmlmeext->sitesurvey_res.ch_num = rtw_scan_ch_decision(padapter
10694 , pmlmeext->sitesurvey_res.ch, RTW_CHANNEL_SCAN_AMOUNT
10695 , pparm->ch, pparm->ch_num
10698 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode;
10700 #ifdef CONFIG_DUALMAC_CONCURRENT
10701 bdelayscan = dc_handle_site_survey(padapter);
10704 /* issue null data if associating to the AP */
10705 if (is_client_associated_to_ap(padapter) == _TRUE)
10707 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
10709 /* switch to correct channel of current network before issue keep-alive frames */
10710 if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
10711 SelectChannel(padapter, pmlmeext->cur_channel);
10714 issue_nulldata(padapter, NULL, 1, 3, 500);
10716 #ifdef CONFIG_CONCURRENT_MODE
10717 if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
10719 DBG_8723A("adapter is scanning(buddy_adapter is linked), issue nulldata(pwrbit=1)\n");
10721 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
10724 bdelayscan = _TRUE;
10726 #ifdef CONFIG_CONCURRENT_MODE
10727 else if(is_client_associated_to_ap(padapter->pbuddy_adapter) == _TRUE)
10730 if(padapter->pbuddy_adapter->wdinfo.wfd_tdls_enable == 1)
10732 issue_tunneled_probe_req(padapter->pbuddy_adapter);
10734 #endif /* CONFIG_TDLS */
10736 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
10738 issue_nulldata(padapter->pbuddy_adapter, NULL, 1, 3, 500);
10740 bdelayscan = _TRUE;
10745 /* delay 50ms to protect nulldata(1). */
10746 set_survey_timer(pmlmeext, 50);
10747 return H2C_SUCCESS;
10751 if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL))
10753 /* disable dynamic functions, such as high power, DIG */
10754 Save_DM_Func_Flag(padapter);
10755 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, _FALSE);
10757 /* config the initial gain under scaning, need to write the BB registers */
10758 #ifdef CONFIG_IOCTL_CFG80211
10759 if((wdev_to_priv(padapter->rtw_wdev))->p2p_enabled == _TRUE)
10761 initialgain = 0x30;
10764 initialgain = 0x1E;
10765 #else /* go through the WEXT interface CONFIG_IOCTL_CFG80211 */
10767 if ( rtw_p2p_chk_state( pwdinfo, P2P_STATE_NONE ) )
10768 initialgain = 0x1E;
10770 initialgain = 0x28;
10771 #else /* CONFIG_P2P */
10772 initialgain = 0x1E;
10773 #endif /* CONFIG_P2P */
10774 #endif /* CONFIG_IOCTL_CFG80211 */
10776 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain));
10778 /* set MSR to no link state */
10779 Set_MSR(padapter, _HW_STATE_NOLINK_);
10781 val8 = 1; /* under site survey */
10782 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
10784 pmlmeext->sitesurvey_res.state = SCAN_PROCESS;
10787 site_survey(padapter);
10789 return H2C_SUCCESS;
10792 u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf)
10794 struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
10795 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10796 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10798 if (pparm->mode < 4)
10800 pmlmeinfo->auth_algo = pparm->mode;
10803 return H2C_SUCCESS;
10806 u8 setkey_hdl(_adapter *padapter, u8 *pbuf)
10808 unsigned short ctrl;
10809 struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
10810 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10811 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10812 unsigned char null_sta[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
10814 /* main tx key for wep. */
10816 pmlmeinfo->key_index = pparm->keyid;
10819 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
10821 DBG_8723A_LEVEL(_drv_always_, "set group key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) "
10822 "keyid:%d\n", pparm->algorithm, pparm->keyid);
10823 write_cam(padapter, pparm->keyid, ctrl, null_sta, pparm->key);
10825 /* allow multicast packets to driver */
10826 padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_ON_RCR_AM, null_addr);
10828 return H2C_SUCCESS;
10831 u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf)
10834 u8 cam_id;/* cam_entry */
10835 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10836 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10837 struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
10839 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
10840 struct sta_priv *pstapriv = &padapter->stapriv;
10841 struct sta_info *psta;
10842 #endif /* CONFIG_TDLS */
10845 /* 0~3 for default key */
10847 /* for concurrent mode (ap+sta): */
10848 /* default key is disable, using sw encrypt/decrypt */
10849 /* cam_entry = 4 for sta mode (macid=0) */
10850 /* cam_entry(macid+3) = 5 ~ N for ap mode (aid=1~N, macid=2 ~N) */
10852 /* for concurrent mode (sta+sta): */
10853 /* default key is disable, using sw encrypt/decrypt */
10854 /* cam_entry = 4 mapping to macid=0 */
10855 /* cam_entry = 5 mapping to macid=2 */
10857 #ifdef CONFIG_CONCURRENT_MODE
10858 if((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
10860 struct sta_priv *pstapriv = &padapter->stapriv;
10861 struct sta_info *psta;
10863 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
10865 if(psta && psta->mac_id==2)
10874 if(padapter->iface_type > PRIMARY_IFACE)
10888 DBG_8723A_LEVEL(_drv_always_, "set pairwise key to hw: alg:%d(WEP40-1 WEP104-5 TKIP-2 AES-4) camid:%d\n",
10889 pparm->algorithm, cam_id);
10890 if((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)
10893 struct sta_info *psta;
10894 struct sta_priv *pstapriv = &padapter->stapriv;
10896 if(pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */
10898 clear_cam_entry(padapter, pparm->id);
10899 return H2C_SUCCESS_RSP;
10902 psta = rtw_get_stainfo(pstapriv, pparm->addr);
10905 ctrl = (BIT(15) | ((pparm->algorithm) << 2));
10907 DBG_8723A("r871x_set_stakey_hdl(): enc_algorithm=%d\n", pparm->algorithm);
10909 if((psta->mac_id<1) || (psta->mac_id>(NUM_STA-4)))
10911 DBG_8723A("r871x_set_stakey_hdl():set_stakey failed, mac_id(aid)=%d\n", psta->mac_id);
10912 return H2C_REJECTED;
10915 cam_id = (psta->mac_id + 3);/* 0~3 for default key, cmd_id=macid + 3, macid=aid+1; */
10917 DBG_8723A("Write CAM, mac_addr=%x:%x:%x:%x:%x:%x, cam_entry=%d\n", pparm->addr[0],
10918 pparm->addr[1], pparm->addr[2], pparm->addr[3], pparm->addr[4],
10919 pparm->addr[5], cam_id);
10921 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
10923 return H2C_SUCCESS_RSP;
10928 DBG_8723A("r871x_set_stakey_hdl(): sta has been free\n");
10929 return H2C_REJECTED;
10934 /* below for sta mode */
10936 if(pparm->algorithm == _NO_PRIVACY_) /* clear cam entry */
10938 clear_cam_entry(padapter, pparm->id);
10939 return H2C_SUCCESS;
10942 ctrl = BIT(15) | ((pparm->algorithm) << 2);
10945 if(ptdlsinfo->clear_cam!=0){
10946 clear_cam_entry(padapter, ptdlsinfo->clear_cam);
10947 ptdlsinfo->clear_cam=0;
10949 return H2C_SUCCESS;
10952 psta = rtw_get_stainfo(pstapriv, pparm->addr);/* Get TDLS Peer STA */
10953 if( psta->tdls_sta_state&TDLS_LINKED_STATE ){
10954 write_cam(padapter, psta->mac_id, ctrl, pparm->addr, pparm->key);
10957 #endif /* CONFIG_TDLS */
10958 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
10960 pmlmeinfo->enc_algo = pparm->algorithm;
10962 return H2C_SUCCESS;
10965 u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf)
10967 struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
10968 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10969 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10971 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
10974 return H2C_SUCCESS;
10976 #ifdef CONFIG_80211N_HT
10977 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
10978 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
10980 /* pmlmeinfo->ADDBA_retry_count = 0; */
10981 /* pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid); */
10982 /* psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid); */
10983 issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
10984 /* _set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO); */
10985 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
10988 else if((psta->tdls_sta_state & TDLS_LINKED_STATE)&&
10989 (psta->htpriv.ht_option==_TRUE) &&
10990 (psta->htpriv.ampdu_enable==_TRUE) )
10992 issue_action_BA(padapter, pparm->addr, RTW_WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid);
10993 /* _set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO); */
10994 _set_timer(&psta->addba_retry_timer, ADDBA_TO);
10996 #endif /* CONFIG */
10999 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
11001 #endif /* CONFIG_80211N_HT */
11002 return H2C_SUCCESS;
11005 u8 set_tx_beacon_cmd(_adapter* padapter)
11007 struct cmd_obj *ph2c;
11008 struct Tx_Beacon_param *ptxBeacon_parm;
11009 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
11010 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11011 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11017 if ((ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj))) == NULL)
11023 if ((ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param))) == NULL)
11025 rtw_mfree((unsigned char *)ph2c, sizeof(struct cmd_obj));
11030 memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
11032 len_diff = update_hidden_ssid(
11033 ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_
11034 , ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_
11035 , pmlmeinfo->hidden_ssid_mode
11037 ptxBeacon_parm->network.IELength += len_diff;
11039 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
11041 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
11050 u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf)
11052 u8 evt_code, evt_seq;
11055 void (*event_callback)(_adapter *dev, u8 *pbuf);
11056 struct evt_priv *pevt_priv = &(padapter->evtpriv);
11058 peventbuf = (uint*)pbuf;
11059 evt_sz = (u16)(*peventbuf&0xffff);
11060 evt_seq = (u8)((*peventbuf>>24)&0x7f);
11061 evt_code = (u8)((*peventbuf>>16)&0xff);
11063 #ifdef CHECK_EVENT_SEQ
11064 /* checking event sequence... */
11065 if (evt_seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f) )
11067 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)));
11069 pevt_priv->event_seq = (evt_seq+1)&0x7f;
11071 goto _abort_event_;
11075 /* checking if event code is valid */
11076 if (evt_code >= MAX_C2HEVT) {
11077 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent Code(%d) mismatch!\n", evt_code));
11078 goto _abort_event_;
11081 /* checking if event size match the event parm size */
11082 if ((wlanevents[evt_code].parmsize != 0) &&
11083 (wlanevents[evt_code].parmsize != evt_sz)) {
11084 RT_TRACE(_module_rtl871x_cmd_c_,_drv_err_,("\nEvent(%d) Parm Size mismatch (%d vs %d)!\n",
11085 evt_code, wlanevents[evt_code].parmsize, evt_sz));
11086 goto _abort_event_;
11089 ATOMIC_INC(&pevt_priv->event_seq);
11094 event_callback = wlanevents[evt_code].event_callback;
11095 event_callback(padapter, (u8*)peventbuf);
11097 pevt_priv->evt_done_cnt++;
11102 return H2C_SUCCESS;
11105 u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf)
11108 return H2C_PARAMETERS_ERROR;
11110 return H2C_SUCCESS;
11113 u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf)
11115 if(send_beacon(padapter)==_FAIL)
11117 DBG_8723A("issue_beacon, fail!\n");
11118 return H2C_PARAMETERS_ERROR;
11120 #ifdef CONFIG_AP_MODE
11121 else /* tx bc/mc frames after update TIM */
11124 struct sta_info *psta_bmc;
11125 _list *xmitframe_plist, *xmitframe_phead;
11126 struct xmit_frame *pxmitframe=NULL;
11127 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
11128 struct sta_priv *pstapriv = &padapter->stapriv;
11130 /* for BC/MC Frames */
11131 psta_bmc = rtw_get_bcmc_stainfo(padapter);
11133 return H2C_SUCCESS;
11135 if((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len>0))
11137 #ifndef CONFIG_PCI_HCI
11138 rtw_msleep_os(10);/* 10ms, ATIM(HIQ) Windows */
11140 /* spin_lock_bh(&psta_bmc->sleep_q.lock); */
11141 spin_lock_bh(&pxmitpriv->lock);
11143 xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
11144 xmitframe_plist = get_next(xmitframe_phead);
11146 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
11148 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
11150 xmitframe_plist = get_next(xmitframe_plist);
11152 rtw_list_delete(&pxmitframe->list);
11154 psta_bmc->sleepq_len--;
11155 if(psta_bmc->sleepq_len>0)
11156 pxmitframe->attrib.mdata = 1;
11158 pxmitframe->attrib.mdata = 0;
11160 pxmitframe->attrib.triggered=1;
11162 pxmitframe->attrib.qsel = 0x11;/* HIQ */
11164 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
11166 /* pstapriv->tim_bitmap &= ~BIT(0); */
11170 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */
11171 spin_unlock_bh(&pxmitpriv->lock);
11173 /* if defined(CONFIG_PCI_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI) */
11174 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
11175 rtw_chk_hi_queue_cmd(padapter);
11183 return H2C_SUCCESS;
11186 #ifdef CONFIG_DUALMAC_CONCURRENT
11187 void dc_SelectChannel(_adapter *padapter, unsigned char channel)
11189 PADAPTER ptarget_adapter;
11191 if( (padapter->pbuddy_adapter != NULL) &&
11192 (padapter->DualMacConcurrent == _TRUE) &&
11193 (padapter->adapter_type == SECONDARY_ADAPTER))
11195 /* only mac0 could control BB&RF */
11196 ptarget_adapter = padapter->pbuddy_adapter;
11200 ptarget_adapter = padapter;
11203 _enter_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setch_mutex), NULL);
11205 rtw_hal_set_chan(ptarget_adapter, channel);
11207 _exit_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setch_mutex), NULL);
11210 void dc_SetBWMode(_adapter *padapter, unsigned short bwmode, unsigned char channel_offset)
11212 PADAPTER ptarget_adapter;
11214 if( (padapter->pbuddy_adapter != NULL) &&
11215 (padapter->DualMacConcurrent == _TRUE) &&
11216 (padapter->adapter_type == SECONDARY_ADAPTER))
11218 /* only mac0 could control BB&RF */
11219 ptarget_adapter = padapter->pbuddy_adapter;
11223 ptarget_adapter = padapter;
11226 _enter_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setbw_mutex), NULL);
11228 rtw_hal_set_bwmode(ptarget_adapter, (HT_CHANNEL_WIDTH)bwmode, channel_offset);
11230 _exit_critical_mutex(&(adapter_to_dvobj(ptarget_adapter)->setbw_mutex), NULL);
11233 static void dc_change_band(_adapter *padapter, WLAN_BSSID_EX *pnetwork)
11235 u8 network_type,rate_len, total_rate_len,remainder_rate_len;
11236 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
11237 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11240 /* DBG_8723A("%s\n", __FUNCTION__); */
11242 if(pmlmeext->cur_channel >= 36)
11244 network_type = WIRELESS_11A;
11245 total_rate_len = IEEE80211_NUM_OFDM_RATESLEN;
11246 DBG_8723A("%s(): change to 5G Band\n",__FUNCTION__);
11247 rtw_remove_bcn_ie(padapter, pnetwork, _ERPINFO_IE_);
11251 network_type = WIRELESS_11BG;
11252 total_rate_len = IEEE80211_CCK_RATE_LEN+IEEE80211_NUM_OFDM_RATESLEN;
11253 DBG_8723A("%s(): change to 2.4G Band\n",__FUNCTION__);
11254 rtw_add_bcn_ie(padapter, pnetwork, _ERPINFO_IE_, &erpinfo, 1);
11257 rtw_set_supported_rate(pnetwork->SupportedRates, network_type);
11259 UpdateBrateTbl(padapter, pnetwork->SupportedRates);
11260 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, pnetwork->SupportedRates);
11262 if(total_rate_len > 8)
11265 remainder_rate_len = total_rate_len - 8;
11269 rate_len = total_rate_len;
11270 remainder_rate_len = 0;
11273 rtw_add_bcn_ie(padapter, pnetwork, _SUPPORTEDRATES_IE_, pnetwork->SupportedRates, rate_len);
11275 if(remainder_rate_len)
11277 rtw_add_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_, (pnetwork->SupportedRates+8), remainder_rate_len);
11281 rtw_remove_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_);
11285 void dc_set_channel_bwmode_disconnect(_adapter *padapter)
11287 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11288 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
11289 struct mlme_priv *pbuddy_mlmepriv = NULL;
11291 if(pbuddy_adapter != NULL &&
11292 padapter->DualMacConcurrent == _TRUE)
11294 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11295 if((check_fwstate(pbuddy_mlmepriv, _FW_LINKED)) != _TRUE)
11297 /* switch to the 20M Hz mode after disconnect */
11298 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
11299 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11301 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
11306 /* switch to the 20M Hz mode after disconnect */
11307 pmlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
11308 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11310 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
11314 u8 dc_handle_join_request(_adapter *padapter)
11316 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11317 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11318 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX*)(&(pmlmeinfo->network));
11319 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
11320 struct mlme_ext_priv *pbuddy_mlmeext = NULL;
11321 struct mlme_priv *pbuddy_mlmepriv = NULL;
11324 if(pbuddy_adapter != NULL &&
11325 padapter->DualMacConcurrent == _TRUE)
11327 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
11328 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11330 if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel ||
11331 pmlmeext->cur_bwmode != pbuddy_mlmeext->cur_bwmode ||
11332 pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset)
11334 if((check_fwstate(pbuddy_mlmepriv, WIFI_AP_STATE)) == _TRUE)
11336 /* issue deauth to all stas if if2 is at ap mode */
11337 rtw_sta_flush(pbuddy_adapter);
11339 /* rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0); */
11340 rtw_hal_set_hwreg(pbuddy_adapter, HW_VAR_CHECK_TXBUF, 0);
11342 else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED) == _TRUE)
11344 if(pmlmeext->cur_channel == pbuddy_mlmeext->cur_channel)
11346 /* HT_CHANNEL_WIDTH_40 or HT_CHANNEL_WIDTH_20 but channel offset is different */
11347 if((pmlmeext->cur_bwmode == pbuddy_mlmeext->cur_bwmode) &&
11348 (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset) )
11350 report_join_res(padapter, -4);
11356 report_join_res(padapter, -4);
11361 else if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE)
11363 issue_nulldata(pbuddy_adapter, NULL, 1, 0, 0);
11370 void dc_handle_join_done(_adapter *padapter, u8 join_res)
11372 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11373 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11374 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
11375 struct mlme_priv *pbuddy_mlmepriv = NULL;
11376 struct mlme_ext_priv *pbuddy_mlmeext = NULL;
11377 struct mlme_ext_info *pbuddy_mlmeinfo = NULL;
11378 WLAN_BSSID_EX *pbuddy_network_mlmeext = NULL;
11379 u8 change_band = _FALSE;
11381 if(pbuddy_adapter != NULL &&
11382 padapter->DualMacConcurrent == _TRUE)
11384 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11385 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
11386 pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
11387 pbuddy_network_mlmeext = &(pbuddy_mlmeinfo->network);
11389 if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
11390 check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
11392 /* restart and update beacon */
11393 DBG_8723A("after join, current adapter, CH=%d, BW=%d, offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
11399 struct HT_info_element *pht_info=NULL;
11401 if((pbuddy_mlmeext->cur_channel <= 14 && pmlmeext->cur_channel >= 36) ||
11402 (pbuddy_mlmeext->cur_channel >= 36 && pmlmeext->cur_channel <= 14))
11404 change_band = _TRUE;
11407 /* sync channel/bwmode/ch_offset with another adapter */
11408 pbuddy_mlmeext->cur_channel = pmlmeext->cur_channel;
11410 if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
11412 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)));
11415 pht_info = (struct HT_info_element *)(p+2);
11416 pht_info->infos[0] &= ~(BIT(0)|BIT(1)); /* no secondary channel is present */
11419 if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
11421 pbuddy_mlmeext->cur_ch_offset = pmlmeext->cur_ch_offset;
11423 /* to update cur_ch_offset value in beacon */
11426 switch(pmlmeext->cur_ch_offset)
11428 case HAL_PRIME_CHNL_OFFSET_LOWER:
11429 pht_info->infos[0] |= 0x1;
11431 case HAL_PRIME_CHNL_OFFSET_UPPER:
11432 pht_info->infos[0] |= 0x3;
11434 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
11440 else if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20)
11442 pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
11443 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11445 if(pmlmeext->cur_channel>0 && pmlmeext->cur_channel<5)
11448 pht_info->infos[0] |= 0x1;
11450 pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
11451 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
11454 if(pmlmeext->cur_channel>7 && pmlmeext->cur_channel<(14+1))
11457 pht_info->infos[0] |= 0x3;
11459 pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
11460 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
11463 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
11467 /* to update channel value in beacon */
11468 pbuddy_network_mlmeext->Configuration.DSConfig = pmlmeext->cur_channel;
11469 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)));
11471 *(p + 2) = pmlmeext->cur_channel;
11473 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)));
11476 pht_info = (struct HT_info_element *)(p+2);
11477 pht_info->primary_channel = pmlmeext->cur_channel;
11480 /* update mlmepriv's cur_network */
11481 memcpy(&pbuddy_mlmepriv->cur_network.network, pbuddy_network_mlmeext, pbuddy_network_mlmeext->Length);
11485 /* switch back to original channel/bwmode/ch_offset; */
11486 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
11489 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);
11491 if(change_band == _TRUE)
11492 dc_change_band(pbuddy_adapter, pbuddy_network_mlmeext);
11494 DBG_8723A("update pbuddy_adapter's beacon\n");
11496 update_beacon(pbuddy_adapter, 0, NULL, _TRUE);
11498 else if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE)
11500 if((pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
11501 (pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20))
11503 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
11506 issue_nulldata(pbuddy_adapter, NULL, 0, 0, 0);
11511 int dc_check_fwstate(_adapter *padapter, int fw_state)
11513 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
11514 struct mlme_priv *pbuddy_mlmepriv = NULL;
11516 if(padapter->pbuddy_adapter != NULL &&
11517 padapter->DualMacConcurrent == _TRUE)
11520 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11522 return check_fwstate(pbuddy_mlmepriv, fw_state);
11528 u8 dc_handle_site_survey(_adapter *padapter)
11530 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11531 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11532 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
11534 /* only mac0 can do scan request, help issue nulldata(1) for mac1 */
11535 if(pbuddy_adapter != NULL &&
11536 padapter->DualMacConcurrent == _TRUE)
11538 if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE)
11540 pmlmeext->sitesurvey_res.state = SCAN_TXNULL;
11542 issue_nulldata(pbuddy_adapter, NULL, 1, 2, 0);
11551 void dc_report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
11553 if(padapter->pbuddy_adapter != NULL &&
11554 padapter->DualMacConcurrent == _TRUE)
11556 report_survey_event(padapter->pbuddy_adapter, precv_frame);
11560 void dc_set_channel_bwmode_survey_done(_adapter *padapter)
11562 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
11563 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11564 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
11565 struct mlme_priv *pbuddy_mlmepriv = NULL;
11566 struct mlme_ext_priv *pbuddy_mlmeext = NULL;
11567 struct mlme_ext_info *pbuddy_mlmeinfo = NULL;
11572 if(pbuddy_adapter != NULL &&
11573 padapter->DualMacConcurrent == _TRUE)
11575 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11576 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
11577 pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
11579 if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
11581 if(check_fwstate(pmlmepriv, _FW_LINKED) &&
11582 (pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40))
11584 cur_channel = pmlmeext->cur_channel;
11585 cur_bwmode = pmlmeext->cur_bwmode;
11586 cur_ch_offset = pmlmeext->cur_ch_offset;
11590 cur_channel = pbuddy_mlmeext->cur_channel;
11591 cur_bwmode = pbuddy_mlmeext->cur_bwmode;
11592 cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
11597 cur_channel = pmlmeext->cur_channel;
11598 cur_bwmode = pmlmeext->cur_bwmode;
11599 cur_ch_offset = pmlmeext->cur_ch_offset;
11602 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
11604 if (is_client_associated_to_ap(pbuddy_adapter) == _TRUE)
11606 /* issue null data */
11607 issue_nulldata(pbuddy_adapter, NULL, 0, 0, 0);
11610 if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
11611 check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
11614 DBG_8723A("survey done, current CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
11616 DBG_8723A("restart pbuddy_adapter's beacon\n");
11618 update_beacon(pbuddy_adapter, 0, NULL, _TRUE);
11623 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
11627 void dc_set_ap_channel_bandwidth(_adapter *padapter, u8 channel, u8 channel_offset, u8 bwmode)
11630 u8 val8, cur_channel, cur_bwmode, cur_ch_offset, change_band;
11632 struct registry_priv *pregpriv = &padapter->registrypriv;
11633 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
11634 WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&pmlmepriv->cur_network.network;
11635 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
11636 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11637 struct HT_info_element *pht_info=NULL;
11638 _adapter *pbuddy_adapter = padapter->pbuddy_adapter;
11639 struct mlme_priv *pbuddy_mlmepriv = NULL;
11640 struct mlme_ext_priv *pbuddy_mlmeext = NULL;
11642 DBG_8723A("dualmac_concurrent_ap_set_channel_bwmode ==>\n");
11644 cur_channel = channel;
11645 cur_bwmode = bwmode;
11646 cur_ch_offset = channel_offset;
11647 change_band = _FALSE;
11649 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)));
11652 pht_info = (struct HT_info_element *)(p+2);
11655 if(pbuddy_adapter != NULL &&
11656 padapter->DualMacConcurrent == _TRUE)
11658 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11659 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
11661 if(!check_fwstate(pbuddy_mlmepriv, _FW_LINKED|_FW_UNDER_LINKING|_FW_UNDER_SURVEY))
11663 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
11665 else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED)==_TRUE)
11667 /* To sync cur_channel/cur_bwmode/cur_ch_offset with another adapter */
11668 DBG_8723A("Another iface is at linked state, sync cur_channel/cur_bwmode/cur_ch_offset\n");
11669 DBG_8723A("Another adapter, CH=%d, BW=%d, offset=%d\n", pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
11670 DBG_8723A("Current adapter, CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
11672 cur_channel = pbuddy_mlmeext->cur_channel;
11673 if(cur_bwmode == HT_CHANNEL_WIDTH_40)
11676 pht_info->infos[0] &= ~(BIT(0)|BIT(1));
11678 if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
11680 cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
11682 /* to update cur_ch_offset value in beacon */
11685 switch(cur_ch_offset)
11687 case HAL_PRIME_CHNL_OFFSET_LOWER:
11688 pht_info->infos[0] |= 0x1;
11690 case HAL_PRIME_CHNL_OFFSET_UPPER:
11691 pht_info->infos[0] |= 0x3;
11693 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
11699 else if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20)
11701 cur_bwmode = HT_CHANNEL_WIDTH_20;
11702 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
11704 if(cur_channel>0 && cur_channel<5)
11707 pht_info->infos[0] |= 0x1;
11709 cur_bwmode = HT_CHANNEL_WIDTH_40;
11710 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
11713 if(cur_channel>7 && cur_channel<(14+1))
11716 pht_info->infos[0] |= 0x3;
11718 cur_bwmode = HT_CHANNEL_WIDTH_40;
11719 cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
11722 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
11726 /* to update channel value in beacon */
11727 pnetwork->Configuration.DSConfig = cur_channel;
11728 p = rtw_get_ie((pnetwork->IEs + sizeof(NDIS_802_11_FIXED_IEs)), _DSSET_IE_, &ie_len, (pnetwork->IELength - sizeof(NDIS_802_11_FIXED_IEs)));
11730 *(p + 2) = cur_channel;
11733 pht_info->primary_channel = cur_channel;
11738 set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
11741 DBG_8723A("CH=%d, BW=%d, offset=%d\n", cur_channel, cur_bwmode, cur_ch_offset);
11743 if((channel <= 14 && cur_channel >= 36) ||
11744 (channel >= 36 && cur_channel <= 14))
11746 change_band = _TRUE;
11749 pmlmeext->cur_channel = cur_channel;
11750 pmlmeext->cur_bwmode = cur_bwmode;
11751 pmlmeext->cur_ch_offset = cur_ch_offset;
11753 if(change_band == _TRUE)
11754 dc_change_band(padapter, pnetwork);
11756 DBG_8723A("dualmac_concurrent_ap_set_channel_bwmode <==\n");
11759 void dc_resume_xmit(_adapter *padapter)
11761 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
11763 if(pbuddy_adapter != NULL &&
11764 padapter->DualMacConcurrent == _TRUE)
11766 DBG_8723A("dc_resume_xmit, resume pbuddy_adapter Tx\n");
11767 rtw_os_xmit_schedule(pbuddy_adapter);
11771 u8 dc_check_xmit(_adapter *padapter)
11773 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
11774 struct mlme_priv *pbuddy_mlmepriv = NULL;
11776 if(pbuddy_adapter != NULL &&
11777 padapter->DualMacConcurrent == _TRUE)
11779 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11780 if (check_fwstate(pbuddy_mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
11782 DBG_8723A("dc_check_xmit pbuddy_adapter is under survey or under linking\n");
11791 #ifdef CONFIG_CONCURRENT_MODE
11792 int check_buddy_mlmeinfo_state(_adapter *padapter, u32 state)
11794 PADAPTER pbuddy_adapter;
11795 struct mlme_ext_priv *pbuddy_mlmeext;
11796 struct mlme_ext_info *pbuddy_mlmeinfo;
11798 if(padapter == NULL)
11801 pbuddy_adapter = padapter->pbuddy_adapter;
11803 if(pbuddy_adapter == NULL)
11806 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
11807 pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
11809 if((pbuddy_mlmeinfo->state&0x03) == state)
11815 int concurrent_chk_start_clnt_join(_adapter *padapter)
11818 PADAPTER pbuddy_adapter;
11819 struct mlme_ext_priv *pbuddy_mlmeext;
11820 struct mlme_ext_info *pbuddy_pmlmeinfo;
11821 struct mlme_priv *pbuddy_mlmepriv;
11822 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11823 unsigned char cur_ch = pmlmeext->cur_channel;
11824 unsigned char cur_bw = pmlmeext->cur_bwmode;
11825 unsigned char cur_ch_offset = pmlmeext->cur_ch_offset;
11827 if(!rtw_buddy_adapter_up(padapter))
11829 goto start_join_set_ch_bw;
11832 pbuddy_adapter = padapter->pbuddy_adapter;
11833 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
11834 pbuddy_pmlmeinfo = &(pbuddy_mlmeext->mlmext_info);
11835 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11837 if((pbuddy_pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)/* for AP MODE */
11839 bool inform_ch_switch = _FALSE;
11840 if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel)
11842 inform_ch_switch = _TRUE;
11844 else if((pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
11845 (pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
11846 (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset))
11848 inform_ch_switch = _TRUE;
11850 else if((pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20) &&
11851 (pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40))
11853 inform_ch_switch = _FALSE;
11854 cur_ch = pmlmeext->cur_channel;
11855 cur_bw = pbuddy_mlmeext->cur_bwmode;
11856 cur_ch_offset = pbuddy_mlmeext->cur_ch_offset;
11859 if (inform_ch_switch) {
11860 #ifdef CONFIG_SPCT_CH_SWITCH
11862 rtw_ap_inform_ch_switch(pbuddy_adapter, pmlmeext->cur_channel , pmlmeext->cur_ch_offset);
11866 /* issue deauth to all stas if if2 is at ap mode */
11867 rtw_sta_flush(pbuddy_adapter);
11869 rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
11872 else if(check_fwstate(pbuddy_mlmepriv, _FW_LINKED) == _TRUE &&
11873 check_fwstate(pbuddy_mlmepriv, WIFI_STATION_STATE) == _TRUE) /* for Client Mode/p2p client */
11875 #if defined(CONFIG_P2P) && defined(CONFIG_IOCTL_CFG80211)
11876 struct wifidirect_info *pbuddy_wdinfo = &(pbuddy_adapter->wdinfo);
11877 if(!rtw_p2p_chk_state(pbuddy_wdinfo, P2P_STATE_NONE))
11879 goto start_join_set_ch_bw;/* wlan0-sta mode has higher priority than p2p0-p2p client */
11881 #endif /* CONFIG_P2P && CONFIG_IOCTL_CFG80211 */
11883 if(pmlmeext->cur_channel != pbuddy_mlmeext->cur_channel)
11885 DBG_8723A("start_clnt_join(ch=%d), but channel mismatch with buddy(ch=%d) interface\n",
11886 pmlmeext->cur_channel, pbuddy_mlmeext->cur_channel);
11888 report_join_res(padapter, (-4));
11893 if((pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
11894 (pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) &&
11895 (pmlmeext->cur_ch_offset != pbuddy_mlmeext->cur_ch_offset))
11897 DBG_8723A("start_clnt_join(bwmode=%d, ch_offset=%d), but bwmode & ch_offset mismatch with buddy(bwmode=%d, ch_offset=%d) interface\n",
11898 pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode, pbuddy_mlmeext->cur_ch_offset);
11900 report_join_res(padapter, (-4));
11907 start_join_set_ch_bw:
11909 set_channel_bwmode(padapter, cur_ch, cur_ch_offset, cur_bw);
11914 void concurrent_chk_joinbss_done(_adapter *padapter, int join_res)
11916 struct mlme_ext_priv *pmlmeext;
11917 struct mlme_ext_info *pmlmeinfo;
11918 PADAPTER pbuddy_adapter;
11919 struct mlme_priv *pbuddy_mlmepriv;
11920 struct mlme_ext_priv *pbuddy_mlmeext;
11921 struct mlme_ext_info *pbuddy_mlmeinfo;
11922 WLAN_BSSID_EX *pbuddy_network_mlmeext;
11924 if(!rtw_buddy_adapter_up(padapter))
11926 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
11930 pmlmeext = &padapter->mlmeextpriv;
11931 pmlmeinfo = &(pmlmeext->mlmext_info);
11933 pbuddy_adapter = padapter->pbuddy_adapter;
11934 pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
11935 pbuddy_mlmeext = &pbuddy_adapter->mlmeextpriv;
11936 pbuddy_mlmeinfo = &(pbuddy_mlmeext->mlmext_info);
11937 pbuddy_network_mlmeext = &(pbuddy_mlmeinfo->network);
11939 if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_AP_STATE) &&
11940 check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
11942 /* restart and update beacon */
11944 DBG_8723A("after join,primary adapter, CH=%d, BW=%d, offset=%d\n"
11945 , pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
11951 struct HT_info_element *pht_info=NULL;
11953 /* sync channel/bwmode/ch_offset with primary adapter */
11954 pbuddy_mlmeext->cur_channel = pmlmeext->cur_channel;
11955 if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
11957 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)));
11960 pht_info = (struct HT_info_element *)(p+2);
11961 pht_info->infos[0] &= ~(BIT(0)|BIT(1)); /* no secondary channel is present */
11964 if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
11966 pbuddy_mlmeext->cur_ch_offset = pmlmeext->cur_ch_offset;
11968 /* to update cur_ch_offset value in beacon */
11971 switch(pmlmeext->cur_ch_offset)
11973 case HAL_PRIME_CHNL_OFFSET_LOWER:
11974 pht_info->infos[0] |= 0x1;
11976 case HAL_PRIME_CHNL_OFFSET_UPPER:
11977 pht_info->infos[0] |= 0x3;
11979 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
11987 else if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_20)
11989 if(pmlmeext->cur_channel>=1 && pmlmeext->cur_channel<=4)
11992 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
11994 pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
11995 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
11997 else if(pmlmeext->cur_channel>=5 && pmlmeext->cur_channel<=14)
12000 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
12002 pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
12003 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
12007 switch(pmlmeext->cur_channel)
12022 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE;
12023 pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
12024 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
12040 pht_info->infos[0] |= HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
12042 pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_40;
12043 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
12048 pht_info->infos[0] &= ~HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW;
12049 pbuddy_mlmeext->cur_bwmode = HT_CHANNEL_WIDTH_20;
12050 pbuddy_mlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
12059 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
12064 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
12067 /* to update channel value in beacon */
12068 pbuddy_network_mlmeext->Configuration.DSConfig = pmlmeext->cur_channel;
12069 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)));
12071 *(p + 2) = pmlmeext->cur_channel;
12073 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)));
12076 pht_info = (struct HT_info_element *)(p+2);
12077 pht_info->primary_channel = pmlmeext->cur_channel;
12083 /* switch back to original channel/bwmode/ch_offset; */
12084 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
12087 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);
12089 DBG_8723A("update pbuddy_adapter's beacon\n");
12091 update_beacon(pbuddy_adapter, 0, NULL, _TRUE);
12094 else if(((pbuddy_mlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) &&
12095 check_fwstate(pbuddy_mlmepriv, _FW_LINKED))
12099 pbuddy_mlmeext->cur_channel = pmlmeext->cur_channel;
12100 if(pbuddy_mlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
12101 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
12102 else if(pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40)
12103 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
12105 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, HT_CHANNEL_WIDTH_20);
12109 /* switch back to original channel/bwmode/ch_offset; */
12110 set_channel_bwmode(padapter, pbuddy_mlmeext->cur_channel, pbuddy_mlmeext->cur_ch_offset, pbuddy_mlmeext->cur_bwmode);
12115 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
12118 #endif /* CONFIG_CONCURRENT_MODE */
12120 u8 set_ch_hdl(_adapter *padapter, u8 *pbuf)
12122 struct set_ch_parm *set_ch_parm;
12123 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12124 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12127 return H2C_PARAMETERS_ERROR;
12129 set_ch_parm = (struct set_ch_parm *)pbuf;
12131 DBG_8723A(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
12132 FUNC_NDEV_ARG(padapter->pnetdev),
12133 set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
12135 pmlmeext->cur_channel = set_ch_parm->ch;
12136 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
12137 pmlmeext->cur_bwmode = set_ch_parm->bw;
12139 set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
12141 return H2C_SUCCESS;
12144 u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf)
12146 struct SetChannelPlan_param *setChannelPlan_param;
12147 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12148 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12151 return H2C_PARAMETERS_ERROR;
12153 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
12155 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set);
12156 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list);
12158 return H2C_SUCCESS;
12161 u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf)
12163 struct LedBlink_param *ledBlink_param;
12166 return H2C_PARAMETERS_ERROR;
12168 ledBlink_param = (struct LedBlink_param *)pbuf;
12170 #ifdef CONFIG_LED_HANDLED_BY_CMD_THREAD
12171 BlinkHandler(ledBlink_param->pLed);
12174 return H2C_SUCCESS;
12177 u8 set_csa_hdl(_adapter *padapter, unsigned char *pbuf)
12180 struct SetChannelSwitch_param *setChannelSwitch_param;
12181 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12182 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12183 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
12185 u8 gval8 = 0x00, sval8 = 0xff;
12188 return H2C_PARAMETERS_ERROR;
12190 setChannelSwitch_param = (struct SetChannelSwitch_param *)pbuf;
12191 new_ch_no = setChannelSwitch_param->new_ch_no;
12193 rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
12195 rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &sval8);
12197 DBG_8723A("DFS detected! Swiching channel to %d!\n", new_ch_no);
12198 SelectChannel(padapter, new_ch_no);
12200 rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, &gval8);
12202 rtw_free_network_queue(padapter, _TRUE);
12203 rtw_indicate_disconnect(padapter);
12205 if ( ((new_ch_no >= 52) && (new_ch_no <= 64)) ||((new_ch_no >= 100) && (new_ch_no <= 140)) ) {
12206 DBG_8723A("Switched to DFS band (ch %02x) again!!\n", new_ch_no);
12209 return H2C_SUCCESS;
12211 return H2C_REJECTED;
12212 #endif /* CONFIG_DFS */
12215 /* TDLS_WRCR : write RCR DATA BIT */
12216 /* TDLS_SD_PTI : issue peer traffic indication */
12217 /* TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure */
12218 /* TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame */
12219 /* TDLS_DONE_CH_SEN: channel sensing and report candidate channel */
12220 /* TDLS_OFF_CH : first time set channel to off channel */
12221 /* TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel */
12222 /* TDLS_P_OFF_CH : periodically go to off channel */
12223 /* TDLS_P_BASE_CH : periodically go back to base channel */
12224 /* TDLS_RS_RCR : restore RCR */
12225 /* TDLS_CKALV_PH1 : check alive timer phase1 */
12226 /* TDLS_CKALV_PH2 : check alive timer phase2 */
12227 /* TDLS_FREE_STA : free tdls sta */
12228 u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf)
12232 struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
12233 struct TDLSoption_param *TDLSoption;
12234 struct sta_info *ptdls_sta;
12235 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12236 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
12237 u8 survey_channel, i, min, option;
12240 return H2C_PARAMETERS_ERROR;
12242 TDLSoption = (struct TDLSoption_param *)pbuf;
12244 ptdls_sta = rtw_get_stainfo( &(padapter->stapriv), TDLSoption->addr );
12245 option = TDLSoption->option;
12247 if( ptdls_sta == NULL )
12249 if( option != TDLS_RS_RCR )
12250 return H2C_REJECTED;
12253 /* spin_lock_bh(&(ptdlsinfo->hdl_lock)); */
12254 DBG_8723A("[%s] option:%d\n", __FUNCTION__, option);
12258 /* As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0 */
12259 /* such we can receive all kinds of data frames. */
12260 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_WRCR, 0);
12261 DBG_8723A("TDLS with "MAC_FMT"\n", MAC_ARG(ptdls_sta->hwaddr));
12263 pmlmeinfo->FW_sta_info[ptdls_sta->mac_id].psta = ptdls_sta;
12264 /* set TDLS sta rate. */
12265 set_sta_rate(padapter, ptdls_sta);
12268 issue_tdls_peer_traffic_indication(padapter, ptdls_sta);
12271 _cancel_timer_ex(&ptdls_sta->base_ch_timer);
12272 _cancel_timer_ex(&ptdls_sta->off_ch_timer);
12273 SelectChannel(padapter, pmlmeext->cur_channel);
12274 ptdls_sta->tdls_sta_state &= ~(TDLS_CH_SWITCH_ON_STATE |
12275 TDLS_PEER_AT_OFF_STATE |
12276 TDLS_AT_OFF_CH_STATE);
12277 DBG_8723A("go back to base channel\n ");
12278 issue_nulldata(padapter, NULL, 0, 0, 0);
12280 case TDLS_INIT_CH_SEN:
12281 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_INIT_CH_SEN, 0);
12282 pmlmeext->sitesurvey_res.channel_idx = 0;
12283 ptdls_sta->option = TDLS_DONE_CH_SEN;
12284 rtw_tdls_cmd(padapter, ptdls_sta->hwaddr, TDLS_DONE_CH_SEN);
12286 case TDLS_DONE_CH_SEN:
12287 survey_channel = pmlmeext->channel_set[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
12288 if(survey_channel){
12289 SelectChannel(padapter, survey_channel);
12290 ptdlsinfo->cur_channel = survey_channel;
12291 pmlmeext->sitesurvey_res.channel_idx++;
12292 _set_timer(&ptdls_sta->option_timer, SURVEY_TO);
12294 SelectChannel(padapter, pmlmeext->cur_channel);
12296 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_DONE_CH_SEN, 0);
12298 if(ptdlsinfo->ch_sensing==1){
12299 ptdlsinfo->ch_sensing=0;
12300 ptdlsinfo->cur_channel=1;
12301 min=ptdlsinfo->collect_pkt_num[0];
12302 for(i=1; i<MAX_CHANNEL_NUM-1; i++){
12303 if(min > ptdlsinfo->collect_pkt_num[i]){
12304 ptdlsinfo->cur_channel=i+1;
12305 min=ptdlsinfo->collect_pkt_num[i];
12307 ptdlsinfo->collect_pkt_num[i]=0;
12309 ptdlsinfo->collect_pkt_num[0]=0;
12310 ptdlsinfo->candidate_ch=ptdlsinfo->cur_channel;
12311 DBG_8723A("TDLS channel sensing done, candidate channel: %02x\n", ptdlsinfo->candidate_ch);
12312 ptdlsinfo->cur_channel=0;
12316 if(ptdls_sta->tdls_sta_state & TDLS_PEER_SLEEP_STATE){
12317 ptdls_sta->tdls_sta_state |= TDLS_APSD_CHSW_STATE;
12319 /* send null data with pwrbit==1 before send ch_switching_req to peer STA. */
12320 issue_nulldata(padapter, NULL, 1, 0, 0);
12322 ptdls_sta->tdls_sta_state |= TDLS_CH_SW_INITIATOR_STATE;
12324 issue_tdls_ch_switch_req(padapter, ptdls_sta->hwaddr);
12325 DBG_8723A("issue tdls ch switch req\n");
12330 issue_nulldata(padapter, NULL, 1, 0, 0);
12331 SelectChannel(padapter, ptdls_sta->off_ch);
12333 DBG_8723A("change channel to tar ch:%02x\n", ptdls_sta->off_ch);
12334 ptdls_sta->tdls_sta_state |= TDLS_AT_OFF_CH_STATE;
12335 ptdls_sta->tdls_sta_state &= ~(TDLS_PEER_AT_OFF_STATE);
12336 _set_timer(&ptdls_sta->option_timer, (u32)ptdls_sta->ch_switch_time);
12339 _cancel_timer_ex(&ptdls_sta->base_ch_timer);
12340 _cancel_timer_ex(&ptdls_sta->off_ch_timer);
12341 SelectChannel(padapter, pmlmeext->cur_channel);
12342 ptdls_sta->tdls_sta_state &= ~(TDLS_CH_SWITCH_ON_STATE |
12343 TDLS_PEER_AT_OFF_STATE |
12344 TDLS_AT_OFF_CH_STATE);
12345 DBG_8723A("go back to base channel\n ");
12346 issue_nulldata(padapter, NULL, 0, 0, 0);
12347 _set_timer(&ptdls_sta->option_timer, (u32)ptdls_sta->ch_switch_time);
12349 case TDLS_P_OFF_CH:
12350 SelectChannel(padapter, pmlmeext->cur_channel);
12351 issue_nulldata(padapter, NULL, 0, 0, 0);
12352 DBG_8723A("change channel to base ch:%02x\n", pmlmeext->cur_channel);
12353 ptdls_sta->tdls_sta_state &= ~(TDLS_PEER_AT_OFF_STATE| TDLS_AT_OFF_CH_STATE);
12354 _set_timer(&ptdls_sta->off_ch_timer, TDLS_STAY_TIME);
12356 case TDLS_P_BASE_CH:
12357 issue_nulldata(ptdls_sta->padapter, NULL, 1, 0, 0);
12358 SelectChannel(padapter, ptdls_sta->off_ch);
12359 DBG_8723A("change channel to off ch:%02x\n", ptdls_sta->off_ch);
12360 ptdls_sta->tdls_sta_state |= TDLS_AT_OFF_CH_STATE;
12361 if((ptdls_sta->tdls_sta_state & TDLS_PEER_AT_OFF_STATE) != TDLS_PEER_AT_OFF_STATE){
12362 issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta, 0);
12364 _set_timer(&ptdls_sta->base_ch_timer, TDLS_STAY_TIME);
12367 rtw_hal_set_hwreg(padapter, HW_VAR_TDLS_RS_RCR, 0);
12368 DBG_8723A("wirte REG_RCR, set bit6 on\n");
12370 case TDLS_CKALV_PH1:
12371 _set_timer(&ptdls_sta->alive_timer2, TDLS_ALIVE_TIMER_PH2);
12373 case TDLS_CKALV_PH2:
12374 _set_timer(&ptdls_sta->alive_timer1, TDLS_ALIVE_TIMER_PH1);
12376 case TDLS_FREE_STA:
12377 free_tdls_sta(padapter, ptdls_sta);
12382 /* spin_unlock_bh(&(ptdlsinfo->hdl_lock)); */
12384 return H2C_SUCCESS;
12386 return H2C_REJECTED;
12387 #endif /* CONFIG_TDLS */