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