1 // SPDX-License-Identifier: GPL-2.0 2 /****************************************************************************** 3 * 4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. 5 * 6 ******************************************************************************/ 7 #include <drv_types.h> 8 #include <rtw_debug.h> 9 #include <rtw_wifi_regd.h> 10 #include <hal_btcoex.h> 11 #include <linux/kernel.h> 12 #include <asm/unaligned.h> 13 14 static struct mlme_handler mlme_sta_tbl[] = { 15 {WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq}, 16 {WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp}, 17 {WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq}, 18 {WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp}, 19 {WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq}, 20 {WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp}, 21 22 /*---------------------------------------------------------- 23 below 2 are reserved 24 -----------------------------------------------------------*/ 25 {0, "DoReserved", &DoReserved}, 26 {0, "DoReserved", &DoReserved}, 27 {WIFI_BEACON, "OnBeacon", &OnBeacon}, 28 {WIFI_ATIM, "OnATIM", &OnAtim}, 29 {WIFI_DISASSOC, "OnDisassoc", &OnDisassoc}, 30 {WIFI_AUTH, "OnAuth", &OnAuthClient}, 31 {WIFI_DEAUTH, "OnDeAuth", &OnDeAuth}, 32 {WIFI_ACTION, "OnAction", &OnAction}, 33 {WIFI_ACTION_NOACK, "OnActionNoAck", &OnAction}, 34 }; 35 36 static struct action_handler OnAction_tbl[] = { 37 {RTW_WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct}, 38 {RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &DoReserved}, 39 {RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &DoReserved}, 40 {RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back}, 41 {RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public}, 42 {RTW_WLAN_CATEGORY_RADIO_MEASUREMENT, "ACTION_RADIO_MEASUREMENT", &DoReserved}, 43 {RTW_WLAN_CATEGORY_FT, "ACTION_FT", &DoReserved}, 44 {RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht}, 45 {RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &OnAction_sa_query}, 46 {RTW_WLAN_CATEGORY_UNPROTECTED_WNM, "ACTION_UNPROTECTED_WNM", &DoReserved}, 47 {RTW_WLAN_CATEGORY_SELF_PROTECTED, "ACTION_SELF_PROTECTED", &DoReserved}, 48 {RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &DoReserved}, 49 {RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &DoReserved}, 50 }; 51 52 static u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; 53 54 /************************************************** 55 OUI definitions for the vendor specific IE 56 ***************************************************/ 57 unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01}; 58 unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02}; 59 unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04}; 60 unsigned char P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09}; 61 unsigned char WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A}; 62 63 unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; 64 unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; 65 66 static unsigned char REALTEK_96B_IE[] = {0x00, 0xe0, 0x4c, 0x02, 0x01, 0x20}; 67 68 /******************************************************** 69 ChannelPlan definitions 70 *********************************************************/ 71 static struct rt_channel_plan_2g RTW_ChannelPlan2G[RT_CHANNEL_DOMAIN_2G_MAX] = { 72 {{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 */ 73 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, /* 0x01, RT_CHANNEL_DOMAIN_2G_ETSI1 */ 74 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, /* 0x02, RT_CHANNEL_DOMAIN_2G_FCC1 */ 75 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, /* 0x03, RT_CHANNEL_DOMAIN_2G_MIKK1 */ 76 {{10, 11, 12, 13}, 4}, /* 0x04, RT_CHANNEL_DOMAIN_2G_ETSI2 */ 77 {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, /* 0x05, RT_CHANNEL_DOMAIN_2G_GLOBAL , Passive scan CH 12, 13, 14 */ 78 {{}, 0}, /* 0x06, RT_CHANNEL_DOMAIN_2G_NULL */ 79 }; 80 81 static struct rt_channel_plan_map RTW_ChannelPlanMap[RT_CHANNEL_DOMAIN_MAX] = { 82 /* 0x00 ~ 0x1F , Old Define ===== */ 83 {0x02}, /* 0x00, RT_CHANNEL_DOMAIN_FCC */ 84 {0x02}, /* 0x01, RT_CHANNEL_DOMAIN_IC */ 85 {0x01}, /* 0x02, RT_CHANNEL_DOMAIN_ETSI */ 86 {0x01}, /* 0x03, RT_CHANNEL_DOMAIN_SPAIN */ 87 {0x01}, /* 0x04, RT_CHANNEL_DOMAIN_FRANCE */ 88 {0x03}, /* 0x05, RT_CHANNEL_DOMAIN_MKK */ 89 {0x03}, /* 0x06, RT_CHANNEL_DOMAIN_MKK1 */ 90 {0x01}, /* 0x07, RT_CHANNEL_DOMAIN_ISRAEL */ 91 {0x03}, /* 0x08, RT_CHANNEL_DOMAIN_TELEC */ 92 {0x03}, /* 0x09, RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN */ 93 {0x00}, /* 0x0A, RT_CHANNEL_DOMAIN_WORLD_WIDE_13 */ 94 {0x02}, /* 0x0B, RT_CHANNEL_DOMAIN_TAIWAN */ 95 {0x01}, /* 0x0C, RT_CHANNEL_DOMAIN_CHINA */ 96 {0x02}, /* 0x0D, RT_CHANNEL_DOMAIN_SINGAPORE_INDIA_MEXICO */ 97 {0x02}, /* 0x0E, RT_CHANNEL_DOMAIN_KOREA */ 98 {0x02}, /* 0x0F, RT_CHANNEL_DOMAIN_TURKEY */ 99 {0x01}, /* 0x10, RT_CHANNEL_DOMAIN_JAPAN */ 100 {0x02}, /* 0x11, RT_CHANNEL_DOMAIN_FCC_NO_DFS */ 101 {0x01}, /* 0x12, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */ 102 {0x00}, /* 0x13, RT_CHANNEL_DOMAIN_WORLD_WIDE_5G */ 103 {0x02}, /* 0x14, RT_CHANNEL_DOMAIN_TAIWAN_NO_DFS */ 104 {0x00}, /* 0x15, RT_CHANNEL_DOMAIN_ETSI_NO_DFS */ 105 {0x00}, /* 0x16, RT_CHANNEL_DOMAIN_KOREA_NO_DFS */ 106 {0x03}, /* 0x17, RT_CHANNEL_DOMAIN_JAPAN_NO_DFS */ 107 {0x06}, /* 0x18, RT_CHANNEL_DOMAIN_PAKISTAN_NO_DFS */ 108 {0x02}, /* 0x19, RT_CHANNEL_DOMAIN_TAIWAN2_NO_DFS */ 109 {0x00}, /* 0x1A, */ 110 {0x00}, /* 0x1B, */ 111 {0x00}, /* 0x1C, */ 112 {0x00}, /* 0x1D, */ 113 {0x00}, /* 0x1E, */ 114 {0x06}, /* 0x1F, RT_CHANNEL_DOMAIN_WORLD_WIDE_ONLY_5G */ 115 /* 0x20 ~ 0x7F , New Define ===== */ 116 {0x00}, /* 0x20, RT_CHANNEL_DOMAIN_WORLD_NULL */ 117 {0x01}, /* 0x21, RT_CHANNEL_DOMAIN_ETSI1_NULL */ 118 {0x02}, /* 0x22, RT_CHANNEL_DOMAIN_FCC1_NULL */ 119 {0x03}, /* 0x23, RT_CHANNEL_DOMAIN_MKK1_NULL */ 120 {0x04}, /* 0x24, RT_CHANNEL_DOMAIN_ETSI2_NULL */ 121 {0x02}, /* 0x25, RT_CHANNEL_DOMAIN_FCC1_FCC1 */ 122 {0x00}, /* 0x26, RT_CHANNEL_DOMAIN_WORLD_ETSI1 */ 123 {0x03}, /* 0x27, RT_CHANNEL_DOMAIN_MKK1_MKK1 */ 124 {0x00}, /* 0x28, RT_CHANNEL_DOMAIN_WORLD_KCC1 */ 125 {0x00}, /* 0x29, RT_CHANNEL_DOMAIN_WORLD_FCC2 */ 126 {0x00}, /* 0x2A, */ 127 {0x00}, /* 0x2B, */ 128 {0x00}, /* 0x2C, */ 129 {0x00}, /* 0x2D, */ 130 {0x00}, /* 0x2E, */ 131 {0x00}, /* 0x2F, */ 132 {0x00}, /* 0x30, RT_CHANNEL_DOMAIN_WORLD_FCC3 */ 133 {0x00}, /* 0x31, RT_CHANNEL_DOMAIN_WORLD_FCC4 */ 134 {0x00}, /* 0x32, RT_CHANNEL_DOMAIN_WORLD_FCC5 */ 135 {0x00}, /* 0x33, RT_CHANNEL_DOMAIN_WORLD_FCC6 */ 136 {0x02}, /* 0x34, RT_CHANNEL_DOMAIN_FCC1_FCC7 */ 137 {0x00}, /* 0x35, RT_CHANNEL_DOMAIN_WORLD_ETSI2 */ 138 {0x00}, /* 0x36, RT_CHANNEL_DOMAIN_WORLD_ETSI3 */ 139 {0x03}, /* 0x37, RT_CHANNEL_DOMAIN_MKK1_MKK2 */ 140 {0x03}, /* 0x38, RT_CHANNEL_DOMAIN_MKK1_MKK3 */ 141 {0x02}, /* 0x39, RT_CHANNEL_DOMAIN_FCC1_NCC1 */ 142 {0x00}, /* 0x3A, */ 143 {0x00}, /* 0x3B, */ 144 {0x00}, /* 0x3C, */ 145 {0x00}, /* 0x3D, */ 146 {0x00}, /* 0x3E, */ 147 {0x00}, /* 0x3F, */ 148 {0x02}, /* 0x40, RT_CHANNEL_DOMAIN_FCC1_NCC2 */ 149 {0x05}, /* 0x41, RT_CHANNEL_DOMAIN_GLOBAL_NULL */ 150 {0x01}, /* 0x42, RT_CHANNEL_DOMAIN_ETSI1_ETSI4 */ 151 {0x02}, /* 0x43, RT_CHANNEL_DOMAIN_FCC1_FCC2 */ 152 {0x02}, /* 0x44, RT_CHANNEL_DOMAIN_FCC1_NCC3 */ 153 {0x00}, /* 0x45, RT_CHANNEL_DOMAIN_WORLD_ETSI5 */ 154 {0x02}, /* 0x46, RT_CHANNEL_DOMAIN_FCC1_FCC8 */ 155 {0x00}, /* 0x47, RT_CHANNEL_DOMAIN_WORLD_ETSI6 */ 156 {0x00}, /* 0x48, RT_CHANNEL_DOMAIN_WORLD_ETSI7 */ 157 {0x00}, /* 0x49, RT_CHANNEL_DOMAIN_WORLD_ETSI8 */ 158 {0x00}, /* 0x50, RT_CHANNEL_DOMAIN_WORLD_ETSI9 */ 159 {0x00}, /* 0x51, RT_CHANNEL_DOMAIN_WORLD_ETSI10 */ 160 {0x00}, /* 0x52, RT_CHANNEL_DOMAIN_WORLD_ETSI11 */ 161 {0x02}, /* 0x53, RT_CHANNEL_DOMAIN_FCC1_NCC4 */ 162 {0x00}, /* 0x54, RT_CHANNEL_DOMAIN_WORLD_ETSI12 */ 163 {0x02}, /* 0x55, RT_CHANNEL_DOMAIN_FCC1_FCC9 */ 164 {0x00}, /* 0x56, RT_CHANNEL_DOMAIN_WORLD_ETSI13 */ 165 {0x02}, /* 0x57, RT_CHANNEL_DOMAIN_FCC1_FCC10 */ 166 }; 167 168 /* use the combination for max channel numbers */ 169 static struct rt_channel_plan_map RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE = {0x03}; 170 171 /* Search the @param ch in given @param ch_set 172 * @ch_set: the given channel set 173 * @ch: the given channel number 174 * 175 * return the index of channel_num in channel_set, -1 if not found 176 */ 177 int rtw_ch_set_search_ch(struct rt_channel_info *ch_set, const u32 ch) 178 { 179 int i; 180 181 for (i = 0; ch_set[i].ChannelNum != 0; i++) { 182 if (ch == ch_set[i].ChannelNum) 183 break; 184 } 185 186 if (i >= ch_set[i].ChannelNum) 187 return -1; 188 return i; 189 } 190 191 /**************************************************************************** 192 193 Following are the initialization functions for WiFi MLME 194 195 *****************************************************************************/ 196 197 int init_hw_mlme_ext(struct adapter *padapter) 198 { 199 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 200 201 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); 202 return _SUCCESS; 203 } 204 205 void init_mlme_default_rate_set(struct adapter *padapter) 206 { 207 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 208 209 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}; 210 unsigned char mixed_basicrate[NumRates] = {_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_, _6M_RATE_, _12M_RATE_, _24M_RATE_, 0xff,}; 211 unsigned char supported_mcs_set[16] = {0xff, 0xff, 0x00, 0x00, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; 212 213 memcpy(pmlmeext->datarate, mixed_datarate, NumRates); 214 memcpy(pmlmeext->basicrate, mixed_basicrate, NumRates); 215 216 memcpy(pmlmeext->default_supported_mcs_set, supported_mcs_set, sizeof(pmlmeext->default_supported_mcs_set)); 217 } 218 219 static void init_mlme_ext_priv_value(struct adapter *padapter) 220 { 221 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 222 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; 223 224 atomic_set(&pmlmeext->event_seq, 0); 225 pmlmeext->mgnt_seq = 0;/* reset to zero when disconnect at client mode */ 226 pmlmeext->sa_query_seq = 0; 227 pmlmeext->mgnt_80211w_IPN = 0; 228 pmlmeext->mgnt_80211w_IPN_rx = 0; 229 pmlmeext->cur_channel = padapter->registrypriv.channel; 230 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20; 231 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; 232 233 pmlmeext->retry = 0; 234 235 pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode; 236 237 init_mlme_default_rate_set(padapter); 238 239 pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB; 240 pmlmeext->sitesurvey_res.state = SCAN_DISABLE; 241 pmlmeext->sitesurvey_res.channel_idx = 0; 242 pmlmeext->sitesurvey_res.bss_cnt = 0; 243 pmlmeext->scan_abort = false; 244 245 pmlmeinfo->state = WIFI_FW_NULL_STATE; 246 pmlmeinfo->reauth_count = 0; 247 pmlmeinfo->reassoc_count = 0; 248 pmlmeinfo->link_count = 0; 249 pmlmeinfo->auth_seq = 0; 250 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open; 251 pmlmeinfo->key_index = 0; 252 pmlmeinfo->iv = 0; 253 254 pmlmeinfo->enc_algo = _NO_PRIVACY_; 255 pmlmeinfo->authModeToggle = 0; 256 257 memset(pmlmeinfo->chg_txt, 0, 128); 258 259 pmlmeinfo->slotTime = SHORT_SLOT_TIME; 260 pmlmeinfo->preamble_mode = PREAMBLE_AUTO; 261 262 pmlmeinfo->dialogToken = 0; 263 264 pmlmeext->action_public_rxseq = 0xffff; 265 pmlmeext->action_public_dialog_token = 0xff; 266 } 267 268 static int has_channel(struct rt_channel_info *channel_set, 269 u8 chanset_size, 270 u8 chan) 271 { 272 int i; 273 274 for (i = 0; i < chanset_size; i++) { 275 if (channel_set[i].ChannelNum == chan) { 276 return 1; 277 } 278 } 279 280 return 0; 281 } 282 283 static void init_channel_list(struct adapter *padapter, struct rt_channel_info *channel_set, 284 u8 chanset_size, 285 struct p2p_channels *channel_list) 286 { 287 288 static const struct p2p_oper_class_map op_class[] = { 289 { IEEE80211G, 81, 1, 13, 1, BW20 }, 290 { IEEE80211G, 82, 14, 14, 1, BW20 }, 291 { IEEE80211A, 115, 36, 48, 4, BW20 }, 292 { IEEE80211A, 116, 36, 44, 8, BW40PLUS }, 293 { IEEE80211A, 117, 40, 48, 8, BW40MINUS }, 294 { IEEE80211A, 124, 149, 161, 4, BW20 }, 295 { IEEE80211A, 125, 149, 169, 4, BW20 }, 296 { IEEE80211A, 126, 149, 157, 8, BW40PLUS }, 297 { IEEE80211A, 127, 153, 161, 8, BW40MINUS }, 298 { -1, 0, 0, 0, 0, BW20 } 299 }; 300 301 int cla, op; 302 303 cla = 0; 304 305 for (op = 0; op_class[op].op_class; op++) { 306 u8 ch; 307 const struct p2p_oper_class_map *o = &op_class[op]; 308 struct p2p_reg_class *reg = NULL; 309 310 for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) { 311 if (!has_channel(channel_set, chanset_size, ch)) 312 continue; 313 314 if ((0 == padapter->registrypriv.ht_enable) && (8 == o->inc)) 315 continue; 316 317 if ((0 < (padapter->registrypriv.bw_mode & 0xf0)) && 318 ((BW40MINUS == o->bw) || (BW40PLUS == o->bw))) 319 continue; 320 321 if (!reg) { 322 reg = &channel_list->reg_class[cla]; 323 cla++; 324 reg->reg_class = o->op_class; 325 reg->channels = 0; 326 } 327 reg->channel[reg->channels] = ch; 328 reg->channels++; 329 } 330 } 331 channel_list->reg_classes = cla; 332 333 } 334 335 static u8 init_channel_set(struct adapter *padapter, u8 ChannelPlan, struct rt_channel_info *channel_set) 336 { 337 u8 index, chanset_size = 0; 338 u8 b2_4GBand = false; 339 u8 Index2G = 0; 340 341 memset(channel_set, 0, sizeof(struct rt_channel_info)*MAX_CHANNEL_NUM); 342 343 if (ChannelPlan >= RT_CHANNEL_DOMAIN_MAX && ChannelPlan != RT_CHANNEL_DOMAIN_REALTEK_DEFINE) 344 return chanset_size; 345 346 if (IsSupported24G(padapter->registrypriv.wireless_mode)) { 347 b2_4GBand = true; 348 if (RT_CHANNEL_DOMAIN_REALTEK_DEFINE == ChannelPlan) 349 Index2G = RTW_CHANNEL_PLAN_MAP_REALTEK_DEFINE.Index2G; 350 else 351 Index2G = RTW_ChannelPlanMap[ChannelPlan].Index2G; 352 } 353 354 if (b2_4GBand) { 355 for (index = 0; index < RTW_ChannelPlan2G[Index2G].Len; index++) { 356 channel_set[chanset_size].ChannelNum = RTW_ChannelPlan2G[Index2G].Channel[index]; 357 358 if ((RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN == ChannelPlan) ||/* Channel 1~11 is active, and 12~14 is passive */ 359 (RT_CHANNEL_DOMAIN_GLOBAL_NULL == ChannelPlan)) { 360 if (channel_set[chanset_size].ChannelNum >= 1 && channel_set[chanset_size].ChannelNum <= 11) 361 channel_set[chanset_size].ScanType = SCAN_ACTIVE; 362 else if ((channel_set[chanset_size].ChannelNum >= 12 && channel_set[chanset_size].ChannelNum <= 14)) 363 channel_set[chanset_size].ScanType = SCAN_PASSIVE; 364 } else if (RT_CHANNEL_DOMAIN_WORLD_WIDE_13 == ChannelPlan || 365 RT_CHANNEL_DOMAIN_2G_WORLD == Index2G) { /* channel 12~13, passive scan */ 366 if (channel_set[chanset_size].ChannelNum <= 11) 367 channel_set[chanset_size].ScanType = SCAN_ACTIVE; 368 else 369 channel_set[chanset_size].ScanType = SCAN_PASSIVE; 370 } else 371 channel_set[chanset_size].ScanType = SCAN_ACTIVE; 372 373 chanset_size++; 374 } 375 } 376 377 return chanset_size; 378 } 379 380 void init_mlme_ext_priv(struct adapter *padapter) 381 { 382 struct registry_priv *pregistrypriv = &padapter->registrypriv; 383 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 384 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 385 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; 386 387 pmlmeext->padapter = padapter; 388 389 /* fill_fwpriv(padapter, &(pmlmeext->fwpriv)); */ 390 391 init_mlme_ext_priv_value(padapter); 392 pmlmeinfo->accept_addba_req = pregistrypriv->accept_addba_req; 393 394 init_mlme_ext_timer(padapter); 395 396 init_mlme_ap_info(padapter); 397 398 pmlmeext->max_chan_nums = init_channel_set(padapter, pmlmepriv->ChannelPlan, pmlmeext->channel_set); 399 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list); 400 pmlmeext->last_scan_time = 0; 401 pmlmeext->chan_scan_time = SURVEY_TO; 402 pmlmeext->mlmeext_init = true; 403 pmlmeext->active_keep_alive_check = true; 404 405 #ifdef DBG_FIXED_CHAN 406 pmlmeext->fixed_chan = 0xFF; 407 #endif 408 } 409 410 void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext) 411 { 412 struct adapter *padapter = pmlmeext->padapter; 413 414 if (!padapter) 415 return; 416 417 if (padapter->bDriverStopped) { 418 del_timer_sync(&pmlmeext->survey_timer); 419 del_timer_sync(&pmlmeext->link_timer); 420 /* del_timer_sync(&pmlmeext->ADDBA_timer); */ 421 } 422 } 423 424 static void _mgt_dispatcher(struct adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame) 425 { 426 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 427 u8 *pframe = precv_frame->u.hdr.rx_data; 428 429 if (ptable->func) { 430 /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */ 431 if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) && 432 memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) 433 return; 434 435 ptable->func(padapter, precv_frame); 436 } 437 } 438 439 void mgt_dispatcher(struct adapter *padapter, union recv_frame *precv_frame) 440 { 441 int index; 442 struct mlme_handler *ptable; 443 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 444 u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 445 u8 *pframe = precv_frame->u.hdr.rx_data; 446 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(pframe)); 447 struct dvobj_priv *psdpriv = padapter->dvobj; 448 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; 449 450 if (GetFrameType(pframe) != WIFI_MGT_TYPE) 451 return; 452 453 /* receive the frames that ra(a1) is my address or ra(a1) is bc address. */ 454 if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN) && 455 memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN)) { 456 return; 457 } 458 459 ptable = mlme_sta_tbl; 460 461 index = GetFrameSubType(pframe) >> 4; 462 463 if (index >= ARRAY_SIZE(mlme_sta_tbl)) 464 return; 465 466 ptable += index; 467 468 if (psta) { 469 if (GetRetry(pframe)) { 470 if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum) { 471 /* drop the duplicate management frame */ 472 pdbgpriv->dbg_rx_dup_mgt_frame_drop_count++; 473 return; 474 } 475 } 476 psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num; 477 } 478 479 switch (GetFrameSubType(pframe)) { 480 case WIFI_AUTH: 481 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) 482 ptable->func = &OnAuth; 483 else 484 ptable->func = &OnAuthClient; 485 fallthrough; 486 case WIFI_ASSOCREQ: 487 case WIFI_REASSOCREQ: 488 _mgt_dispatcher(padapter, ptable, precv_frame); 489 break; 490 case WIFI_PROBEREQ: 491 _mgt_dispatcher(padapter, ptable, precv_frame); 492 break; 493 case WIFI_BEACON: 494 _mgt_dispatcher(padapter, ptable, precv_frame); 495 break; 496 case WIFI_ACTION: 497 /* if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) */ 498 _mgt_dispatcher(padapter, ptable, precv_frame); 499 break; 500 default: 501 _mgt_dispatcher(padapter, ptable, precv_frame); 502 break; 503 } 504 } 505 506 /**************************************************************************** 507 508 Following are the callback functions for each subtype of the management frames 509 510 *****************************************************************************/ 511 512 unsigned int OnProbeReq(struct adapter *padapter, union recv_frame *precv_frame) 513 { 514 unsigned int ielen; 515 unsigned char *p; 516 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 517 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 518 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info; 519 struct wlan_bssid_ex *cur = &pmlmeinfo->network; 520 u8 *pframe = precv_frame->u.hdr.rx_data; 521 uint len = precv_frame->u.hdr.len; 522 u8 is_valid_p2p_probereq = false; 523 524 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) 525 return _SUCCESS; 526 527 if (check_fwstate(pmlmepriv, _FW_LINKED) == false && 528 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE) == false) { 529 return _SUCCESS; 530 } 531 532 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, WLAN_EID_SSID, (int *)&ielen, 533 len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_); 534 535 536 /* check (wildcard) SSID */ 537 if (p) { 538 if (is_valid_p2p_probereq) 539 goto _issue_probersp; 540 541 if ((ielen != 0 && false == !memcmp((void *)(p+2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength)) 542 || (ielen == 0 && pmlmeinfo->hidden_ssid_mode) 543 ) 544 return _SUCCESS; 545 546 _issue_probersp: 547 if ((check_fwstate(pmlmepriv, _FW_LINKED) && 548 pmlmepriv->cur_network.join_res) || 549 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) 550 issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq); 551 } 552 553 return _SUCCESS; 554 555 } 556 557 unsigned int OnProbeRsp(struct adapter *padapter, union recv_frame *precv_frame) 558 { 559 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 560 561 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { 562 report_survey_event(padapter, precv_frame); 563 return _SUCCESS; 564 } 565 566 return _SUCCESS; 567 568 } 569 570 unsigned int OnBeacon(struct adapter *padapter, union recv_frame *precv_frame) 571 { 572 int cam_idx; 573 struct sta_info *psta; 574 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 575 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 576 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 577 struct sta_priv *pstapriv = &padapter->stapriv; 578 u8 *pframe = precv_frame->u.hdr.rx_data; 579 uint len = precv_frame->u.hdr.len; 580 struct wlan_bssid_ex *pbss; 581 int ret = _SUCCESS; 582 u8 *p = NULL; 583 u32 ielen = 0; 584 585 p = rtw_get_ie(pframe + sizeof(struct ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_, WLAN_EID_EXT_SUPP_RATES, &ielen, precv_frame->u.hdr.len - sizeof(struct ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_); 586 if (p && ielen > 0) { 587 if ((*(p + 1 + ielen) == 0x2D) && (*(p + 2 + ielen) != 0x2D)) 588 /* Invalid value 0x2D is detected in Extended Supported Rates (ESR) IE. Try to fix the IE length to avoid failed Beacon parsing. */ 589 *(p + 1) = ielen - 1; 590 } 591 592 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { 593 report_survey_event(padapter, precv_frame); 594 return _SUCCESS; 595 } 596 597 if (!memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) { 598 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) { 599 /* we should update current network before auth, or some IE is wrong */ 600 pbss = rtw_malloc(sizeof(struct wlan_bssid_ex)); 601 if (pbss) { 602 if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) { 603 update_network(&(pmlmepriv->cur_network.network), pbss, padapter, true); 604 rtw_get_bcn_info(&(pmlmepriv->cur_network)); 605 } 606 kfree(pbss); 607 } 608 609 /* check the vendor of the assoc AP */ 610 pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe+sizeof(struct ieee80211_hdr_3addr), len-sizeof(struct ieee80211_hdr_3addr)); 611 612 /* update TSF Value */ 613 update_TSF(pmlmeext, pframe, len); 614 615 /* reset for adaptive_early_32k */ 616 pmlmeext->adaptive_tsf_done = false; 617 pmlmeext->DrvBcnEarly = 0xff; 618 pmlmeext->DrvBcnTimeOut = 0xff; 619 pmlmeext->bcn_cnt = 0; 620 memset(pmlmeext->bcn_delay_cnt, 0, sizeof(pmlmeext->bcn_delay_cnt)); 621 memset(pmlmeext->bcn_delay_ratio, 0, sizeof(pmlmeext->bcn_delay_ratio)); 622 623 /* start auth */ 624 start_clnt_auth(padapter); 625 626 return _SUCCESS; 627 } 628 629 if (((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) { 630 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); 631 if (psta) { 632 ret = rtw_check_bcn_info(padapter, pframe, len); 633 if (!ret) { 634 netdev_dbg(padapter->pnetdev, 635 "ap has changed, disconnect now\n "); 636 receive_disconnect(padapter, 637 pmlmeinfo->network.MacAddress, 0); 638 return _SUCCESS; 639 } 640 /* update WMM, ERP in the beacon */ 641 /* todo: the timer is used instead of the number of the beacon received */ 642 if ((sta_rx_pkts(psta) & 0xf) == 0) 643 update_beacon_info(padapter, pframe, len, psta); 644 645 adaptive_early_32k(pmlmeext, pframe, len); 646 } 647 } else if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) { 648 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); 649 if (psta) { 650 /* update WMM, ERP in the beacon */ 651 /* todo: the timer is used instead of the number of the beacon received */ 652 if ((sta_rx_pkts(psta) & 0xf) == 0) { 653 update_beacon_info(padapter, pframe, len, psta); 654 } 655 } else { 656 /* allocate a new CAM entry for IBSS station */ 657 cam_idx = allocate_fw_sta_entry(padapter); 658 if (cam_idx == NUM_STA) 659 goto _END_ONBEACON_; 660 661 /* get supported rate */ 662 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) { 663 pmlmeinfo->FW_sta_info[cam_idx].status = 0; 664 goto _END_ONBEACON_; 665 } 666 667 /* update TSF Value */ 668 update_TSF(pmlmeext, pframe, len); 669 670 /* report sta add event */ 671 report_add_sta_event(padapter, GetAddr2Ptr(pframe), cam_idx); 672 } 673 } 674 } 675 676 _END_ONBEACON_: 677 678 return _SUCCESS; 679 680 } 681 682 unsigned int OnAuth(struct adapter *padapter, union recv_frame *precv_frame) 683 { 684 unsigned int auth_mode, seq, ie_len; 685 unsigned char *sa, *p; 686 u16 algorithm; 687 int status; 688 static struct sta_info stat; 689 struct sta_info *pstat = NULL; 690 struct sta_priv *pstapriv = &padapter->stapriv; 691 struct security_priv *psecuritypriv = &padapter->securitypriv; 692 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 693 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 694 u8 *pframe = precv_frame->u.hdr.rx_data; 695 uint len = precv_frame->u.hdr.len; 696 u8 offset = 0; 697 698 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) 699 return _FAIL; 700 701 sa = GetAddr2Ptr(pframe); 702 703 auth_mode = psecuritypriv->dot11AuthAlgrthm; 704 705 if (GetPrivacy(pframe)) { 706 u8 *iv; 707 struct rx_pkt_attrib *prxattrib = &(precv_frame->u.hdr.attrib); 708 709 prxattrib->hdrlen = WLAN_HDR_A3_LEN; 710 prxattrib->encrypt = _WEP40_; 711 712 iv = pframe+prxattrib->hdrlen; 713 prxattrib->key_index = ((iv[3]>>6)&0x3); 714 715 prxattrib->iv_len = 4; 716 prxattrib->icv_len = 4; 717 718 rtw_wep_decrypt(padapter, (u8 *)precv_frame); 719 720 offset = 4; 721 } 722 723 algorithm = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset)); 724 seq = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2)); 725 726 if (auth_mode == 2 && 727 psecuritypriv->dot11PrivacyAlgrthm != _WEP40_ && 728 psecuritypriv->dot11PrivacyAlgrthm != _WEP104_) 729 auth_mode = 0; 730 731 if ((algorithm > 0 && auth_mode == 0) || /* rx a shared-key auth but shared not enabled */ 732 (algorithm == 0 && auth_mode == 1)) { /* rx a open-system auth but shared-key is enabled */ 733 734 status = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG; 735 736 goto auth_fail; 737 } 738 739 if (rtw_access_ctrl(padapter, sa) == false) { 740 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; 741 goto auth_fail; 742 } 743 744 pstat = rtw_get_stainfo(pstapriv, sa); 745 if (pstat == NULL) { 746 747 /* allocate a new one */ 748 pstat = rtw_alloc_stainfo(pstapriv, sa); 749 if (pstat == NULL) { 750 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; 751 goto auth_fail; 752 } 753 754 pstat->state = WIFI_FW_AUTH_NULL; 755 pstat->auth_seq = 0; 756 757 /* pstat->flags = 0; */ 758 /* pstat->capability = 0; */ 759 } else { 760 761 spin_lock_bh(&pstapriv->asoc_list_lock); 762 if (list_empty(&pstat->asoc_list) == false) { 763 list_del_init(&pstat->asoc_list); 764 pstapriv->asoc_list_cnt--; 765 if (pstat->expire_to > 0) { 766 /* TODO: STA re_auth within expire_to */ 767 } 768 } 769 spin_unlock_bh(&pstapriv->asoc_list_lock); 770 771 if (seq == 1) { 772 /* TODO: STA re_auth and auth timeout */ 773 } 774 } 775 776 spin_lock_bh(&pstapriv->auth_list_lock); 777 if (list_empty(&pstat->auth_list)) { 778 779 list_add_tail(&pstat->auth_list, &pstapriv->auth_list); 780 pstapriv->auth_list_cnt++; 781 } 782 spin_unlock_bh(&pstapriv->auth_list_lock); 783 784 if (pstat->auth_seq == 0) 785 pstat->expire_to = pstapriv->auth_to; 786 787 788 if ((pstat->auth_seq + 1) != seq) { 789 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION; 790 goto auth_fail; 791 } 792 793 if (algorithm == 0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3)) { 794 if (seq == 1) { 795 pstat->state &= ~WIFI_FW_AUTH_NULL; 796 pstat->state |= WIFI_FW_AUTH_SUCCESS; 797 pstat->expire_to = pstapriv->assoc_to; 798 pstat->authalg = algorithm; 799 } else { 800 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION; 801 goto auth_fail; 802 } 803 } else { /* shared system or auto authentication */ 804 if (seq == 1) { 805 /* prepare for the challenging txt... */ 806 memset((void *)pstat->chg_txt, 78, 128); 807 808 pstat->state &= ~WIFI_FW_AUTH_NULL; 809 pstat->state |= WIFI_FW_AUTH_STATE; 810 pstat->authalg = algorithm; 811 pstat->auth_seq = 2; 812 } else if (seq == 3) { 813 814 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_, WLAN_EID_CHALLENGE, (int *)&ie_len, 815 len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4); 816 817 if ((p == NULL) || (ie_len <= 0)) { 818 status = WLAN_STATUS_CHALLENGE_FAIL; 819 goto auth_fail; 820 } 821 822 if (!memcmp((void *)(p + 2), pstat->chg_txt, 128)) { 823 pstat->state &= (~WIFI_FW_AUTH_STATE); 824 pstat->state |= WIFI_FW_AUTH_SUCCESS; 825 /* challenging txt is correct... */ 826 pstat->expire_to = pstapriv->assoc_to; 827 } else { 828 status = WLAN_STATUS_CHALLENGE_FAIL; 829 goto auth_fail; 830 } 831 } else { 832 status = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION; 833 goto auth_fail; 834 } 835 } 836 837 838 /* Now, we are going to issue_auth... */ 839 pstat->auth_seq = seq + 1; 840 841 issue_auth(padapter, pstat, (unsigned short)(WLAN_STATUS_SUCCESS)); 842 843 if (pstat->state & WIFI_FW_AUTH_SUCCESS) 844 pstat->auth_seq = 0; 845 846 847 return _SUCCESS; 848 849 auth_fail: 850 851 if (pstat) 852 rtw_free_stainfo(padapter, pstat); 853 854 pstat = &stat; 855 memset((char *)pstat, '\0', sizeof(stat)); 856 pstat->auth_seq = 2; 857 memcpy(pstat->hwaddr, sa, 6); 858 859 issue_auth(padapter, pstat, (unsigned short)status); 860 861 return _FAIL; 862 863 } 864 865 unsigned int OnAuthClient(struct adapter *padapter, union recv_frame *precv_frame) 866 { 867 unsigned int seq, len, status, offset; 868 unsigned char *p; 869 unsigned int go2asoc = 0; 870 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 871 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 872 u8 *pframe = precv_frame->u.hdr.rx_data; 873 uint pkt_len = precv_frame->u.hdr.len; 874 875 /* check A1 matches or not */ 876 if (memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN)) 877 return _SUCCESS; 878 879 if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE)) 880 return _SUCCESS; 881 882 offset = (GetPrivacy(pframe)) ? 4 : 0; 883 884 seq = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2)); 885 status = le16_to_cpu(*(__le16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4)); 886 887 if (status != 0) { 888 if (status == 13) { /* pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */ 889 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) 890 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open; 891 else 892 pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; 893 /* pmlmeinfo->reauth_count = 0; */ 894 } 895 896 set_link_timer(pmlmeext, 1); 897 goto authclnt_fail; 898 } 899 900 if (seq == 2) { 901 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) { 902 /* legendary shared system */ 903 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, WLAN_EID_CHALLENGE, (int *)&len, 904 pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_); 905 906 if (!p) 907 goto authclnt_fail; 908 909 memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len); 910 pmlmeinfo->auth_seq = 3; 911 issue_auth(padapter, NULL, 0); 912 set_link_timer(pmlmeext, REAUTH_TO); 913 914 return _SUCCESS; 915 } else { 916 /* open system */ 917 go2asoc = 1; 918 } 919 } else if (seq == 4) { 920 if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) { 921 go2asoc = 1; 922 } else { 923 goto authclnt_fail; 924 } 925 } else { 926 /* this is also illegal */ 927 goto authclnt_fail; 928 } 929 930 if (go2asoc) { 931 netdev_dbg(padapter->pnetdev, "auth success, start assoc\n"); 932 start_clnt_assoc(padapter); 933 return _SUCCESS; 934 } 935 936 authclnt_fail: 937 938 /* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */ 939 940 return _FAIL; 941 942 } 943 944 unsigned int OnAssocReq(struct adapter *padapter, union recv_frame *precv_frame) 945 { 946 u16 capab_info; 947 struct rtw_ieee802_11_elems elems; 948 struct sta_info *pstat; 949 unsigned char *p, *pos, *wpa_ie; 950 unsigned char WMM_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01}; 951 int i, ie_len, wpa_ie_len, left; 952 unsigned char supportRate[16]; 953 int supportRateNum; 954 unsigned short status = WLAN_STATUS_SUCCESS; 955 unsigned short frame_type, ie_offset = 0; 956 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 957 struct security_priv *psecuritypriv = &padapter->securitypriv; 958 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 959 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 960 struct wlan_bssid_ex *cur = &(pmlmeinfo->network); 961 struct sta_priv *pstapriv = &padapter->stapriv; 962 u8 *pframe = precv_frame->u.hdr.rx_data; 963 uint pkt_len = precv_frame->u.hdr.len; 964 965 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) 966 return _FAIL; 967 968 frame_type = GetFrameSubType(pframe); 969 if (frame_type == WIFI_ASSOCREQ) 970 ie_offset = _ASOCREQ_IE_OFFSET_; 971 else /* WIFI_REASSOCREQ */ 972 ie_offset = _REASOCREQ_IE_OFFSET_; 973 974 975 if (pkt_len < sizeof(struct ieee80211_hdr_3addr) + ie_offset) 976 return _FAIL; 977 978 pstat = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); 979 if (!pstat) { 980 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA; 981 goto asoc_class2_error; 982 } 983 984 capab_info = get_unaligned_le16(pframe + WLAN_HDR_A3_LEN); 985 /* capab_info = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN)); */ 986 987 left = pkt_len - (sizeof(struct ieee80211_hdr_3addr) + ie_offset); 988 pos = pframe + (sizeof(struct ieee80211_hdr_3addr) + ie_offset); 989 990 /* check if this stat has been successfully authenticated/assocated */ 991 if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) { 992 if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) { 993 status = WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA; 994 goto asoc_class2_error; 995 } else { 996 pstat->state &= (~WIFI_FW_ASSOC_SUCCESS); 997 pstat->state |= WIFI_FW_ASSOC_STATE; 998 } 999 } else { 1000 pstat->state &= (~WIFI_FW_AUTH_SUCCESS); 1001 pstat->state |= WIFI_FW_ASSOC_STATE; 1002 } 1003 1004 1005 pstat->capability = capab_info; 1006 1007 /* now parse all ieee802_11 ie to point to elems */ 1008 if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed || 1009 !elems.ssid) { 1010 status = WLAN_STATUS_CHALLENGE_FAIL; 1011 goto OnAssocReqFail; 1012 } 1013 1014 /* now we should check all the fields... */ 1015 /* checking SSID */ 1016 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, WLAN_EID_SSID, &ie_len, 1017 pkt_len - WLAN_HDR_A3_LEN - ie_offset); 1018 1019 if (!p || ie_len == 0) { 1020 /* broadcast ssid, however it is not allowed in assocreq */ 1021 status = WLAN_STATUS_CHALLENGE_FAIL; 1022 goto OnAssocReqFail; 1023 } else { 1024 /* check if ssid match */ 1025 if (memcmp((void *)(p+2), cur->Ssid.Ssid, cur->Ssid.SsidLength)) 1026 status = WLAN_STATUS_CHALLENGE_FAIL; 1027 1028 if (ie_len != cur->Ssid.SsidLength) 1029 status = WLAN_STATUS_CHALLENGE_FAIL; 1030 } 1031 1032 if (status != WLAN_STATUS_SUCCESS) 1033 goto OnAssocReqFail; 1034 1035 /* check if the supported rate is ok */ 1036 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, WLAN_EID_SUPP_RATES, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset); 1037 if (p == NULL) { 1038 /* use our own rate set as statoin used */ 1039 /* memcpy(supportRate, AP_BSSRATE, AP_BSSRATE_LEN); */ 1040 /* supportRateNum = AP_BSSRATE_LEN; */ 1041 1042 status = WLAN_STATUS_CHALLENGE_FAIL; 1043 goto OnAssocReqFail; 1044 } else { 1045 memcpy(supportRate, p+2, ie_len); 1046 supportRateNum = ie_len; 1047 1048 p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + ie_offset, WLAN_EID_EXT_SUPP_RATES, &ie_len, 1049 pkt_len - WLAN_HDR_A3_LEN - ie_offset); 1050 if (p != NULL) { 1051 1052 if (supportRateNum <= sizeof(supportRate)) { 1053 memcpy(supportRate+supportRateNum, p+2, ie_len); 1054 supportRateNum += ie_len; 1055 } 1056 } 1057 } 1058 1059 /* todo: mask supportRate between AP & STA -> move to update raid */ 1060 /* get_matched_rate(pmlmeext, supportRate, &supportRateNum, 0); */ 1061 1062 /* update station supportRate */ 1063 pstat->bssratelen = supportRateNum; 1064 memcpy(pstat->bssrateset, supportRate, supportRateNum); 1065 UpdateBrateTblForSoftAP(pstat->bssrateset, pstat->bssratelen); 1066 1067 /* check RSN/WPA/WPS */ 1068 pstat->dot8021xalg = 0; 1069 pstat->wpa_psk = 0; 1070 pstat->wpa_group_cipher = 0; 1071 pstat->wpa2_group_cipher = 0; 1072 pstat->wpa_pairwise_cipher = 0; 1073 pstat->wpa2_pairwise_cipher = 0; 1074 memset(pstat->wpa_ie, 0, sizeof(pstat->wpa_ie)); 1075 if ((psecuritypriv->wpa_psk & BIT(1)) && elems.rsn_ie) { 1076 1077 int group_cipher = 0, pairwise_cipher = 0; 1078 1079 wpa_ie = elems.rsn_ie; 1080 wpa_ie_len = elems.rsn_ie_len; 1081 1082 if (rtw_parse_wpa2_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { 1083 pstat->dot8021xalg = 1;/* psk, todo:802.1x */ 1084 pstat->wpa_psk |= BIT(1); 1085 1086 pstat->wpa2_group_cipher = group_cipher&psecuritypriv->wpa2_group_cipher; 1087 pstat->wpa2_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa2_pairwise_cipher; 1088 1089 if (!pstat->wpa2_group_cipher) 1090 status = WLAN_STATUS_INVALID_GROUP_CIPHER; 1091 1092 if (!pstat->wpa2_pairwise_cipher) 1093 status = WLAN_STATUS_INVALID_PAIRWISE_CIPHER; 1094 } else { 1095 status = WLAN_STATUS_INVALID_IE; 1096 } 1097 1098 } else if ((psecuritypriv->wpa_psk & BIT(0)) && elems.wpa_ie) { 1099 1100 int group_cipher = 0, pairwise_cipher = 0; 1101 1102 wpa_ie = elems.wpa_ie; 1103 wpa_ie_len = elems.wpa_ie_len; 1104 1105 if (rtw_parse_wpa_ie(wpa_ie-2, wpa_ie_len+2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) { 1106 pstat->dot8021xalg = 1;/* psk, todo:802.1x */ 1107 pstat->wpa_psk |= BIT(0); 1108 1109 pstat->wpa_group_cipher = group_cipher&psecuritypriv->wpa_group_cipher; 1110 pstat->wpa_pairwise_cipher = pairwise_cipher&psecuritypriv->wpa_pairwise_cipher; 1111 1112 if (!pstat->wpa_group_cipher) 1113 status = WLAN_STATUS_INVALID_GROUP_CIPHER; 1114 1115 if (!pstat->wpa_pairwise_cipher) 1116 status = WLAN_STATUS_INVALID_PAIRWISE_CIPHER; 1117 1118 } else { 1119 status = WLAN_STATUS_INVALID_IE; 1120 } 1121 1122 } else { 1123 wpa_ie = NULL; 1124 wpa_ie_len = 0; 1125 } 1126 1127 if (status != WLAN_STATUS_SUCCESS) 1128 goto OnAssocReqFail; 1129 1130 pstat->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS); 1131 if (!wpa_ie) { 1132 if (elems.wps_ie) { 1133 pstat->flags |= WLAN_STA_WPS; 1134 /* wpabuf_free(sta->wps_ie); */ 1135 /* sta->wps_ie = wpabuf_alloc_copy(elems.wps_ie + 4, */ 1136 /* elems.wps_ie_len - 4); */ 1137 } else { 1138 pstat->flags |= WLAN_STA_MAYBE_WPS; 1139 } 1140 1141 1142 /* AP support WPA/RSN, and sta is going to do WPS, but AP is not ready */ 1143 /* that the selected registrar of AP is _FLASE */ 1144 if ((psecuritypriv->wpa_psk > 0) 1145 && (pstat->flags & (WLAN_STA_WPS|WLAN_STA_MAYBE_WPS))) { 1146 if (pmlmepriv->wps_beacon_ie) { 1147 u8 selected_registrar = 0; 1148 1149 rtw_get_wps_attr_content(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len, WPS_ATTR_SELECTED_REGISTRAR, &selected_registrar, NULL); 1150 1151 if (!selected_registrar) { 1152 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; 1153 1154 goto OnAssocReqFail; 1155 } 1156 } 1157 } 1158 1159 } else { 1160 int copy_len; 1161 1162 if (psecuritypriv->wpa_psk == 0) { 1163 status = WLAN_STATUS_INVALID_IE; 1164 1165 goto OnAssocReqFail; 1166 1167 } 1168 1169 if (elems.wps_ie) { 1170 pstat->flags |= WLAN_STA_WPS; 1171 copy_len = 0; 1172 } else { 1173 copy_len = ((wpa_ie_len+2) > sizeof(pstat->wpa_ie)) ? (sizeof(pstat->wpa_ie)):(wpa_ie_len+2); 1174 } 1175 1176 1177 if (copy_len > 0) 1178 memcpy(pstat->wpa_ie, wpa_ie-2, copy_len); 1179 1180 } 1181 1182 1183 /* check if there is WMM IE & support WWM-PS */ 1184 pstat->flags &= ~WLAN_STA_WME; 1185 pstat->qos_option = 0; 1186 pstat->qos_info = 0; 1187 pstat->has_legacy_ac = true; 1188 pstat->uapsd_vo = 0; 1189 pstat->uapsd_vi = 0; 1190 pstat->uapsd_be = 0; 1191 pstat->uapsd_bk = 0; 1192 if (pmlmepriv->qospriv.qos_option) { 1193 p = pframe + WLAN_HDR_A3_LEN + ie_offset; ie_len = 0; 1194 for (;;) { 1195 p = rtw_get_ie(p, WLAN_EID_VENDOR_SPECIFIC, &ie_len, pkt_len - WLAN_HDR_A3_LEN - ie_offset); 1196 if (p) { 1197 if (!memcmp(p+2, WMM_IE, 6)) { 1198 1199 pstat->flags |= WLAN_STA_WME; 1200 1201 pstat->qos_option = 1; 1202 pstat->qos_info = *(p+8); 1203 1204 pstat->max_sp_len = (pstat->qos_info>>5)&0x3; 1205 1206 if ((pstat->qos_info&0xf) != 0xf) 1207 pstat->has_legacy_ac = true; 1208 else 1209 pstat->has_legacy_ac = false; 1210 1211 if (pstat->qos_info&0xf) { 1212 if (pstat->qos_info&BIT(0)) 1213 pstat->uapsd_vo = BIT(0)|BIT(1); 1214 else 1215 pstat->uapsd_vo = 0; 1216 1217 if (pstat->qos_info&BIT(1)) 1218 pstat->uapsd_vi = BIT(0)|BIT(1); 1219 else 1220 pstat->uapsd_vi = 0; 1221 1222 if (pstat->qos_info&BIT(2)) 1223 pstat->uapsd_bk = BIT(0)|BIT(1); 1224 else 1225 pstat->uapsd_bk = 0; 1226 1227 if (pstat->qos_info&BIT(3)) 1228 pstat->uapsd_be = BIT(0)|BIT(1); 1229 else 1230 pstat->uapsd_be = 0; 1231 1232 } 1233 1234 break; 1235 } 1236 } else { 1237 break; 1238 } 1239 p = p + ie_len + 2; 1240 } 1241 } 1242 1243 /* save HT capabilities in the sta object */ 1244 memset(&pstat->htpriv.ht_cap, 0, sizeof(struct ieee80211_ht_cap)); 1245 if (elems.ht_capabilities && elems.ht_capabilities_len >= sizeof(struct ieee80211_ht_cap)) { 1246 pstat->flags |= WLAN_STA_HT; 1247 1248 pstat->flags |= WLAN_STA_WME; 1249 1250 memcpy(&pstat->htpriv.ht_cap, elems.ht_capabilities, sizeof(struct ieee80211_ht_cap)); 1251 1252 } else 1253 pstat->flags &= ~WLAN_STA_HT; 1254 1255 1256 if ((pmlmepriv->htpriv.ht_option == false) && (pstat->flags&WLAN_STA_HT)) { 1257 status = WLAN_STATUS_CHALLENGE_FAIL; 1258 goto OnAssocReqFail; 1259 } 1260 1261 1262 if ((pstat->flags & WLAN_STA_HT) && 1263 ((pstat->wpa2_pairwise_cipher&WPA_CIPHER_TKIP) || 1264 (pstat->wpa_pairwise_cipher&WPA_CIPHER_TKIP))) { 1265 /* status = WLAN_STATUS_CIPHER_SUITE_REJECTED; */ 1266 /* goto OnAssocReqFail; */ 1267 } 1268 pstat->flags |= WLAN_STA_NONERP; 1269 for (i = 0; i < pstat->bssratelen; i++) { 1270 if ((pstat->bssrateset[i] & 0x7f) > 22) { 1271 pstat->flags &= ~WLAN_STA_NONERP; 1272 break; 1273 } 1274 } 1275 1276 if (pstat->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 1277 pstat->flags |= WLAN_STA_SHORT_PREAMBLE; 1278 else 1279 pstat->flags &= ~WLAN_STA_SHORT_PREAMBLE; 1280 1281 1282 1283 if (status != WLAN_STATUS_SUCCESS) 1284 goto OnAssocReqFail; 1285 1286 /* TODO: identify_proprietary_vendor_ie(); */ 1287 /* Realtek proprietary IE */ 1288 /* identify if this is Broadcom sta */ 1289 /* identify if this is ralink sta */ 1290 /* Customer proprietary IE */ 1291 1292 1293 1294 /* get a unique AID */ 1295 if (pstat->aid == 0) { 1296 for (pstat->aid = 1; pstat->aid <= NUM_STA; pstat->aid++) 1297 if (pstapriv->sta_aid[pstat->aid - 1] == NULL) 1298 break; 1299 1300 /* if (pstat->aid > NUM_STA) { */ 1301 if (pstat->aid > pstapriv->max_num_sta) { 1302 1303 pstat->aid = 0; 1304 1305 status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; 1306 1307 goto OnAssocReqFail; 1308 1309 1310 } else { 1311 pstapriv->sta_aid[pstat->aid - 1] = pstat; 1312 } 1313 } 1314 1315 1316 pstat->state &= (~WIFI_FW_ASSOC_STATE); 1317 pstat->state |= WIFI_FW_ASSOC_SUCCESS; 1318 1319 spin_lock_bh(&pstapriv->auth_list_lock); 1320 if (!list_empty(&pstat->auth_list)) { 1321 list_del_init(&pstat->auth_list); 1322 pstapriv->auth_list_cnt--; 1323 } 1324 spin_unlock_bh(&pstapriv->auth_list_lock); 1325 1326 spin_lock_bh(&pstapriv->asoc_list_lock); 1327 if (list_empty(&pstat->asoc_list)) { 1328 pstat->expire_to = pstapriv->expire_to; 1329 list_add_tail(&pstat->asoc_list, &pstapriv->asoc_list); 1330 pstapriv->asoc_list_cnt++; 1331 } 1332 spin_unlock_bh(&pstapriv->asoc_list_lock); 1333 1334 /* now the station is qualified to join our BSS... */ 1335 if (pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (WLAN_STATUS_SUCCESS == status)) { 1336 /* 1 bss_cap_update & sta_info_update */ 1337 bss_cap_update_on_sta_join(padapter, pstat); 1338 sta_info_update(padapter, pstat); 1339 1340 /* 2 issue assoc rsp before notify station join event. */ 1341 if (frame_type == WIFI_ASSOCREQ) 1342 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP); 1343 else 1344 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP); 1345 1346 spin_lock_bh(&pstat->lock); 1347 if (pstat->passoc_req) { 1348 kfree(pstat->passoc_req); 1349 pstat->passoc_req = NULL; 1350 pstat->assoc_req_len = 0; 1351 } 1352 1353 pstat->passoc_req = rtw_zmalloc(pkt_len); 1354 if (pstat->passoc_req) { 1355 memcpy(pstat->passoc_req, pframe, pkt_len); 1356 pstat->assoc_req_len = pkt_len; 1357 } 1358 spin_unlock_bh(&pstat->lock); 1359 1360 /* 3-(1) report sta add event */ 1361 report_add_sta_event(padapter, pstat->hwaddr, pstat->aid); 1362 } 1363 1364 return _SUCCESS; 1365 1366 asoc_class2_error: 1367 1368 issue_deauth(padapter, (void *)GetAddr2Ptr(pframe), status); 1369 1370 return _FAIL; 1371 1372 OnAssocReqFail: 1373 1374 pstat->aid = 0; 1375 if (frame_type == WIFI_ASSOCREQ) 1376 issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP); 1377 else 1378 issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP); 1379 1380 return _FAIL; 1381 } 1382 1383 unsigned int OnAssocRsp(struct adapter *padapter, union recv_frame *precv_frame) 1384 { 1385 uint i; 1386 int res; 1387 unsigned short status; 1388 struct ndis_80211_var_ie *pIE; 1389 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1390 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 1391 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 1392 /* struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); */ 1393 u8 *pframe = precv_frame->u.hdr.rx_data; 1394 uint pkt_len = precv_frame->u.hdr.len; 1395 1396 /* check A1 matches or not */ 1397 if (memcmp(myid(&(padapter->eeprompriv)), get_da(pframe), ETH_ALEN)) 1398 return _SUCCESS; 1399 1400 if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE))) 1401 return _SUCCESS; 1402 1403 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) 1404 return _SUCCESS; 1405 1406 del_timer_sync(&pmlmeext->link_timer); 1407 1408 /* status */ 1409 status = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 2)); 1410 if (status > 0) { 1411 pmlmeinfo->state = WIFI_FW_NULL_STATE; 1412 res = -4; 1413 goto report_assoc_result; 1414 } 1415 1416 /* get capabilities */ 1417 pmlmeinfo->capability = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN)); 1418 1419 /* set slot time */ 1420 pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10)) ? 9 : 20; 1421 1422 /* AID */ 1423 res = pmlmeinfo->aid = (int)(le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN + 4))&0x3fff); 1424 1425 /* following are moved to join event callback function */ 1426 /* to handle HT, WMM, rate adaptive, update MAC reg */ 1427 /* for not to handle the synchronous IO in the tasklet */ 1428 for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;) { 1429 pIE = (struct ndis_80211_var_ie *)(pframe + i); 1430 1431 switch (pIE->ElementID) { 1432 case WLAN_EID_VENDOR_SPECIFIC: 1433 if (!memcmp(pIE->data, WMM_PARA_OUI, 6)) /* WMM */ 1434 WMM_param_handler(padapter, pIE); 1435 break; 1436 1437 case WLAN_EID_HT_CAPABILITY: /* HT caps */ 1438 HT_caps_handler(padapter, pIE); 1439 break; 1440 1441 case WLAN_EID_HT_OPERATION: /* HT info */ 1442 HT_info_handler(padapter, pIE); 1443 break; 1444 1445 case WLAN_EID_ERP_INFO: 1446 ERP_IE_handler(padapter, pIE); 1447 break; 1448 1449 default: 1450 break; 1451 } 1452 1453 i += (pIE->Length + 2); 1454 } 1455 1456 pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE); 1457 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; 1458 1459 /* Update Basic Rate Table for spec, 2010-12-28 , by thomas */ 1460 UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates); 1461 1462 report_assoc_result: 1463 if (res > 0) { 1464 rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len); 1465 } else { 1466 rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len); 1467 } 1468 1469 report_join_res(padapter, res); 1470 1471 return _SUCCESS; 1472 } 1473 1474 unsigned int OnDeAuth(struct adapter *padapter, union recv_frame *precv_frame) 1475 { 1476 unsigned short reason; 1477 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1478 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 1479 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 1480 u8 *pframe = precv_frame->u.hdr.rx_data; 1481 1482 /* check A3 */ 1483 if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) 1484 return _SUCCESS; 1485 1486 reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN)); 1487 1488 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 1489 struct sta_info *psta; 1490 struct sta_priv *pstapriv = &padapter->stapriv; 1491 1492 /* spin_lock_bh(&(pstapriv->sta_hash_lock)); */ 1493 /* rtw_free_stainfo(padapter, psta); */ 1494 /* spin_unlock_bh(&(pstapriv->sta_hash_lock)); */ 1495 1496 netdev_dbg(padapter->pnetdev, 1497 "ap recv deauth reason code(%d) sta:%pM\n", reason, 1498 GetAddr2Ptr(pframe)); 1499 1500 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); 1501 if (psta) { 1502 u8 updated = false; 1503 1504 spin_lock_bh(&pstapriv->asoc_list_lock); 1505 if (list_empty(&psta->asoc_list) == false) { 1506 list_del_init(&psta->asoc_list); 1507 pstapriv->asoc_list_cnt--; 1508 updated = ap_free_sta(padapter, psta, false, reason); 1509 1510 } 1511 spin_unlock_bh(&pstapriv->asoc_list_lock); 1512 1513 associated_clients_update(padapter, updated); 1514 } 1515 1516 1517 return _SUCCESS; 1518 } else { 1519 int ignore_received_deauth = 0; 1520 1521 /* Commented by Albert 20130604 */ 1522 /* Before sending the auth frame to start the STA/GC mode connection with AP/GO, */ 1523 /* we will send the deauth first. */ 1524 /* However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth. */ 1525 /* Added the following code to avoid this case. */ 1526 if ((pmlmeinfo->state & WIFI_FW_AUTH_STATE) || 1527 (pmlmeinfo->state & WIFI_FW_ASSOC_STATE)) { 1528 if (reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA) { 1529 ignore_received_deauth = 1; 1530 } else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) { 1531 /* TODO: 802.11r */ 1532 ignore_received_deauth = 1; 1533 } 1534 } 1535 1536 netdev_dbg(padapter->pnetdev, 1537 "sta recv deauth reason code(%d) sta:%pM, ignore = %d\n", 1538 reason, GetAddr3Ptr(pframe), 1539 ignore_received_deauth); 1540 1541 if (0 == ignore_received_deauth) { 1542 receive_disconnect(padapter, GetAddr3Ptr(pframe), reason); 1543 } 1544 } 1545 pmlmepriv->LinkDetectInfo.bBusyTraffic = false; 1546 return _SUCCESS; 1547 1548 } 1549 1550 unsigned int OnDisassoc(struct adapter *padapter, union recv_frame *precv_frame) 1551 { 1552 unsigned short reason; 1553 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1554 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 1555 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 1556 u8 *pframe = precv_frame->u.hdr.rx_data; 1557 1558 /* check A3 */ 1559 if (memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) 1560 return _SUCCESS; 1561 1562 reason = le16_to_cpu(*(__le16 *)(pframe + WLAN_HDR_A3_LEN)); 1563 1564 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 1565 struct sta_info *psta; 1566 struct sta_priv *pstapriv = &padapter->stapriv; 1567 1568 /* spin_lock_bh(&(pstapriv->sta_hash_lock)); */ 1569 /* rtw_free_stainfo(padapter, psta); */ 1570 /* spin_unlock_bh(&(pstapriv->sta_hash_lock)); */ 1571 1572 netdev_dbg(padapter->pnetdev, 1573 "ap recv disassoc reason code(%d) sta:%pM\n", 1574 reason, GetAddr2Ptr(pframe)); 1575 1576 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); 1577 if (psta) { 1578 u8 updated = false; 1579 1580 spin_lock_bh(&pstapriv->asoc_list_lock); 1581 if (list_empty(&psta->asoc_list) == false) { 1582 list_del_init(&psta->asoc_list); 1583 pstapriv->asoc_list_cnt--; 1584 updated = ap_free_sta(padapter, psta, false, reason); 1585 1586 } 1587 spin_unlock_bh(&pstapriv->asoc_list_lock); 1588 1589 associated_clients_update(padapter, updated); 1590 } 1591 1592 return _SUCCESS; 1593 } else { 1594 netdev_dbg(padapter->pnetdev, 1595 "sta recv disassoc reason code(%d) sta:%pM\n", 1596 reason, GetAddr3Ptr(pframe)); 1597 1598 receive_disconnect(padapter, GetAddr3Ptr(pframe), reason); 1599 } 1600 pmlmepriv->LinkDetectInfo.bBusyTraffic = false; 1601 return _SUCCESS; 1602 1603 } 1604 1605 unsigned int OnAtim(struct adapter *padapter, union recv_frame *precv_frame) 1606 { 1607 return _SUCCESS; 1608 } 1609 1610 unsigned int on_action_spct(struct adapter *padapter, union recv_frame *precv_frame) 1611 { 1612 struct sta_info *psta = NULL; 1613 struct sta_priv *pstapriv = &padapter->stapriv; 1614 u8 *pframe = precv_frame->u.hdr.rx_data; 1615 u8 *frame_body = (u8 *)(pframe + sizeof(struct ieee80211_hdr_3addr)); 1616 u8 category; 1617 u8 action; 1618 1619 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); 1620 1621 if (!psta) 1622 goto exit; 1623 1624 category = frame_body[0]; 1625 if (category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT) 1626 goto exit; 1627 1628 action = frame_body[1]; 1629 switch (action) { 1630 case WLAN_ACTION_SPCT_MSR_REQ: 1631 case WLAN_ACTION_SPCT_MSR_RPRT: 1632 case WLAN_ACTION_SPCT_TPC_REQ: 1633 case WLAN_ACTION_SPCT_TPC_RPRT: 1634 case WLAN_ACTION_SPCT_CHL_SWITCH: 1635 break; 1636 default: 1637 break; 1638 } 1639 1640 exit: 1641 return _FAIL; 1642 } 1643 1644 unsigned int OnAction_back(struct adapter *padapter, union recv_frame *precv_frame) 1645 { 1646 u8 *addr; 1647 struct sta_info *psta = NULL; 1648 struct recv_reorder_ctrl *preorder_ctrl; 1649 unsigned char *frame_body; 1650 unsigned char category, action; 1651 unsigned short tid, status; 1652 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 1653 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 1654 u8 *pframe = precv_frame->u.hdr.rx_data; 1655 struct sta_priv *pstapriv = &padapter->stapriv; 1656 1657 /* check RA matches or not */ 1658 if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN))/* for if1, sta/ap mode */ 1659 return _SUCCESS; 1660 1661 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) 1662 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) 1663 return _SUCCESS; 1664 1665 addr = GetAddr2Ptr(pframe); 1666 psta = rtw_get_stainfo(pstapriv, addr); 1667 1668 if (!psta) 1669 return _SUCCESS; 1670 1671 frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); 1672 1673 category = frame_body[0]; 1674 if (category == RTW_WLAN_CATEGORY_BACK) {/* representing Block Ack */ 1675 if (!pmlmeinfo->HT_enable) 1676 return _SUCCESS; 1677 1678 action = frame_body[1]; 1679 switch (action) { 1680 case WLAN_ACTION_ADDBA_REQ: /* ADDBA request */ 1681 1682 memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request)); 1683 /* process_addba_req(padapter, (u8 *)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe)); */ 1684 process_addba_req(padapter, (u8 *)&(pmlmeinfo->ADDBA_req), addr); 1685 1686 if (pmlmeinfo->accept_addba_req) { 1687 issue_action_BA(padapter, addr, WLAN_ACTION_ADDBA_RESP, 0); 1688 } else { 1689 issue_action_BA(padapter, addr, WLAN_ACTION_ADDBA_RESP, 37);/* reject ADDBA Req */ 1690 } 1691 1692 break; 1693 1694 case WLAN_ACTION_ADDBA_RESP: /* ADDBA response */ 1695 status = get_unaligned_le16(&frame_body[3]); 1696 tid = ((frame_body[5] >> 2) & 0x7); 1697 1698 if (status == 0) { 1699 /* successful */ 1700 psta->htpriv.agg_enable_bitmap |= BIT(tid); 1701 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid); 1702 } else { 1703 psta->htpriv.agg_enable_bitmap &= ~BIT(tid); 1704 } 1705 1706 if (psta->state & WIFI_STA_ALIVE_CHK_STATE) { 1707 psta->htpriv.agg_enable_bitmap &= ~BIT(tid); 1708 psta->expire_to = pstapriv->expire_to; 1709 psta->state ^= WIFI_STA_ALIVE_CHK_STATE; 1710 } 1711 1712 break; 1713 1714 case WLAN_ACTION_DELBA: /* DELBA */ 1715 if ((frame_body[3] & BIT(3)) == 0) { 1716 psta->htpriv.agg_enable_bitmap &= 1717 ~BIT((frame_body[3] >> 4) & 0xf); 1718 psta->htpriv.candidate_tid_bitmap &= 1719 ~BIT((frame_body[3] >> 4) & 0xf); 1720 } else if ((frame_body[3] & BIT(3)) == BIT(3)) { 1721 tid = (frame_body[3] >> 4) & 0x0F; 1722 1723 preorder_ctrl = &psta->recvreorder_ctrl[tid]; 1724 preorder_ctrl->enable = false; 1725 preorder_ctrl->indicate_seq = 0xffff; 1726 } 1727 /* todo: how to notify the host while receiving DELETE BA */ 1728 break; 1729 1730 default: 1731 break; 1732 } 1733 } 1734 return _SUCCESS; 1735 } 1736 1737 static s32 rtw_action_public_decache(union recv_frame *recv_frame, s32 token) 1738 { 1739 struct adapter *adapter = recv_frame->u.hdr.adapter; 1740 struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv); 1741 u8 *frame = recv_frame->u.hdr.rx_data; 1742 u16 seq_ctrl = ((recv_frame->u.hdr.attrib.seq_num&0xffff) << 4) | 1743 (recv_frame->u.hdr.attrib.frag_num & 0xf); 1744 1745 if (GetRetry(frame)) { 1746 if (token >= 0) { 1747 if ((seq_ctrl == mlmeext->action_public_rxseq) 1748 && (token == mlmeext->action_public_dialog_token)) 1749 return _FAIL; 1750 } else { 1751 if (seq_ctrl == mlmeext->action_public_rxseq) 1752 return _FAIL; 1753 } 1754 } 1755 1756 mlmeext->action_public_rxseq = seq_ctrl; 1757 1758 if (token >= 0) 1759 mlmeext->action_public_dialog_token = token; 1760 1761 return _SUCCESS; 1762 } 1763 1764 static unsigned int on_action_public_p2p(union recv_frame *precv_frame) 1765 { 1766 u8 *pframe = precv_frame->u.hdr.rx_data; 1767 u8 *frame_body; 1768 u8 dialogToken = 0; 1769 1770 frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); 1771 1772 dialogToken = frame_body[7]; 1773 1774 if (rtw_action_public_decache(precv_frame, dialogToken) == _FAIL) 1775 return _FAIL; 1776 1777 return _SUCCESS; 1778 } 1779 1780 static unsigned int on_action_public_vendor(union recv_frame *precv_frame) 1781 { 1782 unsigned int ret = _FAIL; 1783 u8 *pframe = precv_frame->u.hdr.rx_data; 1784 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); 1785 1786 if (!memcmp(frame_body + 2, P2P_OUI, 4)) { 1787 ret = on_action_public_p2p(precv_frame); 1788 } 1789 1790 return ret; 1791 } 1792 1793 static unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action) 1794 { 1795 unsigned int ret = _FAIL; 1796 u8 *pframe = precv_frame->u.hdr.rx_data; 1797 uint frame_len = precv_frame->u.hdr.len; 1798 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); 1799 u8 token; 1800 struct adapter *adapter = precv_frame->u.hdr.adapter; 1801 char msg[64]; 1802 1803 token = frame_body[2]; 1804 1805 if (rtw_action_public_decache(precv_frame, token) == _FAIL) 1806 goto exit; 1807 1808 scnprintf(msg, sizeof(msg), "%s(token:%u)", action_public_str(action), token); 1809 rtw_cfg80211_rx_action(adapter, pframe, frame_len, msg); 1810 1811 ret = _SUCCESS; 1812 1813 exit: 1814 return ret; 1815 } 1816 1817 unsigned int on_action_public(struct adapter *padapter, union recv_frame *precv_frame) 1818 { 1819 unsigned int ret = _FAIL; 1820 u8 *pframe = precv_frame->u.hdr.rx_data; 1821 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); 1822 u8 category, action; 1823 1824 /* check RA matches or not */ 1825 if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN)) 1826 goto exit; 1827 1828 category = frame_body[0]; 1829 if (category != RTW_WLAN_CATEGORY_PUBLIC) 1830 goto exit; 1831 1832 action = frame_body[1]; 1833 switch (action) { 1834 case ACT_PUBLIC_VENDOR: 1835 ret = on_action_public_vendor(precv_frame); 1836 break; 1837 default: 1838 ret = on_action_public_default(precv_frame, action); 1839 break; 1840 } 1841 1842 exit: 1843 return ret; 1844 } 1845 1846 unsigned int OnAction_ht(struct adapter *padapter, union recv_frame *precv_frame) 1847 { 1848 u8 *pframe = precv_frame->u.hdr.rx_data; 1849 u8 *frame_body = pframe + sizeof(struct ieee80211_hdr_3addr); 1850 u8 category, action; 1851 1852 /* check RA matches or not */ 1853 if (memcmp(myid(&(padapter->eeprompriv)), GetAddr1Ptr(pframe), ETH_ALEN)) 1854 goto exit; 1855 1856 category = frame_body[0]; 1857 if (category != RTW_WLAN_CATEGORY_HT) 1858 goto exit; 1859 1860 action = frame_body[1]; 1861 switch (action) { 1862 case WLAN_HT_ACTION_COMPRESSED_BF: 1863 break; 1864 default: 1865 break; 1866 } 1867 1868 exit: 1869 1870 return _SUCCESS; 1871 } 1872 1873 unsigned int OnAction_sa_query(struct adapter *padapter, union recv_frame *precv_frame) 1874 { 1875 u8 *pframe = precv_frame->u.hdr.rx_data; 1876 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; 1877 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 1878 unsigned short tid; 1879 1880 switch (pframe[WLAN_HDR_A3_LEN+1]) { 1881 case 0: /* SA Query req */ 1882 memcpy(&tid, &pframe[WLAN_HDR_A3_LEN+2], sizeof(unsigned short)); 1883 issue_action_SA_Query(padapter, GetAddr2Ptr(pframe), 1, tid); 1884 break; 1885 1886 case 1: /* SA Query rsp */ 1887 del_timer_sync(&pmlmeext->sa_query_timer); 1888 break; 1889 default: 1890 break; 1891 } 1892 if (0) { 1893 int pp; 1894 1895 printk("pattrib->pktlen = %d =>", pattrib->pkt_len); 1896 for (pp = 0; pp < pattrib->pkt_len; pp++) 1897 printk(" %02x ", pframe[pp]); 1898 printk("\n"); 1899 } 1900 1901 return _SUCCESS; 1902 } 1903 1904 unsigned int OnAction(struct adapter *padapter, union recv_frame *precv_frame) 1905 { 1906 int i; 1907 unsigned char category; 1908 struct action_handler *ptable; 1909 unsigned char *frame_body; 1910 u8 *pframe = precv_frame->u.hdr.rx_data; 1911 1912 frame_body = (unsigned char *)(pframe + sizeof(struct ieee80211_hdr_3addr)); 1913 1914 category = frame_body[0]; 1915 1916 for (i = 0; i < ARRAY_SIZE(OnAction_tbl); i++) { 1917 ptable = &OnAction_tbl[i]; 1918 1919 if (category == ptable->num) 1920 ptable->func(padapter, precv_frame); 1921 1922 } 1923 1924 return _SUCCESS; 1925 1926 } 1927 1928 unsigned int DoReserved(struct adapter *padapter, union recv_frame *precv_frame) 1929 { 1930 return _SUCCESS; 1931 } 1932 1933 static struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once) 1934 { 1935 struct xmit_frame *pmgntframe; 1936 struct xmit_buf *pxmitbuf; 1937 1938 if (once) 1939 pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv); 1940 else 1941 pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv); 1942 1943 if (!pmgntframe) 1944 goto exit; 1945 1946 pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv); 1947 if (pxmitbuf == NULL) { 1948 rtw_free_xmitframe(pxmitpriv, pmgntframe); 1949 pmgntframe = NULL; 1950 goto exit; 1951 } 1952 1953 pmgntframe->frame_tag = MGNT_FRAMETAG; 1954 pmgntframe->pxmitbuf = pxmitbuf; 1955 pmgntframe->buf_addr = pxmitbuf->pbuf; 1956 pxmitbuf->priv_data = pmgntframe; 1957 1958 exit: 1959 return pmgntframe; 1960 1961 } 1962 1963 inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv) 1964 { 1965 return _alloc_mgtxmitframe(pxmitpriv, false); 1966 } 1967 1968 /**************************************************************************** 1969 1970 Following are some TX functions for WiFi MLME 1971 1972 *****************************************************************************/ 1973 1974 void update_mgnt_tx_rate(struct adapter *padapter, u8 rate) 1975 { 1976 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 1977 1978 pmlmeext->tx_rate = rate; 1979 } 1980 1981 void update_mgntframe_attrib(struct adapter *padapter, struct pkt_attrib *pattrib) 1982 { 1983 u8 wireless_mode; 1984 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 1985 1986 /* memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib)); */ 1987 1988 pattrib->hdrlen = 24; 1989 pattrib->nr_frags = 1; 1990 pattrib->priority = 7; 1991 pattrib->mac_id = 0; 1992 pattrib->qsel = 0x12; 1993 1994 pattrib->pktlen = 0; 1995 1996 if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB) 1997 wireless_mode = WIRELESS_11B; 1998 else 1999 wireless_mode = WIRELESS_11G; 2000 pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode); 2001 pattrib->rate = pmlmeext->tx_rate; 2002 2003 pattrib->encrypt = _NO_PRIVACY_; 2004 pattrib->bswenc = false; 2005 2006 pattrib->qos_en = false; 2007 pattrib->ht_en = false; 2008 pattrib->bwmode = CHANNEL_WIDTH_20; 2009 pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; 2010 pattrib->sgi = false; 2011 2012 pattrib->seqnum = pmlmeext->mgnt_seq; 2013 2014 pattrib->retry_ctrl = true; 2015 2016 pattrib->mbssid = 0; 2017 2018 } 2019 2020 void update_mgntframe_attrib_addr(struct adapter *padapter, struct xmit_frame *pmgntframe) 2021 { 2022 u8 *pframe; 2023 struct pkt_attrib *pattrib = &pmgntframe->attrib; 2024 2025 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 2026 2027 memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN); 2028 memcpy(pattrib->ta, GetAddr2Ptr(pframe), ETH_ALEN); 2029 } 2030 2031 void dump_mgntframe(struct adapter *padapter, struct xmit_frame *pmgntframe) 2032 { 2033 if (padapter->bSurpriseRemoved || 2034 padapter->bDriverStopped) { 2035 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf); 2036 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe); 2037 return; 2038 } 2039 2040 rtw_hal_mgnt_xmit(padapter, pmgntframe); 2041 } 2042 2043 s32 dump_mgntframe_and_wait(struct adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms) 2044 { 2045 s32 ret = _FAIL; 2046 unsigned long irqL; 2047 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 2048 struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf; 2049 struct submit_ctx sctx; 2050 2051 if (padapter->bSurpriseRemoved || 2052 padapter->bDriverStopped) { 2053 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf); 2054 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe); 2055 return ret; 2056 } 2057 2058 rtw_sctx_init(&sctx, timeout_ms); 2059 pxmitbuf->sctx = &sctx; 2060 2061 ret = rtw_hal_mgnt_xmit(padapter, pmgntframe); 2062 2063 if (ret == _SUCCESS) 2064 ret = rtw_sctx_wait(&sctx); 2065 2066 spin_lock_irqsave(&pxmitpriv->lock_sctx, irqL); 2067 pxmitbuf->sctx = NULL; 2068 spin_unlock_irqrestore(&pxmitpriv->lock_sctx, irqL); 2069 2070 return ret; 2071 } 2072 2073 s32 dump_mgntframe_and_wait_ack(struct adapter *padapter, struct xmit_frame *pmgntframe) 2074 { 2075 static u8 seq_no; 2076 s32 ret = _FAIL; 2077 u32 timeout_ms = 500;/* 500ms */ 2078 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 2079 2080 if (padapter->bSurpriseRemoved || 2081 padapter->bDriverStopped) { 2082 rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf); 2083 rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe); 2084 return -1; 2085 } 2086 2087 if (mutex_lock_interruptible(&pxmitpriv->ack_tx_mutex) == 0) { 2088 pxmitpriv->ack_tx = true; 2089 pxmitpriv->seq_no = seq_no++; 2090 pmgntframe->ack_report = 1; 2091 if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS) 2092 ret = rtw_ack_tx_wait(pxmitpriv, timeout_ms); 2093 2094 pxmitpriv->ack_tx = false; 2095 mutex_unlock(&pxmitpriv->ack_tx_mutex); 2096 } 2097 2098 return ret; 2099 } 2100 2101 static int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode) 2102 { 2103 u8 *ssid_ie; 2104 signed int ssid_len_ori; 2105 int len_diff = 0; 2106 2107 ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len); 2108 2109 if (ssid_ie && ssid_len_ori > 0) { 2110 switch (hidden_ssid_mode) { 2111 case 1: 2112 { 2113 u8 *next_ie = ssid_ie + 2 + ssid_len_ori; 2114 u32 remain_len = 0; 2115 2116 remain_len = ies_len - (next_ie-ies); 2117 2118 ssid_ie[1] = 0; 2119 memcpy(ssid_ie+2, next_ie, remain_len); 2120 len_diff -= ssid_len_ori; 2121 2122 break; 2123 } 2124 case 2: 2125 memset(&ssid_ie[2], 0, ssid_len_ori); 2126 break; 2127 default: 2128 break; 2129 } 2130 } 2131 2132 return len_diff; 2133 } 2134 2135 void issue_beacon(struct adapter *padapter, int timeout_ms) 2136 { 2137 struct xmit_frame *pmgntframe; 2138 struct pkt_attrib *pattrib; 2139 unsigned char *pframe; 2140 struct ieee80211_hdr *pwlanhdr; 2141 __le16 *fctrl; 2142 unsigned int rate_len; 2143 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 2144 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2145 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2146 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 2147 struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); 2148 2149 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 2150 if (!pmgntframe) 2151 return; 2152 2153 spin_lock_bh(&pmlmepriv->bcn_update_lock); 2154 2155 /* update attribute */ 2156 pattrib = &pmgntframe->attrib; 2157 update_mgntframe_attrib(padapter, pattrib); 2158 pattrib->qsel = 0x10; 2159 2160 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 2161 2162 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 2163 pwlanhdr = (struct ieee80211_hdr *)pframe; 2164 2165 2166 fctrl = &(pwlanhdr->frame_control); 2167 *(fctrl) = 0; 2168 2169 eth_broadcast_addr(pwlanhdr->addr1); 2170 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 2171 memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN); 2172 2173 SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/); 2174 /* pmlmeext->mgnt_seq++; */ 2175 SetFrameSubType(pframe, WIFI_BEACON); 2176 2177 pframe += sizeof(struct ieee80211_hdr_3addr); 2178 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 2179 2180 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) { 2181 { 2182 int len_diff; 2183 2184 memcpy(pframe, cur_network->IEs, cur_network->IELength); 2185 len_diff = update_hidden_ssid(pframe+_BEACON_IE_OFFSET_, 2186 cur_network->IELength-_BEACON_IE_OFFSET_, 2187 pmlmeinfo->hidden_ssid_mode); 2188 pframe += (cur_network->IELength+len_diff); 2189 pattrib->pktlen += (cur_network->IELength+len_diff); 2190 } 2191 2192 { 2193 u8 *wps_ie; 2194 uint wps_ielen; 2195 u8 sr = 0; 2196 2197 wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct ieee80211_hdr_3addr)+_BEACON_IE_OFFSET_, 2198 pattrib->pktlen-sizeof(struct ieee80211_hdr_3addr)-_BEACON_IE_OFFSET_, NULL, &wps_ielen); 2199 if (wps_ie && wps_ielen > 0) { 2200 rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL); 2201 } 2202 if (sr != 0) 2203 set_fwstate(pmlmepriv, WIFI_UNDER_WPS); 2204 else 2205 _clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS); 2206 } 2207 2208 goto _issue_bcn; 2209 2210 } 2211 2212 /* below for ad-hoc mode */ 2213 2214 /* timestamp will be inserted by hardware */ 2215 pframe += 8; 2216 pattrib->pktlen += 8; 2217 2218 /* beacon interval: 2 bytes */ 2219 2220 memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); 2221 2222 pframe += 2; 2223 pattrib->pktlen += 2; 2224 2225 /* capability info: 2 bytes */ 2226 2227 memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); 2228 2229 pframe += 2; 2230 pattrib->pktlen += 2; 2231 2232 /* SSID */ 2233 pframe = rtw_set_ie(pframe, WLAN_EID_SSID, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen); 2234 2235 /* supported rates... */ 2236 rate_len = rtw_get_rateset_len(cur_network->SupportedRates); 2237 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen); 2238 2239 /* DS parameter set */ 2240 pframe = rtw_set_ie(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen); 2241 2242 /* if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */ 2243 { 2244 u8 erpinfo = 0; 2245 u32 ATIMWindow; 2246 /* IBSS Parameter Set... */ 2247 /* ATIMWindow = cur->Configuration.ATIMWindow; */ 2248 ATIMWindow = 0; 2249 pframe = rtw_set_ie(pframe, WLAN_EID_IBSS_PARAMS, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen); 2250 2251 /* ERP IE */ 2252 pframe = rtw_set_ie(pframe, WLAN_EID_ERP_INFO, 1, &erpinfo, &pattrib->pktlen); 2253 } 2254 2255 2256 /* EXTERNDED SUPPORTED RATE */ 2257 if (rate_len > 8) { 2258 pframe = rtw_set_ie(pframe, WLAN_EID_EXT_SUPP_RATES, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen); 2259 } 2260 2261 2262 /* todo:HT for adhoc */ 2263 2264 _issue_bcn: 2265 2266 pmlmepriv->update_bcn = false; 2267 2268 spin_unlock_bh(&pmlmepriv->bcn_update_lock); 2269 2270 if ((pattrib->pktlen + TXDESC_SIZE) > 512) 2271 return; 2272 2273 pattrib->last_txcmdsz = pattrib->pktlen; 2274 2275 if (timeout_ms > 0) 2276 dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms); 2277 else 2278 dump_mgntframe(padapter, pmgntframe); 2279 2280 } 2281 2282 void issue_probersp(struct adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq) 2283 { 2284 struct xmit_frame *pmgntframe; 2285 struct pkt_attrib *pattrib; 2286 unsigned char *pframe; 2287 struct ieee80211_hdr *pwlanhdr; 2288 __le16 *fctrl; 2289 unsigned char *mac, *bssid; 2290 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 2291 2292 u8 *pwps_ie; 2293 uint wps_ielen; 2294 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2295 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2296 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 2297 struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); 2298 unsigned int rate_len; 2299 2300 if (da == NULL) 2301 return; 2302 2303 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 2304 if (!pmgntframe) 2305 return; 2306 2307 /* update attribute */ 2308 pattrib = &pmgntframe->attrib; 2309 update_mgntframe_attrib(padapter, pattrib); 2310 2311 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 2312 2313 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 2314 pwlanhdr = (struct ieee80211_hdr *)pframe; 2315 2316 mac = myid(&(padapter->eeprompriv)); 2317 bssid = cur_network->MacAddress; 2318 2319 fctrl = &(pwlanhdr->frame_control); 2320 *(fctrl) = 0; 2321 memcpy(pwlanhdr->addr1, da, ETH_ALEN); 2322 memcpy(pwlanhdr->addr2, mac, ETH_ALEN); 2323 memcpy(pwlanhdr->addr3, bssid, ETH_ALEN); 2324 2325 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 2326 pmlmeext->mgnt_seq++; 2327 SetFrameSubType(fctrl, WIFI_PROBERSP); 2328 2329 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr); 2330 pattrib->pktlen = pattrib->hdrlen; 2331 pframe += pattrib->hdrlen; 2332 2333 2334 if (cur_network->IELength > MAX_IE_SZ) 2335 return; 2336 2337 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) { 2338 pwps_ie = rtw_get_wps_ie(cur_network->IEs+_FIXED_IE_LENGTH_, cur_network->IELength-_FIXED_IE_LENGTH_, NULL, &wps_ielen); 2339 2340 /* inerset & update wps_probe_resp_ie */ 2341 if (pmlmepriv->wps_probe_resp_ie && pwps_ie && wps_ielen > 0) { 2342 uint wps_offset, remainder_ielen; 2343 u8 *premainder_ie; 2344 2345 wps_offset = (uint)(pwps_ie - cur_network->IEs); 2346 2347 premainder_ie = pwps_ie + wps_ielen; 2348 2349 remainder_ielen = cur_network->IELength - wps_offset - wps_ielen; 2350 2351 memcpy(pframe, cur_network->IEs, wps_offset); 2352 pframe += wps_offset; 2353 pattrib->pktlen += wps_offset; 2354 2355 wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];/* to get ie data len */ 2356 if ((wps_offset+wps_ielen+2) <= MAX_IE_SZ) { 2357 memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen+2); 2358 pframe += wps_ielen+2; 2359 pattrib->pktlen += wps_ielen+2; 2360 } 2361 2362 if ((wps_offset+wps_ielen+2+remainder_ielen) <= MAX_IE_SZ) { 2363 memcpy(pframe, premainder_ie, remainder_ielen); 2364 pframe += remainder_ielen; 2365 pattrib->pktlen += remainder_ielen; 2366 } 2367 } else { 2368 memcpy(pframe, cur_network->IEs, cur_network->IELength); 2369 pframe += cur_network->IELength; 2370 pattrib->pktlen += cur_network->IELength; 2371 } 2372 2373 /* retrieve SSID IE from cur_network->Ssid */ 2374 { 2375 u8 *ssid_ie; 2376 signed int ssid_ielen; 2377 signed int ssid_ielen_diff; 2378 u8 *buf; 2379 u8 *ies = pmgntframe->buf_addr+TXDESC_OFFSET+sizeof(struct ieee80211_hdr_3addr); 2380 2381 buf = rtw_zmalloc(MAX_IE_SZ); 2382 if (!buf) 2383 return; 2384 2385 ssid_ie = rtw_get_ie(ies+_FIXED_IE_LENGTH_, WLAN_EID_SSID, &ssid_ielen, 2386 (pframe-ies)-_FIXED_IE_LENGTH_); 2387 2388 ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen; 2389 2390 if (ssid_ie && cur_network->Ssid.SsidLength) { 2391 uint remainder_ielen; 2392 u8 *remainder_ie; 2393 2394 remainder_ie = ssid_ie+2; 2395 remainder_ielen = (pframe-remainder_ie); 2396 2397 if (remainder_ielen > MAX_IE_SZ) { 2398 netdev_warn(padapter->pnetdev, 2399 FUNC_ADPT_FMT " remainder_ielen > MAX_IE_SZ\n", 2400 FUNC_ADPT_ARG(padapter)); 2401 remainder_ielen = MAX_IE_SZ; 2402 } 2403 2404 memcpy(buf, remainder_ie, remainder_ielen); 2405 memcpy(remainder_ie+ssid_ielen_diff, buf, remainder_ielen); 2406 *(ssid_ie+1) = cur_network->Ssid.SsidLength; 2407 memcpy(ssid_ie+2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength); 2408 2409 pframe += ssid_ielen_diff; 2410 pattrib->pktlen += ssid_ielen_diff; 2411 } 2412 kfree (buf); 2413 } 2414 } else { 2415 /* timestamp will be inserted by hardware */ 2416 pframe += 8; 2417 pattrib->pktlen += 8; 2418 2419 /* beacon interval: 2 bytes */ 2420 2421 memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2); 2422 2423 pframe += 2; 2424 pattrib->pktlen += 2; 2425 2426 /* capability info: 2 bytes */ 2427 2428 memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2); 2429 2430 pframe += 2; 2431 pattrib->pktlen += 2; 2432 2433 /* below for ad-hoc mode */ 2434 2435 /* SSID */ 2436 pframe = rtw_set_ie(pframe, WLAN_EID_SSID, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen); 2437 2438 /* supported rates... */ 2439 rate_len = rtw_get_rateset_len(cur_network->SupportedRates); 2440 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen); 2441 2442 /* DS parameter set */ 2443 pframe = rtw_set_ie(pframe, WLAN_EID_DS_PARAMS, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen); 2444 2445 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) { 2446 u8 erpinfo = 0; 2447 u32 ATIMWindow; 2448 /* IBSS Parameter Set... */ 2449 /* ATIMWindow = cur->Configuration.ATIMWindow; */ 2450 ATIMWindow = 0; 2451 pframe = rtw_set_ie(pframe, WLAN_EID_IBSS_PARAMS, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen); 2452 2453 /* ERP IE */ 2454 pframe = rtw_set_ie(pframe, WLAN_EID_ERP_INFO, 1, &erpinfo, &pattrib->pktlen); 2455 } 2456 2457 2458 /* EXTERNDED SUPPORTED RATE */ 2459 if (rate_len > 8) { 2460 pframe = rtw_set_ie(pframe, WLAN_EID_EXT_SUPP_RATES, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen); 2461 } 2462 2463 2464 /* todo:HT for adhoc */ 2465 2466 } 2467 2468 pattrib->last_txcmdsz = pattrib->pktlen; 2469 2470 2471 dump_mgntframe(padapter, pmgntframe); 2472 2473 return; 2474 2475 } 2476 2477 static int _issue_probereq(struct adapter *padapter, 2478 struct ndis_802_11_ssid *pssid, 2479 u8 *da, u8 ch, bool append_wps, bool wait_ack) 2480 { 2481 int ret = _FAIL; 2482 struct xmit_frame *pmgntframe; 2483 struct pkt_attrib *pattrib; 2484 unsigned char *pframe; 2485 struct ieee80211_hdr *pwlanhdr; 2486 __le16 *fctrl; 2487 unsigned char *mac; 2488 unsigned char bssrate[NumRates]; 2489 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 2490 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2491 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2492 int bssrate_len = 0; 2493 2494 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 2495 if (!pmgntframe) 2496 goto exit; 2497 2498 /* update attribute */ 2499 pattrib = &pmgntframe->attrib; 2500 update_mgntframe_attrib(padapter, pattrib); 2501 2502 2503 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 2504 2505 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 2506 pwlanhdr = (struct ieee80211_hdr *)pframe; 2507 2508 mac = myid(&(padapter->eeprompriv)); 2509 2510 fctrl = &(pwlanhdr->frame_control); 2511 *(fctrl) = 0; 2512 2513 if (da) { 2514 /* unicast probe request frame */ 2515 memcpy(pwlanhdr->addr1, da, ETH_ALEN); 2516 memcpy(pwlanhdr->addr3, da, ETH_ALEN); 2517 } else { 2518 /* broadcast probe request frame */ 2519 eth_broadcast_addr(pwlanhdr->addr1); 2520 eth_broadcast_addr(pwlanhdr->addr3); 2521 } 2522 2523 memcpy(pwlanhdr->addr2, mac, ETH_ALEN); 2524 2525 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 2526 pmlmeext->mgnt_seq++; 2527 SetFrameSubType(pframe, WIFI_PROBEREQ); 2528 2529 pframe += sizeof(struct ieee80211_hdr_3addr); 2530 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 2531 2532 if (pssid) 2533 pframe = rtw_set_ie(pframe, WLAN_EID_SSID, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen)); 2534 else 2535 pframe = rtw_set_ie(pframe, WLAN_EID_SSID, 0, NULL, &(pattrib->pktlen)); 2536 2537 get_rate_set(padapter, bssrate, &bssrate_len); 2538 2539 if (bssrate_len > 8) { 2540 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, 8, bssrate, &(pattrib->pktlen)); 2541 pframe = rtw_set_ie(pframe, WLAN_EID_EXT_SUPP_RATES, (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen)); 2542 } else { 2543 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, bssrate_len, bssrate, &(pattrib->pktlen)); 2544 } 2545 2546 if (ch) 2547 pframe = rtw_set_ie(pframe, WLAN_EID_DS_PARAMS, 1, &ch, &pattrib->pktlen); 2548 2549 if (append_wps) { 2550 /* add wps_ie for wps2.0 */ 2551 if (pmlmepriv->wps_probe_req_ie_len > 0 && pmlmepriv->wps_probe_req_ie) { 2552 memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len); 2553 pframe += pmlmepriv->wps_probe_req_ie_len; 2554 pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len; 2555 } 2556 } 2557 2558 pattrib->last_txcmdsz = pattrib->pktlen; 2559 2560 if (wait_ack) { 2561 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); 2562 } else { 2563 dump_mgntframe(padapter, pmgntframe); 2564 ret = _SUCCESS; 2565 } 2566 2567 exit: 2568 return ret; 2569 } 2570 2571 inline void issue_probereq(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da) 2572 { 2573 _issue_probereq(padapter, pssid, da, 0, 1, false); 2574 } 2575 2576 int issue_probereq_ex(struct adapter *padapter, struct ndis_802_11_ssid *pssid, u8 *da, u8 ch, bool append_wps, 2577 int try_cnt, int wait_ms) 2578 { 2579 int ret; 2580 int i = 0; 2581 2582 do { 2583 ret = _issue_probereq(padapter, pssid, da, ch, append_wps, 2584 wait_ms > 0); 2585 2586 i++; 2587 2588 if (padapter->bDriverStopped || padapter->bSurpriseRemoved) 2589 break; 2590 2591 if (i < try_cnt && wait_ms > 0 && ret == _FAIL) 2592 msleep(wait_ms); 2593 2594 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); 2595 2596 if (ret != _FAIL) { 2597 ret = _SUCCESS; 2598 #ifndef DBG_XMIT_ACK 2599 goto exit; 2600 #endif 2601 } 2602 2603 exit: 2604 return ret; 2605 } 2606 2607 /* if psta == NULL, indicate we are station(client) now... */ 2608 void issue_auth(struct adapter *padapter, struct sta_info *psta, unsigned short status) 2609 { 2610 struct xmit_frame *pmgntframe; 2611 struct pkt_attrib *pattrib; 2612 unsigned char *pframe; 2613 struct ieee80211_hdr *pwlanhdr; 2614 __le16 *fctrl; 2615 unsigned int val32; 2616 unsigned short val16; 2617 int use_shared_key = 0; 2618 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 2619 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2620 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 2621 __le16 le_tmp; 2622 2623 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 2624 if (pmgntframe == NULL) 2625 return; 2626 2627 /* update attribute */ 2628 pattrib = &pmgntframe->attrib; 2629 update_mgntframe_attrib(padapter, pattrib); 2630 2631 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 2632 2633 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 2634 pwlanhdr = (struct ieee80211_hdr *)pframe; 2635 2636 fctrl = &(pwlanhdr->frame_control); 2637 *(fctrl) = 0; 2638 2639 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 2640 pmlmeext->mgnt_seq++; 2641 SetFrameSubType(pframe, WIFI_AUTH); 2642 2643 pframe += sizeof(struct ieee80211_hdr_3addr); 2644 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 2645 2646 2647 if (psta) { /* for AP mode */ 2648 memcpy(pwlanhdr->addr1, psta->hwaddr, ETH_ALEN); 2649 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 2650 memcpy(pwlanhdr->addr3, myid(&(padapter->eeprompriv)), ETH_ALEN); 2651 2652 /* setting auth algo number */ 2653 val16 = (u16)psta->authalg; 2654 2655 if (status != WLAN_STATUS_SUCCESS) 2656 val16 = 0; 2657 2658 if (val16) 2659 use_shared_key = 1; 2660 2661 le_tmp = cpu_to_le16(val16); 2662 2663 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen)); 2664 2665 /* setting auth seq number */ 2666 val16 = (u16)psta->auth_seq; 2667 le_tmp = cpu_to_le16(val16); 2668 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen)); 2669 2670 /* setting status code... */ 2671 val16 = status; 2672 le_tmp = cpu_to_le16(val16); 2673 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_tmp, &(pattrib->pktlen)); 2674 2675 /* added challenging text... */ 2676 if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) 2677 pframe = rtw_set_ie(pframe, WLAN_EID_CHALLENGE, 128, psta->chg_txt, &(pattrib->pktlen)); 2678 2679 } else { 2680 memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); 2681 memcpy(pwlanhdr->addr2, myid(&padapter->eeprompriv), ETH_ALEN); 2682 memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN); 2683 2684 /* setting auth algo number */ 2685 val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0;/* 0:OPEN System, 1:Shared key */ 2686 if (val16) { 2687 use_shared_key = 1; 2688 } 2689 le_tmp = cpu_to_le16(val16); 2690 2691 /* setting IV for auth seq #3 */ 2692 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) { 2693 __le32 le_tmp32; 2694 2695 val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30)); 2696 le_tmp32 = cpu_to_le32(val32); 2697 pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&le_tmp32, &(pattrib->pktlen)); 2698 2699 pattrib->iv_len = 4; 2700 } 2701 2702 pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen)); 2703 2704 /* setting auth seq number */ 2705 le_tmp = cpu_to_le16(pmlmeinfo->auth_seq); 2706 pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&le_tmp, &(pattrib->pktlen)); 2707 2708 2709 /* setting status code... */ 2710 le_tmp = cpu_to_le16(status); 2711 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&le_tmp, &(pattrib->pktlen)); 2712 2713 /* then checking to see if sending challenging text... */ 2714 if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) { 2715 pframe = rtw_set_ie(pframe, WLAN_EID_CHALLENGE, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen)); 2716 2717 SetPrivacy(fctrl); 2718 2719 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr); 2720 2721 pattrib->encrypt = _WEP40_; 2722 2723 pattrib->icv_len = 4; 2724 2725 pattrib->pktlen += pattrib->icv_len; 2726 2727 } 2728 2729 } 2730 2731 pattrib->last_txcmdsz = pattrib->pktlen; 2732 2733 rtw_wep_encrypt(padapter, (u8 *)pmgntframe); 2734 dump_mgntframe(padapter, pmgntframe); 2735 } 2736 2737 2738 void issue_asocrsp(struct adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type) 2739 { 2740 struct xmit_frame *pmgntframe; 2741 struct ieee80211_hdr *pwlanhdr; 2742 struct pkt_attrib *pattrib; 2743 unsigned char *pbuf, *pframe; 2744 unsigned short val; 2745 __le16 *fctrl; 2746 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 2747 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2748 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 2749 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 2750 struct wlan_bssid_ex *pnetwork = &(pmlmeinfo->network); 2751 u8 *ie = pnetwork->IEs; 2752 __le16 lestatus, le_tmp; 2753 2754 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 2755 if (pmgntframe == NULL) 2756 return; 2757 2758 /* update attribute */ 2759 pattrib = &pmgntframe->attrib; 2760 update_mgntframe_attrib(padapter, pattrib); 2761 2762 2763 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 2764 2765 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 2766 pwlanhdr = (struct ieee80211_hdr *)pframe; 2767 2768 fctrl = &(pwlanhdr->frame_control); 2769 *(fctrl) = 0; 2770 2771 memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->hwaddr, ETH_ALEN); 2772 memcpy((void *)GetAddr2Ptr(pwlanhdr), myid(&(padapter->eeprompriv)), ETH_ALEN); 2773 memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 2774 2775 2776 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 2777 pmlmeext->mgnt_seq++; 2778 if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP)) 2779 SetFrameSubType(pwlanhdr, pkt_type); 2780 else 2781 return; 2782 2783 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr); 2784 pattrib->pktlen += pattrib->hdrlen; 2785 pframe += pattrib->hdrlen; 2786 2787 /* capability */ 2788 val = *(unsigned short *)rtw_get_capability_from_ie(ie); 2789 2790 pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_, (unsigned char *)&val, &(pattrib->pktlen)); 2791 2792 lestatus = cpu_to_le16(status); 2793 pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&lestatus, &(pattrib->pktlen)); 2794 2795 le_tmp = cpu_to_le16(pstat->aid | BIT(14) | BIT(15)); 2796 pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_, (unsigned char *)&le_tmp, &(pattrib->pktlen)); 2797 2798 if (pstat->bssratelen <= 8) { 2799 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen)); 2800 } else { 2801 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, 8, pstat->bssrateset, &(pattrib->pktlen)); 2802 pframe = rtw_set_ie(pframe, WLAN_EID_EXT_SUPP_RATES, (pstat->bssratelen-8), pstat->bssrateset+8, &(pattrib->pktlen)); 2803 } 2804 2805 if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) { 2806 uint ie_len = 0; 2807 2808 /* FILL HT CAP INFO IE */ 2809 /* p = hostapd_eid_ht_capabilities_info(hapd, p); */ 2810 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_HT_CAPABILITY, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); 2811 if (pbuf && ie_len > 0) { 2812 memcpy(pframe, pbuf, ie_len+2); 2813 pframe += (ie_len+2); 2814 pattrib->pktlen += (ie_len+2); 2815 } 2816 2817 /* FILL HT ADD INFO IE */ 2818 /* p = hostapd_eid_ht_operation(hapd, p); */ 2819 pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, WLAN_EID_HT_OPERATION, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_)); 2820 if (pbuf && ie_len > 0) { 2821 memcpy(pframe, pbuf, ie_len+2); 2822 pframe += (ie_len+2); 2823 pattrib->pktlen += (ie_len+2); 2824 } 2825 2826 } 2827 2828 /* FILL WMM IE */ 2829 if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) { 2830 uint ie_len = 0; 2831 unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01}; 2832 2833 for (pbuf = ie + _BEACON_IE_OFFSET_; ; pbuf += (ie_len + 2)) { 2834 pbuf = rtw_get_ie(pbuf, WLAN_EID_VENDOR_SPECIFIC, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2))); 2835 if (pbuf && !memcmp(pbuf+2, WMM_PARA_IE, 6)) { 2836 memcpy(pframe, pbuf, ie_len+2); 2837 pframe += (ie_len+2); 2838 pattrib->pktlen += (ie_len+2); 2839 2840 break; 2841 } 2842 2843 if ((pbuf == NULL) || (ie_len == 0)) { 2844 break; 2845 } 2846 } 2847 2848 } 2849 2850 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) { 2851 pframe = rtw_set_ie(pframe, WLAN_EID_VENDOR_SPECIFIC, 6, REALTEK_96B_IE, &(pattrib->pktlen)); 2852 } 2853 2854 /* add WPS IE ie for wps 2.0 */ 2855 if (pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len > 0) { 2856 memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len); 2857 2858 pframe += pmlmepriv->wps_assoc_resp_ie_len; 2859 pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len; 2860 } 2861 2862 pattrib->last_txcmdsz = pattrib->pktlen; 2863 2864 dump_mgntframe(padapter, pmgntframe); 2865 } 2866 2867 void issue_assocreq(struct adapter *padapter) 2868 { 2869 int ret = _FAIL; 2870 struct xmit_frame *pmgntframe; 2871 struct pkt_attrib *pattrib; 2872 unsigned char *pframe; 2873 struct ieee80211_hdr *pwlanhdr; 2874 __le16 *fctrl; 2875 __le16 val16; 2876 unsigned int i, j, index = 0; 2877 unsigned char bssrate[NumRates], sta_bssrate[NumRates]; 2878 struct ndis_80211_var_ie *pIE; 2879 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 2880 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 2881 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 2882 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 2883 int bssrate_len = 0, sta_bssrate_len = 0; 2884 u8 vs_ie_length = 0; 2885 2886 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 2887 if (pmgntframe == NULL) 2888 goto exit; 2889 2890 /* update attribute */ 2891 pattrib = &pmgntframe->attrib; 2892 update_mgntframe_attrib(padapter, pattrib); 2893 2894 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 2895 2896 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 2897 pwlanhdr = (struct ieee80211_hdr *)pframe; 2898 2899 fctrl = &(pwlanhdr->frame_control); 2900 *(fctrl) = 0; 2901 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 2902 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 2903 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 2904 2905 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 2906 pmlmeext->mgnt_seq++; 2907 SetFrameSubType(pframe, WIFI_ASSOCREQ); 2908 2909 pframe += sizeof(struct ieee80211_hdr_3addr); 2910 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 2911 2912 /* caps */ 2913 memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2); 2914 2915 pframe += 2; 2916 pattrib->pktlen += 2; 2917 2918 /* listen interval */ 2919 /* todo: listen interval for power saving */ 2920 val16 = cpu_to_le16(3); 2921 memcpy(pframe, (unsigned char *)&val16, 2); 2922 pframe += 2; 2923 pattrib->pktlen += 2; 2924 2925 /* SSID */ 2926 pframe = rtw_set_ie(pframe, WLAN_EID_SSID, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen)); 2927 2928 /* supported rate & extended supported rate */ 2929 2930 /* Check if the AP's supported rates are also supported by STA. */ 2931 get_rate_set(padapter, sta_bssrate, &sta_bssrate_len); 2932 2933 if (pmlmeext->cur_channel == 14) /* for JAPAN, channel 14 can only uses B Mode(CCK) */ 2934 sta_bssrate_len = 4; 2935 2936 2937 /* for (i = 0; i < sta_bssrate_len; i++) { */ 2938 /* */ 2939 2940 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { 2941 if (pmlmeinfo->network.SupportedRates[i] == 0) 2942 break; 2943 } 2944 2945 2946 for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) { 2947 if (pmlmeinfo->network.SupportedRates[i] == 0) 2948 break; 2949 2950 2951 /* Check if the AP's supported rates are also supported by STA. */ 2952 for (j = 0; j < sta_bssrate_len; j++) { 2953 /* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */ 2954 if ((pmlmeinfo->network.SupportedRates[i] | IEEE80211_BASIC_RATE_MASK) 2955 == (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) 2956 break; 2957 } 2958 2959 if (j != sta_bssrate_len) 2960 /* the rate is supported by STA */ 2961 bssrate[index++] = pmlmeinfo->network.SupportedRates[i]; 2962 } 2963 2964 bssrate_len = index; 2965 2966 if (bssrate_len == 0) { 2967 rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf); 2968 rtw_free_xmitframe(pxmitpriv, pmgntframe); 2969 goto exit; /* don't connect to AP if no joint supported rate */ 2970 } 2971 2972 2973 if (bssrate_len > 8) { 2974 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, 8, bssrate, &(pattrib->pktlen)); 2975 pframe = rtw_set_ie(pframe, WLAN_EID_EXT_SUPP_RATES, (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen)); 2976 } else 2977 pframe = rtw_set_ie(pframe, WLAN_EID_SUPP_RATES, bssrate_len, bssrate, &(pattrib->pktlen)); 2978 2979 /* vendor specific IE, such as WPA, WMM, WPS */ 2980 for (i = sizeof(struct ndis_802_11_fix_ie); i < pmlmeinfo->network.IELength;) { 2981 pIE = (struct ndis_80211_var_ie *)(pmlmeinfo->network.IEs + i); 2982 2983 switch (pIE->ElementID) { 2984 case WLAN_EID_VENDOR_SPECIFIC: 2985 if ((!memcmp(pIE->data, RTW_WPA_OUI, 4)) || 2986 (!memcmp(pIE->data, WMM_OUI, 4)) || 2987 (!memcmp(pIE->data, WPS_OUI, 4))) { 2988 vs_ie_length = pIE->Length; 2989 if ((!padapter->registrypriv.wifi_spec) && (!memcmp(pIE->data, WPS_OUI, 4))) { 2990 /* Commented by Kurt 20110629 2991 * In some older APs, WPS handshake 2992 * would be fail if we append vendor 2993 * extensions information to AP 2994 */ 2995 2996 vs_ie_length = 14; 2997 } 2998 2999 pframe = rtw_set_ie(pframe, WLAN_EID_VENDOR_SPECIFIC, vs_ie_length, pIE->data, &(pattrib->pktlen)); 3000 } 3001 break; 3002 3003 case WLAN_EID_RSN: 3004 pframe = rtw_set_ie(pframe, WLAN_EID_RSN, pIE->Length, pIE->data, &(pattrib->pktlen)); 3005 break; 3006 case WLAN_EID_HT_CAPABILITY: 3007 if (padapter->mlmepriv.htpriv.ht_option) { 3008 if (!(is_ap_in_tkip(padapter))) { 3009 memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element)); 3010 pframe = rtw_set_ie(pframe, WLAN_EID_HT_CAPABILITY, pIE->Length, (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen)); 3011 } 3012 } 3013 break; 3014 3015 case WLAN_EID_EXT_CAPABILITY: 3016 if (padapter->mlmepriv.htpriv.ht_option) 3017 pframe = rtw_set_ie(pframe, WLAN_EID_EXT_CAPABILITY, pIE->Length, pIE->data, &(pattrib->pktlen)); 3018 break; 3019 default: 3020 break; 3021 } 3022 3023 i += (pIE->Length + 2); 3024 } 3025 3026 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK) 3027 pframe = rtw_set_ie(pframe, WLAN_EID_VENDOR_SPECIFIC, 6, REALTEK_96B_IE, &(pattrib->pktlen)); 3028 3029 3030 pattrib->last_txcmdsz = pattrib->pktlen; 3031 dump_mgntframe(padapter, pmgntframe); 3032 3033 ret = _SUCCESS; 3034 3035 exit: 3036 if (ret == _SUCCESS) 3037 rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen); 3038 else 3039 rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len); 3040 } 3041 3042 /* when wait_ack is true, this function should be called at process context */ 3043 static int _issue_nulldata(struct adapter *padapter, unsigned char *da, 3044 unsigned int power_mode, bool wait_ack) 3045 { 3046 int ret = _FAIL; 3047 struct xmit_frame *pmgntframe; 3048 struct pkt_attrib *pattrib; 3049 unsigned char *pframe; 3050 struct ieee80211_hdr *pwlanhdr; 3051 __le16 *fctrl; 3052 struct xmit_priv *pxmitpriv; 3053 struct mlme_ext_priv *pmlmeext; 3054 struct mlme_ext_info *pmlmeinfo; 3055 3056 if (!padapter) 3057 goto exit; 3058 3059 pxmitpriv = &(padapter->xmitpriv); 3060 pmlmeext = &(padapter->mlmeextpriv); 3061 pmlmeinfo = &(pmlmeext->mlmext_info); 3062 3063 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 3064 if (pmgntframe == NULL) 3065 goto exit; 3066 3067 /* update attribute */ 3068 pattrib = &pmgntframe->attrib; 3069 update_mgntframe_attrib(padapter, pattrib); 3070 pattrib->retry_ctrl = false; 3071 3072 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 3073 3074 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 3075 pwlanhdr = (struct ieee80211_hdr *)pframe; 3076 3077 fctrl = &(pwlanhdr->frame_control); 3078 *(fctrl) = 0; 3079 3080 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) 3081 SetFrDs(fctrl); 3082 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) 3083 SetToDs(fctrl); 3084 3085 if (power_mode) 3086 SetPwrMgt(fctrl); 3087 3088 memcpy(pwlanhdr->addr1, da, ETH_ALEN); 3089 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 3090 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3091 3092 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 3093 pmlmeext->mgnt_seq++; 3094 SetFrameSubType(pframe, WIFI_DATA_NULL); 3095 3096 pframe += sizeof(struct ieee80211_hdr_3addr); 3097 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 3098 3099 pattrib->last_txcmdsz = pattrib->pktlen; 3100 3101 if (wait_ack) { 3102 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); 3103 } else { 3104 dump_mgntframe(padapter, pmgntframe); 3105 ret = _SUCCESS; 3106 } 3107 3108 exit: 3109 return ret; 3110 } 3111 3112 /* 3113 * [IMPORTANT] Don't call this function in interrupt context 3114 * 3115 * When wait_ms > 0, this function should be called at process context 3116 * da == NULL for station mode 3117 */ 3118 int issue_nulldata(struct adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms) 3119 { 3120 int ret; 3121 int i = 0; 3122 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3123 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3124 struct sta_info *psta; 3125 3126 3127 /* da == NULL, assume it's null data for sta to ap*/ 3128 if (!da) 3129 da = get_my_bssid(&(pmlmeinfo->network)); 3130 3131 psta = rtw_get_stainfo(&padapter->stapriv, da); 3132 if (psta) { 3133 if (power_mode) 3134 rtw_hal_macid_sleep(padapter, psta->mac_id); 3135 else 3136 rtw_hal_macid_wakeup(padapter, psta->mac_id); 3137 } else { 3138 rtw_warn_on(1); 3139 } 3140 3141 do { 3142 ret = _issue_nulldata(padapter, da, power_mode, wait_ms > 0); 3143 3144 i++; 3145 3146 if (padapter->bDriverStopped || padapter->bSurpriseRemoved) 3147 break; 3148 3149 if (i < try_cnt && wait_ms > 0 && ret == _FAIL) 3150 msleep(wait_ms); 3151 3152 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); 3153 3154 if (ret != _FAIL) { 3155 ret = _SUCCESS; 3156 #ifndef DBG_XMIT_ACK 3157 goto exit; 3158 #endif 3159 } 3160 3161 exit: 3162 return ret; 3163 } 3164 3165 /* 3166 * [IMPORTANT] This function run in interrupt context 3167 * 3168 * The null data packet would be sent without power bit, 3169 * and not guarantee success. 3170 */ 3171 s32 issue_nulldata_in_interrupt(struct adapter *padapter, u8 *da) 3172 { 3173 struct mlme_ext_priv *pmlmeext; 3174 struct mlme_ext_info *pmlmeinfo; 3175 3176 3177 pmlmeext = &padapter->mlmeextpriv; 3178 pmlmeinfo = &pmlmeext->mlmext_info; 3179 3180 /* da == NULL, assume it's null data for sta to ap*/ 3181 if (!da) 3182 da = get_my_bssid(&(pmlmeinfo->network)); 3183 3184 return _issue_nulldata(padapter, da, 0, false); 3185 } 3186 3187 /* when wait_ack is true, this function should be called at process context */ 3188 static int _issue_qos_nulldata(struct adapter *padapter, unsigned char *da, 3189 u16 tid, bool wait_ack) 3190 { 3191 int ret = _FAIL; 3192 struct xmit_frame *pmgntframe; 3193 struct pkt_attrib *pattrib; 3194 unsigned char *pframe; 3195 struct ieee80211_hdr *pwlanhdr; 3196 __le16 *fctrl; 3197 u16 *qc; 3198 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 3199 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3200 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3201 3202 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 3203 if (pmgntframe == NULL) 3204 goto exit; 3205 3206 /* update attribute */ 3207 pattrib = &pmgntframe->attrib; 3208 update_mgntframe_attrib(padapter, pattrib); 3209 3210 pattrib->hdrlen += 2; 3211 pattrib->qos_en = true; 3212 pattrib->eosp = 1; 3213 pattrib->ack_policy = 0; 3214 pattrib->mdata = 0; 3215 3216 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 3217 3218 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 3219 pwlanhdr = (struct ieee80211_hdr *)pframe; 3220 3221 fctrl = &(pwlanhdr->frame_control); 3222 *(fctrl) = 0; 3223 3224 if ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) 3225 SetFrDs(fctrl); 3226 else if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) 3227 SetToDs(fctrl); 3228 3229 if (pattrib->mdata) 3230 SetMData(fctrl); 3231 3232 qc = (unsigned short *)(pframe + pattrib->hdrlen - 2); 3233 3234 SetPriority(qc, tid); 3235 3236 SetEOSP(qc, pattrib->eosp); 3237 3238 SetAckpolicy(qc, pattrib->ack_policy); 3239 3240 memcpy(pwlanhdr->addr1, da, ETH_ALEN); 3241 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 3242 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3243 3244 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 3245 pmlmeext->mgnt_seq++; 3246 SetFrameSubType(pframe, WIFI_QOS_DATA_NULL); 3247 3248 pframe += sizeof(struct ieee80211_qos_hdr); 3249 pattrib->pktlen = sizeof(struct ieee80211_qos_hdr); 3250 3251 pattrib->last_txcmdsz = pattrib->pktlen; 3252 3253 if (wait_ack) { 3254 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); 3255 } else { 3256 dump_mgntframe(padapter, pmgntframe); 3257 ret = _SUCCESS; 3258 } 3259 3260 exit: 3261 return ret; 3262 } 3263 3264 /* when wait_ms >0 , this function should be called at process context */ 3265 /* da == NULL for station mode */ 3266 int issue_qos_nulldata(struct adapter *padapter, unsigned char *da, u16 tid, int try_cnt, int wait_ms) 3267 { 3268 int ret; 3269 int i = 0; 3270 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3271 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3272 3273 /* da == NULL, assume it's null data for sta to ap*/ 3274 if (!da) 3275 da = get_my_bssid(&(pmlmeinfo->network)); 3276 3277 do { 3278 ret = _issue_qos_nulldata(padapter, da, tid, wait_ms > 0); 3279 3280 i++; 3281 3282 if (padapter->bDriverStopped || padapter->bSurpriseRemoved) 3283 break; 3284 3285 if (i < try_cnt && wait_ms > 0 && ret == _FAIL) 3286 msleep(wait_ms); 3287 3288 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); 3289 3290 if (ret != _FAIL) { 3291 ret = _SUCCESS; 3292 #ifndef DBG_XMIT_ACK 3293 goto exit; 3294 #endif 3295 } 3296 3297 exit: 3298 return ret; 3299 } 3300 3301 static int _issue_deauth(struct adapter *padapter, unsigned char *da, 3302 unsigned short reason, bool wait_ack) 3303 { 3304 struct xmit_frame *pmgntframe; 3305 struct pkt_attrib *pattrib; 3306 unsigned char *pframe; 3307 struct ieee80211_hdr *pwlanhdr; 3308 __le16 *fctrl; 3309 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 3310 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3311 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3312 int ret = _FAIL; 3313 __le16 le_tmp; 3314 3315 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 3316 if (pmgntframe == NULL) { 3317 goto exit; 3318 } 3319 3320 /* update attribute */ 3321 pattrib = &pmgntframe->attrib; 3322 update_mgntframe_attrib(padapter, pattrib); 3323 pattrib->retry_ctrl = false; 3324 3325 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 3326 3327 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 3328 pwlanhdr = (struct ieee80211_hdr *)pframe; 3329 3330 fctrl = &(pwlanhdr->frame_control); 3331 *(fctrl) = 0; 3332 3333 memcpy(pwlanhdr->addr1, da, ETH_ALEN); 3334 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 3335 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3336 3337 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 3338 pmlmeext->mgnt_seq++; 3339 SetFrameSubType(pframe, WIFI_DEAUTH); 3340 3341 pframe += sizeof(struct ieee80211_hdr_3addr); 3342 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 3343 3344 le_tmp = cpu_to_le16(reason); 3345 pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_, (unsigned char *)&le_tmp, &(pattrib->pktlen)); 3346 3347 pattrib->last_txcmdsz = pattrib->pktlen; 3348 3349 3350 if (wait_ack) { 3351 ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe); 3352 } else { 3353 dump_mgntframe(padapter, pmgntframe); 3354 ret = _SUCCESS; 3355 } 3356 3357 exit: 3358 return ret; 3359 } 3360 3361 int issue_deauth(struct adapter *padapter, unsigned char *da, unsigned short reason) 3362 { 3363 return _issue_deauth(padapter, da, reason, false); 3364 } 3365 3366 int issue_deauth_ex(struct adapter *padapter, u8 *da, unsigned short reason, int try_cnt, 3367 int wait_ms) 3368 { 3369 int ret; 3370 int i = 0; 3371 3372 do { 3373 ret = _issue_deauth(padapter, da, reason, wait_ms > 0); 3374 3375 i++; 3376 3377 if (padapter->bDriverStopped || padapter->bSurpriseRemoved) 3378 break; 3379 3380 if (i < try_cnt && wait_ms > 0 && ret == _FAIL) 3381 mdelay(wait_ms); 3382 3383 } while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0))); 3384 3385 if (ret != _FAIL) { 3386 ret = _SUCCESS; 3387 #ifndef DBG_XMIT_ACK 3388 goto exit; 3389 #endif 3390 } 3391 3392 exit: 3393 return ret; 3394 } 3395 3396 void issue_action_SA_Query(struct adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid) 3397 { 3398 u8 category = RTW_WLAN_CATEGORY_SA_QUERY; 3399 struct xmit_frame *pmgntframe; 3400 struct pkt_attrib *pattrib; 3401 u8 *pframe; 3402 struct ieee80211_hdr *pwlanhdr; 3403 __le16 *fctrl; 3404 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 3405 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3406 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3407 __le16 le_tmp; 3408 3409 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 3410 if (!pmgntframe) 3411 return; 3412 3413 /* update attribute */ 3414 pattrib = &pmgntframe->attrib; 3415 update_mgntframe_attrib(padapter, pattrib); 3416 3417 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 3418 3419 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 3420 pwlanhdr = (struct ieee80211_hdr *)pframe; 3421 3422 fctrl = &(pwlanhdr->frame_control); 3423 *(fctrl) = 0; 3424 3425 if (raddr) 3426 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); 3427 else 3428 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3429 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 3430 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3431 3432 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 3433 pmlmeext->mgnt_seq++; 3434 SetFrameSubType(pframe, WIFI_ACTION); 3435 3436 pframe += sizeof(struct ieee80211_hdr_3addr); 3437 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 3438 3439 pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen); 3440 pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen); 3441 3442 switch (action) { 3443 case 0: /* SA Query req */ 3444 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen); 3445 pmlmeext->sa_query_seq++; 3446 /* send sa query request to AP, AP should reply sa query response in 1 second */ 3447 set_sa_query_timer(pmlmeext, 1000); 3448 break; 3449 3450 case 1: /* SA Query rsp */ 3451 le_tmp = cpu_to_le16(tid); 3452 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&le_tmp, &pattrib->pktlen); 3453 break; 3454 default: 3455 break; 3456 } 3457 3458 pattrib->last_txcmdsz = pattrib->pktlen; 3459 3460 dump_mgntframe(padapter, pmgntframe); 3461 } 3462 3463 void issue_action_BA(struct adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short status) 3464 { 3465 u8 category = RTW_WLAN_CATEGORY_BACK; 3466 u16 start_seq; 3467 u16 BA_para_set; 3468 u16 reason_code; 3469 u16 BA_timeout_value; 3470 u16 BA_starting_seqctrl = 0; 3471 enum ieee80211_max_ampdu_length_exp max_rx_ampdu_factor; 3472 struct xmit_frame *pmgntframe; 3473 struct pkt_attrib *pattrib; 3474 u8 *pframe; 3475 struct ieee80211_hdr *pwlanhdr; 3476 __le16 *fctrl; 3477 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 3478 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3479 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3480 struct sta_info *psta; 3481 struct sta_priv *pstapriv = &padapter->stapriv; 3482 struct registry_priv *pregpriv = &padapter->registrypriv; 3483 __le16 le_tmp; 3484 3485 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 3486 if (!pmgntframe) 3487 return; 3488 3489 /* update attribute */ 3490 pattrib = &pmgntframe->attrib; 3491 update_mgntframe_attrib(padapter, pattrib); 3492 3493 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 3494 3495 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 3496 pwlanhdr = (struct ieee80211_hdr *)pframe; 3497 3498 fctrl = &(pwlanhdr->frame_control); 3499 *(fctrl) = 0; 3500 3501 /* memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */ 3502 memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); 3503 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 3504 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3505 3506 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 3507 pmlmeext->mgnt_seq++; 3508 SetFrameSubType(pframe, WIFI_ACTION); 3509 3510 pframe += sizeof(struct ieee80211_hdr_3addr); 3511 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 3512 3513 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); 3514 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); 3515 3516 if (category == 3) { 3517 switch (action) { 3518 case 0: /* ADDBA req */ 3519 do { 3520 pmlmeinfo->dialogToken++; 3521 } while (pmlmeinfo->dialogToken == 0); 3522 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen)); 3523 3524 if (hal_btcoex_IsBTCoexCtrlAMPDUSize(padapter)) { 3525 /* A-MSDU NOT Supported */ 3526 BA_para_set = 0; 3527 /* immediate Block Ack */ 3528 BA_para_set |= BIT(1) & IEEE80211_ADDBA_PARAM_POLICY_MASK; 3529 /* TID */ 3530 BA_para_set |= (status << 2) & IEEE80211_ADDBA_PARAM_TID_MASK; 3531 /* max buffer size is 8 MSDU */ 3532 BA_para_set |= (8 << 6) & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK; 3533 } else { 3534 BA_para_set = (0x1002 | ((status & 0xf) << 2)); /* immediate ack & 64 buffer size */ 3535 } 3536 le_tmp = cpu_to_le16(BA_para_set); 3537 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen)); 3538 3539 BA_timeout_value = 5000;/* 5ms */ 3540 le_tmp = cpu_to_le16(BA_timeout_value); 3541 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen)); 3542 3543 /* if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL) */ 3544 psta = rtw_get_stainfo(pstapriv, raddr); 3545 if (psta) { 3546 start_seq = (psta->sta_xmitpriv.txseq_tid[status & 0x07]&0xfff) + 1; 3547 3548 psta->BA_starting_seqctrl[status & 0x07] = start_seq; 3549 3550 BA_starting_seqctrl = start_seq << 4; 3551 } 3552 3553 le_tmp = cpu_to_le16(BA_starting_seqctrl); 3554 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen)); 3555 break; 3556 3557 case 1: /* ADDBA rsp */ 3558 pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen)); 3559 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen)); 3560 if (padapter->driver_rx_ampdu_factor != 0xFF) 3561 max_rx_ampdu_factor = 3562 (enum ieee80211_max_ampdu_length_exp)padapter->driver_rx_ampdu_factor; 3563 else 3564 rtw_hal_get_def_var(padapter, 3565 HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); 3566 3567 if (IEEE80211_HT_MAX_AMPDU_64K == max_rx_ampdu_factor) 3568 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */ 3569 else if (IEEE80211_HT_MAX_AMPDU_32K == max_rx_ampdu_factor) 3570 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0800); /* 32 buffer size */ 3571 else if (IEEE80211_HT_MAX_AMPDU_16K == max_rx_ampdu_factor) 3572 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0400); /* 16 buffer size */ 3573 else if (IEEE80211_HT_MAX_AMPDU_8K == max_rx_ampdu_factor) 3574 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x0200); /* 8 buffer size */ 3575 else 3576 BA_para_set = ((le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set) & 0x3f) | 0x1000); /* 64 buffer size */ 3577 3578 if (hal_btcoex_IsBTCoexCtrlAMPDUSize(padapter) && 3579 padapter->driver_rx_ampdu_factor == 0xFF) { 3580 /* max buffer size is 8 MSDU */ 3581 BA_para_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK; 3582 BA_para_set |= (8 << 6) & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK; 3583 } 3584 3585 if (pregpriv->ampdu_amsdu == 0)/* disabled */ 3586 le_tmp = cpu_to_le16(BA_para_set & ~BIT(0)); 3587 else if (pregpriv->ampdu_amsdu == 1)/* enabled */ 3588 le_tmp = cpu_to_le16(BA_para_set | BIT(0)); 3589 else /* auto */ 3590 le_tmp = cpu_to_le16(BA_para_set); 3591 3592 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen)); 3593 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen)); 3594 break; 3595 case 2:/* DELBA */ 3596 BA_para_set = (status & 0x1F) << 3; 3597 le_tmp = cpu_to_le16(BA_para_set); 3598 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen)); 3599 3600 reason_code = 37; 3601 le_tmp = cpu_to_le16(reason_code); 3602 pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(le_tmp)), &(pattrib->pktlen)); 3603 break; 3604 default: 3605 break; 3606 } 3607 } 3608 3609 pattrib->last_txcmdsz = pattrib->pktlen; 3610 3611 dump_mgntframe(padapter, pmgntframe); 3612 } 3613 3614 static void issue_action_BSSCoexistPacket(struct adapter *padapter) 3615 { 3616 struct list_head *plist, *phead; 3617 unsigned char category, action; 3618 struct xmit_frame *pmgntframe; 3619 struct pkt_attrib *pattrib; 3620 unsigned char *pframe; 3621 struct ieee80211_hdr *pwlanhdr; 3622 __le16 *fctrl; 3623 struct wlan_network *pnetwork = NULL; 3624 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 3625 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 3626 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 3627 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3628 struct __queue *queue = &(pmlmepriv->scanned_queue); 3629 u8 InfoContent[16] = {0}; 3630 u8 ICS[8][15]; 3631 3632 if ((pmlmepriv->num_FortyMHzIntolerant == 0) || (pmlmepriv->num_sta_no_ht == 0)) 3633 return; 3634 3635 if (true == pmlmeinfo->bwmode_updated) 3636 return; 3637 3638 category = RTW_WLAN_CATEGORY_PUBLIC; 3639 action = ACT_PUBLIC_BSSCOEXIST; 3640 3641 pmgntframe = alloc_mgtxmitframe(pxmitpriv); 3642 if (pmgntframe == NULL) { 3643 return; 3644 } 3645 3646 /* update attribute */ 3647 pattrib = &pmgntframe->attrib; 3648 update_mgntframe_attrib(padapter, pattrib); 3649 3650 memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET); 3651 3652 pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET; 3653 pwlanhdr = (struct ieee80211_hdr *)pframe; 3654 3655 fctrl = &(pwlanhdr->frame_control); 3656 *(fctrl) = 0; 3657 3658 memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3659 memcpy(pwlanhdr->addr2, myid(&(padapter->eeprompriv)), ETH_ALEN); 3660 memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); 3661 3662 SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq); 3663 pmlmeext->mgnt_seq++; 3664 SetFrameSubType(pframe, WIFI_ACTION); 3665 3666 pframe += sizeof(struct ieee80211_hdr_3addr); 3667 pattrib->pktlen = sizeof(struct ieee80211_hdr_3addr); 3668 3669 pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen)); 3670 pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen)); 3671 3672 3673 /* */ 3674 if (pmlmepriv->num_FortyMHzIntolerant > 0) { 3675 u8 iedata = 0; 3676 3677 iedata |= BIT(2);/* 20 MHz BSS Width Request */ 3678 3679 pframe = rtw_set_ie(pframe, WLAN_EID_BSS_COEX_2040, 1, &iedata, &(pattrib->pktlen)); 3680 3681 } 3682 3683 3684 /* */ 3685 memset(ICS, 0, sizeof(ICS)); 3686 if (pmlmepriv->num_sta_no_ht > 0) { 3687 int i; 3688 3689 spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); 3690 3691 phead = get_list_head(queue); 3692 plist = get_next(phead); 3693 3694 while (1) { 3695 int len; 3696 u8 *p; 3697 struct wlan_bssid_ex *pbss_network; 3698 3699 if (phead == plist) 3700 break; 3701 3702 pnetwork = container_of(plist, struct wlan_network, list); 3703 3704 plist = get_next(plist); 3705 3706 pbss_network = (struct wlan_bssid_ex *)&pnetwork->network; 3707 3708 p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, WLAN_EID_HT_CAPABILITY, &len, pbss_network->IELength - _FIXED_IE_LENGTH_); 3709 if ((p == NULL) || (len == 0)) {/* non-HT */ 3710 3711 if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14)) 3712 continue; 3713 3714 ICS[0][pbss_network->Configuration.DSConfig] = 1; 3715 3716 if (ICS[0][0] == 0) 3717 ICS[0][0] = 1; 3718 } 3719 3720 } 3721 3722 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); 3723 3724 3725 for (i = 0; i < 8; i++) { 3726 if (ICS[i][0] == 1) { 3727 int j, k = 0; 3728 3729 InfoContent[k] = i; 3730 /* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent, i); */ 3731 k++; 3732 3733 for (j = 1; j <= 14; j++) { 3734 if (ICS[i][j] == 1) { 3735 if (k < 16) { 3736 InfoContent[k] = j; /* channel number */ 3737 /* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */ 3738 k++; 3739 } 3740 } 3741 } 3742 3743 pframe = rtw_set_ie(pframe, WLAN_EID_BSS_INTOLERANT_CHL_REPORT, k, InfoContent, &(pattrib->pktlen)); 3744 3745 } 3746 3747 } 3748 3749 3750 } 3751 3752 3753 pattrib->last_txcmdsz = pattrib->pktlen; 3754 3755 dump_mgntframe(padapter, pmgntframe); 3756 } 3757 3758 unsigned int send_delba(struct adapter *padapter, u8 initiator, u8 *addr) 3759 { 3760 struct sta_priv *pstapriv = &padapter->stapriv; 3761 struct sta_info *psta = NULL; 3762 /* struct recv_reorder_ctrl *preorder_ctrl; */ 3763 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 3764 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3765 u16 tid; 3766 3767 if ((pmlmeinfo->state&0x03) != WIFI_FW_AP_STATE) 3768 if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) 3769 return _SUCCESS; 3770 3771 psta = rtw_get_stainfo(pstapriv, addr); 3772 if (psta == NULL) 3773 return _SUCCESS; 3774 3775 if (initiator == 0) {/* recipient */ 3776 for (tid = 0; tid < MAXTID; tid++) { 3777 if (psta->recvreorder_ctrl[tid].enable) { 3778 issue_action_BA(padapter, addr, WLAN_ACTION_DELBA, (((tid << 1) | initiator)&0x1F)); 3779 psta->recvreorder_ctrl[tid].enable = false; 3780 psta->recvreorder_ctrl[tid].indicate_seq = 0xffff; 3781 } 3782 } 3783 } else if (initiator == 1) {/* originator */ 3784 for (tid = 0; tid < MAXTID; tid++) { 3785 if (psta->htpriv.agg_enable_bitmap & BIT(tid)) { 3786 issue_action_BA(padapter, addr, WLAN_ACTION_DELBA, (((tid << 1) | initiator)&0x1F)); 3787 psta->htpriv.agg_enable_bitmap &= ~BIT(tid); 3788 psta->htpriv.candidate_tid_bitmap &= ~BIT(tid); 3789 3790 } 3791 } 3792 } 3793 3794 return _SUCCESS; 3795 3796 } 3797 3798 unsigned int send_beacon(struct adapter *padapter) 3799 { 3800 u8 bxmitok = false; 3801 int issue = 0; 3802 int poll = 0; 3803 3804 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL); 3805 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL); 3806 do { 3807 issue_beacon(padapter, 100); 3808 issue++; 3809 do { 3810 cond_resched(); 3811 rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok)); 3812 poll++; 3813 } while ((poll%10) != 0 && false == bxmitok && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); 3814 3815 } while (false == bxmitok && issue < 100 && !padapter->bSurpriseRemoved && !padapter->bDriverStopped); 3816 3817 if (padapter->bSurpriseRemoved || padapter->bDriverStopped) { 3818 return _FAIL; 3819 } 3820 3821 3822 if (!bxmitok) 3823 return _FAIL; 3824 else 3825 return _SUCCESS; 3826 } 3827 3828 /**************************************************************************** 3829 3830 Following are some utility functions for WiFi MLME 3831 3832 *****************************************************************************/ 3833 3834 void site_survey(struct adapter *padapter) 3835 { 3836 unsigned char survey_channel = 0, val8; 3837 enum rt_scan_type ScanType = SCAN_PASSIVE; 3838 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 3839 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3840 u32 initialgain = 0; 3841 u32 channel_scan_time_ms = 0; 3842 3843 { 3844 struct rtw_ieee80211_channel *ch; 3845 3846 if (pmlmeext->sitesurvey_res.channel_idx < pmlmeext->sitesurvey_res.ch_num) { 3847 ch = &pmlmeext->sitesurvey_res.ch[pmlmeext->sitesurvey_res.channel_idx]; 3848 survey_channel = ch->hw_value; 3849 ScanType = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE; 3850 } 3851 } 3852 3853 if (survey_channel != 0) { 3854 /* PAUSE 4-AC Queue when site_survey */ 3855 /* rtw_hal_get_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */ 3856 /* val8 |= 0x0f; */ 3857 /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */ 3858 if (pmlmeext->sitesurvey_res.channel_idx == 0) { 3859 #ifdef DBG_FIXED_CHAN 3860 if (pmlmeext->fixed_chan != 0xff) 3861 set_channel_bwmode(padapter, pmlmeext->fixed_chan, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); 3862 else 3863 #endif 3864 set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); 3865 } else { 3866 #ifdef DBG_FIXED_CHAN 3867 if (pmlmeext->fixed_chan != 0xff) 3868 SelectChannel(padapter, pmlmeext->fixed_chan); 3869 else 3870 #endif 3871 SelectChannel(padapter, survey_channel); 3872 } 3873 3874 if (ScanType == SCAN_ACTIVE) { /* obey the channel plan setting... */ 3875 { 3876 int i; 3877 3878 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { 3879 if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) { 3880 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */ 3881 if (padapter->registrypriv.wifi_spec) 3882 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL); 3883 else 3884 issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0); 3885 issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL); 3886 } 3887 } 3888 3889 if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) { 3890 /* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */ 3891 if (padapter->registrypriv.wifi_spec) 3892 issue_probereq(padapter, NULL, NULL); 3893 else 3894 issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0); 3895 issue_probereq(padapter, NULL, NULL); 3896 } 3897 } 3898 } 3899 3900 channel_scan_time_ms = pmlmeext->chan_scan_time; 3901 3902 set_survey_timer(pmlmeext, channel_scan_time_ms); 3903 } else { 3904 3905 /* channel number is 0 or this channel is not valid. */ 3906 3907 { 3908 pmlmeext->sitesurvey_res.state = SCAN_COMPLETE; 3909 3910 /* switch back to the original channel */ 3911 /* SelectChannel(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset); */ 3912 3913 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); 3914 3915 /* flush 4-AC Queue after site_survey */ 3916 /* val8 = 0; */ 3917 /* rtw_hal_set_hwreg(padapter, HW_VAR_TXPAUSE, (u8 *)(&val8)); */ 3918 3919 /* config MSR */ 3920 Set_MSR(padapter, (pmlmeinfo->state & 0x3)); 3921 3922 initialgain = 0xff; /* restore RX GAIN */ 3923 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); 3924 /* turn on dynamic functions */ 3925 Restore_DM_Func_Flag(padapter); 3926 /* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); */ 3927 3928 if (is_client_associated_to_ap(padapter)) 3929 issue_nulldata(padapter, NULL, 0, 3, 500); 3930 3931 val8 = 0; /* survey done */ 3932 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); 3933 3934 report_surveydone_event(padapter); 3935 3936 pmlmeext->chan_scan_time = SURVEY_TO; 3937 pmlmeext->sitesurvey_res.state = SCAN_DISABLE; 3938 3939 issue_action_BSSCoexistPacket(padapter); 3940 issue_action_BSSCoexistPacket(padapter); 3941 issue_action_BSSCoexistPacket(padapter); 3942 } 3943 } 3944 3945 return; 3946 3947 } 3948 3949 /* collect bss info from Beacon and Probe request/response frames. */ 3950 u8 collect_bss_info(struct adapter *padapter, union recv_frame *precv_frame, struct wlan_bssid_ex *bssid) 3951 { 3952 int i; 3953 u32 len; 3954 u8 *p; 3955 u16 val16, subtype; 3956 u8 *pframe = precv_frame->u.hdr.rx_data; 3957 u32 packet_len = precv_frame->u.hdr.len; 3958 u8 ie_offset; 3959 struct registry_priv *pregistrypriv = &padapter->registrypriv; 3960 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 3961 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 3962 __le32 le32_tmp; 3963 3964 len = packet_len - sizeof(struct ieee80211_hdr_3addr); 3965 3966 if (len > MAX_IE_SZ) 3967 return _FAIL; 3968 3969 memset(bssid, 0, sizeof(struct wlan_bssid_ex)); 3970 3971 subtype = GetFrameSubType(pframe); 3972 3973 if (subtype == WIFI_BEACON) { 3974 bssid->Reserved[0] = 1; 3975 ie_offset = _BEACON_IE_OFFSET_; 3976 } else { 3977 /* FIXME : more type */ 3978 if (subtype == WIFI_PROBERSP) { 3979 ie_offset = _PROBERSP_IE_OFFSET_; 3980 bssid->Reserved[0] = 3; 3981 } else if (subtype == WIFI_PROBEREQ) { 3982 ie_offset = _PROBEREQ_IE_OFFSET_; 3983 bssid->Reserved[0] = 2; 3984 } else { 3985 bssid->Reserved[0] = 0; 3986 ie_offset = _FIXED_IE_LENGTH_; 3987 } 3988 } 3989 3990 bssid->Length = sizeof(struct wlan_bssid_ex) - MAX_IE_SZ + len; 3991 3992 /* below is to copy the information element */ 3993 bssid->IELength = len; 3994 memcpy(bssid->IEs, (pframe + sizeof(struct ieee80211_hdr_3addr)), bssid->IELength); 3995 3996 /* get the signal strength */ 3997 bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.RecvSignalPower; /* in dBM.raw data */ 3998 bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.SignalQuality;/* in percentage */ 3999 bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.SignalStrength;/* in percentage */ 4000 4001 /* checking SSID */ 4002 p = rtw_get_ie(bssid->IEs + ie_offset, WLAN_EID_SSID, &len, bssid->IELength - ie_offset); 4003 if (!p) 4004 return _FAIL; 4005 4006 if (*(p + 1)) { 4007 if (len > NDIS_802_11_LENGTH_SSID) 4008 return _FAIL; 4009 4010 memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1)); 4011 bssid->Ssid.SsidLength = *(p + 1); 4012 } else 4013 bssid->Ssid.SsidLength = 0; 4014 4015 memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX); 4016 4017 /* checking rate info... */ 4018 i = 0; 4019 p = rtw_get_ie(bssid->IEs + ie_offset, WLAN_EID_SUPP_RATES, &len, bssid->IELength - ie_offset); 4020 if (p) { 4021 if (len > NDIS_802_11_LENGTH_RATES_EX) 4022 return _FAIL; 4023 4024 memcpy(bssid->SupportedRates, (p + 2), len); 4025 i = len; 4026 } 4027 4028 p = rtw_get_ie(bssid->IEs + ie_offset, WLAN_EID_EXT_SUPP_RATES, &len, bssid->IELength - ie_offset); 4029 if (p) { 4030 if (len > (NDIS_802_11_LENGTH_RATES_EX-i)) 4031 return _FAIL; 4032 4033 memcpy(bssid->SupportedRates + i, (p + 2), len); 4034 } 4035 4036 bssid->NetworkTypeInUse = Ndis802_11OFDM24; 4037 4038 if (bssid->IELength < 12) 4039 return _FAIL; 4040 4041 /* Checking for DSConfig */ 4042 p = rtw_get_ie(bssid->IEs + ie_offset, WLAN_EID_DS_PARAMS, &len, bssid->IELength - ie_offset); 4043 4044 bssid->Configuration.DSConfig = 0; 4045 bssid->Configuration.Length = 0; 4046 4047 if (p) { 4048 bssid->Configuration.DSConfig = *(p + 2); 4049 } else { 4050 /* In 5G, some ap do not have DSSET IE */ 4051 /* checking HT info for channel */ 4052 p = rtw_get_ie(bssid->IEs + ie_offset, WLAN_EID_HT_OPERATION, &len, bssid->IELength - ie_offset); 4053 if (p) { 4054 struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2); 4055 4056 bssid->Configuration.DSConfig = HT_info->primary_channel; 4057 } else { /* use current channel */ 4058 bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter); 4059 } 4060 } 4061 4062 memcpy(&le32_tmp, rtw_get_beacon_interval_from_ie(bssid->IEs), 2); 4063 bssid->Configuration.BeaconPeriod = le32_to_cpu(le32_tmp); 4064 4065 val16 = rtw_get_capability((struct wlan_bssid_ex *)bssid); 4066 4067 if (val16 & BIT(0)) { 4068 bssid->InfrastructureMode = Ndis802_11Infrastructure; 4069 memcpy(bssid->MacAddress, GetAddr2Ptr(pframe), ETH_ALEN); 4070 } else { 4071 bssid->InfrastructureMode = Ndis802_11IBSS; 4072 memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN); 4073 } 4074 4075 if (val16 & BIT(4)) 4076 bssid->Privacy = 1; 4077 else 4078 bssid->Privacy = 0; 4079 4080 bssid->Configuration.ATIMWindow = 0; 4081 4082 /* 20/40 BSS Coexistence check */ 4083 if ((pregistrypriv->wifi_spec == 1) && (false == pmlmeinfo->bwmode_updated)) { 4084 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 4085 4086 p = rtw_get_ie(bssid->IEs + ie_offset, WLAN_EID_HT_CAPABILITY, &len, bssid->IELength - ie_offset); 4087 if (p && len > 0) { 4088 struct HT_caps_element *pHT_caps; 4089 4090 pHT_caps = (struct HT_caps_element *)(p + 2); 4091 4092 if (le16_to_cpu(pHT_caps->u.HT_cap_element.HT_caps_info) & BIT(14)) 4093 pmlmepriv->num_FortyMHzIntolerant++; 4094 } else 4095 pmlmepriv->num_sta_no_ht++; 4096 } 4097 4098 /* mark bss info receiving from nearby channel as SignalQuality 101 */ 4099 if (bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter)) 4100 bssid->PhyInfo.SignalQuality = 101; 4101 4102 return _SUCCESS; 4103 } 4104 4105 void start_create_ibss(struct adapter *padapter) 4106 { 4107 unsigned short caps; 4108 u8 val8; 4109 u8 join_type; 4110 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4111 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4112 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); 4113 4114 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig; 4115 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork); 4116 4117 /* update wireless mode */ 4118 update_wireless_mode(padapter); 4119 4120 /* update capability */ 4121 caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork); 4122 update_capinfo(padapter, caps); 4123 if (caps&WLAN_CAPABILITY_IBSS) {/* adhoc master */ 4124 val8 = 0xcf; 4125 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); 4126 4127 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL); 4128 4129 /* switch channel */ 4130 /* SelectChannel(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE); */ 4131 set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20); 4132 4133 beacon_timing_control(padapter); 4134 4135 /* set msr to WIFI_FW_ADHOC_STATE */ 4136 pmlmeinfo->state = WIFI_FW_ADHOC_STATE; 4137 Set_MSR(padapter, (pmlmeinfo->state & 0x3)); 4138 4139 /* issue beacon */ 4140 if (send_beacon(padapter) == _FAIL) { 4141 report_join_res(padapter, -1); 4142 pmlmeinfo->state = WIFI_FW_NULL_STATE; 4143 } else { 4144 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress); 4145 join_type = 0; 4146 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); 4147 4148 report_join_res(padapter, 1); 4149 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; 4150 rtw_indicate_connect(padapter); 4151 } 4152 } else { 4153 return; 4154 } 4155 /* update bc/mc sta_info */ 4156 update_bmc_sta(padapter); 4157 4158 } 4159 4160 void start_clnt_join(struct adapter *padapter) 4161 { 4162 unsigned short caps; 4163 u8 val8; 4164 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4165 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4166 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); 4167 int beacon_timeout; 4168 4169 /* update wireless mode */ 4170 update_wireless_mode(padapter); 4171 4172 /* update capability */ 4173 caps = rtw_get_capability((struct wlan_bssid_ex *)pnetwork); 4174 update_capinfo(padapter, caps); 4175 if (caps&WLAN_CAPABILITY_ESS) { 4176 Set_MSR(padapter, WIFI_FW_STATION_STATE); 4177 4178 val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf; 4179 4180 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); 4181 4182 /* Because of AP's not receiving deauth before */ 4183 /* AP may: 1)not response auth or 2)deauth us after link is complete */ 4184 /* issue deauth before issuing auth to deal with the situation */ 4185 4186 /* Commented by Albert 2012/07/21 */ 4187 /* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */ 4188 { 4189 /* To avoid connecting to AP fail during resume process, change retry count from 5 to 1 */ 4190 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100); 4191 } 4192 4193 /* here wait for receiving the beacon to start auth */ 4194 /* and enable a timer */ 4195 beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval); 4196 set_link_timer(pmlmeext, beacon_timeout); 4197 _set_timer(&padapter->mlmepriv.assoc_timer, 4198 (REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO*REASSOC_LIMIT) + beacon_timeout); 4199 4200 pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE; 4201 } else if (caps&WLAN_CAPABILITY_IBSS) { /* adhoc client */ 4202 Set_MSR(padapter, WIFI_FW_ADHOC_STATE); 4203 4204 val8 = 0xcf; 4205 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8)); 4206 4207 beacon_timing_control(padapter); 4208 4209 pmlmeinfo->state = WIFI_FW_ADHOC_STATE; 4210 4211 report_join_res(padapter, 1); 4212 } else { 4213 return; 4214 } 4215 4216 } 4217 4218 void start_clnt_auth(struct adapter *padapter) 4219 { 4220 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4221 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4222 4223 del_timer_sync(&pmlmeext->link_timer); 4224 4225 pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL); 4226 pmlmeinfo->state |= WIFI_FW_AUTH_STATE; 4227 4228 pmlmeinfo->auth_seq = 1; 4229 pmlmeinfo->reauth_count = 0; 4230 pmlmeinfo->reassoc_count = 0; 4231 pmlmeinfo->link_count = 0; 4232 pmlmeext->retry = 0; 4233 4234 4235 netdev_dbg(padapter->pnetdev, "start auth\n"); 4236 issue_auth(padapter, NULL, 0); 4237 4238 set_link_timer(pmlmeext, REAUTH_TO); 4239 4240 } 4241 4242 4243 void start_clnt_assoc(struct adapter *padapter) 4244 { 4245 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4246 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4247 4248 del_timer_sync(&pmlmeext->link_timer); 4249 4250 pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE)); 4251 pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE); 4252 4253 issue_assocreq(padapter); 4254 4255 set_link_timer(pmlmeext, REASSOC_TO); 4256 } 4257 4258 unsigned int receive_disconnect(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason) 4259 { 4260 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4261 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4262 4263 /* check A3 */ 4264 if (!(!memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN))) 4265 return _SUCCESS; 4266 4267 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) { 4268 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { 4269 pmlmeinfo->state = WIFI_FW_NULL_STATE; 4270 report_del_sta_event(padapter, MacAddr, reason); 4271 4272 } else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) { 4273 pmlmeinfo->state = WIFI_FW_NULL_STATE; 4274 report_join_res(padapter, -2); 4275 } 4276 } 4277 4278 return _SUCCESS; 4279 } 4280 4281 static void process_80211d(struct adapter *padapter, struct wlan_bssid_ex *bssid) 4282 { 4283 struct registry_priv *pregistrypriv; 4284 struct mlme_ext_priv *pmlmeext; 4285 struct rt_channel_info *chplan_new; 4286 u8 channel; 4287 u8 i; 4288 4289 4290 pregistrypriv = &padapter->registrypriv; 4291 pmlmeext = &padapter->mlmeextpriv; 4292 4293 /* Adjust channel plan by AP Country IE */ 4294 if (pregistrypriv->enable80211d && 4295 (!pmlmeext->update_channel_plan_by_ap_done)) { 4296 u8 *ie, *p; 4297 u32 len; 4298 struct rt_channel_plan chplan_ap; 4299 struct rt_channel_info chplan_sta[MAX_CHANNEL_NUM]; 4300 u8 country[4]; 4301 u8 fcn; /* first channel number */ 4302 u8 noc; /* number of channel */ 4303 u8 j, k; 4304 4305 ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, WLAN_EID_COUNTRY, &len, bssid->IELength - _FIXED_IE_LENGTH_); 4306 if (!ie) 4307 return; 4308 if (len < 6) 4309 return; 4310 4311 ie += 2; 4312 p = ie; 4313 ie += len; 4314 4315 memset(country, 0, 4); 4316 memcpy(country, p, 3); 4317 p += 3; 4318 4319 i = 0; 4320 while ((ie - p) >= 3) { 4321 fcn = *(p++); 4322 noc = *(p++); 4323 p++; 4324 4325 for (j = 0; j < noc; j++) { 4326 if (fcn <= 14) 4327 channel = fcn + j; /* 2.4 GHz */ 4328 else 4329 channel = fcn + j*4; /* 5 GHz */ 4330 4331 chplan_ap.Channel[i++] = channel; 4332 } 4333 } 4334 chplan_ap.Len = i; 4335 4336 memcpy(chplan_sta, pmlmeext->channel_set, sizeof(chplan_sta)); 4337 4338 memset(pmlmeext->channel_set, 0, sizeof(pmlmeext->channel_set)); 4339 chplan_new = pmlmeext->channel_set; 4340 4341 i = j = k = 0; 4342 if (pregistrypriv->wireless_mode & WIRELESS_11G) { 4343 do { 4344 if ((i == MAX_CHANNEL_NUM) || 4345 (chplan_sta[i].ChannelNum == 0) || 4346 (chplan_sta[i].ChannelNum > 14)) 4347 break; 4348 4349 if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14)) 4350 break; 4351 4352 if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) { 4353 chplan_new[k].ChannelNum = chplan_ap.Channel[j]; 4354 chplan_new[k].ScanType = SCAN_ACTIVE; 4355 i++; 4356 j++; 4357 k++; 4358 } else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) { 4359 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; 4360 /* chplan_new[k].ScanType = chplan_sta[i].ScanType; */ 4361 chplan_new[k].ScanType = SCAN_PASSIVE; 4362 i++; 4363 k++; 4364 } else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) { 4365 chplan_new[k].ChannelNum = chplan_ap.Channel[j]; 4366 chplan_new[k].ScanType = SCAN_ACTIVE; 4367 j++; 4368 k++; 4369 } 4370 } while (1); 4371 4372 /* change AP not support channel to Passive scan */ 4373 while ((i < MAX_CHANNEL_NUM) && 4374 (chplan_sta[i].ChannelNum != 0) && 4375 (chplan_sta[i].ChannelNum <= 14)) { 4376 4377 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; 4378 /* chplan_new[k].ScanType = chplan_sta[i].ScanType; */ 4379 chplan_new[k].ScanType = SCAN_PASSIVE; 4380 i++; 4381 k++; 4382 } 4383 4384 /* add channel AP supported */ 4385 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) { 4386 chplan_new[k].ChannelNum = chplan_ap.Channel[j]; 4387 chplan_new[k].ScanType = SCAN_ACTIVE; 4388 j++; 4389 k++; 4390 } 4391 } else { 4392 /* keep original STA 2.4G channel plan */ 4393 while ((i < MAX_CHANNEL_NUM) && 4394 (chplan_sta[i].ChannelNum != 0) && 4395 (chplan_sta[i].ChannelNum <= 14)) { 4396 chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum; 4397 chplan_new[k].ScanType = chplan_sta[i].ScanType; 4398 i++; 4399 k++; 4400 } 4401 4402 /* skip AP 2.4G channel plan */ 4403 while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) { 4404 j++; 4405 } 4406 } 4407 4408 pmlmeext->update_channel_plan_by_ap_done = 1; 4409 } 4410 4411 /* If channel is used by AP, set channel scan type to active */ 4412 channel = bssid->Configuration.DSConfig; 4413 chplan_new = pmlmeext->channel_set; 4414 i = 0; 4415 while ((i < MAX_CHANNEL_NUM) && (chplan_new[i].ChannelNum != 0)) { 4416 if (chplan_new[i].ChannelNum == channel) { 4417 if (chplan_new[i].ScanType == SCAN_PASSIVE) { 4418 chplan_new[i].ScanType = SCAN_ACTIVE; 4419 } 4420 break; 4421 } 4422 i++; 4423 } 4424 } 4425 4426 /**************************************************************************** 4427 4428 Following are the functions to report events 4429 4430 *****************************************************************************/ 4431 4432 void report_survey_event(struct adapter *padapter, union recv_frame *precv_frame) 4433 { 4434 struct cmd_obj *pcmd_obj; 4435 u8 *pevtcmd; 4436 u32 cmdsz; 4437 struct survey_event *psurvey_evt; 4438 struct C2HEvent_Header *pc2h_evt_hdr; 4439 struct mlme_ext_priv *pmlmeext; 4440 struct cmd_priv *pcmdpriv; 4441 /* u8 *pframe = precv_frame->u.hdr.rx_data; */ 4442 /* uint len = precv_frame->u.hdr.len; */ 4443 4444 if (!padapter) 4445 return; 4446 4447 pmlmeext = &padapter->mlmeextpriv; 4448 pcmdpriv = &padapter->cmdpriv; 4449 4450 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); 4451 if (!pcmd_obj) 4452 return; 4453 4454 cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header)); 4455 pevtcmd = rtw_zmalloc(cmdsz); 4456 if (!pevtcmd) { 4457 kfree(pcmd_obj); 4458 return; 4459 } 4460 4461 INIT_LIST_HEAD(&pcmd_obj->list); 4462 4463 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); 4464 pcmd_obj->cmdsz = cmdsz; 4465 pcmd_obj->parmbuf = pevtcmd; 4466 4467 pcmd_obj->rsp = NULL; 4468 pcmd_obj->rspsz = 0; 4469 4470 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); 4471 pc2h_evt_hdr->len = sizeof(struct survey_event); 4472 pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey); 4473 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); 4474 4475 psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); 4476 4477 if (collect_bss_info(padapter, precv_frame, (struct wlan_bssid_ex *)&psurvey_evt->bss) == _FAIL) { 4478 kfree(pcmd_obj); 4479 kfree(pevtcmd); 4480 return; 4481 } 4482 4483 process_80211d(padapter, &psurvey_evt->bss); 4484 4485 rtw_enqueue_cmd(pcmdpriv, pcmd_obj); 4486 4487 pmlmeext->sitesurvey_res.bss_cnt++; 4488 4489 return; 4490 4491 } 4492 4493 void report_surveydone_event(struct adapter *padapter) 4494 { 4495 struct cmd_obj *pcmd_obj; 4496 u8 *pevtcmd; 4497 u32 cmdsz; 4498 struct surveydone_event *psurveydone_evt; 4499 struct C2HEvent_Header *pc2h_evt_hdr; 4500 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4501 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 4502 4503 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); 4504 if (!pcmd_obj) 4505 return; 4506 4507 cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header)); 4508 pevtcmd = rtw_zmalloc(cmdsz); 4509 if (!pevtcmd) { 4510 kfree(pcmd_obj); 4511 return; 4512 } 4513 4514 INIT_LIST_HEAD(&pcmd_obj->list); 4515 4516 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); 4517 pcmd_obj->cmdsz = cmdsz; 4518 pcmd_obj->parmbuf = pevtcmd; 4519 4520 pcmd_obj->rsp = NULL; 4521 pcmd_obj->rspsz = 0; 4522 4523 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); 4524 pc2h_evt_hdr->len = sizeof(struct surveydone_event); 4525 pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone); 4526 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); 4527 4528 psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); 4529 psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt; 4530 4531 rtw_enqueue_cmd(pcmdpriv, pcmd_obj); 4532 4533 return; 4534 4535 } 4536 4537 void report_join_res(struct adapter *padapter, int res) 4538 { 4539 struct cmd_obj *pcmd_obj; 4540 u8 *pevtcmd; 4541 u32 cmdsz; 4542 struct joinbss_event *pjoinbss_evt; 4543 struct C2HEvent_Header *pc2h_evt_hdr; 4544 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4545 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4546 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 4547 4548 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); 4549 if (!pcmd_obj) 4550 return; 4551 4552 cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header)); 4553 pevtcmd = rtw_zmalloc(cmdsz); 4554 if (!pevtcmd) { 4555 kfree(pcmd_obj); 4556 return; 4557 } 4558 4559 INIT_LIST_HEAD(&pcmd_obj->list); 4560 4561 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); 4562 pcmd_obj->cmdsz = cmdsz; 4563 pcmd_obj->parmbuf = pevtcmd; 4564 4565 pcmd_obj->rsp = NULL; 4566 pcmd_obj->rspsz = 0; 4567 4568 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); 4569 pc2h_evt_hdr->len = sizeof(struct joinbss_event); 4570 pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss); 4571 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); 4572 4573 pjoinbss_evt = (struct joinbss_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); 4574 memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(struct wlan_bssid_ex)); 4575 pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = res; 4576 4577 4578 rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network); 4579 4580 4581 rtw_enqueue_cmd(pcmdpriv, pcmd_obj); 4582 4583 return; 4584 4585 } 4586 4587 void report_wmm_edca_update(struct adapter *padapter) 4588 { 4589 struct cmd_obj *pcmd_obj; 4590 u8 *pevtcmd; 4591 u32 cmdsz; 4592 struct wmm_event *pwmm_event; 4593 struct C2HEvent_Header *pc2h_evt_hdr; 4594 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4595 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 4596 4597 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); 4598 if (!pcmd_obj) 4599 return; 4600 4601 cmdsz = (sizeof(struct wmm_event) + sizeof(struct C2HEvent_Header)); 4602 pevtcmd = rtw_zmalloc(cmdsz); 4603 if (!pevtcmd) { 4604 kfree(pcmd_obj); 4605 return; 4606 } 4607 4608 INIT_LIST_HEAD(&pcmd_obj->list); 4609 4610 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); 4611 pcmd_obj->cmdsz = cmdsz; 4612 pcmd_obj->parmbuf = pevtcmd; 4613 4614 pcmd_obj->rsp = NULL; 4615 pcmd_obj->rspsz = 0; 4616 4617 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); 4618 pc2h_evt_hdr->len = sizeof(struct wmm_event); 4619 pc2h_evt_hdr->ID = GEN_EVT_CODE(_WMM); 4620 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); 4621 4622 pwmm_event = (struct wmm_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); 4623 pwmm_event->wmm = 0; 4624 4625 rtw_enqueue_cmd(pcmdpriv, pcmd_obj); 4626 4627 return; 4628 4629 } 4630 4631 void report_del_sta_event(struct adapter *padapter, unsigned char *MacAddr, unsigned short reason) 4632 { 4633 struct cmd_obj *pcmd_obj; 4634 u8 *pevtcmd; 4635 u32 cmdsz; 4636 struct sta_info *psta; 4637 int mac_id; 4638 struct stadel_event *pdel_sta_evt; 4639 struct C2HEvent_Header *pc2h_evt_hdr; 4640 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4641 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 4642 4643 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); 4644 if (pcmd_obj == NULL) { 4645 return; 4646 } 4647 4648 cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header)); 4649 pevtcmd = rtw_zmalloc(cmdsz); 4650 if (pevtcmd == NULL) { 4651 kfree(pcmd_obj); 4652 return; 4653 } 4654 4655 INIT_LIST_HEAD(&pcmd_obj->list); 4656 4657 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); 4658 pcmd_obj->cmdsz = cmdsz; 4659 pcmd_obj->parmbuf = pevtcmd; 4660 4661 pcmd_obj->rsp = NULL; 4662 pcmd_obj->rspsz = 0; 4663 4664 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); 4665 pc2h_evt_hdr->len = sizeof(struct stadel_event); 4666 pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA); 4667 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); 4668 4669 pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); 4670 memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN); 4671 memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2); 4672 4673 4674 psta = rtw_get_stainfo(&padapter->stapriv, MacAddr); 4675 if (psta) 4676 mac_id = (int)psta->mac_id; 4677 else 4678 mac_id = (-1); 4679 4680 pdel_sta_evt->mac_id = mac_id; 4681 4682 rtw_enqueue_cmd(pcmdpriv, pcmd_obj); 4683 } 4684 4685 void report_add_sta_event(struct adapter *padapter, unsigned char *MacAddr, int cam_idx) 4686 { 4687 struct cmd_obj *pcmd_obj; 4688 u8 *pevtcmd; 4689 u32 cmdsz; 4690 struct stassoc_event *padd_sta_evt; 4691 struct C2HEvent_Header *pc2h_evt_hdr; 4692 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4693 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 4694 4695 pcmd_obj = rtw_zmalloc(sizeof(struct cmd_obj)); 4696 if (pcmd_obj == NULL) 4697 return; 4698 4699 cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header)); 4700 pevtcmd = rtw_zmalloc(cmdsz); 4701 if (pevtcmd == NULL) { 4702 kfree(pcmd_obj); 4703 return; 4704 } 4705 4706 INIT_LIST_HEAD(&pcmd_obj->list); 4707 4708 pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT); 4709 pcmd_obj->cmdsz = cmdsz; 4710 pcmd_obj->parmbuf = pevtcmd; 4711 4712 pcmd_obj->rsp = NULL; 4713 pcmd_obj->rspsz = 0; 4714 4715 pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd); 4716 pc2h_evt_hdr->len = sizeof(struct stassoc_event); 4717 pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA); 4718 pc2h_evt_hdr->seq = atomic_inc_return(&pmlmeext->event_seq); 4719 4720 padd_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct C2HEvent_Header)); 4721 memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN); 4722 padd_sta_evt->cam_id = cam_idx; 4723 4724 rtw_enqueue_cmd(pcmdpriv, pcmd_obj); 4725 } 4726 4727 /**************************************************************************** 4728 4729 Following are the event callback functions 4730 4731 *****************************************************************************/ 4732 4733 /* for sta/adhoc mode */ 4734 void update_sta_info(struct adapter *padapter, struct sta_info *psta) 4735 { 4736 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 4737 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4738 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4739 4740 /* ERP */ 4741 VCS_update(padapter, psta); 4742 4743 /* HT */ 4744 if (pmlmepriv->htpriv.ht_option) { 4745 psta->htpriv.ht_option = true; 4746 4747 psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable; 4748 4749 psta->htpriv.rx_ampdu_min_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para&IEEE80211_HT_CAP_AMPDU_DENSITY)>>2; 4750 4751 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_20)) 4752 psta->htpriv.sgi_20m = true; 4753 4754 if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_40)) 4755 psta->htpriv.sgi_40m = true; 4756 4757 psta->qos_option = true; 4758 4759 psta->htpriv.ldpc_cap = pmlmepriv->htpriv.ldpc_cap; 4760 psta->htpriv.stbc_cap = pmlmepriv->htpriv.stbc_cap; 4761 psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap; 4762 4763 memcpy(&psta->htpriv.ht_cap, &pmlmeinfo->HT_caps, sizeof(struct ieee80211_ht_cap)); 4764 } else { 4765 psta->htpriv.ht_option = false; 4766 4767 psta->htpriv.ampdu_enable = false; 4768 4769 psta->htpriv.sgi_20m = false; 4770 psta->htpriv.sgi_40m = false; 4771 psta->qos_option = false; 4772 4773 } 4774 4775 psta->htpriv.ch_offset = pmlmeext->cur_ch_offset; 4776 4777 psta->htpriv.agg_enable_bitmap = 0x0;/* reset */ 4778 psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */ 4779 4780 psta->bw_mode = pmlmeext->cur_bwmode; 4781 4782 /* QoS */ 4783 if (pmlmepriv->qospriv.qos_option) 4784 psta->qos_option = true; 4785 4786 update_ldpc_stbc_cap(psta); 4787 4788 spin_lock_bh(&psta->lock); 4789 psta->state = _FW_LINKED; 4790 spin_unlock_bh(&psta->lock); 4791 4792 } 4793 4794 static void rtw_mlmeext_disconnect(struct adapter *padapter) 4795 { 4796 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 4797 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4798 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4799 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); 4800 4801 /* set_opmode_cmd(padapter, infra_client_with_mlme); */ 4802 4803 /* For safety, prevent from keeping macid sleep. 4804 * If we can sure all power mode enter/leave are paired, 4805 * this check can be removed. 4806 * Lucas@20131113 4807 */ 4808 /* wakeup macid after disconnect. */ 4809 { 4810 struct sta_info *psta; 4811 4812 psta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(pnetwork)); 4813 if (psta) 4814 rtw_hal_macid_wakeup(padapter, psta->mac_id); 4815 } 4816 4817 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL); 4818 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr); 4819 4820 /* set MSR to no link state -> infra. mode */ 4821 Set_MSR(padapter, _HW_STATE_STATION_); 4822 4823 pmlmeinfo->state = WIFI_FW_NULL_STATE; 4824 4825 /* switch to the 20M Hz mode after disconnect */ 4826 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20; 4827 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; 4828 4829 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); 4830 4831 flush_all_cam_entry(padapter); 4832 4833 del_timer_sync(&pmlmeext->link_timer); 4834 4835 /* pmlmepriv->LinkDetectInfo.TrafficBusyState = false; */ 4836 pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0; 4837 pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0; 4838 4839 } 4840 4841 void mlmeext_joinbss_event_callback(struct adapter *padapter, int join_res) 4842 { 4843 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4844 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4845 struct wlan_bssid_ex *cur_network = &(pmlmeinfo->network); 4846 struct sta_priv *pstapriv = &padapter->stapriv; 4847 u8 join_type; 4848 struct sta_info *psta; 4849 4850 if (join_res < 0) { 4851 join_type = 1; 4852 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); 4853 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr); 4854 4855 return; 4856 } 4857 4858 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) 4859 /* update bc/mc sta_info */ 4860 update_bmc_sta(padapter); 4861 4862 4863 /* turn on dynamic functions */ 4864 Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, true); 4865 4866 /* update IOT-related issue */ 4867 update_IOT_info(padapter); 4868 4869 rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates); 4870 4871 /* BCN interval */ 4872 rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval)); 4873 4874 /* update capability */ 4875 update_capinfo(padapter, pmlmeinfo->capability); 4876 4877 /* WMM, Update EDCA param */ 4878 WMMOnAssocRsp(padapter); 4879 4880 /* HT */ 4881 HTOnAssocRsp(padapter); 4882 4883 /* Set cur_channel&cur_bwmode&cur_ch_offset */ 4884 set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode); 4885 4886 psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress); 4887 if (psta) { /* only for infra. mode */ 4888 4889 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta; 4890 4891 psta->wireless_mode = pmlmeext->cur_wireless_mode; 4892 4893 /* set per sta rate after updating HT cap. */ 4894 set_sta_rate(padapter, psta); 4895 4896 rtw_sta_media_status_rpt(padapter, psta, 1); 4897 4898 /* wakeup macid after join bss successfully to ensure 4899 the subsequent data frames can be sent out normally */ 4900 rtw_hal_macid_wakeup(padapter, psta->mac_id); 4901 } 4902 4903 join_type = 2; 4904 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); 4905 4906 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) { 4907 /* correcting TSF */ 4908 correct_TSF(padapter, pmlmeext); 4909 4910 /* set_link_timer(pmlmeext, DISCONNECT_TO); */ 4911 } 4912 4913 if (get_iface_type(padapter) == IFACE_PORT0) 4914 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, 0); 4915 } 4916 4917 /* currently only adhoc mode will go here */ 4918 void mlmeext_sta_add_event_callback(struct adapter *padapter, struct sta_info *psta) 4919 { 4920 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv); 4921 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4922 u8 join_type; 4923 4924 if ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) { 4925 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { /* adhoc master or sta_count>1 */ 4926 4927 /* nothing to do */ 4928 } else { /* adhoc client */ 4929 /* update TSF Value */ 4930 /* update_TSF(pmlmeext, pframe, len); */ 4931 4932 /* correcting TSF */ 4933 correct_TSF(padapter, pmlmeext); 4934 4935 /* start beacon */ 4936 if (send_beacon(padapter) == _FAIL) { 4937 pmlmeinfo->FW_sta_info[psta->mac_id].status = 0; 4938 4939 pmlmeinfo->state ^= WIFI_FW_ADHOC_STATE; 4940 4941 return; 4942 } 4943 4944 pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS; 4945 4946 } 4947 4948 join_type = 2; 4949 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); 4950 } 4951 4952 pmlmeinfo->FW_sta_info[psta->mac_id].psta = psta; 4953 4954 psta->bssratelen = rtw_get_rateset_len(pmlmeinfo->FW_sta_info[psta->mac_id].SupportedRates); 4955 memcpy(psta->bssrateset, pmlmeinfo->FW_sta_info[psta->mac_id].SupportedRates, psta->bssratelen); 4956 4957 /* update adhoc sta_info */ 4958 update_sta_info(padapter, psta); 4959 4960 rtw_hal_update_sta_rate_mask(padapter, psta); 4961 4962 /* ToDo: HT for Ad-hoc */ 4963 psta->wireless_mode = rtw_check_network_type(psta->bssrateset, psta->bssratelen, pmlmeext->cur_channel); 4964 psta->raid = networktype_to_raid_ex(padapter, psta); 4965 4966 /* rate radaptive */ 4967 Update_RA_Entry(padapter, psta); 4968 } 4969 4970 void mlmeext_sta_del_event_callback(struct adapter *padapter) 4971 { 4972 if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter)) 4973 rtw_mlmeext_disconnect(padapter); 4974 } 4975 4976 /**************************************************************************** 4977 4978 Following are the functions for the timer handlers 4979 4980 *****************************************************************************/ 4981 void _linked_info_dump(struct adapter *padapter) 4982 { 4983 int i; 4984 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 4985 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 4986 int UndecoratedSmoothedPWDB; 4987 struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); 4988 4989 if (padapter->bLinkInfoDump) { 4990 4991 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE) 4992 rtw_hal_get_def_var(padapter, HAL_DEF_UNDERCORATEDSMOOTHEDPWDB, &UndecoratedSmoothedPWDB); 4993 4994 for (i = 0; i < NUM_STA; i++) { 4995 if (pdvobj->macid[i]) { 4996 if (i != 1) /* skip bc/mc sta */ 4997 /* tx info ============ */ 4998 rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, &i); 4999 } 5000 } 5001 rtw_hal_set_def_var(padapter, HAL_DEF_DBG_RX_INFO_DUMP, NULL); 5002 } 5003 } 5004 5005 static u8 chk_ap_is_alive(struct adapter *padapter, struct sta_info *psta) 5006 { 5007 u8 ret = false; 5008 5009 if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)) 5010 && sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta) 5011 && sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta) 5012 ) { 5013 ret = false; 5014 } else { 5015 ret = true; 5016 } 5017 5018 sta_update_last_rx_pkts(psta); 5019 5020 return ret; 5021 } 5022 5023 void linked_status_chk(struct adapter *padapter) 5024 { 5025 u32 i; 5026 struct sta_info *psta; 5027 struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); 5028 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5029 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5030 struct sta_priv *pstapriv = &padapter->stapriv; 5031 5032 5033 if (is_client_associated_to_ap(padapter)) { 5034 /* linked infrastructure client mode */ 5035 5036 int tx_chk = _SUCCESS, rx_chk = _SUCCESS; 5037 int rx_chk_limit; 5038 int link_count_limit; 5039 5040 #if defined(DBG_ROAMING_TEST) 5041 rx_chk_limit = 1; 5042 #else 5043 rx_chk_limit = 8; 5044 #endif 5045 link_count_limit = 7; /* 16 sec */ 5046 5047 /* Marked by Kurt 20130715 */ 5048 /* For WiDi 3.5 and latered on, they don't ask WiDi sink to do roaming, so we could not check rx limit that strictly. */ 5049 /* todo: To check why we under miracast session, rx_chk would be false */ 5050 psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress); 5051 if (psta) { 5052 if (chk_ap_is_alive(padapter, psta) == false) 5053 rx_chk = _FAIL; 5054 5055 if (pxmitpriv->last_tx_pkts == pxmitpriv->tx_pkts) 5056 tx_chk = _FAIL; 5057 5058 { 5059 if (rx_chk != _SUCCESS) { 5060 if (pmlmeext->retry == 0) { 5061 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0); 5062 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0); 5063 issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, 0); 5064 } 5065 } 5066 5067 if (tx_chk != _SUCCESS && 5068 pmlmeinfo->link_count++ == link_count_limit) 5069 tx_chk = issue_nulldata_in_interrupt(padapter, NULL); 5070 } 5071 5072 if (rx_chk == _FAIL) { 5073 pmlmeext->retry++; 5074 if (pmlmeext->retry > rx_chk_limit) { 5075 netdev_dbg(padapter->pnetdev, 5076 FUNC_ADPT_FMT " disconnect or roaming\n", 5077 FUNC_ADPT_ARG(padapter)); 5078 receive_disconnect(padapter, pmlmeinfo->network.MacAddress 5079 , WLAN_REASON_EXPIRATION_CHK); 5080 return; 5081 } 5082 } else { 5083 pmlmeext->retry = 0; 5084 } 5085 5086 if (tx_chk == _FAIL) { 5087 pmlmeinfo->link_count %= (link_count_limit+1); 5088 } else { 5089 pxmitpriv->last_tx_pkts = pxmitpriv->tx_pkts; 5090 pmlmeinfo->link_count = 0; 5091 } 5092 5093 } /* end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) */ 5094 } else if (is_client_associated_to_ibss(padapter)) { 5095 /* linked IBSS mode */ 5096 /* for each assoc list entry to check the rx pkt counter */ 5097 for (i = IBSS_START_MAC_ID; i < NUM_STA; i++) { 5098 if (pmlmeinfo->FW_sta_info[i].status == 1) { 5099 psta = pmlmeinfo->FW_sta_info[i].psta; 5100 5101 if (NULL == psta) 5102 continue; 5103 5104 if (pmlmeinfo->FW_sta_info[i].rx_pkt == sta_rx_pkts(psta)) { 5105 5106 if (pmlmeinfo->FW_sta_info[i].retry < 3) { 5107 pmlmeinfo->FW_sta_info[i].retry++; 5108 } else { 5109 pmlmeinfo->FW_sta_info[i].retry = 0; 5110 pmlmeinfo->FW_sta_info[i].status = 0; 5111 report_del_sta_event(padapter, psta->hwaddr 5112 , 65535/* indicate disconnect caused by no rx */ 5113 ); 5114 } 5115 } else { 5116 pmlmeinfo->FW_sta_info[i].retry = 0; 5117 pmlmeinfo->FW_sta_info[i].rx_pkt = (u32)sta_rx_pkts(psta); 5118 } 5119 } 5120 } 5121 5122 /* set_link_timer(pmlmeext, DISCONNECT_TO); */ 5123 5124 } 5125 5126 } 5127 5128 void survey_timer_hdl(struct timer_list *t) 5129 { 5130 struct adapter *padapter = 5131 from_timer(padapter, t, mlmeextpriv.survey_timer); 5132 struct cmd_obj *ph2c; 5133 struct sitesurvey_parm *psurveyPara; 5134 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 5135 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5136 5137 /* issue rtw_sitesurvey_cmd */ 5138 if (pmlmeext->sitesurvey_res.state > SCAN_START) { 5139 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) { 5140 pmlmeext->sitesurvey_res.channel_idx++; 5141 } 5142 5143 if (pmlmeext->scan_abort) { 5144 pmlmeext->sitesurvey_res.channel_idx = pmlmeext->sitesurvey_res.ch_num; 5145 5146 pmlmeext->scan_abort = false;/* reset */ 5147 } 5148 5149 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 5150 if (ph2c == NULL) { 5151 goto exit_survey_timer_hdl; 5152 } 5153 5154 psurveyPara = rtw_zmalloc(sizeof(struct sitesurvey_parm)); 5155 if (psurveyPara == NULL) { 5156 kfree(ph2c); 5157 goto exit_survey_timer_hdl; 5158 } 5159 5160 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey)); 5161 rtw_enqueue_cmd(pcmdpriv, ph2c); 5162 } 5163 5164 5165 exit_survey_timer_hdl: 5166 5167 return; 5168 } 5169 5170 void link_timer_hdl(struct timer_list *t) 5171 { 5172 struct adapter *padapter = 5173 from_timer(padapter, t, mlmeextpriv.link_timer); 5174 /* static unsigned int rx_pkt = 0; */ 5175 /* static u64 tx_cnt = 0; */ 5176 /* struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); */ 5177 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5178 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5179 /* struct sta_priv *pstapriv = &padapter->stapriv; */ 5180 5181 5182 if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) { 5183 pmlmeinfo->state = WIFI_FW_NULL_STATE; 5184 report_join_res(padapter, -3); 5185 } else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) { 5186 /* re-auth timer */ 5187 if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) { 5188 /* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */ 5189 /* */ 5190 pmlmeinfo->state = 0; 5191 report_join_res(padapter, -1); 5192 return; 5193 /* */ 5194 /* else */ 5195 /* */ 5196 /* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */ 5197 /* pmlmeinfo->reauth_count = 0; */ 5198 /* */ 5199 } 5200 5201 pmlmeinfo->auth_seq = 1; 5202 issue_auth(padapter, NULL, 0); 5203 set_link_timer(pmlmeext, REAUTH_TO); 5204 } else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) { 5205 /* re-assoc timer */ 5206 if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) { 5207 pmlmeinfo->state = WIFI_FW_NULL_STATE; 5208 report_join_res(padapter, -2); 5209 return; 5210 } 5211 5212 issue_assocreq(padapter); 5213 set_link_timer(pmlmeext, REASSOC_TO); 5214 } 5215 } 5216 5217 void addba_timer_hdl(struct timer_list *t) 5218 { 5219 struct sta_info *psta = from_timer(psta, t, addba_retry_timer); 5220 struct ht_priv *phtpriv; 5221 5222 if (!psta) 5223 return; 5224 5225 phtpriv = &psta->htpriv; 5226 5227 if (phtpriv->ht_option && phtpriv->ampdu_enable) { 5228 if (phtpriv->candidate_tid_bitmap) 5229 phtpriv->candidate_tid_bitmap = 0x0; 5230 5231 } 5232 } 5233 5234 void sa_query_timer_hdl(struct timer_list *t) 5235 { 5236 struct adapter *padapter = 5237 from_timer(padapter, t, mlmeextpriv.sa_query_timer); 5238 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 5239 /* disconnect */ 5240 spin_lock_bh(&pmlmepriv->lock); 5241 5242 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 5243 rtw_disassoc_cmd(padapter, 0, true); 5244 rtw_indicate_disconnect(padapter); 5245 rtw_free_assoc_resources(padapter, 1); 5246 } 5247 5248 spin_unlock_bh(&pmlmepriv->lock); 5249 } 5250 5251 u8 NULL_hdl(struct adapter *padapter, u8 *pbuf) 5252 { 5253 return H2C_SUCCESS; 5254 } 5255 5256 u8 setopmode_hdl(struct adapter *padapter, u8 *pbuf) 5257 { 5258 u8 type; 5259 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5260 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5261 struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf; 5262 5263 if (psetop->mode == Ndis802_11APMode) { 5264 pmlmeinfo->state = WIFI_FW_AP_STATE; 5265 type = _HW_STATE_AP_; 5266 /* start_ap_mode(padapter); */ 5267 } else if (psetop->mode == Ndis802_11Infrastructure) { 5268 pmlmeinfo->state &= ~(BIT(0)|BIT(1));/* clear state */ 5269 pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */ 5270 type = _HW_STATE_STATION_; 5271 } else if (psetop->mode == Ndis802_11IBSS) { 5272 type = _HW_STATE_ADHOC_; 5273 } else { 5274 type = _HW_STATE_NOLINK_; 5275 } 5276 5277 rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type)); 5278 /* Set_MSR(padapter, type); */ 5279 5280 if (psetop->mode == Ndis802_11APMode) { 5281 /* Do this after port switch to */ 5282 /* prevent from downloading rsvd page to wrong port */ 5283 rtw_btcoex_MediaStatusNotify(padapter, 1); /* connect */ 5284 } 5285 5286 return H2C_SUCCESS; 5287 5288 } 5289 5290 u8 createbss_hdl(struct adapter *padapter, u8 *pbuf) 5291 { 5292 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5293 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5294 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); 5295 struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf; 5296 /* u32 initialgain; */ 5297 5298 if (pmlmeinfo->state == WIFI_FW_AP_STATE) { 5299 start_bss_network(padapter); 5300 return H2C_SUCCESS; 5301 } 5302 5303 /* below is for ad-hoc master */ 5304 if (pparm->network.InfrastructureMode == Ndis802_11IBSS) { 5305 rtw_joinbss_reset(padapter); 5306 5307 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20; 5308 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; 5309 pmlmeinfo->ERP_enable = 0; 5310 pmlmeinfo->WMM_enable = 0; 5311 pmlmeinfo->HT_enable = 0; 5312 pmlmeinfo->HT_caps_enable = 0; 5313 pmlmeinfo->HT_info_enable = 0; 5314 pmlmeinfo->agg_enable_bitmap = 0; 5315 pmlmeinfo->candidate_tid_bitmap = 0; 5316 5317 /* disable dynamic functions, such as high power, DIG */ 5318 Save_DM_Func_Flag(padapter); 5319 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false); 5320 5321 /* config the initial gain under linking, need to write the BB registers */ 5322 /* initialgain = 0x1E; */ 5323 /* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */ 5324 5325 /* cancel link timer */ 5326 del_timer_sync(&pmlmeext->link_timer); 5327 5328 /* clear CAM */ 5329 flush_all_cam_entry(padapter); 5330 5331 memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, IELength)); 5332 pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength; 5333 5334 if (pnetwork->IELength > MAX_IE_SZ)/* Check pbuf->IELength */ 5335 return H2C_PARAMETERS_ERROR; 5336 5337 memcpy(pnetwork->IEs, ((struct wlan_bssid_ex *)pbuf)->IEs, pnetwork->IELength); 5338 5339 start_create_ibss(padapter); 5340 5341 } 5342 5343 return H2C_SUCCESS; 5344 5345 } 5346 5347 u8 join_cmd_hdl(struct adapter *padapter, u8 *pbuf) 5348 { 5349 u8 join_type; 5350 struct ndis_80211_var_ie *pIE; 5351 struct registry_priv *pregpriv = &padapter->registrypriv; 5352 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5353 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5354 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); 5355 u32 i; 5356 u8 cbw40_enable = 0; 5357 /* u32 initialgain; */ 5358 /* u32 acparm; */ 5359 u8 ch, bw, offset; 5360 5361 /* check already connecting to AP or not */ 5362 if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { 5363 if (pmlmeinfo->state & WIFI_FW_STATION_STATE) { 5364 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100); 5365 } 5366 pmlmeinfo->state = WIFI_FW_NULL_STATE; 5367 5368 /* clear CAM */ 5369 flush_all_cam_entry(padapter); 5370 5371 del_timer_sync(&pmlmeext->link_timer); 5372 5373 /* set MSR to nolink -> infra. mode */ 5374 /* Set_MSR(padapter, _HW_STATE_NOLINK_); */ 5375 Set_MSR(padapter, _HW_STATE_STATION_); 5376 5377 5378 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, NULL); 5379 } 5380 5381 rtw_joinbss_reset(padapter); 5382 5383 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20; 5384 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; 5385 pmlmeinfo->ERP_enable = 0; 5386 pmlmeinfo->WMM_enable = 0; 5387 pmlmeinfo->HT_enable = 0; 5388 pmlmeinfo->HT_caps_enable = 0; 5389 pmlmeinfo->HT_info_enable = 0; 5390 pmlmeinfo->agg_enable_bitmap = 0; 5391 pmlmeinfo->candidate_tid_bitmap = 0; 5392 pmlmeinfo->bwmode_updated = false; 5393 /* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */ 5394 pmlmeinfo->VHT_enable = 0; 5395 5396 memcpy(pnetwork, pbuf, FIELD_OFFSET(struct wlan_bssid_ex, IELength)); 5397 pnetwork->IELength = ((struct wlan_bssid_ex *)pbuf)->IELength; 5398 5399 if (pnetwork->IELength > MAX_IE_SZ)/* Check pbuf->IELength */ 5400 return H2C_PARAMETERS_ERROR; 5401 5402 memcpy(pnetwork->IEs, ((struct wlan_bssid_ex *)pbuf)->IEs, pnetwork->IELength); 5403 5404 pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig; 5405 pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork); 5406 5407 /* Check AP vendor to move rtw_joinbss_cmd() */ 5408 /* pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength); */ 5409 5410 /* sizeof(struct ndis_802_11_fix_ie) */ 5411 for (i = _FIXED_IE_LENGTH_; i < pnetwork->IELength;) { 5412 pIE = (struct ndis_80211_var_ie *)(pnetwork->IEs + i); 5413 5414 switch (pIE->ElementID) { 5415 case WLAN_EID_VENDOR_SPECIFIC:/* Get WMM IE. */ 5416 if (!memcmp(pIE->data, WMM_OUI, 4)) 5417 WMM_param_handler(padapter, pIE); 5418 break; 5419 5420 case WLAN_EID_HT_CAPABILITY: /* Get HT Cap IE. */ 5421 pmlmeinfo->HT_caps_enable = 1; 5422 break; 5423 5424 case WLAN_EID_HT_OPERATION: /* Get HT Info IE. */ 5425 pmlmeinfo->HT_info_enable = 1; 5426 5427 /* spec case only for cisco's ap because cisco's ap issue assoc rsp using mcs rate @40MHz or @20MHz */ 5428 { 5429 struct HT_info_element *pht_info = (struct HT_info_element *)(pIE->data); 5430 5431 if (pnetwork->Configuration.DSConfig > 14) { 5432 if ((pregpriv->bw_mode >> 4) > CHANNEL_WIDTH_20) 5433 cbw40_enable = 1; 5434 } else { 5435 if ((pregpriv->bw_mode & 0x0f) > CHANNEL_WIDTH_20) 5436 cbw40_enable = 1; 5437 } 5438 5439 if ((cbw40_enable) && (pht_info->infos[0] & BIT(2))) { 5440 /* switch to the 40M Hz mode according to the AP */ 5441 pmlmeext->cur_bwmode = CHANNEL_WIDTH_40; 5442 switch (pht_info->infos[0] & 0x3) { 5443 case 1: 5444 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER; 5445 break; 5446 5447 case 3: 5448 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER; 5449 break; 5450 5451 default: 5452 pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; 5453 pmlmeext->cur_bwmode = CHANNEL_WIDTH_20; 5454 break; 5455 } 5456 } 5457 } 5458 break; 5459 default: 5460 break; 5461 } 5462 5463 i += (pIE->Length + 2); 5464 } 5465 5466 /* check channel, bandwidth, offset and switch */ 5467 if (rtw_chk_start_clnt_join(padapter, &ch, &bw, &offset) == _FAIL) { 5468 report_join_res(padapter, (-4)); 5469 return H2C_SUCCESS; 5470 } 5471 5472 /* disable dynamic functions, such as high power, DIG */ 5473 /* Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false); */ 5474 5475 /* config the initial gain under linking, need to write the BB registers */ 5476 /* initialgain = 0x1E; */ 5477 /* rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); */ 5478 5479 rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress); 5480 join_type = 0; 5481 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type)); 5482 rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, NULL); 5483 5484 set_channel_bwmode(padapter, ch, offset, bw); 5485 5486 /* cancel link timer */ 5487 del_timer_sync(&pmlmeext->link_timer); 5488 5489 start_clnt_join(padapter); 5490 5491 return H2C_SUCCESS; 5492 5493 } 5494 5495 u8 disconnect_hdl(struct adapter *padapter, unsigned char *pbuf) 5496 { 5497 struct disconnect_parm *param = (struct disconnect_parm *)pbuf; 5498 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5499 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5500 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)(&(pmlmeinfo->network)); 5501 u8 val8; 5502 5503 if (is_client_associated_to_ap(padapter)) { 5504 issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms/100, 100); 5505 } 5506 5507 if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) { 5508 /* Stop BCN */ 5509 val8 = 0; 5510 rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8)); 5511 } 5512 5513 rtw_mlmeext_disconnect(padapter); 5514 5515 rtw_free_uc_swdec_pending_queue(padapter); 5516 5517 return H2C_SUCCESS; 5518 } 5519 5520 static int rtw_scan_ch_decision(struct adapter *padapter, struct rtw_ieee80211_channel *out, 5521 u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num) 5522 { 5523 int i, j; 5524 int set_idx; 5525 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5526 5527 /* clear first */ 5528 memset(out, 0, sizeof(struct rtw_ieee80211_channel)*out_num); 5529 5530 /* acquire channels from in */ 5531 j = 0; 5532 for (i = 0; i < in_num; i++) { 5533 5534 set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, in[i].hw_value); 5535 if (in[i].hw_value && !(in[i].flags & RTW_IEEE80211_CHAN_DISABLED) 5536 && set_idx >= 0 5537 ) { 5538 if (j >= out_num) { 5539 netdev_dbg(padapter->pnetdev, 5540 FUNC_ADPT_FMT " out_num:%u not enough\n", 5541 FUNC_ADPT_ARG(padapter), out_num); 5542 break; 5543 } 5544 5545 memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel)); 5546 5547 if (pmlmeext->channel_set[set_idx].ScanType == SCAN_PASSIVE) 5548 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN; 5549 5550 j++; 5551 } 5552 if (j >= out_num) 5553 break; 5554 } 5555 5556 /* if out is empty, use channel_set as default */ 5557 if (j == 0) { 5558 for (i = 0; i < pmlmeext->max_chan_nums; i++) { 5559 5560 if (j >= out_num) { 5561 netdev_dbg(padapter->pnetdev, 5562 FUNC_ADPT_FMT " out_num:%u not enough\n", 5563 FUNC_ADPT_ARG(padapter), 5564 out_num); 5565 break; 5566 } 5567 5568 out[j].hw_value = pmlmeext->channel_set[i].ChannelNum; 5569 5570 if (pmlmeext->channel_set[i].ScanType == SCAN_PASSIVE) 5571 out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN; 5572 5573 j++; 5574 } 5575 } 5576 5577 return j; 5578 } 5579 5580 u8 sitesurvey_cmd_hdl(struct adapter *padapter, u8 *pbuf) 5581 { 5582 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5583 struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf; 5584 u8 bdelayscan = false; 5585 u8 val8; 5586 u32 initialgain; 5587 u32 i; 5588 5589 if (pmlmeext->sitesurvey_res.state == SCAN_DISABLE) { 5590 pmlmeext->sitesurvey_res.state = SCAN_START; 5591 pmlmeext->sitesurvey_res.bss_cnt = 0; 5592 pmlmeext->sitesurvey_res.channel_idx = 0; 5593 5594 for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) { 5595 if (pparm->ssid[i].SsidLength) { 5596 memcpy(pmlmeext->sitesurvey_res.ssid[i].Ssid, pparm->ssid[i].Ssid, IW_ESSID_MAX_SIZE); 5597 pmlmeext->sitesurvey_res.ssid[i].SsidLength = pparm->ssid[i].SsidLength; 5598 } else { 5599 pmlmeext->sitesurvey_res.ssid[i].SsidLength = 0; 5600 } 5601 } 5602 5603 pmlmeext->sitesurvey_res.ch_num = rtw_scan_ch_decision(padapter 5604 , pmlmeext->sitesurvey_res.ch, RTW_CHANNEL_SCAN_AMOUNT 5605 , pparm->ch, pparm->ch_num 5606 ); 5607 5608 pmlmeext->sitesurvey_res.scan_mode = pparm->scan_mode; 5609 5610 /* issue null data if associating to the AP */ 5611 if (is_client_associated_to_ap(padapter)) { 5612 pmlmeext->sitesurvey_res.state = SCAN_TXNULL; 5613 5614 issue_nulldata(padapter, NULL, 1, 3, 500); 5615 5616 bdelayscan = true; 5617 } 5618 if (bdelayscan) { 5619 /* delay 50ms to protect nulldata(1). */ 5620 set_survey_timer(pmlmeext, 50); 5621 return H2C_SUCCESS; 5622 } 5623 } 5624 5625 if ((pmlmeext->sitesurvey_res.state == SCAN_START) || (pmlmeext->sitesurvey_res.state == SCAN_TXNULL)) { 5626 /* disable dynamic functions, such as high power, DIG */ 5627 Save_DM_Func_Flag(padapter); 5628 Switch_DM_Func(padapter, DYNAMIC_FUNC_DISABLE, false); 5629 5630 /* config the initial gain under scanning, need to write the BB 5631 * registers 5632 */ 5633 initialgain = 0x1e; 5634 5635 rtw_hal_set_hwreg(padapter, HW_VAR_INITIAL_GAIN, (u8 *)(&initialgain)); 5636 5637 /* set MSR to no link state */ 5638 Set_MSR(padapter, _HW_STATE_NOLINK_); 5639 5640 val8 = 1; /* under site survey */ 5641 rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8)); 5642 5643 pmlmeext->sitesurvey_res.state = SCAN_PROCESS; 5644 } 5645 5646 site_survey(padapter); 5647 5648 return H2C_SUCCESS; 5649 5650 } 5651 5652 u8 setauth_hdl(struct adapter *padapter, unsigned char *pbuf) 5653 { 5654 struct setauth_parm *pparm = (struct setauth_parm *)pbuf; 5655 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5656 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5657 5658 if (pparm->mode < 4) 5659 pmlmeinfo->auth_algo = pparm->mode; 5660 5661 return H2C_SUCCESS; 5662 } 5663 5664 u8 setkey_hdl(struct adapter *padapter, u8 *pbuf) 5665 { 5666 u16 ctrl = 0; 5667 s16 cam_id = 0; 5668 struct setkey_parm *pparm = (struct setkey_parm *)pbuf; 5669 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5670 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5671 unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 5672 u8 *addr; 5673 5674 /* main tx key for wep. */ 5675 if (pparm->set_tx) 5676 pmlmeinfo->key_index = pparm->keyid; 5677 5678 cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid); 5679 5680 if (cam_id < 0) { 5681 } else { 5682 if (cam_id > 3) /* not default key, searched by A2 */ 5683 addr = get_bssid(&padapter->mlmepriv); 5684 else 5685 addr = null_addr; 5686 5687 ctrl = BIT(15) | BIT6 | ((pparm->algorithm) << 2) | pparm->keyid; 5688 write_cam(padapter, cam_id, ctrl, addr, pparm->key); 5689 netdev_dbg(padapter->pnetdev, 5690 "set group key camid:%d, addr:%pM, kid:%d, type:%s\n", 5691 cam_id, MAC_ARG(addr), pparm->keyid, 5692 security_type_str(pparm->algorithm)); 5693 } 5694 5695 if (cam_id >= 0 && cam_id <= 3) 5696 rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)true); 5697 5698 /* allow multicast packets to driver */ 5699 padapter->HalFunc.SetHwRegHandler(padapter, HW_VAR_ON_RCR_AM, null_addr); 5700 5701 return H2C_SUCCESS; 5702 } 5703 5704 u8 set_stakey_hdl(struct adapter *padapter, u8 *pbuf) 5705 { 5706 u16 ctrl = 0; 5707 s16 cam_id = 0; 5708 u8 ret = H2C_SUCCESS; 5709 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5710 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5711 struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf; 5712 struct sta_priv *pstapriv = &padapter->stapriv; 5713 struct sta_info *psta; 5714 5715 if (pparm->algorithm == _NO_PRIVACY_) 5716 goto write_to_cam; 5717 5718 psta = rtw_get_stainfo(pstapriv, pparm->addr); 5719 if (!psta) { 5720 netdev_dbg(padapter->pnetdev, "%s sta:%pM not found\n", 5721 __func__, MAC_ARG(pparm->addr)); 5722 ret = H2C_REJECTED; 5723 goto exit; 5724 } 5725 5726 pmlmeinfo->enc_algo = pparm->algorithm; 5727 cam_id = rtw_camid_alloc(padapter, psta, 0); 5728 if (cam_id < 0) 5729 goto exit; 5730 5731 write_to_cam: 5732 if (pparm->algorithm == _NO_PRIVACY_) { 5733 while ((cam_id = rtw_camid_search(padapter, pparm->addr, -1)) >= 0) { 5734 netdev_dbg(padapter->pnetdev, 5735 "clear key for addr:%pM, camid:%d\n", 5736 MAC_ARG(pparm->addr), cam_id); 5737 clear_cam_entry(padapter, cam_id); 5738 rtw_camid_free(padapter, cam_id); 5739 } 5740 } else { 5741 netdev_dbg(padapter->pnetdev, 5742 "set pairwise key camid:%d, addr:%pM, kid:%d, type:%s\n", 5743 cam_id, MAC_ARG(pparm->addr), pparm->keyid, 5744 security_type_str(pparm->algorithm)); 5745 ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid; 5746 write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key); 5747 } 5748 ret = H2C_SUCCESS_RSP; 5749 5750 exit: 5751 return ret; 5752 } 5753 5754 u8 add_ba_hdl(struct adapter *padapter, unsigned char *pbuf) 5755 { 5756 struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf; 5757 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5758 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5759 5760 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr); 5761 5762 if (!psta) 5763 return H2C_SUCCESS; 5764 5765 if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) || 5766 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE)) { 5767 /* pmlmeinfo->ADDBA_retry_count = 0; */ 5768 /* pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid); */ 5769 /* psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid); */ 5770 issue_action_BA(padapter, pparm->addr, WLAN_ACTION_ADDBA_REQ, (u16)pparm->tid); 5771 /* _set_timer(&pmlmeext->ADDBA_timer, ADDBA_TO); */ 5772 _set_timer(&psta->addba_retry_timer, ADDBA_TO); 5773 } else { 5774 psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid); 5775 } 5776 return H2C_SUCCESS; 5777 } 5778 5779 5780 u8 chk_bmc_sleepq_cmd(struct adapter *padapter) 5781 { 5782 struct cmd_obj *ph2c; 5783 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); 5784 u8 res = _SUCCESS; 5785 5786 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 5787 if (ph2c == NULL) { 5788 res = _FAIL; 5789 goto exit; 5790 } 5791 5792 init_h2fwcmd_w_parm_no_parm_rsp(ph2c, GEN_CMD_CODE(_ChkBMCSleepq)); 5793 5794 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 5795 5796 exit: 5797 return res; 5798 } 5799 5800 u8 set_tx_beacon_cmd(struct adapter *padapter) 5801 { 5802 struct cmd_obj *ph2c; 5803 struct Tx_Beacon_param *ptxBeacon_parm; 5804 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); 5805 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5806 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 5807 u8 res = _SUCCESS; 5808 int len_diff = 0; 5809 5810 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 5811 if (ph2c == NULL) { 5812 res = _FAIL; 5813 goto exit; 5814 } 5815 5816 ptxBeacon_parm = rtw_zmalloc(sizeof(struct Tx_Beacon_param)); 5817 if (ptxBeacon_parm == NULL) { 5818 kfree(ph2c); 5819 res = _FAIL; 5820 goto exit; 5821 } 5822 5823 memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(struct wlan_bssid_ex)); 5824 5825 len_diff = update_hidden_ssid(ptxBeacon_parm->network.IEs+_BEACON_IE_OFFSET_, 5826 ptxBeacon_parm->network.IELength-_BEACON_IE_OFFSET_, 5827 pmlmeinfo->hidden_ssid_mode); 5828 ptxBeacon_parm->network.IELength += len_diff; 5829 5830 init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon)); 5831 5832 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 5833 5834 exit: 5835 return res; 5836 } 5837 5838 static struct fwevent wlanevents[] = { 5839 {0, rtw_dummy_event_callback}, /*0*/ 5840 {0, NULL}, 5841 {0, NULL}, 5842 {0, NULL}, 5843 {0, NULL}, 5844 {0, NULL}, 5845 {0, NULL}, 5846 {0, NULL}, 5847 {0, &rtw_survey_event_callback}, /*8*/ 5848 {sizeof(struct surveydone_event), &rtw_surveydone_event_callback}, /*9*/ 5849 5850 {0, &rtw_joinbss_event_callback}, /*10*/ 5851 {sizeof(struct stassoc_event), &rtw_stassoc_event_callback}, 5852 {sizeof(struct stadel_event), &rtw_stadel_event_callback}, 5853 {0, &rtw_atimdone_event_callback}, 5854 {0, rtw_dummy_event_callback}, 5855 {0, NULL}, /*15*/ 5856 {0, NULL}, 5857 {0, NULL}, 5858 {0, NULL}, 5859 {0, rtw_fwdbg_event_callback}, 5860 {0, NULL}, /*20*/ 5861 {0, NULL}, 5862 {0, NULL}, 5863 {0, &rtw_cpwm_event_callback}, 5864 {0, NULL}, 5865 {0, &rtw_wmm_event_callback}, 5866 5867 }; 5868 5869 u8 mlme_evt_hdl(struct adapter *padapter, unsigned char *pbuf) 5870 { 5871 u8 evt_code; 5872 u16 evt_sz; 5873 uint *peventbuf; 5874 void (*event_callback)(struct adapter *dev, u8 *pbuf); 5875 struct evt_priv *pevt_priv = &(padapter->evtpriv); 5876 5877 if (pbuf == NULL) 5878 goto _abort_event_; 5879 5880 peventbuf = (uint *)pbuf; 5881 evt_sz = (u16)(*peventbuf&0xffff); 5882 evt_code = (u8)((*peventbuf>>16)&0xff); 5883 5884 /* checking if event code is valid */ 5885 if (evt_code >= MAX_C2HEVT) 5886 goto _abort_event_; 5887 5888 /* checking if event size match the event parm size */ 5889 if ((wlanevents[evt_code].parmsize != 0) && 5890 (wlanevents[evt_code].parmsize != evt_sz)) 5891 goto _abort_event_; 5892 5893 atomic_inc(&pevt_priv->event_seq); 5894 5895 peventbuf += 2; 5896 5897 if (peventbuf) { 5898 event_callback = wlanevents[evt_code].event_callback; 5899 event_callback(padapter, (u8 *)peventbuf); 5900 5901 pevt_priv->evt_done_cnt++; 5902 } 5903 5904 5905 _abort_event_: 5906 5907 5908 return H2C_SUCCESS; 5909 5910 } 5911 5912 u8 h2c_msg_hdl(struct adapter *padapter, unsigned char *pbuf) 5913 { 5914 if (!pbuf) 5915 return H2C_PARAMETERS_ERROR; 5916 5917 return H2C_SUCCESS; 5918 } 5919 5920 u8 chk_bmc_sleepq_hdl(struct adapter *padapter, unsigned char *pbuf) 5921 { 5922 struct sta_info *psta_bmc; 5923 struct list_head *xmitframe_plist, *xmitframe_phead, *tmp; 5924 struct xmit_frame *pxmitframe = NULL; 5925 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 5926 struct sta_priv *pstapriv = &padapter->stapriv; 5927 5928 /* for BC/MC Frames */ 5929 psta_bmc = rtw_get_bcmc_stainfo(padapter); 5930 if (!psta_bmc) 5931 return H2C_SUCCESS; 5932 5933 if ((pstapriv->tim_bitmap&BIT(0)) && (psta_bmc->sleepq_len > 0)) { 5934 msleep(10);/* 10ms, ATIM(HIQ) Windows */ 5935 5936 /* spin_lock_bh(&psta_bmc->sleep_q.lock); */ 5937 spin_lock_bh(&pxmitpriv->lock); 5938 5939 xmitframe_phead = get_list_head(&psta_bmc->sleep_q); 5940 list_for_each_safe(xmitframe_plist, tmp, xmitframe_phead) { 5941 pxmitframe = list_entry(xmitframe_plist, 5942 struct xmit_frame, list); 5943 5944 list_del_init(&pxmitframe->list); 5945 5946 psta_bmc->sleepq_len--; 5947 if (psta_bmc->sleepq_len > 0) 5948 pxmitframe->attrib.mdata = 1; 5949 else 5950 pxmitframe->attrib.mdata = 0; 5951 5952 pxmitframe->attrib.triggered = 1; 5953 5954 if (xmitframe_hiq_filter(pxmitframe)) 5955 pxmitframe->attrib.qsel = 0x11;/* HIQ */ 5956 5957 rtw_hal_xmitframe_enqueue(padapter, pxmitframe); 5958 } 5959 5960 /* spin_unlock_bh(&psta_bmc->sleep_q.lock); */ 5961 spin_unlock_bh(&pxmitpriv->lock); 5962 5963 /* check hi queue and bmc_sleepq */ 5964 rtw_chk_hi_queue_cmd(padapter); 5965 } 5966 5967 return H2C_SUCCESS; 5968 } 5969 5970 u8 tx_beacon_hdl(struct adapter *padapter, unsigned char *pbuf) 5971 { 5972 if (send_beacon(padapter) == _FAIL) 5973 return H2C_PARAMETERS_ERROR; 5974 5975 /* tx bc/mc frames after update TIM */ 5976 chk_bmc_sleepq_hdl(padapter, NULL); 5977 5978 return H2C_SUCCESS; 5979 } 5980 5981 int rtw_chk_start_clnt_join(struct adapter *padapter, u8 *ch, u8 *bw, u8 *offset) 5982 { 5983 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 5984 unsigned char cur_ch = pmlmeext->cur_channel; 5985 unsigned char cur_bw = pmlmeext->cur_bwmode; 5986 unsigned char cur_ch_offset = pmlmeext->cur_ch_offset; 5987 bool connect_allow = true; 5988 5989 if (!ch || !bw || !offset) { 5990 rtw_warn_on(1); 5991 connect_allow = false; 5992 } 5993 5994 if (connect_allow) { 5995 *ch = cur_ch; 5996 *bw = cur_bw; 5997 *offset = cur_ch_offset; 5998 } 5999 6000 return connect_allow ? _SUCCESS : _FAIL; 6001 } 6002 6003 /* Find union about ch, bw, ch_offset of all linked/linking interfaces */ 6004 int rtw_get_ch_setting_union(struct adapter *adapter, u8 *ch, u8 *bw, u8 *offset) 6005 { 6006 struct dvobj_priv *dvobj = adapter_to_dvobj(adapter); 6007 struct adapter *iface; 6008 6009 if (ch) 6010 *ch = 0; 6011 if (bw) 6012 *bw = CHANNEL_WIDTH_20; 6013 if (offset) 6014 *offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE; 6015 6016 iface = dvobj->padapters; 6017 6018 if (!check_fwstate(&iface->mlmepriv, _FW_LINKED|_FW_UNDER_LINKING)) 6019 return 0; 6020 6021 return 1; 6022 } 6023 6024 u8 set_ch_hdl(struct adapter *padapter, u8 *pbuf) 6025 { 6026 struct set_ch_parm *set_ch_parm; 6027 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 6028 6029 if (!pbuf) 6030 return H2C_PARAMETERS_ERROR; 6031 6032 set_ch_parm = (struct set_ch_parm *)pbuf; 6033 6034 pmlmeext->cur_channel = set_ch_parm->ch; 6035 pmlmeext->cur_ch_offset = set_ch_parm->ch_offset; 6036 pmlmeext->cur_bwmode = set_ch_parm->bw; 6037 6038 set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw); 6039 6040 return H2C_SUCCESS; 6041 } 6042 6043 u8 set_chplan_hdl(struct adapter *padapter, unsigned char *pbuf) 6044 { 6045 struct SetChannelPlan_param *setChannelPlan_param; 6046 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 6047 6048 if (!pbuf) 6049 return H2C_PARAMETERS_ERROR; 6050 6051 setChannelPlan_param = (struct SetChannelPlan_param *)pbuf; 6052 6053 pmlmeext->max_chan_nums = init_channel_set(padapter, setChannelPlan_param->channel_plan, pmlmeext->channel_set); 6054 init_channel_list(padapter, pmlmeext->channel_set, pmlmeext->max_chan_nums, &pmlmeext->channel_list); 6055 6056 if (padapter->rtw_wdev && padapter->rtw_wdev->wiphy) { 6057 struct regulatory_request request; 6058 6059 request.initiator = NL80211_REGDOM_SET_BY_DRIVER; 6060 rtw_reg_notifier(padapter->rtw_wdev->wiphy, &request); 6061 } 6062 6063 return H2C_SUCCESS; 6064 } 6065 6066 u8 set_csa_hdl(struct adapter *padapter, unsigned char *pbuf) 6067 { 6068 return H2C_REJECTED; 6069 } 6070 6071 /* TDLS_ESTABLISHED : write RCR DATA BIT */ 6072 /* TDLS_CS_OFF : go back to the channel linked with AP, terminating channel switch procedure */ 6073 /* TDLS_INIT_CH_SEN : init channel sensing, receive all data and mgnt frame */ 6074 /* TDLS_DONE_CH_SEN: channel sensing and report candidate channel */ 6075 /* TDLS_OFF_CH : first time set channel to off channel */ 6076 /* TDLS_BASE_CH : go back tp the channel linked with AP when set base channel as target channel */ 6077 /* TDLS_P_OFF_CH : periodically go to off channel */ 6078 /* TDLS_P_BASE_CH : periodically go back to base channel */ 6079 /* TDLS_RS_RCR : restore RCR */ 6080 /* TDLS_TEAR_STA : free tdls sta */ 6081 u8 tdls_hdl(struct adapter *padapter, unsigned char *pbuf) 6082 { 6083 return H2C_REJECTED; 6084 } 6085 6086 u8 run_in_thread_hdl(struct adapter *padapter, u8 *pbuf) 6087 { 6088 struct RunInThread_param *p; 6089 6090 6091 if (NULL == pbuf) 6092 return H2C_PARAMETERS_ERROR; 6093 p = (struct RunInThread_param *)pbuf; 6094 6095 if (p->func) 6096 p->func(p->context); 6097 6098 return H2C_SUCCESS; 6099 } 6100