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