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