1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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.
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
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
19 ******************************************************************************/
22 #include <osdep_service.h>
23 #include <drv_types.h>
24 #include <recv_osdep.h>
25 #include <mlme_osdep.h>
26 #include <rtw_mlme_ext.h>
29 Caller and the rtw_cmd_thread can protect cmd_q by spin_lock.
30 No irqsave is necessary.
33 int rtw_init_cmd_priv(struct cmd_priv
*pcmdpriv
)
35 sema_init(&(pcmdpriv
->cmd_queue_sema
), 0);
36 sema_init(&(pcmdpriv
->terminate_cmdthread_sema
), 0);
38 _rtw_init_queue(&(pcmdpriv
->cmd_queue
));
45 rtw_enqueue_cmd can only be called between kernel thread,
46 since only spin_lock is used.
48 ISR/Call-Back functions can't call this sub-function.
52 static int _rtw_enqueue_cmd(struct __queue
*queue
, struct cmd_obj
*obj
)
60 spin_lock_irqsave(&queue
->lock
, irqL
);
62 list_add_tail(&obj
->list
, &queue
->queue
);
64 spin_unlock_irqrestore(&queue
->lock
, irqL
);
72 struct cmd_obj
*rtw_dequeue_cmd(struct __queue
*queue
)
78 spin_lock_irqsave(&queue
->lock
, irqL
);
79 if (list_empty(&(queue
->queue
))) {
82 obj
= container_of((&queue
->queue
)->next
, struct cmd_obj
, list
);
83 list_del_init(&obj
->list
);
86 spin_unlock_irqrestore(&queue
->lock
, irqL
);
92 static int rtw_cmd_filter(struct cmd_priv
*pcmdpriv
, struct cmd_obj
*cmd_obj
)
94 u8 bAllow
= false; /* set to true to allow enqueuing cmd when hw_init_completed is false */
96 /* To decide allow or not */
97 if ((pcmdpriv
->padapter
->pwrctrlpriv
.bHWPwrPindetect
) &&
98 (!pcmdpriv
->padapter
->registrypriv
.usbss_enable
)) {
99 if (cmd_obj
->cmdcode
== GEN_CMD_CODE(_Set_Drv_Extra
)) {
100 struct drvextra_cmd_parm
*pdrvextra_cmd_parm
= (struct drvextra_cmd_parm
*)cmd_obj
->parmbuf
;
102 if (pdrvextra_cmd_parm
->ec_id
== POWER_SAVING_CTRL_WK_CID
)
107 if (cmd_obj
->cmdcode
== GEN_CMD_CODE(_SetChannelPlan
))
110 if ((!pcmdpriv
->padapter
->hw_init_completed
&& !bAllow
) ||
111 !pcmdpriv
->cmdthd_running
) /* com_thread not running */
116 u32
rtw_enqueue_cmd(struct cmd_priv
*pcmdpriv
, struct cmd_obj
*cmd_obj
)
119 struct adapter
*padapter
= pcmdpriv
->padapter
;
125 cmd_obj
->padapter
= padapter
;
127 res
= rtw_cmd_filter(pcmdpriv
, cmd_obj
);
129 rtw_free_cmd_obj(cmd_obj
);
133 res
= _rtw_enqueue_cmd(&pcmdpriv
->cmd_queue
, cmd_obj
);
136 up(&pcmdpriv
->cmd_queue_sema
);
144 void rtw_free_cmd_obj(struct cmd_obj
*pcmd
)
147 if ((pcmd
->cmdcode
!= _JoinBss_CMD_
) && (pcmd
->cmdcode
!= _CreateBss_CMD_
)) {
148 /* free parmbuf in cmd_obj */
149 kfree(pcmd
->parmbuf
);
152 if (pcmd
->rsp
!= NULL
) {
153 if (pcmd
->rspsz
!= 0) {
154 /* free rsp in cmd_obj */
164 int rtw_cmd_thread(void *context
)
167 struct cmd_obj
*pcmd
;
168 u8 (*cmd_hdl
)(struct adapter
*padapter
, u8
*pbuf
);
169 void (*pcmd_callback
)(struct adapter
*dev
, struct cmd_obj
*pcmd
);
170 struct adapter
*padapter
= context
;
171 struct cmd_priv
*pcmdpriv
= &(padapter
->cmdpriv
);
173 allow_signal(SIGTERM
);
175 pcmdpriv
->cmdthd_running
= true;
176 up(&pcmdpriv
->terminate_cmdthread_sema
);
178 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_info_
, ("start r871x rtw_cmd_thread !!!!\n"));
181 if (_rtw_down_sema(&pcmdpriv
->cmd_queue_sema
) == _FAIL
)
184 if (padapter
->bDriverStopped
||
185 padapter
->bSurpriseRemoved
) {
186 DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n",
187 __func__
, padapter
->bDriverStopped
, padapter
->bSurpriseRemoved
, __LINE__
);
191 if (padapter
->bDriverStopped
||
192 padapter
->bSurpriseRemoved
) {
193 DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n",
194 __func__
, padapter
->bDriverStopped
, padapter
->bSurpriseRemoved
, __LINE__
);
198 pcmd
= rtw_dequeue_cmd(&pcmdpriv
->cmd_queue
);
202 if (rtw_cmd_filter(pcmdpriv
, pcmd
) == _FAIL
) {
203 pcmd
->res
= H2C_DROPPED
;
205 if (pcmd
->cmdcode
< ARRAY_SIZE(wlancmds
)) {
206 cmd_hdl
= wlancmds
[pcmd
->cmdcode
].h2cfuns
;
209 ret
= cmd_hdl(pcmd
->padapter
, pcmd
->parmbuf
);
213 pcmd
->res
= H2C_PARAMETERS_ERROR
;
219 /* call callback function for post-processed */
220 if (pcmd
->cmdcode
< ARRAY_SIZE(rtw_cmd_callback
)) {
221 pcmd_callback
= rtw_cmd_callback
[pcmd
->cmdcode
].callback
;
222 if (pcmd_callback
== NULL
) {
223 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_info_
, ("mlme_cmd_hdl(): pcmd_callback = 0x%p, cmdcode = 0x%x\n", pcmd_callback
, pcmd
->cmdcode
));
224 rtw_free_cmd_obj(pcmd
);
226 /* todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!= NULL) */
227 pcmd_callback(pcmd
->padapter
, pcmd
);/* need conider that free cmd_obj in rtw_cmd_callback */
230 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("%s: cmdcode = 0x%x callback not defined!\n", __func__
, pcmd
->cmdcode
));
231 rtw_free_cmd_obj(pcmd
);
234 if (signal_pending(current
))
235 flush_signals(current
);
239 pcmdpriv
->cmdthd_running
= false;
241 /* free all cmd_obj resources */
242 while ((pcmd
= rtw_dequeue_cmd(&pcmdpriv
->cmd_queue
))) {
243 /* DBG_88E("%s: leaving... drop cmdcode:%u\n", __func__, pcmd->cmdcode); */
245 rtw_free_cmd_obj(pcmd
);
248 up(&pcmdpriv
->terminate_cmdthread_sema
);
251 complete_and_exit(NULL
, 0);
255 rtw_sitesurvey_cmd(~)
257 MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE LOCKED pmlmepriv->lock
259 u8
rtw_sitesurvey_cmd(struct adapter
*padapter
, struct ndis_802_11_ssid
*ssid
, int ssid_num
,
260 struct rtw_ieee80211_channel
*ch
, int ch_num
)
263 struct cmd_obj
*ph2c
;
264 struct sitesurvey_parm
*psurveyPara
;
265 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
266 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
268 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true)
269 rtw_lps_ctrl_wk_cmd(padapter
, LPS_CTRL_SCAN
, 1);
271 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
275 psurveyPara
= kzalloc(sizeof(struct sitesurvey_parm
), GFP_ATOMIC
);
276 if (psurveyPara
== NULL
) {
281 rtw_free_network_queue(padapter
, false);
283 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_info_
, ("%s: flush network queue\n", __func__
));
285 init_h2fwcmd_w_parm_no_rsp(ph2c
, psurveyPara
, GEN_CMD_CODE(_SiteSurvey
));
287 /* psurveyPara->bsslimit = 48; */
288 psurveyPara
->scan_mode
= pmlmepriv
->scan_mode
;
290 /* prepare ssid list */
294 for (i
= 0; i
< ssid_num
&& i
< RTW_SSID_SCAN_AMOUNT
; i
++) {
295 if (ssid
[i
].SsidLength
) {
296 memcpy(&psurveyPara
->ssid
[i
], &ssid
[i
], sizeof(struct ndis_802_11_ssid
));
297 psurveyPara
->ssid_num
++;
302 /* prepare channel list */
306 for (i
= 0; i
< ch_num
&& i
< RTW_CHANNEL_SCAN_AMOUNT
; i
++) {
307 if (ch
[i
].hw_value
&& !(ch
[i
].flags
& RTW_IEEE80211_CHAN_DISABLED
)) {
308 memcpy(&psurveyPara
->ch
[i
], &ch
[i
], sizeof(struct rtw_ieee80211_channel
));
309 psurveyPara
->ch_num
++;
314 set_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
);
316 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
318 if (res
== _SUCCESS
) {
319 pmlmepriv
->scan_start_time
= jiffies
;
321 mod_timer(&pmlmepriv
->scan_to_timer
,
322 jiffies
+ msecs_to_jiffies(SCANNING_TIMEOUT
));
324 rtw_led_control(padapter
, LED_CTL_SITE_SURVEY
);
326 pmlmepriv
->scan_interval
= SCAN_INTERVAL
;/* 30*2 sec = 60sec */
328 _clr_fwstate_(pmlmepriv
, _FW_UNDER_SURVEY
);
335 void rtw_readtssi_cmdrsp_callback(struct adapter
*padapter
, struct cmd_obj
*pcmd
)
338 kfree(pcmd
->parmbuf
);
342 u8
rtw_createbss_cmd(struct adapter
*padapter
)
344 struct cmd_obj
*pcmd
;
345 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
346 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
347 struct wlan_bssid_ex
*pdev_network
= &padapter
->registrypriv
.dev_network
;
351 rtw_led_control(padapter
, LED_CTL_START_TO_LINK
);
353 if (pmlmepriv
->assoc_ssid
.SsidLength
== 0)
354 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_info_
, (" createbss for Any SSid:%s\n", pmlmepriv
->assoc_ssid
.Ssid
));
356 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_info_
, (" createbss for SSid:%s\n", pmlmepriv
->assoc_ssid
.Ssid
));
358 pcmd
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
364 INIT_LIST_HEAD(&pcmd
->list
);
365 pcmd
->cmdcode
= _CreateBss_CMD_
;
366 pcmd
->parmbuf
= (unsigned char *)pdev_network
;
367 pcmd
->cmdsz
= get_wlan_bssid_ex_sz((struct wlan_bssid_ex
*)pdev_network
);
370 pdev_network
->Length
= pcmd
->cmdsz
;
371 res
= rtw_enqueue_cmd(pcmdpriv
, pcmd
);
378 u8
rtw_joinbss_cmd(struct adapter
*padapter
, struct wlan_network
*pnetwork
)
382 struct wlan_bssid_ex
*psecnetwork
;
383 struct cmd_obj
*pcmd
;
384 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
385 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
386 struct qos_priv
*pqospriv
= &pmlmepriv
->qospriv
;
387 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
388 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
389 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
390 enum ndis_802_11_network_infra ndis_network_mode
= pnetwork
->network
.InfrastructureMode
;
391 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
392 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
395 rtw_led_control(padapter
, LED_CTL_START_TO_LINK
);
397 if (pmlmepriv
->assoc_ssid
.SsidLength
== 0)
398 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_info_
, ("+Join cmd: Any SSid\n"));
400 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_notice_
, ("+Join cmd: SSid =[%s]\n", pmlmepriv
->assoc_ssid
.Ssid
));
402 pcmd
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
405 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("rtw_joinbss_cmd: memory allocate for cmd_obj fail!!!\n"));
408 /* for IEs is fix buf size */
409 t_len
= sizeof(struct wlan_bssid_ex
);
412 /* for hidden ap to set fw_state here */
413 if (!check_fwstate(pmlmepriv
, WIFI_STATION_STATE
|WIFI_ADHOC_STATE
)) {
414 switch (ndis_network_mode
) {
416 set_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
);
418 case Ndis802_11Infrastructure
:
419 set_fwstate(pmlmepriv
, WIFI_STATION_STATE
);
421 case Ndis802_11APMode
:
422 case Ndis802_11AutoUnknown
:
423 case Ndis802_11InfrastructureMax
:
428 psecnetwork
= (struct wlan_bssid_ex
*)&psecuritypriv
->sec_bss
;
429 if (psecnetwork
== NULL
) {
434 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("rtw_joinbss_cmd :psecnetwork == NULL!!!\n"));
439 memset(psecnetwork
, 0, t_len
);
441 memcpy(psecnetwork
, &pnetwork
->network
, get_wlan_bssid_ex_sz(&pnetwork
->network
));
443 psecuritypriv
->authenticator_ie
[0] = (unsigned char)psecnetwork
->IELength
;
445 if ((psecnetwork
->IELength
-12) < (256-1))
446 memcpy(&psecuritypriv
->authenticator_ie
[1], &psecnetwork
->IEs
[12], psecnetwork
->IELength
-12);
448 memcpy(&psecuritypriv
->authenticator_ie
[1], &psecnetwork
->IEs
[12], (256-1));
450 psecnetwork
->IELength
= 0;
451 /* Added by Albert 2009/02/18 */
452 /* If the driver wants to use the bssid to create the connection. */
453 /* If not, we have to copy the connecting AP's MAC address to it so that */
454 /* the driver just has the bssid information for PMKIDList searching. */
456 if (!pmlmepriv
->assoc_by_bssid
)
457 memcpy(&pmlmepriv
->assoc_bssid
[0], &pnetwork
->network
.MacAddress
[0], ETH_ALEN
);
459 psecnetwork
->IELength
= rtw_restruct_sec_ie(padapter
, &pnetwork
->network
.IEs
[0], &psecnetwork
->IEs
[0], pnetwork
->network
.IELength
);
462 pqospriv
->qos_option
= 0;
464 if (pregistrypriv
->wmm_enable
) {
467 tmp_len
= rtw_restruct_wmm_ie(padapter
, &pnetwork
->network
.IEs
[0], &psecnetwork
->IEs
[0], pnetwork
->network
.IELength
, psecnetwork
->IELength
);
469 if (psecnetwork
->IELength
!= tmp_len
) {
470 psecnetwork
->IELength
= tmp_len
;
471 pqospriv
->qos_option
= 1; /* There is WMM IE in this corresp. beacon */
473 pqospriv
->qos_option
= 0;/* There is no WMM IE in this corresp. beacon */
477 phtpriv
->ht_option
= false;
478 if (pregistrypriv
->ht_enable
) {
480 * Added by Albert 2010/06/23
481 * For the WEP mode, we will use the bg mode to do
482 * the connection to avoid some IOT issue.
483 * Especially for Realtek 8192u SoftAP.
485 if ((padapter
->securitypriv
.dot11PrivacyAlgrthm
!= _WEP40_
) &&
486 (padapter
->securitypriv
.dot11PrivacyAlgrthm
!= _WEP104_
) &&
487 (padapter
->securitypriv
.dot11PrivacyAlgrthm
!= _TKIP_
)) {
488 /* rtw_restructure_ht_ie */
489 rtw_restructure_ht_ie(padapter
, &pnetwork
->network
.IEs
[0], &psecnetwork
->IEs
[0],
490 pnetwork
->network
.IELength
, &psecnetwork
->IELength
);
494 pmlmeinfo
->assoc_AP_vendor
= check_assoc_AP(pnetwork
->network
.IEs
, pnetwork
->network
.IELength
);
496 if (pmlmeinfo
->assoc_AP_vendor
== HT_IOT_PEER_TENDA
)
497 padapter
->pwrctrlpriv
.smart_ps
= 0;
499 padapter
->pwrctrlpriv
.smart_ps
= padapter
->registrypriv
.smart_ps
;
501 DBG_88E("%s: smart_ps =%d\n", __func__
, padapter
->pwrctrlpriv
.smart_ps
);
503 pcmd
->cmdsz
= get_wlan_bssid_ex_sz(psecnetwork
);/* get cmdsz before endian conversion */
505 INIT_LIST_HEAD(&pcmd
->list
);
506 pcmd
->cmdcode
= _JoinBss_CMD_
;/* GEN_CMD_CODE(_JoinBss) */
507 pcmd
->parmbuf
= (unsigned char *)psecnetwork
;
511 res
= rtw_enqueue_cmd(pcmdpriv
, pcmd
);
519 u8
rtw_disassoc_cmd(struct adapter
*padapter
, u32 deauth_timeout_ms
, bool enqueue
) /* for sta_mode */
521 struct cmd_obj
*cmdobj
= NULL
;
522 struct disconnect_parm
*param
= NULL
;
523 struct cmd_priv
*cmdpriv
= &padapter
->cmdpriv
;
527 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_notice_
, ("+rtw_disassoc_cmd\n"));
529 /* prepare cmd parameter */
530 param
= kzalloc(sizeof(*param
), GFP_KERNEL
);
535 param
->deauth_timeout_ms
= deauth_timeout_ms
;
538 /* need enqueue, prepare cmd_obj and enqueue */
539 cmdobj
= kzalloc(sizeof(*cmdobj
), GFP_KERNEL
);
540 if (cmdobj
== NULL
) {
545 init_h2fwcmd_w_parm_no_rsp(cmdobj
, param
, _DisConnect_CMD_
);
546 res
= rtw_enqueue_cmd(cmdpriv
, cmdobj
);
548 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */
549 if (disconnect_hdl(padapter
, (u8
*)param
) != H2C_SUCCESS
)
560 u8
rtw_setopmode_cmd(struct adapter
*padapter
, enum ndis_802_11_network_infra networktype
)
562 struct cmd_obj
*ph2c
;
563 struct setopmode_parm
*psetop
;
565 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
569 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
574 psetop
= kzalloc(sizeof(struct setopmode_parm
), GFP_KERNEL
);
576 if (psetop
== NULL
) {
582 init_h2fwcmd_w_parm_no_rsp(ph2c
, psetop
, _SetOpMode_CMD_
);
583 psetop
->mode
= (u8
)networktype
;
585 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
593 u8
rtw_setstakey_cmd(struct adapter
*padapter
, u8
*psta
, u8 unicast_key
)
595 struct cmd_obj
*ph2c
;
596 struct set_stakey_parm
*psetstakey_para
;
597 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
598 struct set_stakey_rsp
*psetstakey_rsp
= NULL
;
600 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
601 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
602 struct sta_info
*sta
= (struct sta_info
*)psta
;
606 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
612 psetstakey_para
= kzalloc(sizeof(struct set_stakey_parm
), GFP_KERNEL
);
613 if (psetstakey_para
== NULL
) {
619 psetstakey_rsp
= kzalloc(sizeof(struct set_stakey_rsp
), GFP_KERNEL
);
620 if (psetstakey_rsp
== NULL
) {
622 kfree(psetstakey_para
);
627 init_h2fwcmd_w_parm_no_rsp(ph2c
, psetstakey_para
, _SetStaKey_CMD_
);
628 ph2c
->rsp
= (u8
*)psetstakey_rsp
;
629 ph2c
->rspsz
= sizeof(struct set_stakey_rsp
);
631 ether_addr_copy(psetstakey_para
->addr
, sta
->hwaddr
);
633 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
))
634 psetstakey_para
->algorithm
= (unsigned char)psecuritypriv
->dot11PrivacyAlgrthm
;
636 GET_ENCRY_ALGO(psecuritypriv
, sta
, psetstakey_para
->algorithm
, false);
639 memcpy(&psetstakey_para
->key
, &sta
->dot118021x_UncstKey
, 16);
641 memcpy(&psetstakey_para
->key
, &psecuritypriv
->dot118021XGrpKey
[psecuritypriv
->dot118021XGrpKeyid
].skey
, 16);
643 /* jeff: set this because at least sw key is ready */
644 padapter
->securitypriv
.busetkipkey
= true;
646 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
654 u8
rtw_clearstakey_cmd(struct adapter
*padapter
, u8
*psta
, u8 entry
, u8 enqueue
)
656 struct cmd_obj
*ph2c
;
657 struct set_stakey_parm
*psetstakey_para
;
658 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
659 struct set_stakey_rsp
*psetstakey_rsp
= NULL
;
660 struct sta_info
*sta
= (struct sta_info
*)psta
;
665 clear_cam_entry(padapter
, entry
);
667 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
673 psetstakey_para
= kzalloc(sizeof(struct set_stakey_parm
), GFP_ATOMIC
);
674 if (psetstakey_para
== NULL
) {
680 psetstakey_rsp
= kzalloc(sizeof(struct set_stakey_rsp
), GFP_ATOMIC
);
681 if (psetstakey_rsp
== NULL
) {
683 kfree(psetstakey_para
);
688 init_h2fwcmd_w_parm_no_rsp(ph2c
, psetstakey_para
, _SetStaKey_CMD_
);
689 ph2c
->rsp
= (u8
*)psetstakey_rsp
;
690 ph2c
->rspsz
= sizeof(struct set_stakey_rsp
);
692 ether_addr_copy(psetstakey_para
->addr
, sta
->hwaddr
);
694 psetstakey_para
->algorithm
= _NO_PRIVACY_
;
696 psetstakey_para
->id
= entry
;
698 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
706 u8
rtw_addbareq_cmd(struct adapter
*padapter
, u8 tid
, u8
*addr
)
708 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
709 struct cmd_obj
*ph2c
;
710 struct addBaReq_parm
*paddbareq_parm
;
714 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
720 paddbareq_parm
= kzalloc(sizeof(struct addBaReq_parm
), GFP_KERNEL
);
721 if (paddbareq_parm
== NULL
) {
727 paddbareq_parm
->tid
= tid
;
728 memcpy(paddbareq_parm
->addr
, addr
, ETH_ALEN
);
730 init_h2fwcmd_w_parm_no_rsp(ph2c
, paddbareq_parm
, GEN_CMD_CODE(_AddBAReq
));
732 /* DBG_88E("rtw_addbareq_cmd, tid =%d\n", tid); */
734 /* rtw_enqueue_cmd(pcmdpriv, ph2c); */
735 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
743 u8
rtw_dynamic_chk_wk_cmd(struct adapter
*padapter
)
745 struct cmd_obj
*ph2c
;
746 struct drvextra_cmd_parm
*pdrvextra_cmd_parm
;
747 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
751 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
757 pdrvextra_cmd_parm
= kzalloc(sizeof(struct drvextra_cmd_parm
), GFP_ATOMIC
);
758 if (pdrvextra_cmd_parm
== NULL
) {
764 pdrvextra_cmd_parm
->ec_id
= DYNAMIC_CHK_WK_CID
;
765 pdrvextra_cmd_parm
->type_size
= 0;
766 pdrvextra_cmd_parm
->pbuf
= (u8
*)padapter
;
768 init_h2fwcmd_w_parm_no_rsp(ph2c
, pdrvextra_cmd_parm
, GEN_CMD_CODE(_Set_Drv_Extra
));
771 /* rtw_enqueue_cmd(pcmdpriv, ph2c); */
772 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
777 u8
rtw_set_chplan_cmd(struct adapter
*padapter
, u8 chplan
, u8 enqueue
)
779 struct cmd_obj
*pcmdobj
;
780 struct SetChannelPlan_param
*setChannelPlan_param
;
781 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
786 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_notice_
, ("+rtw_set_chplan_cmd\n"));
788 /* check input parameter */
789 if (!rtw_is_channel_plan_valid(chplan
)) {
794 /* prepare cmd parameter */
795 setChannelPlan_param
= kzalloc(sizeof(struct SetChannelPlan_param
), GFP_KERNEL
);
796 if (setChannelPlan_param
== NULL
) {
800 setChannelPlan_param
->channel_plan
= chplan
;
803 /* need enqueue, prepare cmd_obj and enqueue */
804 pcmdobj
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
805 if (pcmdobj
== NULL
) {
806 kfree(setChannelPlan_param
);
811 init_h2fwcmd_w_parm_no_rsp(pcmdobj
, setChannelPlan_param
, GEN_CMD_CODE(_SetChannelPlan
));
812 res
= rtw_enqueue_cmd(pcmdpriv
, pcmdobj
);
814 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */
815 if (set_chplan_hdl(padapter
, (unsigned char *)setChannelPlan_param
) != H2C_SUCCESS
)
818 kfree(setChannelPlan_param
);
821 /* do something based on res... */
823 padapter
->mlmepriv
.ChannelPlan
= chplan
;
831 static void traffic_status_watchdog(struct adapter
*padapter
)
834 u8 bBusyTraffic
= false, bTxBusyTraffic
= false, bRxBusyTraffic
= false;
835 u8 bHigherBusyTraffic
= false, bHigherBusyRxTraffic
= false, bHigherBusyTxTraffic
= false;
836 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
839 /* Determine if our traffic is busy now */
841 if (check_fwstate(pmlmepriv
, _FW_LINKED
)) {
842 if (pmlmepriv
->LinkDetectInfo
.NumRxOkInPeriod
> 100 ||
843 pmlmepriv
->LinkDetectInfo
.NumTxOkInPeriod
> 100) {
846 if (pmlmepriv
->LinkDetectInfo
.NumRxOkInPeriod
> pmlmepriv
->LinkDetectInfo
.NumTxOkInPeriod
)
847 bRxBusyTraffic
= true;
849 bTxBusyTraffic
= true;
852 /* Higher Tx/Rx data. */
853 if (pmlmepriv
->LinkDetectInfo
.NumRxOkInPeriod
> 4000 ||
854 pmlmepriv
->LinkDetectInfo
.NumTxOkInPeriod
> 4000) {
855 bHigherBusyTraffic
= true;
857 if (pmlmepriv
->LinkDetectInfo
.NumRxOkInPeriod
> pmlmepriv
->LinkDetectInfo
.NumTxOkInPeriod
)
858 bHigherBusyRxTraffic
= true;
860 bHigherBusyTxTraffic
= true;
863 /* check traffic for powersaving. */
864 if (((pmlmepriv
->LinkDetectInfo
.NumRxUnicastOkInPeriod
+ pmlmepriv
->LinkDetectInfo
.NumTxOkInPeriod
) > 8) ||
865 (pmlmepriv
->LinkDetectInfo
.NumRxUnicastOkInPeriod
> 2))
870 /* LeisurePS only work in infra mode. */
879 pmlmepriv
->LinkDetectInfo
.NumRxOkInPeriod
= 0;
880 pmlmepriv
->LinkDetectInfo
.NumTxOkInPeriod
= 0;
881 pmlmepriv
->LinkDetectInfo
.NumRxUnicastOkInPeriod
= 0;
882 pmlmepriv
->LinkDetectInfo
.bBusyTraffic
= bBusyTraffic
;
883 pmlmepriv
->LinkDetectInfo
.bTxBusyTraffic
= bTxBusyTraffic
;
884 pmlmepriv
->LinkDetectInfo
.bRxBusyTraffic
= bRxBusyTraffic
;
885 pmlmepriv
->LinkDetectInfo
.bHigherBusyTraffic
= bHigherBusyTraffic
;
886 pmlmepriv
->LinkDetectInfo
.bHigherBusyRxTraffic
= bHigherBusyRxTraffic
;
887 pmlmepriv
->LinkDetectInfo
.bHigherBusyTxTraffic
= bHigherBusyTxTraffic
;
890 static void dynamic_chk_wk_hdl(struct adapter
*padapter
, u8
*pbuf
, int sz
)
892 struct mlme_priv
*pmlmepriv
;
894 padapter
= (struct adapter
*)pbuf
;
895 pmlmepriv
= &(padapter
->mlmepriv
);
897 #ifdef CONFIG_88EU_AP_MODE
898 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) == true)
899 expire_timeout_chk(padapter
);
902 linked_status_chk(padapter
);
903 traffic_status_watchdog(padapter
);
905 rtw_hal_dm_watchdog(padapter
);
908 static void lps_ctrl_wk_hdl(struct adapter
*padapter
, u8 lps_ctrl_type
)
910 struct pwrctrl_priv
*pwrpriv
= &padapter
->pwrctrlpriv
;
911 struct mlme_priv
*pmlmepriv
= &(padapter
->mlmepriv
);
915 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
) == true) ||
916 (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) == true))
919 switch (lps_ctrl_type
) {
921 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true) {
926 case LPS_CTRL_JOINBSS
:
929 case LPS_CTRL_CONNECT
:
930 mstatus
= 1;/* connect */
931 /* Reset LPS Setting */
932 padapter
->pwrctrlpriv
.LpsIdleCount
= 0;
933 rtw_hal_set_hwreg(padapter
, HW_VAR_H2C_FW_JOINBSSRPT
, (u8
*)(&mstatus
));
935 case LPS_CTRL_DISCONNECT
:
936 mstatus
= 0;/* disconnect */
938 rtw_hal_set_hwreg(padapter
, HW_VAR_H2C_FW_JOINBSSRPT
, (u8
*)(&mstatus
));
940 case LPS_CTRL_SPECIAL_PACKET
:
941 /* DBG_88E("LPS_CTRL_SPECIAL_PACKET\n"); */
942 pwrpriv
->DelayLPSLastTimeStamp
= jiffies
;
954 u8
rtw_lps_ctrl_wk_cmd(struct adapter
*padapter
, u8 lps_ctrl_type
, u8 enqueue
)
956 struct cmd_obj
*ph2c
;
957 struct drvextra_cmd_parm
*pdrvextra_cmd_parm
;
958 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
959 /* struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; */
963 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
969 pdrvextra_cmd_parm
= kzalloc(sizeof(struct drvextra_cmd_parm
), GFP_ATOMIC
);
970 if (pdrvextra_cmd_parm
== NULL
) {
976 pdrvextra_cmd_parm
->ec_id
= LPS_CTRL_WK_CID
;
977 pdrvextra_cmd_parm
->type_size
= lps_ctrl_type
;
978 pdrvextra_cmd_parm
->pbuf
= NULL
;
980 init_h2fwcmd_w_parm_no_rsp(ph2c
, pdrvextra_cmd_parm
, GEN_CMD_CODE(_Set_Drv_Extra
));
982 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
984 lps_ctrl_wk_hdl(padapter
, lps_ctrl_type
);
993 static void rpt_timer_setting_wk_hdl(struct adapter
*padapter
, u16 min_time
)
995 rtw_hal_set_hwreg(padapter
, HW_VAR_RPT_TIMER_SETTING
, (u8
*)(&min_time
));
998 u8
rtw_rpt_timer_cfg_cmd(struct adapter
*padapter
, u16 min_time
)
1000 struct cmd_obj
*ph2c
;
1001 struct drvextra_cmd_parm
*pdrvextra_cmd_parm
;
1002 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
1006 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
1012 pdrvextra_cmd_parm
= kzalloc(sizeof(struct drvextra_cmd_parm
), GFP_ATOMIC
);
1013 if (pdrvextra_cmd_parm
== NULL
) {
1019 pdrvextra_cmd_parm
->ec_id
= RTP_TIMER_CFG_WK_CID
;
1020 pdrvextra_cmd_parm
->type_size
= min_time
;
1021 pdrvextra_cmd_parm
->pbuf
= NULL
;
1022 init_h2fwcmd_w_parm_no_rsp(ph2c
, pdrvextra_cmd_parm
, GEN_CMD_CODE(_Set_Drv_Extra
));
1023 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
1030 static void antenna_select_wk_hdl(struct adapter
*padapter
, u8 antenna
)
1032 rtw_hal_set_hwreg(padapter
, HW_VAR_ANTENNA_DIVERSITY_SELECT
, (u8
*)(&antenna
));
1035 u8
rtw_antenna_select_cmd(struct adapter
*padapter
, u8 antenna
, u8 enqueue
)
1037 struct cmd_obj
*ph2c
;
1038 struct drvextra_cmd_parm
*pdrvextra_cmd_parm
;
1039 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
1043 rtw_hal_get_def_var(padapter
, HAL_DEF_IS_SUPPORT_ANT_DIV
, &support_ant_div
);
1044 if (!support_ant_div
)
1048 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
1054 pdrvextra_cmd_parm
= kzalloc(sizeof(struct drvextra_cmd_parm
), GFP_KERNEL
);
1055 if (pdrvextra_cmd_parm
== NULL
) {
1061 pdrvextra_cmd_parm
->ec_id
= ANT_SELECT_WK_CID
;
1062 pdrvextra_cmd_parm
->type_size
= antenna
;
1063 pdrvextra_cmd_parm
->pbuf
= NULL
;
1064 init_h2fwcmd_w_parm_no_rsp(ph2c
, pdrvextra_cmd_parm
, GEN_CMD_CODE(_Set_Drv_Extra
));
1066 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
1068 antenna_select_wk_hdl(padapter
, antenna
);
1076 u8
rtw_ps_cmd(struct adapter
*padapter
)
1078 struct cmd_obj
*ppscmd
;
1079 struct drvextra_cmd_parm
*pdrvextra_cmd_parm
;
1080 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
1084 ppscmd
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
1085 if (ppscmd
== NULL
) {
1090 pdrvextra_cmd_parm
= kzalloc(sizeof(struct drvextra_cmd_parm
), GFP_ATOMIC
);
1091 if (pdrvextra_cmd_parm
== NULL
) {
1097 pdrvextra_cmd_parm
->ec_id
= POWER_SAVING_CTRL_WK_CID
;
1098 pdrvextra_cmd_parm
->pbuf
= NULL
;
1099 init_h2fwcmd_w_parm_no_rsp(ppscmd
, pdrvextra_cmd_parm
, GEN_CMD_CODE(_Set_Drv_Extra
));
1101 res
= rtw_enqueue_cmd(pcmdpriv
, ppscmd
);
1109 #ifdef CONFIG_88EU_AP_MODE
1111 static void rtw_chk_hi_queue_hdl(struct adapter
*padapter
)
1114 struct sta_info
*psta_bmc
;
1115 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1117 psta_bmc
= rtw_get_bcmc_stainfo(padapter
);
1121 if (psta_bmc
->sleepq_len
== 0) {
1124 /* while ((rtw_read32(padapter, 0x414)&0x00ffff00)!= 0) */
1125 /* while ((rtw_read32(padapter, 0x414)&0x0000ff00)!= 0) */
1127 rtw_hal_get_hwreg(padapter
, HW_VAR_CHK_HI_QUEUE_EMPTY
, &val
);
1137 rtw_hal_get_hwreg(padapter
, HW_VAR_CHK_HI_QUEUE_EMPTY
, &val
);
1141 pstapriv
->tim_bitmap
&= ~BIT(0);
1142 pstapriv
->sta_dz_bitmap
&= ~BIT(0);
1144 update_beacon(padapter
, _TIM_IE_
, NULL
, false);
1145 } else { /* re check again */
1146 rtw_chk_hi_queue_cmd(padapter
);
1151 u8
rtw_chk_hi_queue_cmd(struct adapter
*padapter
)
1153 struct cmd_obj
*ph2c
;
1154 struct drvextra_cmd_parm
*pdrvextra_cmd_parm
;
1155 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
1158 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
1164 pdrvextra_cmd_parm
= kzalloc(sizeof(struct drvextra_cmd_parm
), GFP_KERNEL
);
1165 if (pdrvextra_cmd_parm
== NULL
) {
1171 pdrvextra_cmd_parm
->ec_id
= CHECK_HIQ_WK_CID
;
1172 pdrvextra_cmd_parm
->type_size
= 0;
1173 pdrvextra_cmd_parm
->pbuf
= NULL
;
1175 init_h2fwcmd_w_parm_no_rsp(ph2c
, pdrvextra_cmd_parm
, GEN_CMD_CODE(_Set_Drv_Extra
));
1177 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
1183 u8
rtw_drvextra_cmd_hdl(struct adapter
*padapter
, unsigned char *pbuf
)
1185 struct drvextra_cmd_parm
*pdrvextra_cmd
;
1188 return H2C_PARAMETERS_ERROR
;
1190 pdrvextra_cmd
= (struct drvextra_cmd_parm
*)pbuf
;
1192 switch (pdrvextra_cmd
->ec_id
) {
1193 case DYNAMIC_CHK_WK_CID
:
1194 dynamic_chk_wk_hdl(padapter
, pdrvextra_cmd
->pbuf
, pdrvextra_cmd
->type_size
);
1196 case POWER_SAVING_CTRL_WK_CID
:
1197 rtw_ps_processor(padapter
);
1199 case LPS_CTRL_WK_CID
:
1200 lps_ctrl_wk_hdl(padapter
, (u8
)pdrvextra_cmd
->type_size
);
1202 case RTP_TIMER_CFG_WK_CID
:
1203 rpt_timer_setting_wk_hdl(padapter
, pdrvextra_cmd
->type_size
);
1205 case ANT_SELECT_WK_CID
:
1206 antenna_select_wk_hdl(padapter
, pdrvextra_cmd
->type_size
);
1208 #ifdef CONFIG_88EU_AP_MODE
1209 case CHECK_HIQ_WK_CID
:
1210 rtw_chk_hi_queue_hdl(padapter
);
1212 #endif /* CONFIG_88EU_AP_MODE */
1217 if (pdrvextra_cmd
->pbuf
&& pdrvextra_cmd
->type_size
> 0)
1218 kfree(pdrvextra_cmd
->pbuf
);
1223 void rtw_survey_cmd_callback(struct adapter
*padapter
, struct cmd_obj
*pcmd
)
1225 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1228 if (pcmd
->res
== H2C_DROPPED
) {
1229 /* TODO: cancel timer and do timeout handler directly... */
1230 /* need to make timeout handlerOS independent */
1231 mod_timer(&pmlmepriv
->scan_to_timer
,
1232 jiffies
+ msecs_to_jiffies(1));
1233 } else if (pcmd
->res
!= H2C_SUCCESS
) {
1234 mod_timer(&pmlmepriv
->scan_to_timer
,
1235 jiffies
+ msecs_to_jiffies(1));
1236 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("\n ********Error: MgntActrtw_set_802_11_bssid_LIST_SCAN Fail ************\n\n."));
1240 rtw_free_cmd_obj(pcmd
);
1243 void rtw_disassoc_cmd_callback(struct adapter
*padapter
, struct cmd_obj
*pcmd
)
1245 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1248 if (pcmd
->res
!= H2C_SUCCESS
) {
1249 spin_lock_bh(&pmlmepriv
->lock
);
1250 set_fwstate(pmlmepriv
, _FW_LINKED
);
1251 spin_unlock_bh(&pmlmepriv
->lock
);
1253 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("\n ***Error: disconnect_cmd_callback Fail ***\n."));
1258 rtw_free_cmd_obj(pcmd
);
1261 void rtw_joinbss_cmd_callback(struct adapter
*padapter
, struct cmd_obj
*pcmd
)
1263 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1266 if (pcmd
->res
== H2C_DROPPED
) {
1267 /* TODO: cancel timer and do timeout handler directly... */
1268 /* need to make timeout handlerOS independent */
1269 mod_timer(&pmlmepriv
->assoc_timer
,
1270 jiffies
+ msecs_to_jiffies(1));
1271 } else if (pcmd
->res
!= H2C_SUCCESS
) {
1272 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("********Error:rtw_select_and_join_from_scanned_queue Wait Sema Fail ************\n"));
1273 mod_timer(&pmlmepriv
->assoc_timer
,
1274 jiffies
+ msecs_to_jiffies(1));
1277 rtw_free_cmd_obj(pcmd
);
1281 void rtw_createbss_cmd_callback(struct adapter
*padapter
, struct cmd_obj
*pcmd
)
1283 struct sta_info
*psta
= NULL
;
1284 struct wlan_network
*pwlan
= NULL
;
1285 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1286 struct wlan_bssid_ex
*pnetwork
= (struct wlan_bssid_ex
*)pcmd
->parmbuf
;
1287 struct wlan_network
*tgt_network
= &(pmlmepriv
->cur_network
);
1290 if (pcmd
->res
!= H2C_SUCCESS
) {
1291 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("\n ********Error: rtw_createbss_cmd_callback Fail ************\n\n."));
1292 mod_timer(&pmlmepriv
->assoc_timer
,
1293 jiffies
+ msecs_to_jiffies(1));
1296 del_timer_sync(&pmlmepriv
->assoc_timer
);
1298 spin_lock_bh(&pmlmepriv
->lock
);
1300 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
1301 psta
= rtw_get_stainfo(&padapter
->stapriv
, pnetwork
->MacAddress
);
1303 psta
= rtw_alloc_stainfo(&padapter
->stapriv
, pnetwork
->MacAddress
);
1305 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("\nCan't alloc sta_info when createbss_cmd_callback\n"));
1306 goto createbss_cmd_fail
;
1310 rtw_indicate_connect(padapter
);
1312 pwlan
= _rtw_alloc_network(pmlmepriv
);
1313 spin_lock_bh(&(pmlmepriv
->scanned_queue
.lock
));
1314 if (pwlan
== NULL
) {
1315 pwlan
= rtw_get_oldest_wlan_network(&pmlmepriv
->scanned_queue
);
1316 if (pwlan
== NULL
) {
1317 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("\n Error: can't get pwlan in rtw_joinbss_event_callback\n"));
1318 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1319 goto createbss_cmd_fail
;
1321 pwlan
->last_scanned
= jiffies
;
1323 list_add_tail(&(pwlan
->list
), &pmlmepriv
->scanned_queue
.queue
);
1326 pnetwork
->Length
= get_wlan_bssid_ex_sz(pnetwork
);
1327 memcpy(&(pwlan
->network
), pnetwork
, pnetwork
->Length
);
1329 memcpy(&tgt_network
->network
, pnetwork
, (get_wlan_bssid_ex_sz(pnetwork
)));
1331 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
1333 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1334 /* we will set _FW_LINKED when there is one more sat to join us (rtw_stassoc_event_callback) */
1339 spin_unlock_bh(&pmlmepriv
->lock
);
1341 rtw_free_cmd_obj(pcmd
);
1345 void rtw_setstaKey_cmdrsp_callback(struct adapter
*padapter
, struct cmd_obj
*pcmd
)
1347 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1348 struct set_stakey_rsp
*psetstakey_rsp
= (struct set_stakey_rsp
*)(pcmd
->rsp
);
1349 struct sta_info
*psta
= rtw_get_stainfo(pstapriv
, psetstakey_rsp
->addr
);
1353 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("\nERROR: rtw_setstaKey_cmdrsp_callback => can't get sta_info\n\n"));
1357 rtw_free_cmd_obj(pcmd
);
1360 void rtw_setassocsta_cmdrsp_callback(struct adapter
*padapter
, struct cmd_obj
*pcmd
)
1362 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1363 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1364 struct set_assocsta_parm
*passocsta_parm
= (struct set_assocsta_parm
*)(pcmd
->parmbuf
);
1365 struct set_assocsta_rsp
*passocsta_rsp
= (struct set_assocsta_rsp
*)(pcmd
->rsp
);
1366 struct sta_info
*psta
= rtw_get_stainfo(pstapriv
, passocsta_parm
->addr
);
1370 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("\nERROR: setassocsta_cmdrsp_callbac => can't get sta_info\n\n"));
1374 psta
->aid
= passocsta_rsp
->cam_id
;
1375 psta
->mac_id
= passocsta_rsp
->cam_id
;
1377 spin_lock_bh(&pmlmepriv
->lock
);
1379 if ((check_fwstate(pmlmepriv
, WIFI_MP_STATE
) == true) && (check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
) == true))
1380 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
1382 set_fwstate(pmlmepriv
, _FW_LINKED
);
1383 spin_unlock_bh(&pmlmepriv
->lock
);
1386 rtw_free_cmd_obj(pcmd
);