1 /****************************************************************************** 2 * 3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 ******************************************************************************/ 15 #define _RTW_CMD_C_ 16 17 #include <drv_types.h> 18 #include <rtw_debug.h> 19 #include <linux/jiffies.h> 20 21 static struct _cmd_callback rtw_cmd_callback[] = { 22 {GEN_CMD_CODE(_Read_MACREG), NULL}, /*0*/ 23 {GEN_CMD_CODE(_Write_MACREG), NULL}, 24 {GEN_CMD_CODE(_Read_BBREG), &rtw_getbbrfreg_cmdrsp_callback}, 25 {GEN_CMD_CODE(_Write_BBREG), NULL}, 26 {GEN_CMD_CODE(_Read_RFREG), &rtw_getbbrfreg_cmdrsp_callback}, 27 {GEN_CMD_CODE(_Write_RFREG), NULL}, /*5*/ 28 {GEN_CMD_CODE(_Read_EEPROM), NULL}, 29 {GEN_CMD_CODE(_Write_EEPROM), NULL}, 30 {GEN_CMD_CODE(_Read_EFUSE), NULL}, 31 {GEN_CMD_CODE(_Write_EFUSE), NULL}, 32 33 {GEN_CMD_CODE(_Read_CAM), NULL}, /*10*/ 34 {GEN_CMD_CODE(_Write_CAM), NULL}, 35 {GEN_CMD_CODE(_setBCNITV), NULL}, 36 {GEN_CMD_CODE(_setMBIDCFG), NULL}, 37 {GEN_CMD_CODE(_JoinBss), &rtw_joinbss_cmd_callback}, /*14*/ 38 {GEN_CMD_CODE(_DisConnect), &rtw_disassoc_cmd_callback}, /*15*/ 39 {GEN_CMD_CODE(_CreateBss), &rtw_createbss_cmd_callback}, 40 {GEN_CMD_CODE(_SetOpMode), NULL}, 41 {GEN_CMD_CODE(_SiteSurvey), &rtw_survey_cmd_callback}, /*18*/ 42 {GEN_CMD_CODE(_SetAuth), NULL}, 43 44 {GEN_CMD_CODE(_SetKey), NULL}, /*20*/ 45 {GEN_CMD_CODE(_SetStaKey), &rtw_setstaKey_cmdrsp_callback}, 46 {GEN_CMD_CODE(_SetAssocSta), &rtw_setassocsta_cmdrsp_callback}, 47 {GEN_CMD_CODE(_DelAssocSta), NULL}, 48 {GEN_CMD_CODE(_SetStaPwrState), NULL}, 49 {GEN_CMD_CODE(_SetBasicRate), NULL}, /*25*/ 50 {GEN_CMD_CODE(_GetBasicRate), NULL}, 51 {GEN_CMD_CODE(_SetDataRate), NULL}, 52 {GEN_CMD_CODE(_GetDataRate), NULL}, 53 {GEN_CMD_CODE(_SetPhyInfo), NULL}, 54 55 {GEN_CMD_CODE(_GetPhyInfo), NULL}, /*30*/ 56 {GEN_CMD_CODE(_SetPhy), NULL}, 57 {GEN_CMD_CODE(_GetPhy), NULL}, 58 {GEN_CMD_CODE(_readRssi), NULL}, 59 {GEN_CMD_CODE(_readGain), NULL}, 60 {GEN_CMD_CODE(_SetAtim), NULL}, /*35*/ 61 {GEN_CMD_CODE(_SetPwrMode), NULL}, 62 {GEN_CMD_CODE(_JoinbssRpt), NULL}, 63 {GEN_CMD_CODE(_SetRaTable), NULL}, 64 {GEN_CMD_CODE(_GetRaTable), NULL}, 65 66 {GEN_CMD_CODE(_GetCCXReport), NULL}, /*40*/ 67 {GEN_CMD_CODE(_GetDTMReport), NULL}, 68 {GEN_CMD_CODE(_GetTXRateStatistics), NULL}, 69 {GEN_CMD_CODE(_SetUsbSuspend), NULL}, 70 {GEN_CMD_CODE(_SetH2cLbk), NULL}, 71 {GEN_CMD_CODE(_AddBAReq), NULL}, /*45*/ 72 {GEN_CMD_CODE(_SetChannel), NULL}, /*46*/ 73 {GEN_CMD_CODE(_SetTxPower), NULL}, 74 {GEN_CMD_CODE(_SwitchAntenna), NULL}, 75 {GEN_CMD_CODE(_SetCrystalCap), NULL}, 76 {GEN_CMD_CODE(_SetSingleCarrierTx), NULL}, /*50*/ 77 78 {GEN_CMD_CODE(_SetSingleToneTx), NULL}, /*51*/ 79 {GEN_CMD_CODE(_SetCarrierSuppressionTx), NULL}, 80 {GEN_CMD_CODE(_SetContinuousTx), NULL}, 81 {GEN_CMD_CODE(_SwitchBandwidth), NULL}, /*54*/ 82 {GEN_CMD_CODE(_TX_Beacon), NULL},/*55*/ 83 84 {GEN_CMD_CODE(_Set_MLME_EVT), NULL},/*56*/ 85 {GEN_CMD_CODE(_Set_Drv_Extra), NULL},/*57*/ 86 {GEN_CMD_CODE(_Set_H2C_MSG), NULL},/*58*/ 87 {GEN_CMD_CODE(_SetChannelPlan), NULL},/*59*/ 88 {GEN_CMD_CODE(_LedBlink), NULL},/*60*/ 89 90 {GEN_CMD_CODE(_SetChannelSwitch), NULL},/*61*/ 91 {GEN_CMD_CODE(_TDLS), NULL},/*62*/ 92 {GEN_CMD_CODE(_ChkBMCSleepq), NULL}, /*63*/ 93 94 {GEN_CMD_CODE(_RunInThreadCMD), NULL},/*64*/ 95 }; 96 97 static struct cmd_hdl wlancmds[] = { 98 GEN_DRV_CMD_HANDLER(0, NULL) /*0*/ 99 GEN_DRV_CMD_HANDLER(0, NULL) 100 GEN_DRV_CMD_HANDLER(0, NULL) 101 GEN_DRV_CMD_HANDLER(0, NULL) 102 GEN_DRV_CMD_HANDLER(0, NULL) 103 GEN_DRV_CMD_HANDLER(0, NULL) 104 GEN_MLME_EXT_HANDLER(0, NULL) 105 GEN_MLME_EXT_HANDLER(0, NULL) 106 GEN_MLME_EXT_HANDLER(0, NULL) 107 GEN_MLME_EXT_HANDLER(0, NULL) 108 GEN_MLME_EXT_HANDLER(0, NULL) /*10*/ 109 GEN_MLME_EXT_HANDLER(0, NULL) 110 GEN_MLME_EXT_HANDLER(0, NULL) 111 GEN_MLME_EXT_HANDLER(0, NULL) 112 GEN_MLME_EXT_HANDLER(sizeof(struct joinbss_parm), join_cmd_hdl) /*14*/ 113 GEN_MLME_EXT_HANDLER(sizeof(struct disconnect_parm), disconnect_hdl) 114 GEN_MLME_EXT_HANDLER(sizeof(struct createbss_parm), createbss_hdl) 115 GEN_MLME_EXT_HANDLER(sizeof(struct setopmode_parm), setopmode_hdl) 116 GEN_MLME_EXT_HANDLER(sizeof(struct sitesurvey_parm), sitesurvey_cmd_hdl) /*18*/ 117 GEN_MLME_EXT_HANDLER(sizeof(struct setauth_parm), setauth_hdl) 118 GEN_MLME_EXT_HANDLER(sizeof(struct setkey_parm), setkey_hdl) /*20*/ 119 GEN_MLME_EXT_HANDLER(sizeof(struct set_stakey_parm), set_stakey_hdl) 120 GEN_MLME_EXT_HANDLER(sizeof(struct set_assocsta_parm), NULL) 121 GEN_MLME_EXT_HANDLER(sizeof(struct del_assocsta_parm), NULL) 122 GEN_MLME_EXT_HANDLER(sizeof(struct setstapwrstate_parm), NULL) 123 GEN_MLME_EXT_HANDLER(sizeof(struct setbasicrate_parm), NULL) 124 GEN_MLME_EXT_HANDLER(sizeof(struct getbasicrate_parm), NULL) 125 GEN_MLME_EXT_HANDLER(sizeof(struct setdatarate_parm), NULL) 126 GEN_MLME_EXT_HANDLER(sizeof(struct getdatarate_parm), NULL) 127 GEN_MLME_EXT_HANDLER(sizeof(struct setphyinfo_parm), NULL) 128 GEN_MLME_EXT_HANDLER(sizeof(struct getphyinfo_parm), NULL) /*30*/ 129 GEN_MLME_EXT_HANDLER(sizeof(struct setphy_parm), NULL) 130 GEN_MLME_EXT_HANDLER(sizeof(struct getphy_parm), NULL) 131 GEN_MLME_EXT_HANDLER(0, NULL) 132 GEN_MLME_EXT_HANDLER(0, NULL) 133 GEN_MLME_EXT_HANDLER(0, NULL) 134 GEN_MLME_EXT_HANDLER(0, NULL) 135 GEN_MLME_EXT_HANDLER(0, NULL) 136 GEN_MLME_EXT_HANDLER(0, NULL) 137 GEN_MLME_EXT_HANDLER(0, NULL) 138 GEN_MLME_EXT_HANDLER(0, NULL) /*40*/ 139 GEN_MLME_EXT_HANDLER(0, NULL) 140 GEN_MLME_EXT_HANDLER(0, NULL) 141 GEN_MLME_EXT_HANDLER(0, NULL) 142 GEN_MLME_EXT_HANDLER(0, NULL) 143 GEN_MLME_EXT_HANDLER(sizeof(struct addBaReq_parm), add_ba_hdl) 144 GEN_MLME_EXT_HANDLER(sizeof(struct set_ch_parm), set_ch_hdl) /* 46 */ 145 GEN_MLME_EXT_HANDLER(0, NULL) 146 GEN_MLME_EXT_HANDLER(0, NULL) 147 GEN_MLME_EXT_HANDLER(0, NULL) 148 GEN_MLME_EXT_HANDLER(0, NULL) /*50*/ 149 GEN_MLME_EXT_HANDLER(0, NULL) 150 GEN_MLME_EXT_HANDLER(0, NULL) 151 GEN_MLME_EXT_HANDLER(0, NULL) 152 GEN_MLME_EXT_HANDLER(0, NULL) 153 GEN_MLME_EXT_HANDLER(sizeof(struct Tx_Beacon_param), tx_beacon_hdl) /*55*/ 154 155 GEN_MLME_EXT_HANDLER(0, mlme_evt_hdl) /*56*/ 156 GEN_MLME_EXT_HANDLER(0, rtw_drvextra_cmd_hdl) /*57*/ 157 158 GEN_MLME_EXT_HANDLER(0, h2c_msg_hdl) /*58*/ 159 GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelPlan_param), set_chplan_hdl) /*59*/ 160 GEN_MLME_EXT_HANDLER(sizeof(struct LedBlink_param), led_blink_hdl) /*60*/ 161 162 GEN_MLME_EXT_HANDLER(sizeof(struct SetChannelSwitch_param), set_csa_hdl) /*61*/ 163 GEN_MLME_EXT_HANDLER(sizeof(struct TDLSoption_param), tdls_hdl) /*62*/ 164 GEN_MLME_EXT_HANDLER(0, chk_bmc_sleepq_hdl) /*63*/ 165 GEN_MLME_EXT_HANDLER(sizeof(struct RunInThread_param), run_in_thread_hdl) /*63*/ 166 }; 167 168 /* 169 Caller and the rtw_cmd_thread can protect cmd_q by spin_lock. 170 No irqsave is necessary. 171 */ 172 173 sint _rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) 174 { 175 sint res = _SUCCESS; 176 177 sema_init(&(pcmdpriv->cmd_queue_sema), 0); 178 /* sema_init(&(pcmdpriv->cmd_done_sema), 0); */ 179 sema_init(&(pcmdpriv->terminate_cmdthread_sema), 0); 180 181 182 _rtw_init_queue(&(pcmdpriv->cmd_queue)); 183 184 /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ 185 186 pcmdpriv->cmd_seq = 1; 187 188 pcmdpriv->cmd_allocated_buf = rtw_zmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ); 189 190 if (pcmdpriv->cmd_allocated_buf == NULL) { 191 res = _FAIL; 192 goto exit; 193 } 194 195 pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ - ((SIZE_PTR)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ-1)); 196 197 pcmdpriv->rsp_allocated_buf = rtw_zmalloc(MAX_RSPSZ + 4); 198 199 if (pcmdpriv->rsp_allocated_buf == NULL) { 200 res = _FAIL; 201 goto exit; 202 } 203 204 pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 - ((SIZE_PTR)(pcmdpriv->rsp_allocated_buf) & 3); 205 206 pcmdpriv->cmd_issued_cnt = pcmdpriv->cmd_done_cnt = pcmdpriv->rsp_cnt = 0; 207 208 mutex_init(&pcmdpriv->sctx_mutex); 209 exit: 210 return res; 211 } 212 213 static void c2h_wk_callback(_workitem *work); 214 sint _rtw_init_evt_priv(struct evt_priv *pevtpriv) 215 { 216 sint res = _SUCCESS; 217 218 /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ 219 atomic_set(&pevtpriv->event_seq, 0); 220 pevtpriv->evt_done_cnt = 0; 221 222 _init_workitem(&pevtpriv->c2h_wk, c2h_wk_callback, NULL); 223 pevtpriv->c2h_wk_alive = false; 224 pevtpriv->c2h_queue = rtw_cbuf_alloc(C2H_QUEUE_MAX_LEN+1); 225 226 return res; 227 } 228 229 void _rtw_free_evt_priv(struct evt_priv *pevtpriv) 230 { 231 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+_rtw_free_evt_priv\n")); 232 233 _cancel_workitem_sync(&pevtpriv->c2h_wk); 234 while (pevtpriv->c2h_wk_alive) 235 msleep(10); 236 237 while (!rtw_cbuf_empty(pevtpriv->c2h_queue)) { 238 void *c2h = rtw_cbuf_pop(pevtpriv->c2h_queue); 239 if (c2h != NULL && c2h != (void *)pevtpriv) { 240 kfree(c2h); 241 } 242 } 243 kfree(pevtpriv->c2h_queue); 244 245 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("-_rtw_free_evt_priv\n")); 246 } 247 248 void _rtw_free_cmd_priv(struct cmd_priv *pcmdpriv) 249 { 250 if (pcmdpriv) { 251 kfree(pcmdpriv->cmd_allocated_buf); 252 253 kfree(pcmdpriv->rsp_allocated_buf); 254 255 mutex_destroy(&pcmdpriv->sctx_mutex); 256 } 257 } 258 259 /* 260 Calling Context: 261 262 rtw_enqueue_cmd can only be called between kernel thread, 263 since only spin_lock is used. 264 265 ISR/Call-Back functions can't call this sub-function. 266 267 */ 268 269 sint _rtw_enqueue_cmd(struct __queue *queue, struct cmd_obj *obj) 270 { 271 _irqL irqL; 272 273 if (obj == NULL) 274 goto exit; 275 276 /* spin_lock_bh(&queue->lock); */ 277 spin_lock_irqsave(&queue->lock, irqL); 278 279 list_add_tail(&obj->list, &queue->queue); 280 281 /* spin_unlock_bh(&queue->lock); */ 282 spin_unlock_irqrestore(&queue->lock, irqL); 283 284 exit: 285 return _SUCCESS; 286 } 287 288 struct cmd_obj *_rtw_dequeue_cmd(struct __queue *queue) 289 { 290 _irqL irqL; 291 struct cmd_obj *obj; 292 293 /* spin_lock_bh(&(queue->lock)); */ 294 spin_lock_irqsave(&queue->lock, irqL); 295 if (list_empty(&(queue->queue))) 296 obj = NULL; 297 else{ 298 obj = LIST_CONTAINOR(get_next(&(queue->queue)), struct cmd_obj, list); 299 list_del_init(&obj->list); 300 } 301 302 /* spin_unlock_bh(&(queue->lock)); */ 303 spin_unlock_irqrestore(&queue->lock, irqL); 304 305 return obj; 306 } 307 308 u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) 309 { 310 u32 res; 311 312 res = _rtw_init_cmd_priv(pcmdpriv); 313 return res; 314 } 315 316 u32 rtw_init_evt_priv(struct evt_priv *pevtpriv) 317 { 318 int res; 319 320 res = _rtw_init_evt_priv(pevtpriv); 321 return res; 322 } 323 324 void rtw_free_evt_priv(struct evt_priv *pevtpriv) 325 { 326 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("rtw_free_evt_priv\n")); 327 _rtw_free_evt_priv(pevtpriv); 328 } 329 330 void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv) 331 { 332 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("rtw_free_cmd_priv\n")); 333 _rtw_free_cmd_priv(pcmdpriv); 334 } 335 336 int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj); 337 int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) 338 { 339 u8 bAllow = false; /* set to true to allow enqueuing cmd when hw_init_completed is false */ 340 341 if (cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan)) 342 bAllow = true; 343 344 if ((pcmdpriv->padapter->hw_init_completed == false && bAllow == false) 345 || atomic_read(&(pcmdpriv->cmdthd_running)) == false /* com_thread not running */ 346 ) { 347 /* DBG_871X("%s:%s: drop cmdcode:%u, hw_init_completed:%u, cmdthd_running:%u\n", caller_func, __func__, */ 348 /* cmd_obj->cmdcode, */ 349 /* pcmdpriv->padapter->hw_init_completed, */ 350 /* pcmdpriv->cmdthd_running */ 351 /* */ 352 353 return _FAIL; 354 } 355 return _SUCCESS; 356 } 357 358 359 360 u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) 361 { 362 int res = _FAIL; 363 struct adapter *padapter = pcmdpriv->padapter; 364 365 if (cmd_obj == NULL) { 366 goto exit; 367 } 368 369 cmd_obj->padapter = padapter; 370 371 res = rtw_cmd_filter(pcmdpriv, cmd_obj); 372 if (_FAIL == res) { 373 rtw_free_cmd_obj(cmd_obj); 374 goto exit; 375 } 376 377 res = _rtw_enqueue_cmd(&pcmdpriv->cmd_queue, cmd_obj); 378 379 if (res == _SUCCESS) 380 up(&pcmdpriv->cmd_queue_sema); 381 382 exit: 383 return res; 384 } 385 386 struct cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv) 387 { 388 struct cmd_obj *cmd_obj; 389 390 cmd_obj = _rtw_dequeue_cmd(&pcmdpriv->cmd_queue); 391 392 return cmd_obj; 393 } 394 395 void rtw_free_cmd_obj(struct cmd_obj *pcmd) 396 { 397 if ((pcmd->cmdcode != _JoinBss_CMD_) && 398 (pcmd->cmdcode != _CreateBss_CMD_)) { 399 /* free parmbuf in cmd_obj */ 400 kfree((unsigned char *)pcmd->parmbuf); 401 } 402 403 if (pcmd->rsp != NULL) { 404 if (pcmd->rspsz != 0) { 405 /* free rsp in cmd_obj */ 406 kfree((unsigned char *)pcmd->rsp); 407 } 408 } 409 410 /* free cmd_obj */ 411 kfree(pcmd); 412 } 413 414 415 void rtw_stop_cmd_thread(struct adapter *adapter) 416 { 417 if (adapter->cmdThread && 418 atomic_read(&(adapter->cmdpriv.cmdthd_running)) == true && 419 adapter->cmdpriv.stop_req == 0) { 420 adapter->cmdpriv.stop_req = 1; 421 up(&adapter->cmdpriv.cmd_queue_sema); 422 down(&adapter->cmdpriv.terminate_cmdthread_sema); 423 } 424 } 425 426 int rtw_cmd_thread(void *context) 427 { 428 u8 ret; 429 struct cmd_obj *pcmd; 430 u8 *pcmdbuf, *prspbuf; 431 unsigned long cmd_start_time; 432 unsigned long cmd_process_time; 433 u8 (*cmd_hdl)(struct adapter *padapter, u8 *pbuf); 434 void (*pcmd_callback)(struct adapter *dev, struct cmd_obj *pcmd); 435 struct adapter *padapter = context; 436 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); 437 struct drvextra_cmd_parm *extra_parm = NULL; 438 439 thread_enter("RTW_CMD_THREAD"); 440 441 pcmdbuf = pcmdpriv->cmd_buf; 442 prspbuf = pcmdpriv->rsp_buf; 443 444 pcmdpriv->stop_req = 0; 445 atomic_set(&(pcmdpriv->cmdthd_running), true); 446 up(&pcmdpriv->terminate_cmdthread_sema); 447 448 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("start r871x rtw_cmd_thread !!!!\n")); 449 450 while (1) { 451 if (down_interruptible(&pcmdpriv->cmd_queue_sema)) { 452 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" down_interruptible(&pcmdpriv->cmd_queue_sema) return != 0, break\n", FUNC_ADPT_ARG(padapter)); 453 break; 454 } 455 456 if ((padapter->bDriverStopped == true) || (padapter->bSurpriseRemoved == true)) { 457 DBG_871X_LEVEL(_drv_always_, "%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n", 458 __func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__); 459 break; 460 } 461 462 if (pcmdpriv->stop_req) { 463 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" stop_req:%u, break\n", FUNC_ADPT_ARG(padapter), pcmdpriv->stop_req); 464 break; 465 } 466 467 if (list_empty(&(pcmdpriv->cmd_queue.queue))) { 468 /* DBG_871X("%s: cmd queue is empty!\n", __func__); */ 469 continue; 470 } 471 472 if (rtw_register_cmd_alive(padapter) != _SUCCESS) { 473 RT_TRACE(_module_hal_xmit_c_, _drv_notice_, 474 ("%s: wait to leave LPS_LCLK\n", __func__)); 475 continue; 476 } 477 478 _next: 479 if ((padapter->bDriverStopped == true) || (padapter->bSurpriseRemoved == true)) { 480 DBG_871X_LEVEL(_drv_always_, "%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n", 481 __func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__); 482 break; 483 } 484 485 pcmd = rtw_dequeue_cmd(pcmdpriv); 486 if (!pcmd) { 487 rtw_unregister_cmd_alive(padapter); 488 continue; 489 } 490 491 cmd_start_time = jiffies; 492 493 if (_FAIL == rtw_cmd_filter(pcmdpriv, pcmd)) { 494 pcmd->res = H2C_DROPPED; 495 goto post_process; 496 } 497 498 pcmdpriv->cmd_issued_cnt++; 499 500 pcmd->cmdsz = _RND4((pcmd->cmdsz));/* _RND4 */ 501 502 memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz); 503 504 if (pcmd->cmdcode < ARRAY_SIZE(wlancmds)) { 505 cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns; 506 507 if (cmd_hdl) { 508 ret = cmd_hdl(pcmd->padapter, pcmdbuf); 509 pcmd->res = ret; 510 } 511 512 pcmdpriv->cmd_seq++; 513 } else{ 514 pcmd->res = H2C_PARAMETERS_ERROR; 515 } 516 517 cmd_hdl = NULL; 518 519 post_process: 520 521 if (mutex_lock_interruptible(&(pcmd->padapter->cmdpriv.sctx_mutex)) == 0) { 522 if (pcmd->sctx) { 523 DBG_871X_LEVEL(_drv_always_, FUNC_ADPT_FMT" pcmd->sctx\n", 524 FUNC_ADPT_ARG(pcmd->padapter)); 525 526 if (pcmd->res == H2C_SUCCESS) 527 rtw_sctx_done(&pcmd->sctx); 528 else 529 rtw_sctx_done_err(&pcmd->sctx, RTW_SCTX_DONE_CMD_ERROR); 530 } 531 mutex_unlock(&(pcmd->padapter->cmdpriv.sctx_mutex)); 532 } 533 534 cmd_process_time = jiffies_to_msecs(jiffies - cmd_start_time); 535 if (cmd_process_time > 1000) { 536 if (pcmd->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { 537 DBG_871X(ADPT_FMT" cmd =%d process_time =%lu > 1 sec\n", 538 ADPT_ARG(pcmd->padapter), pcmd->cmdcode, cmd_process_time); 539 /* rtw_warn_on(1); */ 540 } else if (pcmd->cmdcode == GEN_CMD_CODE(_Set_MLME_EVT)) { 541 DBG_871X(ADPT_FMT" cmd =%d, process_time =%lu > 1 sec\n", 542 ADPT_ARG(pcmd->padapter), pcmd->cmdcode, cmd_process_time); 543 /* rtw_warn_on(1); */ 544 } else { 545 DBG_871X(ADPT_FMT" cmd =%d, process_time =%lu > 1 sec\n", 546 ADPT_ARG(pcmd->padapter), pcmd->cmdcode, cmd_process_time); 547 /* rtw_warn_on(1); */ 548 } 549 } 550 551 /* call callback function for post-processed */ 552 if (pcmd->cmdcode < ARRAY_SIZE(rtw_cmd_callback)) { 553 pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback; 554 if (pcmd_callback == NULL) { 555 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("mlme_cmd_hdl(): pcmd_callback = 0x%p, cmdcode = 0x%x\n", pcmd_callback, pcmd->cmdcode)); 556 rtw_free_cmd_obj(pcmd); 557 } else{ 558 /* todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!= NULL) */ 559 pcmd_callback(pcmd->padapter, pcmd);/* need conider that free cmd_obj in rtw_cmd_callback */ 560 } 561 } else{ 562 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("%s: cmdcode = 0x%x callback not defined!\n", __func__, pcmd->cmdcode)); 563 rtw_free_cmd_obj(pcmd); 564 } 565 566 flush_signals_thread(); 567 568 goto _next; 569 570 } 571 572 /* free all cmd_obj resources */ 573 do { 574 pcmd = rtw_dequeue_cmd(pcmdpriv); 575 if (pcmd == NULL) { 576 rtw_unregister_cmd_alive(padapter); 577 break; 578 } 579 580 /* DBG_871X("%s: leaving... drop cmdcode:%u size:%d\n", __func__, pcmd->cmdcode, pcmd->cmdsz); */ 581 582 if (pcmd->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { 583 extra_parm = (struct drvextra_cmd_parm *)pcmd->parmbuf; 584 if (extra_parm->pbuf && extra_parm->size > 0) { 585 kfree(extra_parm->pbuf); 586 } 587 } 588 589 rtw_free_cmd_obj(pcmd); 590 } while (1); 591 592 up(&pcmdpriv->terminate_cmdthread_sema); 593 atomic_set(&(pcmdpriv->cmdthd_running), false); 594 595 thread_exit(); 596 } 597 598 /* 599 rtw_sitesurvey_cmd(~) 600 ### NOTE:#### (!!!!) 601 MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock 602 */ 603 u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, int ssid_num, 604 struct rtw_ieee80211_channel *ch, int ch_num) 605 { 606 u8 res = _FAIL; 607 struct cmd_obj *ph2c; 608 struct sitesurvey_parm *psurveyPara; 609 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 610 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 611 612 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { 613 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1); 614 } 615 616 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 617 if (ph2c == NULL) 618 return _FAIL; 619 620 psurveyPara = rtw_zmalloc(sizeof(struct sitesurvey_parm)); 621 if (psurveyPara == NULL) { 622 kfree(ph2c); 623 return _FAIL; 624 } 625 626 rtw_free_network_queue(padapter, false); 627 628 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("%s: flush network queue\n", __func__)); 629 630 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey)); 631 632 /* psurveyPara->bsslimit = 48; */ 633 psurveyPara->scan_mode = pmlmepriv->scan_mode; 634 635 /* prepare ssid list */ 636 if (ssid) { 637 int i; 638 for (i = 0; i < ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) { 639 if (ssid[i].SsidLength) { 640 memcpy(&psurveyPara->ssid[i], &ssid[i], sizeof(struct ndis_802_11_ssid)); 641 psurveyPara->ssid_num++; 642 643 DBG_871X(FUNC_ADPT_FMT" ssid:(%s, %d)\n", FUNC_ADPT_ARG(padapter), 644 psurveyPara->ssid[i].Ssid, psurveyPara->ssid[i].SsidLength); 645 } 646 } 647 } 648 649 /* prepare channel list */ 650 if (ch) { 651 int i; 652 for (i = 0; i < ch_num && i < RTW_CHANNEL_SCAN_AMOUNT; i++) { 653 if (ch[i].hw_value && !(ch[i].flags & RTW_IEEE80211_CHAN_DISABLED)) { 654 memcpy(&psurveyPara->ch[i], &ch[i], sizeof(struct rtw_ieee80211_channel)); 655 psurveyPara->ch_num++; 656 657 DBG_871X(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), 658 psurveyPara->ch[i].hw_value); 659 } 660 } 661 } 662 663 set_fwstate(pmlmepriv, _FW_UNDER_SURVEY); 664 665 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 666 667 if (res == _SUCCESS) { 668 669 pmlmepriv->scan_start_time = jiffies; 670 _set_timer(&pmlmepriv->scan_to_timer, SCANNING_TIMEOUT); 671 } else { 672 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); 673 } 674 return res; 675 } 676 677 u8 rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset) 678 { 679 struct cmd_obj *ph2c; 680 struct setdatarate_parm *pbsetdataratepara; 681 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 682 u8 res = _SUCCESS; 683 684 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 685 if (ph2c == NULL) { 686 res = _FAIL; 687 goto exit; 688 } 689 690 pbsetdataratepara = rtw_zmalloc(sizeof(struct setdatarate_parm)); 691 if (pbsetdataratepara == NULL) { 692 kfree(ph2c); 693 res = _FAIL; 694 goto exit; 695 } 696 697 init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, GEN_CMD_CODE(_SetDataRate)); 698 pbsetdataratepara->mac_id = 5; 699 memcpy(pbsetdataratepara->datarates, rateset, NumRates); 700 701 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 702 exit: 703 return res; 704 } 705 706 void rtw_getbbrfreg_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) 707 { 708 /* rtw_free_cmd_obj(pcmd); */ 709 kfree(pcmd->parmbuf); 710 kfree(pcmd); 711 } 712 713 u8 rtw_createbss_cmd(struct adapter *padapter) 714 { 715 struct cmd_obj *pcmd; 716 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 717 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 718 struct wlan_bssid_ex *pdev_network = &padapter->registrypriv.dev_network; 719 u8 res = _SUCCESS; 720 721 if (pmlmepriv->assoc_ssid.SsidLength == 0) { 722 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for Any SSid:%s\n", pmlmepriv->assoc_ssid.Ssid)); 723 } else { 724 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid)); 725 } 726 727 pcmd = rtw_zmalloc(sizeof(struct cmd_obj)); 728 if (pcmd == NULL) { 729 res = _FAIL; 730 goto exit; 731 } 732 733 INIT_LIST_HEAD(&pcmd->list); 734 pcmd->cmdcode = _CreateBss_CMD_; 735 pcmd->parmbuf = (unsigned char *)pdev_network; 736 pcmd->cmdsz = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network); 737 pcmd->rsp = NULL; 738 pcmd->rspsz = 0; 739 740 pdev_network->Length = pcmd->cmdsz; 741 742 res = rtw_enqueue_cmd(pcmdpriv, pcmd); 743 744 exit: 745 return res; 746 } 747 748 u8 rtw_startbss_cmd(struct adapter *padapter, int flags) 749 { 750 struct cmd_obj *pcmd; 751 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 752 struct submit_ctx sctx; 753 u8 res = _SUCCESS; 754 755 if (flags & RTW_CMDF_DIRECTLY) { 756 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ 757 start_bss_network(padapter, (u8 *)&(padapter->mlmepriv.cur_network.network)); 758 } else { 759 /* need enqueue, prepare cmd_obj and enqueue */ 760 pcmd = rtw_zmalloc(sizeof(struct cmd_obj)); 761 if (pcmd == NULL) { 762 res = _FAIL; 763 goto exit; 764 } 765 766 INIT_LIST_HEAD(&pcmd->list); 767 pcmd->cmdcode = GEN_CMD_CODE(_CreateBss); 768 pcmd->parmbuf = NULL; 769 pcmd->cmdsz = 0; 770 pcmd->rsp = NULL; 771 pcmd->rspsz = 0; 772 773 if (flags & RTW_CMDF_WAIT_ACK) { 774 pcmd->sctx = &sctx; 775 rtw_sctx_init(&sctx, 2000); 776 } 777 778 res = rtw_enqueue_cmd(pcmdpriv, pcmd); 779 780 if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) { 781 rtw_sctx_wait(&sctx, __func__); 782 if (mutex_lock_interruptible(&pcmdpriv->sctx_mutex) == 0) { 783 if (sctx.status == RTW_SCTX_SUBMITTED) 784 pcmd->sctx = NULL; 785 mutex_unlock(&pcmdpriv->sctx_mutex); 786 } 787 } 788 } 789 790 exit: 791 return res; 792 } 793 794 u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) 795 { 796 u8 *auth, res = _SUCCESS; 797 uint t_len = 0; 798 struct wlan_bssid_ex *psecnetwork; 799 struct cmd_obj *pcmd; 800 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 801 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 802 struct qos_priv *pqospriv = &pmlmepriv->qospriv; 803 struct security_priv *psecuritypriv = &padapter->securitypriv; 804 struct registry_priv *pregistrypriv = &padapter->registrypriv; 805 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 806 enum NDIS_802_11_NETWORK_INFRASTRUCTURE ndis_network_mode = pnetwork->network.InfrastructureMode; 807 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 808 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 809 u32 tmp_len; 810 u8 *ptmp = NULL; 811 812 if (pmlmepriv->assoc_ssid.SsidLength == 0) { 813 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+Join cmd: Any SSid\n")); 814 } else { 815 RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.Ssid)); 816 } 817 818 pcmd = rtw_zmalloc(sizeof(struct cmd_obj)); 819 if (pcmd == NULL) { 820 res = _FAIL; 821 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd: memory allocate for cmd_obj fail!!!\n")); 822 goto exit; 823 } 824 /* for IEs is fix buf size */ 825 t_len = sizeof(struct wlan_bssid_ex); 826 827 828 /* for hidden ap to set fw_state here */ 829 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) != true) { 830 switch (ndis_network_mode) { 831 case Ndis802_11IBSS: 832 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); 833 break; 834 835 case Ndis802_11Infrastructure: 836 set_fwstate(pmlmepriv, WIFI_STATION_STATE); 837 break; 838 839 case Ndis802_11APMode: 840 case Ndis802_11AutoUnknown: 841 case Ndis802_11InfrastructureMax: 842 break; 843 844 } 845 } 846 847 psecnetwork = (struct wlan_bssid_ex *)&psecuritypriv->sec_bss; 848 if (psecnetwork == NULL) { 849 kfree(pcmd); 850 res = _FAIL; 851 852 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd :psecnetwork == NULL!!!\n")); 853 854 goto exit; 855 } 856 857 memset(psecnetwork, 0, t_len); 858 859 memcpy(psecnetwork, &pnetwork->network, get_wlan_bssid_ex_sz(&pnetwork->network)); 860 861 auth = &psecuritypriv->authenticator_ie[0]; 862 psecuritypriv->authenticator_ie[0] = (unsigned char)psecnetwork->IELength; 863 864 if ((psecnetwork->IELength-12) < (256-1)) { 865 memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], psecnetwork->IELength-12); 866 } else { 867 memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], (256-1)); 868 } 869 870 psecnetwork->IELength = 0; 871 /* Added by Albert 2009/02/18 */ 872 /* If the the driver wants to use the bssid to create the connection. */ 873 /* If not, we have to copy the connecting AP's MAC address to it so that */ 874 /* the driver just has the bssid information for PMKIDList searching. */ 875 876 if (pmlmepriv->assoc_by_bssid == false) { 877 memcpy(&pmlmepriv->assoc_bssid[0], &pnetwork->network.MacAddress[0], ETH_ALEN); 878 } 879 880 psecnetwork->IELength = rtw_restruct_sec_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength); 881 882 883 pqospriv->qos_option = 0; 884 885 if (pregistrypriv->wmm_enable) { 886 tmp_len = rtw_restruct_wmm_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength, psecnetwork->IELength); 887 888 if (psecnetwork->IELength != tmp_len) { 889 psecnetwork->IELength = tmp_len; 890 pqospriv->qos_option = 1; /* There is WMM IE in this corresp. beacon */ 891 } else{ 892 pqospriv->qos_option = 0;/* There is no WMM IE in this corresp. beacon */ 893 } 894 } 895 896 phtpriv->ht_option = false; 897 ptmp = rtw_get_ie(&pnetwork->network.IEs[12], _HT_CAPABILITY_IE_, &tmp_len, pnetwork->network.IELength-12); 898 if (pregistrypriv->ht_enable && ptmp && tmp_len > 0) { 899 /* Added by Albert 2010/06/23 */ 900 /* For the WEP mode, we will use the bg mode to do the connection to avoid some IOT issue. */ 901 /* Especially for Realtek 8192u SoftAP. */ 902 if ((padapter->securitypriv.dot11PrivacyAlgrthm != _WEP40_) && 903 (padapter->securitypriv.dot11PrivacyAlgrthm != _WEP104_) && 904 (padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_)) { 905 rtw_ht_use_default_setting(padapter); 906 907 rtw_build_wmm_ie_ht(padapter, &psecnetwork->IEs[12], &psecnetwork->IELength); 908 909 /* rtw_restructure_ht_ie */ 910 rtw_restructure_ht_ie(padapter, &pnetwork->network.IEs[12], &psecnetwork->IEs[0], 911 pnetwork->network.IELength-12, &psecnetwork->IELength, 912 pnetwork->network.Configuration.DSConfig); 913 } 914 } 915 916 rtw_append_exented_cap(padapter, &psecnetwork->IEs[0], &psecnetwork->IELength); 917 918 pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->network.IEs, pnetwork->network.IELength); 919 920 pcmd->cmdsz = get_wlan_bssid_ex_sz(psecnetwork);/* get cmdsz before endian conversion */ 921 922 INIT_LIST_HEAD(&pcmd->list); 923 pcmd->cmdcode = _JoinBss_CMD_;/* GEN_CMD_CODE(_JoinBss) */ 924 pcmd->parmbuf = (unsigned char *)psecnetwork; 925 pcmd->rsp = NULL; 926 pcmd->rspsz = 0; 927 928 res = rtw_enqueue_cmd(pcmdpriv, pcmd); 929 930 exit: 931 return res; 932 } 933 934 u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueue) /* for sta_mode */ 935 { 936 struct cmd_obj *cmdobj = NULL; 937 struct disconnect_parm *param = NULL; 938 struct cmd_priv *cmdpriv = &padapter->cmdpriv; 939 u8 res = _SUCCESS; 940 941 RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_disassoc_cmd\n")); 942 943 /* prepare cmd parameter */ 944 param = rtw_zmalloc(sizeof(*param)); 945 if (param == NULL) { 946 res = _FAIL; 947 goto exit; 948 } 949 param->deauth_timeout_ms = deauth_timeout_ms; 950 951 if (enqueue) { 952 /* need enqueue, prepare cmd_obj and enqueue */ 953 cmdobj = rtw_zmalloc(sizeof(*cmdobj)); 954 if (cmdobj == NULL) { 955 res = _FAIL; 956 kfree(param); 957 goto exit; 958 } 959 init_h2fwcmd_w_parm_no_rsp(cmdobj, param, _DisConnect_CMD_); 960 res = rtw_enqueue_cmd(cmdpriv, cmdobj); 961 } else { 962 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ 963 if (H2C_SUCCESS != disconnect_hdl(padapter, (u8 *)param)) 964 res = _FAIL; 965 kfree(param); 966 } 967 968 exit: 969 return res; 970 } 971 972 u8 rtw_setopmode_cmd(struct adapter *padapter, enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype, bool enqueue) 973 { 974 struct cmd_obj *ph2c; 975 struct setopmode_parm *psetop; 976 977 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 978 u8 res = _SUCCESS; 979 980 psetop = rtw_zmalloc(sizeof(struct setopmode_parm)); 981 982 if (psetop == NULL) { 983 res = _FAIL; 984 goto exit; 985 } 986 psetop->mode = (u8)networktype; 987 988 if (enqueue) { 989 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 990 if (ph2c == NULL) { 991 kfree(psetop); 992 res = _FAIL; 993 goto exit; 994 } 995 996 init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_); 997 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 998 } else{ 999 setopmode_hdl(padapter, (u8 *)psetop); 1000 kfree(psetop); 1001 } 1002 exit: 1003 return res; 1004 } 1005 1006 u8 rtw_setstakey_cmd(struct adapter *padapter, struct sta_info *sta, u8 unicast_key, bool enqueue) 1007 { 1008 struct cmd_obj *ph2c; 1009 struct set_stakey_parm *psetstakey_para; 1010 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1011 struct set_stakey_rsp *psetstakey_rsp = NULL; 1012 1013 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1014 struct security_priv *psecuritypriv = &padapter->securitypriv; 1015 u8 res = _SUCCESS; 1016 1017 psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm)); 1018 if (psetstakey_para == NULL) { 1019 res = _FAIL; 1020 goto exit; 1021 } 1022 1023 memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN); 1024 1025 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 1026 psetstakey_para->algorithm = (unsigned char) psecuritypriv->dot11PrivacyAlgrthm; 1027 } else { 1028 GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, false); 1029 } 1030 1031 if (unicast_key == true) { 1032 memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16); 1033 } else{ 1034 memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16); 1035 } 1036 1037 /* jeff: set this becasue at least sw key is ready */ 1038 padapter->securitypriv.busetkipkey = true; 1039 1040 if (enqueue) { 1041 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1042 if (ph2c == NULL) { 1043 kfree(psetstakey_para); 1044 res = _FAIL; 1045 goto exit; 1046 } 1047 1048 psetstakey_rsp = rtw_zmalloc(sizeof(struct set_stakey_rsp)); 1049 if (psetstakey_rsp == NULL) { 1050 kfree(ph2c); 1051 kfree(psetstakey_para); 1052 res = _FAIL; 1053 goto exit; 1054 } 1055 1056 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); 1057 ph2c->rsp = (u8 *) psetstakey_rsp; 1058 ph2c->rspsz = sizeof(struct set_stakey_rsp); 1059 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1060 } else{ 1061 set_stakey_hdl(padapter, (u8 *)psetstakey_para); 1062 kfree(psetstakey_para); 1063 } 1064 exit: 1065 return res; 1066 } 1067 1068 u8 rtw_clearstakey_cmd(struct adapter *padapter, struct sta_info *sta, u8 enqueue) 1069 { 1070 struct cmd_obj *ph2c; 1071 struct set_stakey_parm *psetstakey_para; 1072 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1073 struct set_stakey_rsp *psetstakey_rsp = NULL; 1074 s16 cam_id = 0; 1075 u8 res = _SUCCESS; 1076 1077 if (!enqueue) { 1078 while ((cam_id = rtw_camid_search(padapter, sta->hwaddr, -1)) >= 0) { 1079 DBG_871X_LEVEL(_drv_always_, "clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(sta->hwaddr), cam_id); 1080 clear_cam_entry(padapter, cam_id); 1081 rtw_camid_free(padapter, cam_id); 1082 } 1083 } else{ 1084 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1085 if (ph2c == NULL) { 1086 res = _FAIL; 1087 goto exit; 1088 } 1089 1090 psetstakey_para = rtw_zmalloc(sizeof(struct set_stakey_parm)); 1091 if (psetstakey_para == NULL) { 1092 kfree(ph2c); 1093 res = _FAIL; 1094 goto exit; 1095 } 1096 1097 psetstakey_rsp = rtw_zmalloc(sizeof(struct set_stakey_rsp)); 1098 if (psetstakey_rsp == NULL) { 1099 kfree(ph2c); 1100 kfree(psetstakey_para); 1101 res = _FAIL; 1102 goto exit; 1103 } 1104 1105 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); 1106 ph2c->rsp = (u8 *) psetstakey_rsp; 1107 ph2c->rspsz = sizeof(struct set_stakey_rsp); 1108 1109 memcpy(psetstakey_para->addr, sta->hwaddr, ETH_ALEN); 1110 1111 psetstakey_para->algorithm = _NO_PRIVACY_; 1112 1113 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1114 1115 } 1116 1117 exit: 1118 return res; 1119 } 1120 1121 u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr) 1122 { 1123 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1124 struct cmd_obj *ph2c; 1125 struct addBaReq_parm *paddbareq_parm; 1126 1127 u8 res = _SUCCESS; 1128 1129 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1130 if (ph2c == NULL) { 1131 res = _FAIL; 1132 goto exit; 1133 } 1134 1135 paddbareq_parm = rtw_zmalloc(sizeof(struct addBaReq_parm)); 1136 if (paddbareq_parm == NULL) { 1137 kfree(ph2c); 1138 res = _FAIL; 1139 goto exit; 1140 } 1141 1142 paddbareq_parm->tid = tid; 1143 memcpy(paddbareq_parm->addr, addr, ETH_ALEN); 1144 1145 init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, GEN_CMD_CODE(_AddBAReq)); 1146 1147 /* DBG_871X("rtw_addbareq_cmd, tid =%d\n", tid); */ 1148 1149 /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ 1150 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1151 1152 exit: 1153 return res; 1154 } 1155 /* add for CONFIG_IEEE80211W, none 11w can use it */ 1156 u8 rtw_reset_securitypriv_cmd(struct adapter *padapter) 1157 { 1158 struct cmd_obj *ph2c; 1159 struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1160 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1161 u8 res = _SUCCESS; 1162 1163 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1164 if (ph2c == NULL) { 1165 res = _FAIL; 1166 goto exit; 1167 } 1168 1169 pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1170 if (pdrvextra_cmd_parm == NULL) { 1171 kfree(ph2c); 1172 res = _FAIL; 1173 goto exit; 1174 } 1175 1176 pdrvextra_cmd_parm->ec_id = RESET_SECURITYPRIV; 1177 pdrvextra_cmd_parm->type = 0; 1178 pdrvextra_cmd_parm->size = 0; 1179 pdrvextra_cmd_parm->pbuf = NULL; 1180 1181 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1182 1183 1184 /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ 1185 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1186 1187 exit: 1188 return res; 1189 } 1190 1191 u8 rtw_free_assoc_resources_cmd(struct adapter *padapter) 1192 { 1193 struct cmd_obj *ph2c; 1194 struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1195 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1196 u8 res = _SUCCESS; 1197 1198 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1199 if (ph2c == NULL) { 1200 res = _FAIL; 1201 goto exit; 1202 } 1203 1204 pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1205 if (pdrvextra_cmd_parm == NULL) { 1206 kfree(ph2c); 1207 res = _FAIL; 1208 goto exit; 1209 } 1210 1211 pdrvextra_cmd_parm->ec_id = FREE_ASSOC_RESOURCES; 1212 pdrvextra_cmd_parm->type = 0; 1213 pdrvextra_cmd_parm->size = 0; 1214 pdrvextra_cmd_parm->pbuf = NULL; 1215 1216 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1217 1218 1219 /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ 1220 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1221 1222 exit: 1223 return res; 1224 } 1225 1226 u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter) 1227 { 1228 struct cmd_obj *ph2c; 1229 struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1230 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1231 u8 res = _SUCCESS; 1232 1233 /* only primary padapter does this cmd */ 1234 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1235 if (ph2c == NULL) { 1236 res = _FAIL; 1237 goto exit; 1238 } 1239 1240 pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1241 if (pdrvextra_cmd_parm == NULL) { 1242 kfree(ph2c); 1243 res = _FAIL; 1244 goto exit; 1245 } 1246 1247 pdrvextra_cmd_parm->ec_id = DYNAMIC_CHK_WK_CID; 1248 pdrvextra_cmd_parm->type = 0; 1249 pdrvextra_cmd_parm->size = 0; 1250 pdrvextra_cmd_parm->pbuf = NULL; 1251 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1252 1253 1254 /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ 1255 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1256 1257 exit: 1258 return res; 1259 } 1260 1261 u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue, u8 swconfig) 1262 { 1263 struct cmd_obj *pcmdobj; 1264 struct SetChannelPlan_param *setChannelPlan_param; 1265 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1266 1267 u8 res = _SUCCESS; 1268 1269 RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_chplan_cmd\n")); 1270 1271 /* check if allow software config */ 1272 if (swconfig && rtw_hal_is_disable_sw_channel_plan(padapter) == true) { 1273 res = _FAIL; 1274 goto exit; 1275 } 1276 1277 /* check input parameter */ 1278 if (!rtw_is_channel_plan_valid(chplan)) { 1279 res = _FAIL; 1280 goto exit; 1281 } 1282 1283 /* prepare cmd parameter */ 1284 setChannelPlan_param = rtw_zmalloc(sizeof(struct SetChannelPlan_param)); 1285 if (setChannelPlan_param == NULL) { 1286 res = _FAIL; 1287 goto exit; 1288 } 1289 setChannelPlan_param->channel_plan = chplan; 1290 1291 if (enqueue) { 1292 /* need enqueue, prepare cmd_obj and enqueue */ 1293 pcmdobj = rtw_zmalloc(sizeof(struct cmd_obj)); 1294 if (pcmdobj == NULL) { 1295 kfree(setChannelPlan_param); 1296 res = _FAIL; 1297 goto exit; 1298 } 1299 1300 init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelPlan_param, GEN_CMD_CODE(_SetChannelPlan)); 1301 res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); 1302 } else{ 1303 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ 1304 if (H2C_SUCCESS != set_chplan_hdl(padapter, (unsigned char *)setChannelPlan_param)) 1305 res = _FAIL; 1306 1307 kfree(setChannelPlan_param); 1308 } 1309 1310 /* do something based on res... */ 1311 if (res == _SUCCESS) 1312 padapter->mlmepriv.ChannelPlan = chplan; 1313 1314 exit: 1315 return res; 1316 } 1317 1318 static void collect_traffic_statistics(struct adapter *padapter) 1319 { 1320 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter); 1321 1322 /* Tx */ 1323 pdvobjpriv->traffic_stat.tx_bytes = padapter->xmitpriv.tx_bytes; 1324 pdvobjpriv->traffic_stat.tx_pkts = padapter->xmitpriv.tx_pkts; 1325 pdvobjpriv->traffic_stat.tx_drop = padapter->xmitpriv.tx_drop; 1326 1327 /* Rx */ 1328 pdvobjpriv->traffic_stat.rx_bytes = padapter->recvpriv.rx_bytes; 1329 pdvobjpriv->traffic_stat.rx_pkts = padapter->recvpriv.rx_pkts; 1330 pdvobjpriv->traffic_stat.rx_drop = padapter->recvpriv.rx_drop; 1331 1332 /* Calculate throughput in last interval */ 1333 pdvobjpriv->traffic_stat.cur_tx_bytes = pdvobjpriv->traffic_stat.tx_bytes - pdvobjpriv->traffic_stat.last_tx_bytes; 1334 pdvobjpriv->traffic_stat.cur_rx_bytes = pdvobjpriv->traffic_stat.rx_bytes - pdvobjpriv->traffic_stat.last_rx_bytes; 1335 pdvobjpriv->traffic_stat.last_tx_bytes = pdvobjpriv->traffic_stat.tx_bytes; 1336 pdvobjpriv->traffic_stat.last_rx_bytes = pdvobjpriv->traffic_stat.rx_bytes; 1337 1338 pdvobjpriv->traffic_stat.cur_tx_tp = (u32)(pdvobjpriv->traffic_stat.cur_tx_bytes * 8/2/1024/1024); 1339 pdvobjpriv->traffic_stat.cur_rx_tp = (u32)(pdvobjpriv->traffic_stat.cur_rx_bytes * 8/2/1024/1024); 1340 } 1341 1342 u8 traffic_status_watchdog(struct adapter *padapter, u8 from_timer) 1343 { 1344 u8 bEnterPS = false; 1345 u16 BusyThresholdHigh = 25; 1346 u16 BusyThresholdLow = 10; 1347 u16 BusyThreshold = BusyThresholdHigh; 1348 u8 bBusyTraffic = false, bTxBusyTraffic = false, bRxBusyTraffic = false; 1349 u8 bHigherBusyTraffic = false, bHigherBusyRxTraffic = false, bHigherBusyTxTraffic = false; 1350 1351 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1352 1353 collect_traffic_statistics(padapter); 1354 1355 /* */ 1356 /* Determine if our traffic is busy now */ 1357 /* */ 1358 if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) 1359 /*&& !MgntInitAdapterInProgress(pMgntInfo)*/) { 1360 /* if we raise bBusyTraffic in last watchdog, using lower threshold. */ 1361 if (pmlmepriv->LinkDetectInfo.bBusyTraffic) 1362 BusyThreshold = BusyThresholdLow; 1363 1364 if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > BusyThreshold || 1365 pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > BusyThreshold) { 1366 bBusyTraffic = true; 1367 1368 if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) 1369 bRxBusyTraffic = true; 1370 else 1371 bTxBusyTraffic = true; 1372 } 1373 1374 /* Higher Tx/Rx data. */ 1375 if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 4000 || 1376 pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000) { 1377 bHigherBusyTraffic = true; 1378 1379 if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) 1380 bHigherBusyRxTraffic = true; 1381 else 1382 bHigherBusyTxTraffic = true; 1383 } 1384 1385 /* check traffic for powersaving. */ 1386 if (((pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) > 8) || 1387 (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 2)) { 1388 /* DBG_871X("(-)Tx = %d, Rx = %d\n", pmlmepriv->LinkDetectInfo.NumTxOkInPeriod, pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod); */ 1389 bEnterPS = false; 1390 1391 if (bBusyTraffic == true) { 1392 if (pmlmepriv->LinkDetectInfo.TrafficTransitionCount <= 4) 1393 pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 4; 1394 1395 pmlmepriv->LinkDetectInfo.TrafficTransitionCount++; 1396 1397 /* DBG_871X("Set TrafficTransitionCount to %d\n", pmlmepriv->LinkDetectInfo.TrafficTransitionCount); */ 1398 1399 if (pmlmepriv->LinkDetectInfo.TrafficTransitionCount > 30/*TrafficTransitionLevel*/) { 1400 pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 30; 1401 } 1402 } 1403 } else{ 1404 /* DBG_871X("(+)Tx = %d, Rx = %d\n", pmlmepriv->LinkDetectInfo.NumTxOkInPeriod, pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod); */ 1405 1406 if (pmlmepriv->LinkDetectInfo.TrafficTransitionCount >= 2) 1407 pmlmepriv->LinkDetectInfo.TrafficTransitionCount -= 2; 1408 else 1409 pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0; 1410 1411 if (pmlmepriv->LinkDetectInfo.TrafficTransitionCount == 0) 1412 bEnterPS = true; 1413 } 1414 1415 /* LeisurePS only work in infra mode. */ 1416 if (bEnterPS) { 1417 if (!from_timer) 1418 LPS_Enter(padapter, "TRAFFIC_IDLE"); 1419 } else { 1420 if (!from_timer) 1421 LPS_Leave(padapter, "TRAFFIC_BUSY"); 1422 else 1423 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_TRAFFIC_BUSY, 1); 1424 } 1425 } else{ 1426 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter); 1427 int n_assoc_iface = 0; 1428 1429 if (check_fwstate(&(dvobj->padapters->mlmepriv), WIFI_ASOC_STATE)) 1430 n_assoc_iface++; 1431 1432 if (!from_timer && n_assoc_iface == 0) 1433 LPS_Leave(padapter, "NON_LINKED"); 1434 } 1435 1436 pmlmepriv->LinkDetectInfo.NumRxOkInPeriod = 0; 1437 pmlmepriv->LinkDetectInfo.NumTxOkInPeriod = 0; 1438 pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod = 0; 1439 pmlmepriv->LinkDetectInfo.bBusyTraffic = bBusyTraffic; 1440 pmlmepriv->LinkDetectInfo.bTxBusyTraffic = bTxBusyTraffic; 1441 pmlmepriv->LinkDetectInfo.bRxBusyTraffic = bRxBusyTraffic; 1442 pmlmepriv->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic; 1443 pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic; 1444 pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic; 1445 1446 return bEnterPS; 1447 1448 } 1449 1450 static void dynamic_chk_wk_hdl(struct adapter *padapter) 1451 { 1452 struct mlme_priv *pmlmepriv; 1453 pmlmepriv = &(padapter->mlmepriv); 1454 1455 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) { 1456 expire_timeout_chk(padapter); 1457 } 1458 1459 /* for debug purpose */ 1460 _linked_info_dump(padapter); 1461 1462 1463 /* if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING|_FW_UNDER_SURVEY) ==false) */ 1464 { 1465 linked_status_chk(padapter); 1466 traffic_status_watchdog(padapter, 0); 1467 } 1468 1469 rtw_hal_dm_watchdog(padapter); 1470 1471 /* check_hw_pbc(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type); */ 1472 1473 /* */ 1474 /* BT-Coexist */ 1475 /* */ 1476 rtw_btcoex_Handler(padapter); 1477 1478 1479 /* always call rtw_ps_processor() at last one. */ 1480 if (is_primary_adapter(padapter)) 1481 rtw_ps_processor(padapter); 1482 } 1483 1484 void lps_ctrl_wk_hdl(struct adapter *padapter, u8 lps_ctrl_type); 1485 void lps_ctrl_wk_hdl(struct adapter *padapter, u8 lps_ctrl_type) 1486 { 1487 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); 1488 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1489 u8 mstatus; 1490 1491 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) 1492 || (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) { 1493 return; 1494 } 1495 1496 switch (lps_ctrl_type) { 1497 case LPS_CTRL_SCAN: 1498 /* DBG_871X("LPS_CTRL_SCAN\n"); */ 1499 rtw_btcoex_ScanNotify(padapter, true); 1500 1501 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { 1502 /* connect */ 1503 LPS_Leave(padapter, "LPS_CTRL_SCAN"); 1504 } 1505 break; 1506 case LPS_CTRL_JOINBSS: 1507 /* DBG_871X("LPS_CTRL_JOINBSS\n"); */ 1508 LPS_Leave(padapter, "LPS_CTRL_JOINBSS"); 1509 break; 1510 case LPS_CTRL_CONNECT: 1511 /* DBG_871X("LPS_CTRL_CONNECT\n"); */ 1512 mstatus = 1;/* connect */ 1513 /* Reset LPS Setting */ 1514 pwrpriv->LpsIdleCount = 0; 1515 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus)); 1516 rtw_btcoex_MediaStatusNotify(padapter, mstatus); 1517 break; 1518 case LPS_CTRL_DISCONNECT: 1519 /* DBG_871X("LPS_CTRL_DISCONNECT\n"); */ 1520 mstatus = 0;/* disconnect */ 1521 rtw_btcoex_MediaStatusNotify(padapter, mstatus); 1522 LPS_Leave(padapter, "LPS_CTRL_DISCONNECT"); 1523 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus)); 1524 break; 1525 case LPS_CTRL_SPECIAL_PACKET: 1526 /* DBG_871X("LPS_CTRL_SPECIAL_PACKET\n"); */ 1527 pwrpriv->DelayLPSLastTimeStamp = jiffies; 1528 rtw_btcoex_SpecialPacketNotify(padapter, PACKET_DHCP); 1529 LPS_Leave(padapter, "LPS_CTRL_SPECIAL_PACKET"); 1530 break; 1531 case LPS_CTRL_LEAVE: 1532 /* DBG_871X("LPS_CTRL_LEAVE\n"); */ 1533 LPS_Leave(padapter, "LPS_CTRL_LEAVE"); 1534 break; 1535 case LPS_CTRL_TRAFFIC_BUSY: 1536 LPS_Leave(padapter, "LPS_CTRL_TRAFFIC_BUSY"); 1537 default: 1538 break; 1539 } 1540 } 1541 1542 u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue) 1543 { 1544 struct cmd_obj *ph2c; 1545 struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1546 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1547 /* struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter); */ 1548 u8 res = _SUCCESS; 1549 1550 /* if (!pwrctrlpriv->bLeisurePs) */ 1551 /* return res; */ 1552 1553 if (enqueue) { 1554 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1555 if (ph2c == NULL) { 1556 res = _FAIL; 1557 goto exit; 1558 } 1559 1560 pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1561 if (pdrvextra_cmd_parm == NULL) { 1562 kfree(ph2c); 1563 res = _FAIL; 1564 goto exit; 1565 } 1566 1567 pdrvextra_cmd_parm->ec_id = LPS_CTRL_WK_CID; 1568 pdrvextra_cmd_parm->type = lps_ctrl_type; 1569 pdrvextra_cmd_parm->size = 0; 1570 pdrvextra_cmd_parm->pbuf = NULL; 1571 1572 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1573 1574 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1575 } else{ 1576 lps_ctrl_wk_hdl(padapter, lps_ctrl_type); 1577 } 1578 1579 exit: 1580 return res; 1581 } 1582 1583 static void rtw_dm_in_lps_hdl(struct adapter *padapter) 1584 { 1585 rtw_hal_set_hwreg(padapter, HW_VAR_DM_IN_LPS, NULL); 1586 } 1587 1588 u8 rtw_dm_in_lps_wk_cmd(struct adapter *padapter) 1589 { 1590 struct cmd_obj *ph2c; 1591 struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1592 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1593 u8 res = _SUCCESS; 1594 1595 1596 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1597 if (ph2c == NULL) { 1598 res = _FAIL; 1599 goto exit; 1600 } 1601 1602 pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1603 if (pdrvextra_cmd_parm == NULL) { 1604 kfree(ph2c); 1605 res = _FAIL; 1606 goto exit; 1607 } 1608 1609 pdrvextra_cmd_parm->ec_id = DM_IN_LPS_WK_CID; 1610 pdrvextra_cmd_parm->type = 0; 1611 pdrvextra_cmd_parm->size = 0; 1612 pdrvextra_cmd_parm->pbuf = NULL; 1613 1614 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1615 1616 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1617 1618 exit: 1619 1620 return res; 1621 1622 } 1623 1624 static void rtw_lps_change_dtim_hdl(struct adapter *padapter, u8 dtim) 1625 { 1626 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter); 1627 1628 if (dtim <= 0 || dtim > 16) 1629 return; 1630 1631 if (rtw_btcoex_IsBtControlLps(padapter) == true) 1632 return; 1633 1634 down(&pwrpriv->lock); 1635 1636 if (pwrpriv->dtim != dtim) { 1637 DBG_871X("change DTIM from %d to %d, bFwCurrentInPSMode =%d, ps_mode =%d\n", pwrpriv->dtim, dtim, 1638 pwrpriv->bFwCurrentInPSMode, pwrpriv->pwr_mode); 1639 1640 pwrpriv->dtim = dtim; 1641 } 1642 1643 if ((pwrpriv->bFwCurrentInPSMode == true) && (pwrpriv->pwr_mode > PS_MODE_ACTIVE)) { 1644 u8 ps_mode = pwrpriv->pwr_mode; 1645 1646 /* DBG_871X("change DTIM from %d to %d, ps_mode =%d\n", pwrpriv->dtim, dtim, ps_mode); */ 1647 1648 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_PWRMODE, (u8 *)(&ps_mode)); 1649 } 1650 1651 up(&pwrpriv->lock); 1652 } 1653 1654 static void rtw_dm_ra_mask_hdl(struct adapter *padapter, struct sta_info *psta) 1655 { 1656 if (psta) { 1657 set_sta_rate(padapter, psta); 1658 } 1659 } 1660 1661 u8 rtw_dm_ra_mask_wk_cmd(struct adapter *padapter, u8 *psta) 1662 { 1663 struct cmd_obj *ph2c; 1664 struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1665 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1666 u8 res = _SUCCESS; 1667 1668 1669 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1670 if (ph2c == NULL) { 1671 res = _FAIL; 1672 goto exit; 1673 } 1674 1675 pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1676 if (pdrvextra_cmd_parm == NULL) { 1677 kfree(ph2c); 1678 res = _FAIL; 1679 goto exit; 1680 } 1681 1682 pdrvextra_cmd_parm->ec_id = DM_RA_MSK_WK_CID; 1683 pdrvextra_cmd_parm->type = 0; 1684 pdrvextra_cmd_parm->size = 0; 1685 pdrvextra_cmd_parm->pbuf = psta; 1686 1687 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1688 1689 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1690 1691 exit: 1692 1693 return res; 1694 1695 } 1696 1697 static void power_saving_wk_hdl(struct adapter *padapter) 1698 { 1699 rtw_ps_processor(padapter); 1700 } 1701 1702 /* add for CONFIG_IEEE80211W, none 11w can use it */ 1703 static void reset_securitypriv_hdl(struct adapter *padapter) 1704 { 1705 rtw_reset_securitypriv(padapter); 1706 } 1707 1708 static void free_assoc_resources_hdl(struct adapter *padapter) 1709 { 1710 rtw_free_assoc_resources(padapter, 1); 1711 } 1712 1713 u8 rtw_ps_cmd(struct adapter *padapter) 1714 { 1715 struct cmd_obj *ppscmd; 1716 struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1717 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1718 u8 res = _SUCCESS; 1719 1720 ppscmd = rtw_zmalloc(sizeof(struct cmd_obj)); 1721 if (ppscmd == NULL) { 1722 res = _FAIL; 1723 goto exit; 1724 } 1725 1726 pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1727 if (pdrvextra_cmd_parm == NULL) { 1728 kfree(ppscmd); 1729 res = _FAIL; 1730 goto exit; 1731 } 1732 1733 pdrvextra_cmd_parm->ec_id = POWER_SAVING_CTRL_WK_CID; 1734 pdrvextra_cmd_parm->type = 0; 1735 pdrvextra_cmd_parm->size = 0; 1736 pdrvextra_cmd_parm->pbuf = NULL; 1737 init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1738 1739 res = rtw_enqueue_cmd(pcmdpriv, ppscmd); 1740 1741 exit: 1742 return res; 1743 } 1744 1745 u32 g_wait_hiq_empty = 0; 1746 1747 static void rtw_chk_hi_queue_hdl(struct adapter *padapter) 1748 { 1749 struct sta_info *psta_bmc; 1750 struct sta_priv *pstapriv = &padapter->stapriv; 1751 unsigned long start = jiffies; 1752 u8 empty = false; 1753 1754 psta_bmc = rtw_get_bcmc_stainfo(padapter); 1755 if (!psta_bmc) 1756 return; 1757 1758 rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &empty); 1759 1760 while (false == empty && jiffies_to_msecs(jiffies - start) < g_wait_hiq_empty) { 1761 msleep(100); 1762 rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &empty); 1763 } 1764 1765 if (psta_bmc->sleepq_len == 0) { 1766 if (empty == _SUCCESS) { 1767 bool update_tim = false; 1768 1769 if (pstapriv->tim_bitmap & BIT(0)) 1770 update_tim = true; 1771 1772 pstapriv->tim_bitmap &= ~BIT(0); 1773 pstapriv->sta_dz_bitmap &= ~BIT(0); 1774 1775 if (update_tim == true) 1776 update_beacon(padapter, _TIM_IE_, NULL, true); 1777 } else{/* re check again */ 1778 rtw_chk_hi_queue_cmd(padapter); 1779 } 1780 1781 } 1782 1783 } 1784 1785 u8 rtw_chk_hi_queue_cmd(struct adapter *padapter) 1786 { 1787 struct cmd_obj *ph2c; 1788 struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1789 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1790 u8 res = _SUCCESS; 1791 1792 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1793 if (ph2c == NULL) { 1794 res = _FAIL; 1795 goto exit; 1796 } 1797 1798 pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1799 if (pdrvextra_cmd_parm == NULL) { 1800 kfree(ph2c); 1801 res = _FAIL; 1802 goto exit; 1803 } 1804 1805 pdrvextra_cmd_parm->ec_id = CHECK_HIQ_WK_CID; 1806 pdrvextra_cmd_parm->type = 0; 1807 pdrvextra_cmd_parm->size = 0; 1808 pdrvextra_cmd_parm->pbuf = NULL; 1809 1810 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1811 1812 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1813 1814 exit: 1815 1816 return res; 1817 1818 } 1819 1820 struct btinfo { 1821 u8 cid; 1822 u8 len; 1823 1824 u8 bConnection:1; 1825 u8 bSCOeSCO:1; 1826 u8 bInQPage:1; 1827 u8 bACLBusy:1; 1828 u8 bSCOBusy:1; 1829 u8 bHID:1; 1830 u8 bA2DP:1; 1831 u8 bFTP:1; 1832 1833 u8 retry_cnt:4; 1834 u8 rsvd_34:1; 1835 u8 rsvd_35:1; 1836 u8 rsvd_36:1; 1837 u8 rsvd_37:1; 1838 1839 u8 rssi; 1840 1841 u8 rsvd_50:1; 1842 u8 rsvd_51:1; 1843 u8 rsvd_52:1; 1844 u8 rsvd_53:1; 1845 u8 rsvd_54:1; 1846 u8 rsvd_55:1; 1847 u8 eSCO_SCO:1; 1848 u8 Master_Slave:1; 1849 1850 u8 rsvd_6; 1851 u8 rsvd_7; 1852 }; 1853 1854 static void rtw_btinfo_hdl(struct adapter *adapter, u8 *buf, u16 buf_len) 1855 { 1856 #define BTINFO_WIFI_FETCH 0x23 1857 #define BTINFO_BT_AUTO_RPT 0x27 1858 struct btinfo *info = (struct btinfo *)buf; 1859 u8 cmd_idx; 1860 u8 len; 1861 1862 cmd_idx = info->cid; 1863 1864 if (info->len > buf_len-2) { 1865 rtw_warn_on(1); 1866 len = buf_len-2; 1867 } else { 1868 len = info->len; 1869 } 1870 1871 /* define DBG_PROC_SET_BTINFO_EVT */ 1872 #ifdef DBG_PROC_SET_BTINFO_EVT 1873 btinfo_evt_dump(RTW_DBGDUMP, info); 1874 #endif 1875 1876 /* transform BT-FW btinfo to WiFI-FW C2H format and notify */ 1877 if (cmd_idx == BTINFO_WIFI_FETCH) 1878 buf[1] = 0; 1879 else if (cmd_idx == BTINFO_BT_AUTO_RPT) 1880 buf[1] = 2; 1881 rtw_btcoex_BtInfoNotify(adapter, len+1, &buf[1]); 1882 } 1883 1884 u8 rtw_c2h_packet_wk_cmd(struct adapter *padapter, u8 *pbuf, u16 length) 1885 { 1886 struct cmd_obj *ph2c; 1887 struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1888 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1889 u8 res = _SUCCESS; 1890 1891 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1892 if (ph2c == NULL) { 1893 res = _FAIL; 1894 goto exit; 1895 } 1896 1897 pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1898 if (pdrvextra_cmd_parm == NULL) { 1899 kfree(ph2c); 1900 res = _FAIL; 1901 goto exit; 1902 } 1903 1904 pdrvextra_cmd_parm->ec_id = C2H_WK_CID; 1905 pdrvextra_cmd_parm->type = 0; 1906 pdrvextra_cmd_parm->size = length; 1907 pdrvextra_cmd_parm->pbuf = pbuf; 1908 1909 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1910 1911 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1912 1913 exit: 1914 return res; 1915 } 1916 1917 /* dont call R/W in this function, beucase SDIO interrupt have claim host */ 1918 /* or deadlock will happen and cause special-systemserver-died in android */ 1919 u8 rtw_c2h_wk_cmd(struct adapter *padapter, u8 *c2h_evt) 1920 { 1921 struct cmd_obj *ph2c; 1922 struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1923 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1924 u8 res = _SUCCESS; 1925 1926 ph2c = rtw_zmalloc(sizeof(struct cmd_obj)); 1927 if (ph2c == NULL) { 1928 res = _FAIL; 1929 goto exit; 1930 } 1931 1932 pdrvextra_cmd_parm = rtw_zmalloc(sizeof(struct drvextra_cmd_parm)); 1933 if (pdrvextra_cmd_parm == NULL) { 1934 kfree(ph2c); 1935 res = _FAIL; 1936 goto exit; 1937 } 1938 1939 pdrvextra_cmd_parm->ec_id = C2H_WK_CID; 1940 pdrvextra_cmd_parm->type = 0; 1941 pdrvextra_cmd_parm->size = c2h_evt?16:0; 1942 pdrvextra_cmd_parm->pbuf = c2h_evt; 1943 1944 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1945 1946 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1947 1948 exit: 1949 1950 return res; 1951 } 1952 1953 static void c2h_wk_callback(_workitem *work) 1954 { 1955 struct evt_priv *evtpriv = container_of(work, struct evt_priv, c2h_wk); 1956 struct adapter *adapter = container_of(evtpriv, struct adapter, evtpriv); 1957 u8 *c2h_evt; 1958 c2h_id_filter ccx_id_filter = rtw_hal_c2h_id_filter_ccx(adapter); 1959 1960 evtpriv->c2h_wk_alive = true; 1961 1962 while (!rtw_cbuf_empty(evtpriv->c2h_queue)) { 1963 c2h_evt = (u8 *)rtw_cbuf_pop(evtpriv->c2h_queue); 1964 if (c2h_evt != NULL) { 1965 /* This C2H event is read, clear it */ 1966 c2h_evt_clear(adapter); 1967 } else{ 1968 c2h_evt = rtw_malloc(16); 1969 if (c2h_evt != NULL) { 1970 /* This C2H event is not read, read & clear now */ 1971 if (rtw_hal_c2h_evt_read(adapter, c2h_evt) != _SUCCESS) { 1972 kfree(c2h_evt); 1973 continue; 1974 } 1975 } 1976 } 1977 1978 /* Special pointer to trigger c2h_evt_clear only */ 1979 if ((void *)c2h_evt == (void *)evtpriv) 1980 continue; 1981 1982 if (!rtw_hal_c2h_valid(adapter, c2h_evt)) { 1983 kfree(c2h_evt); 1984 continue; 1985 } 1986 1987 if (ccx_id_filter(c2h_evt) == true) { 1988 /* Handle CCX report here */ 1989 rtw_hal_c2h_handler(adapter, c2h_evt); 1990 kfree(c2h_evt); 1991 } else{ 1992 /* Enqueue into cmd_thread for others */ 1993 rtw_c2h_wk_cmd(adapter, c2h_evt); 1994 } 1995 } 1996 1997 evtpriv->c2h_wk_alive = false; 1998 } 1999 2000 u8 rtw_drvextra_cmd_hdl(struct adapter *padapter, unsigned char *pbuf) 2001 { 2002 struct drvextra_cmd_parm *pdrvextra_cmd; 2003 2004 if (!pbuf) 2005 return H2C_PARAMETERS_ERROR; 2006 2007 pdrvextra_cmd = (struct drvextra_cmd_parm *)pbuf; 2008 2009 switch (pdrvextra_cmd->ec_id) { 2010 case DYNAMIC_CHK_WK_CID:/* only primary padapter go to this cmd, but execute dynamic_chk_wk_hdl() for two interfaces */ 2011 dynamic_chk_wk_hdl(padapter); 2012 break; 2013 case POWER_SAVING_CTRL_WK_CID: 2014 power_saving_wk_hdl(padapter); 2015 break; 2016 case LPS_CTRL_WK_CID: 2017 lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type); 2018 break; 2019 case DM_IN_LPS_WK_CID: 2020 rtw_dm_in_lps_hdl(padapter); 2021 break; 2022 case LPS_CHANGE_DTIM_CID: 2023 rtw_lps_change_dtim_hdl(padapter, (u8)pdrvextra_cmd->type); 2024 break; 2025 case CHECK_HIQ_WK_CID: 2026 rtw_chk_hi_queue_hdl(padapter); 2027 break; 2028 #ifdef CONFIG_INTEL_WIDI 2029 case INTEl_WIDI_WK_CID: 2030 intel_widi_wk_hdl(padapter, pdrvextra_cmd->type, pdrvextra_cmd->pbuf); 2031 break; 2032 #endif /* CONFIG_INTEL_WIDI */ 2033 /* add for CONFIG_IEEE80211W, none 11w can use it */ 2034 case RESET_SECURITYPRIV: 2035 reset_securitypriv_hdl(padapter); 2036 break; 2037 case FREE_ASSOC_RESOURCES: 2038 free_assoc_resources_hdl(padapter); 2039 break; 2040 case C2H_WK_CID: 2041 rtw_hal_set_hwreg_with_buf(padapter, HW_VAR_C2H_HANDLE, pdrvextra_cmd->pbuf, pdrvextra_cmd->size); 2042 break; 2043 case DM_RA_MSK_WK_CID: 2044 rtw_dm_ra_mask_hdl(padapter, (struct sta_info *)pdrvextra_cmd->pbuf); 2045 break; 2046 case BTINFO_WK_CID: 2047 rtw_btinfo_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->size); 2048 break; 2049 default: 2050 break; 2051 } 2052 2053 if (pdrvextra_cmd->pbuf && pdrvextra_cmd->size > 0) { 2054 kfree(pdrvextra_cmd->pbuf); 2055 } 2056 2057 return H2C_SUCCESS; 2058 } 2059 2060 void rtw_survey_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) 2061 { 2062 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2063 2064 if (pcmd->res == H2C_DROPPED) { 2065 /* TODO: cancel timer and do timeout handler directly... */ 2066 /* need to make timeout handlerOS independent */ 2067 _set_timer(&pmlmepriv->scan_to_timer, 1); 2068 } else if (pcmd->res != H2C_SUCCESS) { 2069 _set_timer(&pmlmepriv->scan_to_timer, 1); 2070 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n ********Error: MgntActrtw_set_802_11_bssid_LIST_SCAN Fail ************\n\n.")); 2071 } 2072 2073 /* free cmd */ 2074 rtw_free_cmd_obj(pcmd); 2075 } 2076 2077 void rtw_disassoc_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) 2078 { 2079 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2080 2081 if (pcmd->res != H2C_SUCCESS) { 2082 spin_lock_bh(&pmlmepriv->lock); 2083 set_fwstate(pmlmepriv, _FW_LINKED); 2084 spin_unlock_bh(&pmlmepriv->lock); 2085 2086 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n ***Error: disconnect_cmd_callback Fail ***\n.")); 2087 return; 2088 } 2089 /* free cmd */ 2090 rtw_free_cmd_obj(pcmd); 2091 } 2092 2093 void rtw_joinbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) 2094 { 2095 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2096 2097 if (pcmd->res == H2C_DROPPED) { 2098 /* TODO: cancel timer and do timeout handler directly... */ 2099 /* need to make timeout handlerOS independent */ 2100 _set_timer(&pmlmepriv->assoc_timer, 1); 2101 } else if (pcmd->res != H2C_SUCCESS) { 2102 _set_timer(&pmlmepriv->assoc_timer, 1); 2103 } 2104 2105 rtw_free_cmd_obj(pcmd); 2106 } 2107 2108 void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) 2109 { 2110 u8 timer_cancelled; 2111 struct sta_info *psta = NULL; 2112 struct wlan_network *pwlan = NULL; 2113 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2114 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)pcmd->parmbuf; 2115 struct wlan_network *tgt_network = &(pmlmepriv->cur_network); 2116 2117 if (pcmd->parmbuf == NULL) 2118 goto exit; 2119 2120 if ((pcmd->res != H2C_SUCCESS)) { 2121 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n ********Error: rtw_createbss_cmd_callback Fail ************\n\n.")); 2122 _set_timer(&pmlmepriv->assoc_timer, 1); 2123 } 2124 2125 _cancel_timer(&pmlmepriv->assoc_timer, &timer_cancelled); 2126 2127 spin_lock_bh(&pmlmepriv->lock); 2128 2129 2130 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 2131 psta = rtw_get_stainfo(&padapter->stapriv, pnetwork->MacAddress); 2132 if (!psta) { 2133 psta = rtw_alloc_stainfo(&padapter->stapriv, pnetwork->MacAddress); 2134 if (psta == NULL) { 2135 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nCan't alloc sta_info when createbss_cmd_callback\n")); 2136 goto createbss_cmd_fail; 2137 } 2138 } 2139 2140 rtw_indicate_connect(padapter); 2141 } else{ 2142 pwlan = _rtw_alloc_network(pmlmepriv); 2143 spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); 2144 if (pwlan == NULL) { 2145 pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue); 2146 if (pwlan == NULL) { 2147 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n Error: can't get pwlan in rtw_joinbss_event_callback\n")); 2148 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); 2149 goto createbss_cmd_fail; 2150 } 2151 pwlan->last_scanned = jiffies; 2152 } else{ 2153 list_add_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue); 2154 } 2155 2156 pnetwork->Length = get_wlan_bssid_ex_sz(pnetwork); 2157 memcpy(&(pwlan->network), pnetwork, pnetwork->Length); 2158 /* pwlan->fixed = true; */ 2159 2160 /* list_add_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue); */ 2161 2162 /* copy pdev_network information to pmlmepriv->cur_network */ 2163 memcpy(&tgt_network->network, pnetwork, (get_wlan_bssid_ex_sz(pnetwork))); 2164 2165 /* reset DSConfig */ 2166 /* tgt_network->network.Configuration.DSConfig = (u32)rtw_ch2freq(pnetwork->Configuration.DSConfig); */ 2167 2168 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 2169 2170 spin_unlock_bh(&(pmlmepriv->scanned_queue.lock)); 2171 /* we will set _FW_LINKED when there is one more sat to join us (rtw_stassoc_event_callback) */ 2172 2173 } 2174 2175 createbss_cmd_fail: 2176 2177 spin_unlock_bh(&pmlmepriv->lock); 2178 exit: 2179 rtw_free_cmd_obj(pcmd); 2180 } 2181 2182 2183 2184 void rtw_setstaKey_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) 2185 { 2186 2187 struct sta_priv *pstapriv = &padapter->stapriv; 2188 struct set_stakey_rsp *psetstakey_rsp = (struct set_stakey_rsp *) (pcmd->rsp); 2189 struct sta_info *psta = rtw_get_stainfo(pstapriv, psetstakey_rsp->addr); 2190 2191 if (psta == NULL) { 2192 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nERROR: rtw_setstaKey_cmdrsp_callback => can't get sta_info\n\n")); 2193 goto exit; 2194 } 2195 exit: 2196 rtw_free_cmd_obj(pcmd); 2197 } 2198 2199 void rtw_setassocsta_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) 2200 { 2201 struct sta_priv *pstapriv = &padapter->stapriv; 2202 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2203 struct set_assocsta_parm *passocsta_parm = (struct set_assocsta_parm *)(pcmd->parmbuf); 2204 struct set_assocsta_rsp *passocsta_rsp = (struct set_assocsta_rsp *) (pcmd->rsp); 2205 struct sta_info *psta = rtw_get_stainfo(pstapriv, passocsta_parm->addr); 2206 2207 if (psta == NULL) { 2208 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nERROR: setassocsta_cmdrsp_callbac => can't get sta_info\n\n")); 2209 goto exit; 2210 } 2211 2212 psta->aid = psta->mac_id = passocsta_rsp->cam_id; 2213 2214 spin_lock_bh(&pmlmepriv->lock); 2215 2216 if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) && (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)) 2217 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 2218 2219 set_fwstate(pmlmepriv, _FW_LINKED); 2220 spin_unlock_bh(&pmlmepriv->lock); 2221 2222 exit: 2223 rtw_free_cmd_obj(pcmd); 2224 } 2225