rtw_cmd.c revision 2f3c7d5362fb54876a274bcdf9d91d3d02caa4bd
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 * You should have received a copy of the GNU General Public License along with 15 * this program; if not, write to the Free Software Foundation, Inc., 16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 17 * 18 * 19 ******************************************************************************/ 20#define _RTW_CMD_C_ 21 22#include <osdep_service.h> 23#include <drv_types.h> 24#include <recv_osdep.h> 25#include <cmd_osdep.h> 26#include <mlme_osdep.h> 27#include <rtw_mlme_ext.h> 28 29/* 30Caller and the rtw_cmd_thread can protect cmd_q by spin_lock. 31No irqsave is necessary. 32*/ 33 34int _rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) 35{ 36 int res = _SUCCESS; 37 38 39 sema_init(&(pcmdpriv->cmd_queue_sema), 0); 40 /* sema_init(&(pcmdpriv->cmd_done_sema), 0); */ 41 sema_init(&(pcmdpriv->terminate_cmdthread_sema), 0); 42 43 44 _rtw_init_queue(&(pcmdpriv->cmd_queue)); 45 46 /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */ 47 48 pcmdpriv->cmd_seq = 1; 49 50 pcmdpriv->cmd_allocated_buf = kzalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ, GFP_KERNEL); 51 52 if (pcmdpriv->cmd_allocated_buf == NULL) { 53 res = _FAIL; 54 goto exit; 55 } 56 57 pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ - ((size_t)(pcmdpriv->cmd_allocated_buf) & (CMDBUFF_ALIGN_SZ-1)); 58 59 pcmdpriv->rsp_allocated_buf = kzalloc(MAX_RSPSZ + 4, GFP_KERNEL); 60 61 if (pcmdpriv->rsp_allocated_buf == NULL) { 62 res = _FAIL; 63 goto exit; 64 } 65 66 pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 - ((size_t)(pcmdpriv->rsp_allocated_buf) & 3); 67 68 pcmdpriv->cmd_issued_cnt = 0; 69 pcmdpriv->cmd_done_cnt = 0; 70 pcmdpriv->rsp_cnt = 0; 71exit: 72 return res; 73} 74 75void _rtw_free_cmd_priv(struct cmd_priv *pcmdpriv) 76{ 77 78 if (pcmdpriv) { 79 kfree(pcmdpriv->cmd_allocated_buf); 80 kfree(pcmdpriv->rsp_allocated_buf); 81 } 82} 83 84/* 85Calling Context: 86 87rtw_enqueue_cmd can only be called between kernel thread, 88since only spin_lock is used. 89 90ISR/Call-Back functions can't call this sub-function. 91 92*/ 93 94int _rtw_enqueue_cmd(struct __queue *queue, struct cmd_obj *obj) 95{ 96 unsigned long irqL; 97 98 99 if (obj == NULL) 100 goto exit; 101 102 spin_lock_irqsave(&queue->lock, irqL); 103 104 list_add_tail(&obj->list, &queue->queue); 105 106 spin_unlock_irqrestore(&queue->lock, irqL); 107 108exit: 109 110 111 return _SUCCESS; 112} 113 114struct cmd_obj *_rtw_dequeue_cmd(struct __queue *queue) 115{ 116 unsigned long irqL; 117 struct cmd_obj *obj; 118 119 120 spin_lock_irqsave(&queue->lock, irqL); 121 if (list_empty(&(queue->queue))) { 122 obj = NULL; 123 } else { 124 obj = container_of((&queue->queue)->next, struct cmd_obj, list); 125 list_del_init(&obj->list); 126 } 127 128 spin_unlock_irqrestore(&queue->lock, irqL); 129 130 131 return obj; 132} 133 134u32 rtw_init_cmd_priv(struct cmd_priv *pcmdpriv) 135{ 136 u32 res; 137 res = _rtw_init_cmd_priv(pcmdpriv); 138 return res; 139} 140 141void rtw_free_cmd_priv(struct cmd_priv *pcmdpriv) 142{ 143 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("rtw_free_cmd_priv\n")); 144 _rtw_free_cmd_priv(pcmdpriv); 145} 146 147static int rtw_cmd_filter(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) 148{ 149 u8 bAllow = false; /* set to true to allow enqueuing cmd when hw_init_completed is false */ 150 151 /* To decide allow or not */ 152 if ((pcmdpriv->padapter->pwrctrlpriv.bHWPwrPindetect) && 153 (!pcmdpriv->padapter->registrypriv.usbss_enable)) { 154 if (cmd_obj->cmdcode == GEN_CMD_CODE(_Set_Drv_Extra)) { 155 struct drvextra_cmd_parm *pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)cmd_obj->parmbuf; 156 if (pdrvextra_cmd_parm->ec_id == POWER_SAVING_CTRL_WK_CID) 157 bAllow = true; 158 } 159 } 160 161 if (cmd_obj->cmdcode == GEN_CMD_CODE(_SetChannelPlan)) 162 bAllow = true; 163 164 if ((!pcmdpriv->padapter->hw_init_completed && !bAllow) || 165 !pcmdpriv->cmdthd_running) /* com_thread not running */ 166 return _FAIL; 167 return _SUCCESS; 168} 169 170u32 rtw_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *cmd_obj) 171{ 172 int res = _FAIL; 173 struct adapter *padapter = pcmdpriv->padapter; 174 175 176 if (cmd_obj == NULL) 177 goto exit; 178 179 cmd_obj->padapter = padapter; 180 181 res = rtw_cmd_filter(pcmdpriv, cmd_obj); 182 if (_FAIL == res) { 183 rtw_free_cmd_obj(cmd_obj); 184 goto exit; 185 } 186 187 res = _rtw_enqueue_cmd(&pcmdpriv->cmd_queue, cmd_obj); 188 189 if (res == _SUCCESS) 190 up(&pcmdpriv->cmd_queue_sema); 191 192exit: 193 194 195 return res; 196} 197 198struct cmd_obj *rtw_dequeue_cmd(struct cmd_priv *pcmdpriv) 199{ 200 struct cmd_obj *cmd_obj; 201 202 203 cmd_obj = _rtw_dequeue_cmd(&pcmdpriv->cmd_queue); 204 205 return cmd_obj; 206} 207 208void rtw_cmd_clr_isr(struct cmd_priv *pcmdpriv) 209{ 210 pcmdpriv->cmd_done_cnt++; 211 /* up(&(pcmdpriv->cmd_done_sema)); */ 212} 213 214void rtw_free_cmd_obj(struct cmd_obj *pcmd) 215{ 216 217 if ((pcmd->cmdcode != _JoinBss_CMD_) && (pcmd->cmdcode != _CreateBss_CMD_)) { 218 /* free parmbuf in cmd_obj */ 219 kfree(pcmd->parmbuf); 220 } 221 222 if (pcmd->rsp != NULL) { 223 if (pcmd->rspsz != 0) { 224 /* free rsp in cmd_obj */ 225 kfree(pcmd->rsp); 226 } 227 } 228 229 /* free cmd_obj */ 230 kfree(pcmd); 231 232} 233 234int rtw_cmd_thread(void *context) 235{ 236 u8 ret; 237 struct cmd_obj *pcmd; 238 u8 *pcmdbuf; 239 u8 (*cmd_hdl)(struct adapter *padapter, u8 *pbuf); 240 void (*pcmd_callback)(struct adapter *dev, struct cmd_obj *pcmd); 241 struct adapter *padapter = (struct adapter *)context; 242 struct cmd_priv *pcmdpriv = &(padapter->cmdpriv); 243 244 allow_signal(SIGTERM); 245 246 pcmdbuf = pcmdpriv->cmd_buf; 247 248 pcmdpriv->cmdthd_running = true; 249 up(&pcmdpriv->terminate_cmdthread_sema); 250 251 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("start r871x rtw_cmd_thread !!!!\n")); 252 253 while (1) { 254 if (_rtw_down_sema(&pcmdpriv->cmd_queue_sema) == _FAIL) 255 break; 256 257 if (padapter->bDriverStopped || 258 padapter->bSurpriseRemoved) { 259 DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n", 260 __func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__); 261 break; 262 } 263_next: 264 if (padapter->bDriverStopped || 265 padapter->bSurpriseRemoved) { 266 DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n", 267 __func__, padapter->bDriverStopped, padapter->bSurpriseRemoved, __LINE__); 268 break; 269 } 270 271 pcmd = rtw_dequeue_cmd(pcmdpriv); 272 if (!pcmd) 273 continue; 274 275 if (_FAIL == rtw_cmd_filter(pcmdpriv, pcmd)) { 276 pcmd->res = H2C_DROPPED; 277 goto post_process; 278 } 279 280 pcmdpriv->cmd_issued_cnt++; 281 282 pcmd->cmdsz = round_up(pcmd->cmdsz, 4); 283 284 memcpy(pcmdbuf, pcmd->parmbuf, pcmd->cmdsz); 285 286 if (pcmd->cmdcode < ARRAY_SIZE(wlancmds)) { 287 cmd_hdl = wlancmds[pcmd->cmdcode].h2cfuns; 288 289 if (cmd_hdl) { 290 ret = cmd_hdl(pcmd->padapter, pcmdbuf); 291 pcmd->res = ret; 292 } 293 294 pcmdpriv->cmd_seq++; 295 } else { 296 pcmd->res = H2C_PARAMETERS_ERROR; 297 } 298 299 cmd_hdl = NULL; 300 301post_process: 302 303 /* call callback function for post-processed */ 304 if (pcmd->cmdcode < ARRAY_SIZE(rtw_cmd_callback)) { 305 pcmd_callback = rtw_cmd_callback[pcmd->cmdcode].callback; 306 if (pcmd_callback == NULL) { 307 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("mlme_cmd_hdl(): pcmd_callback = 0x%p, cmdcode = 0x%x\n", pcmd_callback, pcmd->cmdcode)); 308 rtw_free_cmd_obj(pcmd); 309 } else { 310 /* todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!= NULL) */ 311 pcmd_callback(pcmd->padapter, pcmd);/* need conider that free cmd_obj in rtw_cmd_callback */ 312 } 313 } else { 314 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("%s: cmdcode = 0x%x callback not defined!\n", __func__, pcmd->cmdcode)); 315 rtw_free_cmd_obj(pcmd); 316 } 317 318 if (signal_pending(current)) 319 flush_signals(current); 320 321 goto _next; 322 } 323 pcmdpriv->cmdthd_running = false; 324 325 /* free all cmd_obj resources */ 326 do { 327 pcmd = rtw_dequeue_cmd(pcmdpriv); 328 if (pcmd == NULL) 329 break; 330 331 /* DBG_88E("%s: leaving... drop cmdcode:%u\n", __func__, pcmd->cmdcode); */ 332 333 rtw_free_cmd_obj(pcmd); 334 } while (1); 335 336 up(&pcmdpriv->terminate_cmdthread_sema); 337 338 339 complete_and_exit(NULL, 0); 340} 341 342u8 rtw_setstandby_cmd(struct adapter *padapter, uint action) 343{ 344 struct cmd_obj *ph2c; 345 struct usb_suspend_parm *psetusbsuspend; 346 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 347 348 u8 ret = _SUCCESS; 349 350 351 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 352 if (ph2c == NULL) { 353 ret = _FAIL; 354 goto exit; 355 } 356 357 psetusbsuspend = kzalloc(sizeof(struct usb_suspend_parm), GFP_KERNEL); 358 if (psetusbsuspend == NULL) { 359 kfree(ph2c); 360 ret = _FAIL; 361 goto exit; 362 } 363 364 psetusbsuspend->action = action; 365 366 init_h2fwcmd_w_parm_no_rsp(ph2c, psetusbsuspend, GEN_CMD_CODE(_SetUsbSuspend)); 367 368 ret = rtw_enqueue_cmd(pcmdpriv, ph2c); 369 370exit: 371 372 373 return ret; 374} 375 376/* 377rtw_sitesurvey_cmd(~) 378 ### NOTE:#### (!!!!) 379 MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock 380*/ 381u8 rtw_sitesurvey_cmd(struct adapter *padapter, struct ndis_802_11_ssid *ssid, int ssid_num, 382 struct rtw_ieee80211_channel *ch, int ch_num) 383{ 384 u8 res = _FAIL; 385 struct cmd_obj *ph2c; 386 struct sitesurvey_parm *psurveyPara; 387 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 388 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 389 390 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) 391 rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SCAN, 1); 392 393 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 394 if (ph2c == NULL) 395 return _FAIL; 396 397 psurveyPara = kzalloc(sizeof(struct sitesurvey_parm), GFP_KERNEL); 398 if (psurveyPara == NULL) { 399 kfree(ph2c); 400 return _FAIL; 401 } 402 403 rtw_free_network_queue(padapter, false); 404 405 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("%s: flush network queue\n", __func__)); 406 407 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara, GEN_CMD_CODE(_SiteSurvey)); 408 409 /* psurveyPara->bsslimit = 48; */ 410 psurveyPara->scan_mode = pmlmepriv->scan_mode; 411 412 /* prepare ssid list */ 413 if (ssid) { 414 int i; 415 for (i = 0; i < ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) { 416 if (ssid[i].SsidLength) { 417 memcpy(&psurveyPara->ssid[i], &ssid[i], sizeof(struct ndis_802_11_ssid)); 418 psurveyPara->ssid_num++; 419 } 420 } 421 } 422 423 /* prepare channel list */ 424 if (ch) { 425 int i; 426 for (i = 0; i < ch_num && i < RTW_CHANNEL_SCAN_AMOUNT; i++) { 427 if (ch[i].hw_value && !(ch[i].flags & RTW_IEEE80211_CHAN_DISABLED)) { 428 memcpy(&psurveyPara->ch[i], &ch[i], sizeof(struct rtw_ieee80211_channel)); 429 psurveyPara->ch_num++; 430 } 431 } 432 } 433 434 set_fwstate(pmlmepriv, _FW_UNDER_SURVEY); 435 436 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 437 438 if (res == _SUCCESS) { 439 pmlmepriv->scan_start_time = jiffies; 440 441 _set_timer(&pmlmepriv->scan_to_timer, SCANNING_TIMEOUT); 442 443 rtw_led_control(padapter, LED_CTL_SITE_SURVEY); 444 445 pmlmepriv->scan_interval = SCAN_INTERVAL;/* 30*2 sec = 60sec */ 446 } else { 447 _clr_fwstate_(pmlmepriv, _FW_UNDER_SURVEY); 448 } 449 450 451 return res; 452} 453 454u8 rtw_setdatarate_cmd(struct adapter *padapter, u8 *rateset) 455{ 456 struct cmd_obj *ph2c; 457 struct setdatarate_parm *pbsetdataratepara; 458 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 459 u8 res = _SUCCESS; 460 461 462 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 463 if (ph2c == NULL) { 464 res = _FAIL; 465 goto exit; 466 } 467 468 pbsetdataratepara = kzalloc(sizeof(struct setdatarate_parm), GFP_KERNEL); 469 if (pbsetdataratepara == NULL) { 470 kfree(ph2c); 471 res = _FAIL; 472 goto exit; 473 } 474 475 init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara, GEN_CMD_CODE(_SetDataRate)); 476 pbsetdataratepara->mac_id = 5; 477 memcpy(pbsetdataratepara->datarates, rateset, NumRates); 478 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 479exit: 480 481 482 return res; 483} 484 485/* 486unsigned char rtw_setphy_cmd(unsigned char *adapter) 487 4881. be called only after rtw_update_registrypriv_dev_network(~) or mp testing program 4892. for AdHoc/Ap mode or mp mode? 490 491*/ 492u8 rtw_setphy_cmd(struct adapter *padapter, u8 modem, u8 ch) 493{ 494 struct cmd_obj *ph2c; 495 struct setphy_parm *psetphypara; 496 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 497 u8 res = _SUCCESS; 498 499 500 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 501 if (ph2c == NULL) { 502 res = _FAIL; 503 goto exit; 504 } 505 psetphypara = kzalloc(sizeof(struct setphy_parm), GFP_KERNEL); 506 507 if (psetphypara == NULL) { 508 kfree(ph2c); 509 res = _FAIL; 510 goto exit; 511 } 512 513 init_h2fwcmd_w_parm_no_rsp(ph2c, psetphypara, _SetPhy_CMD_); 514 515 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("CH =%d, modem =%d", ch, modem)); 516 517 psetphypara->modem = modem; 518 psetphypara->rfchannel = ch; 519 520 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 521exit: 522 return res; 523} 524 525u8 rtw_setbbreg_cmd(struct adapter *padapter, u8 offset, u8 val) 526{ 527 struct cmd_obj *ph2c; 528 struct writeBB_parm *pwritebbparm; 529 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 530 u8 res = _SUCCESS; 531 532 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 533 if (ph2c == NULL) { 534 res = _FAIL; 535 goto exit; 536 } 537 pwritebbparm = kzalloc(sizeof(struct writeBB_parm), GFP_KERNEL); 538 539 if (pwritebbparm == NULL) { 540 kfree(ph2c); 541 res = _FAIL; 542 goto exit; 543 } 544 545 init_h2fwcmd_w_parm_no_rsp(ph2c, pwritebbparm, GEN_CMD_CODE(_SetBBReg)); 546 547 pwritebbparm->offset = offset; 548 pwritebbparm->value = val; 549 550 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 551exit: 552 return res; 553} 554 555u8 rtw_getbbreg_cmd(struct adapter *padapter, u8 offset, u8 *pval) 556{ 557 struct cmd_obj *ph2c; 558 struct readBB_parm *prdbbparm; 559 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 560 u8 res = _SUCCESS; 561 562 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 563 if (ph2c == NULL) { 564 res = _FAIL; 565 goto exit; 566 } 567 prdbbparm = kzalloc(sizeof(struct readBB_parm), GFP_KERNEL); 568 569 if (prdbbparm == NULL) { 570 kfree(ph2c); 571 return _FAIL; 572 } 573 574 INIT_LIST_HEAD(&ph2c->list); 575 ph2c->cmdcode = GEN_CMD_CODE(_GetBBReg); 576 ph2c->parmbuf = (unsigned char *)prdbbparm; 577 ph2c->cmdsz = sizeof(struct readBB_parm); 578 ph2c->rsp = pval; 579 ph2c->rspsz = sizeof(struct readBB_rsp); 580 581 prdbbparm->offset = offset; 582 583 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 584exit: 585 return res; 586} 587 588u8 rtw_setrfreg_cmd(struct adapter *padapter, u8 offset, u32 val) 589{ 590 struct cmd_obj *ph2c; 591 struct writeRF_parm *pwriterfparm; 592 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 593 u8 res = _SUCCESS; 594 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 595 if (ph2c == NULL) { 596 res = _FAIL; 597 goto exit; 598 } 599 pwriterfparm = kzalloc(sizeof(struct writeRF_parm), GFP_KERNEL); 600 601 if (pwriterfparm == NULL) { 602 kfree(ph2c); 603 res = _FAIL; 604 goto exit; 605 } 606 607 init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg)); 608 609 pwriterfparm->offset = offset; 610 pwriterfparm->value = val; 611 612 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 613exit: 614 return res; 615} 616 617u8 rtw_getrfreg_cmd(struct adapter *padapter, u8 offset, u8 *pval) 618{ 619 struct cmd_obj *ph2c; 620 struct readRF_parm *prdrfparm; 621 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 622 u8 res = _SUCCESS; 623 624 625 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 626 if (ph2c == NULL) { 627 res = _FAIL; 628 goto exit; 629 } 630 631 prdrfparm = kzalloc(sizeof(struct readRF_parm), GFP_KERNEL); 632 if (prdrfparm == NULL) { 633 kfree(ph2c); 634 res = _FAIL; 635 goto exit; 636 } 637 638 INIT_LIST_HEAD(&ph2c->list); 639 ph2c->cmdcode = GEN_CMD_CODE(_GetRFReg); 640 ph2c->parmbuf = (unsigned char *)prdrfparm; 641 ph2c->cmdsz = sizeof(struct readRF_parm); 642 ph2c->rsp = pval; 643 ph2c->rspsz = sizeof(struct readRF_rsp); 644 645 prdrfparm->offset = offset; 646 647 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 648 649exit: 650 651 652 return res; 653} 654 655void rtw_getbbrfreg_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) 656{ 657 658 kfree(pcmd->parmbuf); 659 kfree(pcmd); 660 661} 662 663void rtw_readtssi_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) 664{ 665 666 kfree(pcmd->parmbuf); 667 kfree(pcmd); 668} 669 670u8 rtw_createbss_cmd(struct adapter *padapter) 671{ 672 struct cmd_obj *pcmd; 673 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 674 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 675 struct wlan_bssid_ex *pdev_network = &padapter->registrypriv.dev_network; 676 u8 res = _SUCCESS; 677 678 679 rtw_led_control(padapter, LED_CTL_START_TO_LINK); 680 681 if (pmlmepriv->assoc_ssid.SsidLength == 0) 682 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for Any SSid:%s\n", pmlmepriv->assoc_ssid.Ssid)); 683 else 684 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, (" createbss for SSid:%s\n", pmlmepriv->assoc_ssid.Ssid)); 685 686 pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 687 if (pcmd == NULL) { 688 res = _FAIL; 689 goto exit; 690 } 691 692 INIT_LIST_HEAD(&pcmd->list); 693 pcmd->cmdcode = _CreateBss_CMD_; 694 pcmd->parmbuf = (unsigned char *)pdev_network; 695 pcmd->cmdsz = get_wlan_bssid_ex_sz((struct wlan_bssid_ex *)pdev_network); 696 pcmd->rsp = NULL; 697 pcmd->rspsz = 0; 698 pdev_network->Length = pcmd->cmdsz; 699 res = rtw_enqueue_cmd(pcmdpriv, pcmd); 700exit: 701 702 703 return res; 704} 705 706u8 rtw_createbss_cmd_ex(struct adapter *padapter, unsigned char *pbss, unsigned int sz) 707{ 708 struct cmd_obj *pcmd; 709 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 710 u8 res = _SUCCESS; 711 712 713 pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 714 if (pcmd == NULL) { 715 res = _FAIL; 716 goto exit; 717 } 718 719 INIT_LIST_HEAD(&pcmd->list); 720 pcmd->cmdcode = GEN_CMD_CODE(_CreateBss); 721 pcmd->parmbuf = pbss; 722 pcmd->cmdsz = sz; 723 pcmd->rsp = NULL; 724 pcmd->rspsz = 0; 725 726 res = rtw_enqueue_cmd(pcmdpriv, pcmd); 727 728exit: 729 730 731 return res; 732} 733 734u8 rtw_joinbss_cmd(struct adapter *padapter, struct wlan_network *pnetwork) 735{ 736 u8 res = _SUCCESS; 737 uint t_len = 0; 738 struct wlan_bssid_ex *psecnetwork; 739 struct cmd_obj *pcmd; 740 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 741 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 742 struct qos_priv *pqospriv = &pmlmepriv->qospriv; 743 struct security_priv *psecuritypriv = &padapter->securitypriv; 744 struct registry_priv *pregistrypriv = &padapter->registrypriv; 745 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 746 enum ndis_802_11_network_infra ndis_network_mode = pnetwork->network.InfrastructureMode; 747 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; 748 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 749 750 751 rtw_led_control(padapter, LED_CTL_START_TO_LINK); 752 753 if (pmlmepriv->assoc_ssid.SsidLength == 0) 754 RT_TRACE(_module_rtl871x_cmd_c_, _drv_info_, ("+Join cmd: Any SSid\n")); 755 else 756 RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+Join cmd: SSid =[%s]\n", pmlmepriv->assoc_ssid.Ssid)); 757 758 pcmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 759 if (pcmd == NULL) { 760 res = _FAIL; 761 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd: memory allocate for cmd_obj fail!!!\n")); 762 goto exit; 763 } 764 /* for IEs is fix buf size */ 765 t_len = sizeof(struct wlan_bssid_ex); 766 767 768 /* for hidden ap to set fw_state here */ 769 if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE)) { 770 switch (ndis_network_mode) { 771 case Ndis802_11IBSS: 772 set_fwstate(pmlmepriv, WIFI_ADHOC_STATE); 773 break; 774 case Ndis802_11Infrastructure: 775 set_fwstate(pmlmepriv, WIFI_STATION_STATE); 776 break; 777 case Ndis802_11APMode: 778 case Ndis802_11AutoUnknown: 779 case Ndis802_11InfrastructureMax: 780 break; 781 } 782 } 783 784 psecnetwork = (struct wlan_bssid_ex *)&psecuritypriv->sec_bss; 785 if (psecnetwork == NULL) { 786 if (pcmd != NULL) 787 kfree(pcmd); 788 789 res = _FAIL; 790 791 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("rtw_joinbss_cmd :psecnetwork == NULL!!!\n")); 792 793 goto exit; 794 } 795 796 memset(psecnetwork, 0, t_len); 797 798 memcpy(psecnetwork, &pnetwork->network, get_wlan_bssid_ex_sz(&pnetwork->network)); 799 800 psecuritypriv->authenticator_ie[0] = (unsigned char)psecnetwork->IELength; 801 802 if ((psecnetwork->IELength-12) < (256-1)) 803 memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], psecnetwork->IELength-12); 804 else 805 memcpy(&psecuritypriv->authenticator_ie[1], &psecnetwork->IEs[12], (256-1)); 806 807 psecnetwork->IELength = 0; 808 /* Added by Albert 2009/02/18 */ 809 /* If the the driver wants to use the bssid to create the connection. */ 810 /* If not, we have to copy the connecting AP's MAC address to it so that */ 811 /* the driver just has the bssid information for PMKIDList searching. */ 812 813 if (!pmlmepriv->assoc_by_bssid) 814 memcpy(&pmlmepriv->assoc_bssid[0], &pnetwork->network.MacAddress[0], ETH_ALEN); 815 816 psecnetwork->IELength = rtw_restruct_sec_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength); 817 818 819 pqospriv->qos_option = 0; 820 821 if (pregistrypriv->wmm_enable) { 822 u32 tmp_len; 823 824 tmp_len = rtw_restruct_wmm_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], pnetwork->network.IELength, psecnetwork->IELength); 825 826 if (psecnetwork->IELength != tmp_len) { 827 psecnetwork->IELength = tmp_len; 828 pqospriv->qos_option = 1; /* There is WMM IE in this corresp. beacon */ 829 } else { 830 pqospriv->qos_option = 0;/* There is no WMM IE in this corresp. beacon */ 831 } 832 } 833 834 phtpriv->ht_option = false; 835 if (pregistrypriv->ht_enable) { 836 /* 837 * Added by Albert 2010/06/23 838 * For the WEP mode, we will use the bg mode to do 839 * the connection to avoid some IOT issue. 840 * Especially for Realtek 8192u SoftAP. 841 */ 842 if ((padapter->securitypriv.dot11PrivacyAlgrthm != _WEP40_) && 843 (padapter->securitypriv.dot11PrivacyAlgrthm != _WEP104_) && 844 (padapter->securitypriv.dot11PrivacyAlgrthm != _TKIP_)) { 845 /* rtw_restructure_ht_ie */ 846 rtw_restructure_ht_ie(padapter, &pnetwork->network.IEs[0], &psecnetwork->IEs[0], 847 pnetwork->network.IELength, &psecnetwork->IELength); 848 } 849 } 850 851 pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->network.IEs, pnetwork->network.IELength); 852 853 if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_TENDA) 854 padapter->pwrctrlpriv.smart_ps = 0; 855 else 856 padapter->pwrctrlpriv.smart_ps = padapter->registrypriv.smart_ps; 857 858 DBG_88E("%s: smart_ps =%d\n", __func__, padapter->pwrctrlpriv.smart_ps); 859 860 pcmd->cmdsz = get_wlan_bssid_ex_sz(psecnetwork);/* get cmdsz before endian conversion */ 861 862 INIT_LIST_HEAD(&pcmd->list); 863 pcmd->cmdcode = _JoinBss_CMD_;/* GEN_CMD_CODE(_JoinBss) */ 864 pcmd->parmbuf = (unsigned char *)psecnetwork; 865 pcmd->rsp = NULL; 866 pcmd->rspsz = 0; 867 868 res = rtw_enqueue_cmd(pcmdpriv, pcmd); 869 870exit: 871 872 873 return res; 874} 875 876u8 rtw_disassoc_cmd(struct adapter *padapter, u32 deauth_timeout_ms, bool enqueue) /* for sta_mode */ 877{ 878 struct cmd_obj *cmdobj = NULL; 879 struct disconnect_parm *param = NULL; 880 struct cmd_priv *cmdpriv = &padapter->cmdpriv; 881 u8 res = _SUCCESS; 882 883 884 RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_disassoc_cmd\n")); 885 886 /* prepare cmd parameter */ 887 param = kzalloc(sizeof(*param), GFP_KERNEL); 888 if (param == NULL) { 889 res = _FAIL; 890 goto exit; 891 } 892 param->deauth_timeout_ms = deauth_timeout_ms; 893 894 if (enqueue) { 895 /* need enqueue, prepare cmd_obj and enqueue */ 896 cmdobj = kzalloc(sizeof(*cmdobj), GFP_KERNEL); 897 if (cmdobj == NULL) { 898 res = _FAIL; 899 kfree(param); 900 goto exit; 901 } 902 init_h2fwcmd_w_parm_no_rsp(cmdobj, param, _DisConnect_CMD_); 903 res = rtw_enqueue_cmd(cmdpriv, cmdobj); 904 } else { 905 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ 906 if (H2C_SUCCESS != disconnect_hdl(padapter, (u8 *)param)) 907 res = _FAIL; 908 kfree(param); 909 } 910 911exit: 912 913 914 return res; 915} 916 917u8 rtw_setopmode_cmd(struct adapter *padapter, enum ndis_802_11_network_infra networktype) 918{ 919 struct cmd_obj *ph2c; 920 struct setopmode_parm *psetop; 921 922 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 923 u8 res = _SUCCESS; 924 925 926 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 927 if (ph2c == NULL) { 928 res = false; 929 goto exit; 930 } 931 psetop = kzalloc(sizeof(struct setopmode_parm), GFP_KERNEL); 932 933 if (psetop == NULL) { 934 kfree(ph2c); 935 res = false; 936 goto exit; 937 } 938 939 init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_); 940 psetop->mode = (u8)networktype; 941 942 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 943 944exit: 945 946 947 return res; 948} 949 950u8 rtw_setstakey_cmd(struct adapter *padapter, u8 *psta, u8 unicast_key) 951{ 952 struct cmd_obj *ph2c; 953 struct set_stakey_parm *psetstakey_para; 954 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 955 struct set_stakey_rsp *psetstakey_rsp = NULL; 956 957 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 958 struct security_priv *psecuritypriv = &padapter->securitypriv; 959 struct sta_info *sta = (struct sta_info *)psta; 960 u8 res = _SUCCESS; 961 962 963 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 964 if (ph2c == NULL) { 965 res = _FAIL; 966 goto exit; 967 } 968 969 psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_KERNEL); 970 if (psetstakey_para == NULL) { 971 kfree(ph2c); 972 res = _FAIL; 973 goto exit; 974 } 975 976 psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp), GFP_KERNEL); 977 if (psetstakey_rsp == NULL) { 978 kfree(ph2c); 979 kfree(psetstakey_para); 980 res = _FAIL; 981 goto exit; 982 } 983 984 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); 985 ph2c->rsp = (u8 *)psetstakey_rsp; 986 ph2c->rspsz = sizeof(struct set_stakey_rsp); 987 988 ether_addr_copy(psetstakey_para->addr, sta->hwaddr); 989 990 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) 991 psetstakey_para->algorithm = (unsigned char) psecuritypriv->dot11PrivacyAlgrthm; 992 else 993 GET_ENCRY_ALGO(psecuritypriv, sta, psetstakey_para->algorithm, false); 994 995 if (unicast_key) 996 memcpy(&psetstakey_para->key, &sta->dot118021x_UncstKey, 16); 997 else 998 memcpy(&psetstakey_para->key, &psecuritypriv->dot118021XGrpKey[psecuritypriv->dot118021XGrpKeyid].skey, 16); 999 1000 /* jeff: set this because at least sw key is ready */ 1001 padapter->securitypriv.busetkipkey = true; 1002 1003 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1004 1005exit: 1006 1007 1008 return res; 1009} 1010 1011u8 rtw_clearstakey_cmd(struct adapter *padapter, u8 *psta, u8 entry, u8 enqueue) 1012{ 1013 struct cmd_obj *ph2c; 1014 struct set_stakey_parm *psetstakey_para; 1015 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1016 struct set_stakey_rsp *psetstakey_rsp = NULL; 1017 struct sta_info *sta = (struct sta_info *)psta; 1018 u8 res = _SUCCESS; 1019 1020 1021 if (!enqueue) { 1022 clear_cam_entry(padapter, entry); 1023 } else { 1024 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC); 1025 if (ph2c == NULL) { 1026 res = _FAIL; 1027 goto exit; 1028 } 1029 1030 psetstakey_para = kzalloc(sizeof(struct set_stakey_parm), GFP_ATOMIC); 1031 if (psetstakey_para == NULL) { 1032 kfree(ph2c); 1033 res = _FAIL; 1034 goto exit; 1035 } 1036 1037 psetstakey_rsp = kzalloc(sizeof(struct set_stakey_rsp), GFP_ATOMIC); 1038 if (psetstakey_rsp == NULL) { 1039 kfree(ph2c); 1040 kfree(psetstakey_para); 1041 res = _FAIL; 1042 goto exit; 1043 } 1044 1045 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_); 1046 ph2c->rsp = (u8 *)psetstakey_rsp; 1047 ph2c->rspsz = sizeof(struct set_stakey_rsp); 1048 1049 ether_addr_copy(psetstakey_para->addr, sta->hwaddr); 1050 1051 psetstakey_para->algorithm = _NO_PRIVACY_; 1052 1053 psetstakey_para->id = entry; 1054 1055 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1056 } 1057exit: 1058 1059 1060 return res; 1061} 1062 1063u8 rtw_setrttbl_cmd(struct adapter *padapter, struct setratable_parm *prate_table) 1064{ 1065 struct cmd_obj *ph2c; 1066 struct setratable_parm *psetrttblparm; 1067 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1068 u8 res = _SUCCESS; 1069 1070 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 1071 if (ph2c == NULL) { 1072 res = _FAIL; 1073 goto exit; 1074 } 1075 psetrttblparm = kzalloc(sizeof(struct setratable_parm), GFP_KERNEL); 1076 1077 if (psetrttblparm == NULL) { 1078 kfree(ph2c); 1079 res = _FAIL; 1080 goto exit; 1081 } 1082 1083 init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm, GEN_CMD_CODE(_SetRaTable)); 1084 1085 memcpy(psetrttblparm, prate_table, sizeof(struct setratable_parm)); 1086 1087 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1088exit: 1089 return res; 1090} 1091 1092u8 rtw_setassocsta_cmd(struct adapter *padapter, u8 *mac_addr) 1093{ 1094 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1095 struct cmd_obj *ph2c; 1096 struct set_assocsta_parm *psetassocsta_para; 1097 struct set_stakey_rsp *psetassocsta_rsp = NULL; 1098 1099 u8 res = _SUCCESS; 1100 1101 1102 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 1103 if (ph2c == NULL) { 1104 res = _FAIL; 1105 goto exit; 1106 } 1107 1108 psetassocsta_para = kzalloc(sizeof(struct set_assocsta_parm), GFP_KERNEL); 1109 if (psetassocsta_para == NULL) { 1110 kfree(ph2c); 1111 res = _FAIL; 1112 goto exit; 1113 } 1114 1115 psetassocsta_rsp = kzalloc(sizeof(struct set_assocsta_rsp), GFP_KERNEL); 1116 if (psetassocsta_rsp == NULL) { 1117 kfree(ph2c); 1118 kfree(psetassocsta_para); 1119 return _FAIL; 1120 } 1121 1122 init_h2fwcmd_w_parm_no_rsp(ph2c, psetassocsta_para, _SetAssocSta_CMD_); 1123 ph2c->rsp = (u8 *)psetassocsta_rsp; 1124 ph2c->rspsz = sizeof(struct set_assocsta_rsp); 1125 1126 ether_addr_copy(psetassocsta_para->addr, mac_addr); 1127 1128 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1129 1130exit: 1131 1132 1133 return res; 1134} 1135 1136u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr) 1137{ 1138 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1139 struct cmd_obj *ph2c; 1140 struct addBaReq_parm *paddbareq_parm; 1141 u8 res = _SUCCESS; 1142 1143 1144 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 1145 if (ph2c == NULL) { 1146 res = _FAIL; 1147 goto exit; 1148 } 1149 1150 paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_KERNEL); 1151 if (paddbareq_parm == NULL) { 1152 kfree(ph2c); 1153 res = _FAIL; 1154 goto exit; 1155 } 1156 1157 paddbareq_parm->tid = tid; 1158 memcpy(paddbareq_parm->addr, addr, ETH_ALEN); 1159 1160 init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm, GEN_CMD_CODE(_AddBAReq)); 1161 1162 /* DBG_88E("rtw_addbareq_cmd, tid =%d\n", tid); */ 1163 1164 /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ 1165 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1166 1167exit: 1168 1169 1170 return res; 1171} 1172 1173u8 rtw_dynamic_chk_wk_cmd(struct adapter *padapter) 1174{ 1175 struct cmd_obj *ph2c; 1176 struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1177 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1178 u8 res = _SUCCESS; 1179 1180 1181 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 1182 if (ph2c == NULL) { 1183 res = _FAIL; 1184 goto exit; 1185 } 1186 1187 pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL); 1188 if (pdrvextra_cmd_parm == NULL) { 1189 kfree(ph2c); 1190 res = _FAIL; 1191 goto exit; 1192 } 1193 1194 pdrvextra_cmd_parm->ec_id = DYNAMIC_CHK_WK_CID; 1195 pdrvextra_cmd_parm->type_size = 0; 1196 pdrvextra_cmd_parm->pbuf = (u8 *)padapter; 1197 1198 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1199 1200 1201 /* rtw_enqueue_cmd(pcmdpriv, ph2c); */ 1202 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1203exit: 1204 return res; 1205} 1206 1207u8 rtw_set_ch_cmd(struct adapter *padapter, u8 ch, u8 bw, u8 ch_offset, u8 enqueue) 1208{ 1209 struct cmd_obj *pcmdobj; 1210 struct set_ch_parm *set_ch_parm; 1211 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1212 1213 u8 res = _SUCCESS; 1214 1215 1216 DBG_88E(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n", 1217 FUNC_NDEV_ARG(padapter->pnetdev), ch, bw, ch_offset); 1218 1219 /* check input parameter */ 1220 1221 /* prepare cmd parameter */ 1222 set_ch_parm = kzalloc(sizeof(*set_ch_parm), GFP_KERNEL); 1223 if (set_ch_parm == NULL) { 1224 res = _FAIL; 1225 goto exit; 1226 } 1227 set_ch_parm->ch = ch; 1228 set_ch_parm->bw = bw; 1229 set_ch_parm->ch_offset = ch_offset; 1230 1231 if (enqueue) { 1232 /* need enqueue, prepare cmd_obj and enqueue */ 1233 pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 1234 if (pcmdobj == NULL) { 1235 kfree(set_ch_parm); 1236 res = _FAIL; 1237 goto exit; 1238 } 1239 1240 init_h2fwcmd_w_parm_no_rsp(pcmdobj, set_ch_parm, GEN_CMD_CODE(_SetChannel)); 1241 res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); 1242 } else { 1243 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ 1244 if (H2C_SUCCESS != set_ch_hdl(padapter, (u8 *)set_ch_parm)) 1245 res = _FAIL; 1246 1247 kfree(set_ch_parm); 1248 } 1249 1250 /* do something based on res... */ 1251 1252exit: 1253 1254 DBG_88E(FUNC_NDEV_FMT" res:%u\n", FUNC_NDEV_ARG(padapter->pnetdev), res); 1255 1256 1257 return res; 1258} 1259 1260u8 rtw_set_chplan_cmd(struct adapter *padapter, u8 chplan, u8 enqueue) 1261{ 1262 struct cmd_obj *pcmdobj; 1263 struct SetChannelPlan_param *setChannelPlan_param; 1264 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1265 1266 u8 res = _SUCCESS; 1267 1268 1269 RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_chplan_cmd\n")); 1270 1271 /* check input parameter */ 1272 if (!rtw_is_channel_plan_valid(chplan)) { 1273 res = _FAIL; 1274 goto exit; 1275 } 1276 1277 /* prepare cmd parameter */ 1278 setChannelPlan_param = kzalloc(sizeof(struct SetChannelPlan_param), GFP_KERNEL); 1279 if (setChannelPlan_param == NULL) { 1280 res = _FAIL; 1281 goto exit; 1282 } 1283 setChannelPlan_param->channel_plan = chplan; 1284 1285 if (enqueue) { 1286 /* need enqueue, prepare cmd_obj and enqueue */ 1287 pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 1288 if (pcmdobj == NULL) { 1289 kfree(setChannelPlan_param); 1290 res = _FAIL; 1291 goto exit; 1292 } 1293 1294 init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelPlan_param, GEN_CMD_CODE(_SetChannelPlan)); 1295 res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); 1296 } else { 1297 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */ 1298 if (H2C_SUCCESS != set_chplan_hdl(padapter, (unsigned char *)setChannelPlan_param)) 1299 res = _FAIL; 1300 1301 kfree(setChannelPlan_param); 1302 } 1303 1304 /* do something based on res... */ 1305 if (res == _SUCCESS) 1306 padapter->mlmepriv.ChannelPlan = chplan; 1307 1308exit: 1309 1310 1311 return res; 1312} 1313 1314u8 rtw_set_csa_cmd(struct adapter *padapter, u8 new_ch_no) 1315{ 1316 struct cmd_obj *pcmdobj; 1317 struct SetChannelSwitch_param *setChannelSwitch_param; 1318 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1319 1320 u8 res = _SUCCESS; 1321 1322 1323 RT_TRACE(_module_rtl871x_cmd_c_, _drv_notice_, ("+rtw_set_csa_cmd\n")); 1324 1325 pcmdobj = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 1326 if (pcmdobj == NULL) { 1327 res = _FAIL; 1328 goto exit; 1329 } 1330 1331 setChannelSwitch_param = kzalloc(sizeof(struct SetChannelSwitch_param), GFP_KERNEL); 1332 if (setChannelSwitch_param == NULL) { 1333 kfree(pcmdobj); 1334 res = _FAIL; 1335 goto exit; 1336 } 1337 1338 setChannelSwitch_param->new_ch_no = new_ch_no; 1339 1340 init_h2fwcmd_w_parm_no_rsp(pcmdobj, setChannelSwitch_param, GEN_CMD_CODE(_SetChannelSwitch)); 1341 res = rtw_enqueue_cmd(pcmdpriv, pcmdobj); 1342 1343exit: 1344 1345 1346 return res; 1347} 1348 1349u8 rtw_tdls_cmd(struct adapter *padapter, u8 *addr, u8 option) 1350{ 1351 return _SUCCESS; 1352} 1353 1354static void traffic_status_watchdog(struct adapter *padapter) 1355{ 1356 u8 bEnterPS; 1357 u8 bBusyTraffic = false, bTxBusyTraffic = false, bRxBusyTraffic = false; 1358 u8 bHigherBusyTraffic = false, bHigherBusyRxTraffic = false, bHigherBusyTxTraffic = false; 1359 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1360 1361 /* */ 1362 /* Determine if our traffic is busy now */ 1363 /* */ 1364 if (check_fwstate(pmlmepriv, _FW_LINKED)) { 1365 if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 100 || 1366 pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 100) { 1367 bBusyTraffic = true; 1368 1369 if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) 1370 bRxBusyTraffic = true; 1371 else 1372 bTxBusyTraffic = true; 1373 } 1374 1375 /* Higher Tx/Rx data. */ 1376 if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > 4000 || 1377 pmlmepriv->LinkDetectInfo.NumTxOkInPeriod > 4000) { 1378 bHigherBusyTraffic = true; 1379 1380 if (pmlmepriv->LinkDetectInfo.NumRxOkInPeriod > pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) 1381 bHigherBusyRxTraffic = true; 1382 else 1383 bHigherBusyTxTraffic = true; 1384 } 1385 1386 /* check traffic for powersaving. */ 1387 if (((pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod + pmlmepriv->LinkDetectInfo.NumTxOkInPeriod) > 8) || 1388 (pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod > 2)) 1389 bEnterPS = false; 1390 else 1391 bEnterPS = true; 1392 1393 /* LeisurePS only work in infra mode. */ 1394 if (bEnterPS) 1395 LPS_Enter(padapter); 1396 else 1397 LPS_Leave(padapter); 1398 } else { 1399 LPS_Leave(padapter); 1400 } 1401 1402 pmlmepriv->LinkDetectInfo.NumRxOkInPeriod = 0; 1403 pmlmepriv->LinkDetectInfo.NumTxOkInPeriod = 0; 1404 pmlmepriv->LinkDetectInfo.NumRxUnicastOkInPeriod = 0; 1405 pmlmepriv->LinkDetectInfo.bBusyTraffic = bBusyTraffic; 1406 pmlmepriv->LinkDetectInfo.bTxBusyTraffic = bTxBusyTraffic; 1407 pmlmepriv->LinkDetectInfo.bRxBusyTraffic = bRxBusyTraffic; 1408 pmlmepriv->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic; 1409 pmlmepriv->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic; 1410 pmlmepriv->LinkDetectInfo.bHigherBusyTxTraffic = bHigherBusyTxTraffic; 1411} 1412 1413static void dynamic_chk_wk_hdl(struct adapter *padapter, u8 *pbuf, int sz) 1414{ 1415 struct mlme_priv *pmlmepriv; 1416 1417 padapter = (struct adapter *)pbuf; 1418 pmlmepriv = &(padapter->mlmepriv); 1419 1420#ifdef CONFIG_88EU_AP_MODE 1421 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) 1422 expire_timeout_chk(padapter); 1423#endif 1424 1425 linked_status_chk(padapter); 1426 traffic_status_watchdog(padapter); 1427 1428 rtw_hal_dm_watchdog(padapter); 1429} 1430 1431static void lps_ctrl_wk_hdl(struct adapter *padapter, u8 lps_ctrl_type) 1432{ 1433 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv; 1434 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); 1435 u8 mstatus; 1436 1437 1438 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true) || 1439 (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)) 1440 return; 1441 1442 switch (lps_ctrl_type) { 1443 case LPS_CTRL_SCAN: 1444 if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { 1445 /* connect */ 1446 LPS_Leave(padapter); 1447 } 1448 break; 1449 case LPS_CTRL_JOINBSS: 1450 LPS_Leave(padapter); 1451 break; 1452 case LPS_CTRL_CONNECT: 1453 mstatus = 1;/* connect */ 1454 /* Reset LPS Setting */ 1455 padapter->pwrctrlpriv.LpsIdleCount = 0; 1456 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus)); 1457 break; 1458 case LPS_CTRL_DISCONNECT: 1459 mstatus = 0;/* disconnect */ 1460 LPS_Leave(padapter); 1461 rtw_hal_set_hwreg(padapter, HW_VAR_H2C_FW_JOINBSSRPT, (u8 *)(&mstatus)); 1462 break; 1463 case LPS_CTRL_SPECIAL_PACKET: 1464 /* DBG_88E("LPS_CTRL_SPECIAL_PACKET\n"); */ 1465 pwrpriv->DelayLPSLastTimeStamp = jiffies; 1466 LPS_Leave(padapter); 1467 break; 1468 case LPS_CTRL_LEAVE: 1469 LPS_Leave(padapter); 1470 break; 1471 default: 1472 break; 1473 } 1474 1475} 1476 1477u8 rtw_lps_ctrl_wk_cmd(struct adapter *padapter, u8 lps_ctrl_type, u8 enqueue) 1478{ 1479 struct cmd_obj *ph2c; 1480 struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1481 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1482 /* struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; */ 1483 u8 res = _SUCCESS; 1484 1485 if (enqueue) { 1486 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 1487 if (ph2c == NULL) { 1488 res = _FAIL; 1489 goto exit; 1490 } 1491 1492 pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL); 1493 if (pdrvextra_cmd_parm == NULL) { 1494 kfree(ph2c); 1495 res = _FAIL; 1496 goto exit; 1497 } 1498 1499 pdrvextra_cmd_parm->ec_id = LPS_CTRL_WK_CID; 1500 pdrvextra_cmd_parm->type_size = lps_ctrl_type; 1501 pdrvextra_cmd_parm->pbuf = NULL; 1502 1503 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1504 1505 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1506 } else { 1507 lps_ctrl_wk_hdl(padapter, lps_ctrl_type); 1508 } 1509 1510exit: 1511 1512 1513 return res; 1514} 1515 1516static void rpt_timer_setting_wk_hdl(struct adapter *padapter, u16 min_time) 1517{ 1518 rtw_hal_set_hwreg(padapter, HW_VAR_RPT_TIMER_SETTING, (u8 *)(&min_time)); 1519} 1520 1521u8 rtw_rpt_timer_cfg_cmd(struct adapter *padapter, u16 min_time) 1522{ 1523 struct cmd_obj *ph2c; 1524 struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1525 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1526 1527 u8 res = _SUCCESS; 1528 1529 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 1530 if (ph2c == NULL) { 1531 res = _FAIL; 1532 goto exit; 1533 } 1534 1535 pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL); 1536 if (pdrvextra_cmd_parm == NULL) { 1537 kfree(ph2c); 1538 res = _FAIL; 1539 goto exit; 1540 } 1541 1542 pdrvextra_cmd_parm->ec_id = RTP_TIMER_CFG_WK_CID; 1543 pdrvextra_cmd_parm->type_size = min_time; 1544 pdrvextra_cmd_parm->pbuf = NULL; 1545 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1546 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1547exit: 1548 1549 1550 return res; 1551} 1552 1553static void antenna_select_wk_hdl(struct adapter *padapter, u8 antenna) 1554{ 1555 rtw_hal_set_hwreg(padapter, HW_VAR_ANTENNA_DIVERSITY_SELECT, (u8 *)(&antenna)); 1556} 1557 1558u8 rtw_antenna_select_cmd(struct adapter *padapter, u8 antenna, u8 enqueue) 1559{ 1560 struct cmd_obj *ph2c; 1561 struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1562 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1563 u8 support_ant_div; 1564 u8 res = _SUCCESS; 1565 1566 rtw_hal_get_def_var(padapter, HAL_DEF_IS_SUPPORT_ANT_DIV, &support_ant_div); 1567 if (!support_ant_div) 1568 return res; 1569 1570 if (enqueue) { 1571 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 1572 if (ph2c == NULL) { 1573 res = _FAIL; 1574 goto exit; 1575 } 1576 1577 pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL); 1578 if (pdrvextra_cmd_parm == NULL) { 1579 kfree(ph2c); 1580 res = _FAIL; 1581 goto exit; 1582 } 1583 1584 pdrvextra_cmd_parm->ec_id = ANT_SELECT_WK_CID; 1585 pdrvextra_cmd_parm->type_size = antenna; 1586 pdrvextra_cmd_parm->pbuf = NULL; 1587 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1588 1589 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1590 } else { 1591 antenna_select_wk_hdl(padapter, antenna); 1592 } 1593exit: 1594 1595 1596 return res; 1597} 1598 1599static void power_saving_wk_hdl(struct adapter *padapter, u8 *pbuf, int sz) 1600{ 1601 rtw_ps_processor(padapter); 1602} 1603 1604u8 rtw_ps_cmd(struct adapter *padapter) 1605{ 1606 struct cmd_obj *ppscmd; 1607 struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1608 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1609 1610 u8 res = _SUCCESS; 1611 1612 ppscmd = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 1613 if (ppscmd == NULL) { 1614 res = _FAIL; 1615 goto exit; 1616 } 1617 1618 pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL); 1619 if (pdrvextra_cmd_parm == NULL) { 1620 kfree(ppscmd); 1621 res = _FAIL; 1622 goto exit; 1623 } 1624 1625 pdrvextra_cmd_parm->ec_id = POWER_SAVING_CTRL_WK_CID; 1626 pdrvextra_cmd_parm->pbuf = NULL; 1627 init_h2fwcmd_w_parm_no_rsp(ppscmd, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1628 1629 res = rtw_enqueue_cmd(pcmdpriv, ppscmd); 1630 1631exit: 1632 1633 1634 return res; 1635} 1636 1637#ifdef CONFIG_88EU_AP_MODE 1638 1639static void rtw_chk_hi_queue_hdl(struct adapter *padapter) 1640{ 1641 int cnt = 0; 1642 struct sta_info *psta_bmc; 1643 struct sta_priv *pstapriv = &padapter->stapriv; 1644 1645 psta_bmc = rtw_get_bcmc_stainfo(padapter); 1646 if (!psta_bmc) 1647 return; 1648 1649 if (psta_bmc->sleepq_len == 0) { 1650 u8 val = 0; 1651 1652 /* while ((rtw_read32(padapter, 0x414)&0x00ffff00)!= 0) */ 1653 /* while ((rtw_read32(padapter, 0x414)&0x0000ff00)!= 0) */ 1654 1655 rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &val); 1656 1657 while (!val) { 1658 msleep(100); 1659 1660 cnt++; 1661 1662 if (cnt > 10) 1663 break; 1664 1665 rtw_hal_get_hwreg(padapter, HW_VAR_CHK_HI_QUEUE_EMPTY, &val); 1666 } 1667 1668 if (cnt <= 10) { 1669 pstapriv->tim_bitmap &= ~BIT(0); 1670 pstapriv->sta_dz_bitmap &= ~BIT(0); 1671 1672 update_beacon(padapter, _TIM_IE_, NULL, false); 1673 } else { /* re check again */ 1674 rtw_chk_hi_queue_cmd(padapter); 1675 } 1676 } 1677} 1678 1679u8 rtw_chk_hi_queue_cmd(struct adapter *padapter) 1680{ 1681 struct cmd_obj *ph2c; 1682 struct drvextra_cmd_parm *pdrvextra_cmd_parm; 1683 struct cmd_priv *pcmdpriv = &padapter->cmdpriv; 1684 u8 res = _SUCCESS; 1685 1686 ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL); 1687 if (ph2c == NULL) { 1688 res = _FAIL; 1689 goto exit; 1690 } 1691 1692 pdrvextra_cmd_parm = kzalloc(sizeof(struct drvextra_cmd_parm), GFP_KERNEL); 1693 if (pdrvextra_cmd_parm == NULL) { 1694 kfree(ph2c); 1695 res = _FAIL; 1696 goto exit; 1697 } 1698 1699 pdrvextra_cmd_parm->ec_id = CHECK_HIQ_WK_CID; 1700 pdrvextra_cmd_parm->type_size = 0; 1701 pdrvextra_cmd_parm->pbuf = NULL; 1702 1703 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra)); 1704 1705 res = rtw_enqueue_cmd(pcmdpriv, ph2c); 1706exit: 1707 return res; 1708} 1709#endif 1710 1711u8 rtw_drvextra_cmd_hdl(struct adapter *padapter, unsigned char *pbuf) 1712{ 1713 struct drvextra_cmd_parm *pdrvextra_cmd; 1714 1715 if (!pbuf) 1716 return H2C_PARAMETERS_ERROR; 1717 1718 pdrvextra_cmd = (struct drvextra_cmd_parm *)pbuf; 1719 1720 switch (pdrvextra_cmd->ec_id) { 1721 case DYNAMIC_CHK_WK_CID: 1722 dynamic_chk_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size); 1723 break; 1724 case POWER_SAVING_CTRL_WK_CID: 1725 power_saving_wk_hdl(padapter, pdrvextra_cmd->pbuf, pdrvextra_cmd->type_size); 1726 break; 1727 case LPS_CTRL_WK_CID: 1728 lps_ctrl_wk_hdl(padapter, (u8)pdrvextra_cmd->type_size); 1729 break; 1730 case RTP_TIMER_CFG_WK_CID: 1731 rpt_timer_setting_wk_hdl(padapter, pdrvextra_cmd->type_size); 1732 break; 1733 case ANT_SELECT_WK_CID: 1734 antenna_select_wk_hdl(padapter, pdrvextra_cmd->type_size); 1735 break; 1736#ifdef CONFIG_88EU_AP_MODE 1737 case CHECK_HIQ_WK_CID: 1738 rtw_chk_hi_queue_hdl(padapter); 1739 break; 1740#endif /* CONFIG_88EU_AP_MODE */ 1741 default: 1742 break; 1743 } 1744 1745 if (pdrvextra_cmd->pbuf && pdrvextra_cmd->type_size > 0) 1746 kfree(pdrvextra_cmd->pbuf); 1747 1748 return H2C_SUCCESS; 1749} 1750 1751void rtw_survey_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) 1752{ 1753 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1754 1755 1756 if (pcmd->res == H2C_DROPPED) { 1757 /* TODO: cancel timer and do timeout handler directly... */ 1758 /* need to make timeout handlerOS independent */ 1759 _set_timer(&pmlmepriv->scan_to_timer, 1); 1760 } else if (pcmd->res != H2C_SUCCESS) { 1761 _set_timer(&pmlmepriv->scan_to_timer, 1); 1762 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n ********Error: MgntActrtw_set_802_11_bssid_LIST_SCAN Fail ************\n\n.")); 1763 } 1764 1765 /* free cmd */ 1766 rtw_free_cmd_obj(pcmd); 1767 1768} 1769void rtw_disassoc_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) 1770{ 1771 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1772 1773 1774 if (pcmd->res != H2C_SUCCESS) { 1775 spin_lock_bh(&pmlmepriv->lock); 1776 set_fwstate(pmlmepriv, _FW_LINKED); 1777 spin_unlock_bh(&pmlmepriv->lock); 1778 1779 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n ***Error: disconnect_cmd_callback Fail ***\n.")); 1780 return; 1781 } 1782 1783 /* free cmd */ 1784 rtw_free_cmd_obj(pcmd); 1785} 1786 1787void rtw_joinbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) 1788{ 1789 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1790 1791 1792 if (pcmd->res == H2C_DROPPED) { 1793 /* TODO: cancel timer and do timeout handler directly... */ 1794 /* need to make timeout handlerOS independent */ 1795 _set_timer(&pmlmepriv->assoc_timer, 1); 1796 } else if (pcmd->res != H2C_SUCCESS) { 1797 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("********Error:rtw_select_and_join_from_scanned_queue Wait Sema Fail ************\n")); 1798 _set_timer(&pmlmepriv->assoc_timer, 1); 1799 } 1800 1801 rtw_free_cmd_obj(pcmd); 1802 1803} 1804 1805void rtw_createbss_cmd_callback(struct adapter *padapter, struct cmd_obj *pcmd) 1806{ 1807 struct sta_info *psta = NULL; 1808 struct wlan_network *pwlan = NULL; 1809 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1810 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)pcmd->parmbuf; 1811 struct wlan_network *tgt_network = &(pmlmepriv->cur_network); 1812 1813 1814 if (pcmd->res != H2C_SUCCESS) { 1815 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n ********Error: rtw_createbss_cmd_callback Fail ************\n\n.")); 1816 _set_timer(&pmlmepriv->assoc_timer, 1); 1817 } 1818 1819 del_timer_sync(&pmlmepriv->assoc_timer); 1820 1821 spin_lock_bh(&pmlmepriv->lock); 1822 1823 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 1824 psta = rtw_get_stainfo(&padapter->stapriv, pnetwork->MacAddress); 1825 if (!psta) { 1826 psta = rtw_alloc_stainfo(&padapter->stapriv, pnetwork->MacAddress); 1827 if (psta == NULL) { 1828 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nCan't alloc sta_info when createbss_cmd_callback\n")); 1829 goto createbss_cmd_fail; 1830 } 1831 } 1832 1833 rtw_indicate_connect(padapter); 1834 } else { 1835 pwlan = _rtw_alloc_network(pmlmepriv); 1836 spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); 1837 if (pwlan == NULL) { 1838 pwlan = rtw_get_oldest_wlan_network(&pmlmepriv->scanned_queue); 1839 if (pwlan == NULL) { 1840 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\n Error: can't get pwlan in rtw_joinbss_event_callback\n")); 1841 spin_unlock_bh(&pmlmepriv->scanned_queue.lock); 1842 goto createbss_cmd_fail; 1843 } 1844 pwlan->last_scanned = jiffies; 1845 } else { 1846 list_add_tail(&(pwlan->list), &pmlmepriv->scanned_queue.queue); 1847 } 1848 1849 pnetwork->Length = get_wlan_bssid_ex_sz(pnetwork); 1850 memcpy(&(pwlan->network), pnetwork, pnetwork->Length); 1851 1852 memcpy(&tgt_network->network, pnetwork, (get_wlan_bssid_ex_sz(pnetwork))); 1853 1854 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 1855 1856 spin_unlock_bh(&pmlmepriv->scanned_queue.lock); 1857 /* we will set _FW_LINKED when there is one more sat to join us (rtw_stassoc_event_callback) */ 1858 } 1859 1860createbss_cmd_fail: 1861 1862 spin_unlock_bh(&pmlmepriv->lock); 1863 1864 rtw_free_cmd_obj(pcmd); 1865 1866} 1867 1868void rtw_setstaKey_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) 1869{ 1870 struct sta_priv *pstapriv = &padapter->stapriv; 1871 struct set_stakey_rsp *psetstakey_rsp = (struct set_stakey_rsp *)(pcmd->rsp); 1872 struct sta_info *psta = rtw_get_stainfo(pstapriv, psetstakey_rsp->addr); 1873 1874 1875 if (psta == NULL) { 1876 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nERROR: rtw_setstaKey_cmdrsp_callback => can't get sta_info\n\n")); 1877 goto exit; 1878 } 1879exit: 1880 rtw_free_cmd_obj(pcmd); 1881} 1882 1883void rtw_setassocsta_cmdrsp_callback(struct adapter *padapter, struct cmd_obj *pcmd) 1884{ 1885 struct sta_priv *pstapriv = &padapter->stapriv; 1886 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 1887 struct set_assocsta_parm *passocsta_parm = (struct set_assocsta_parm *)(pcmd->parmbuf); 1888 struct set_assocsta_rsp *passocsta_rsp = (struct set_assocsta_rsp *)(pcmd->rsp); 1889 struct sta_info *psta = rtw_get_stainfo(pstapriv, passocsta_parm->addr); 1890 1891 1892 if (psta == NULL) { 1893 RT_TRACE(_module_rtl871x_cmd_c_, _drv_err_, ("\nERROR: setassocsta_cmdrsp_callbac => can't get sta_info\n\n")); 1894 goto exit; 1895 } 1896 1897 psta->aid = passocsta_rsp->cam_id; 1898 psta->mac_id = passocsta_rsp->cam_id; 1899 1900 spin_lock_bh(&pmlmepriv->lock); 1901 1902 if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) && (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)) 1903 _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); 1904 1905 set_fwstate(pmlmepriv, _FW_LINKED); 1906 spin_unlock_bh(&pmlmepriv->lock); 1907 1908exit: 1909 rtw_free_cmd_obj(pcmd); 1910 1911} 1912