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 ******************************************************************************/
17 #include <osdep_service.h>
18 #include <drv_types.h>
19 #include <recv_osdep.h>
20 #include <mlme_osdep.h>
21 #include <rtw_mlme_ext.h>
24 * Caller and the rtw_cmd_thread can protect cmd_q by spin_lock.
25 * No irqsave is necessary.
28 int rtw_init_cmd_priv(struct cmd_priv
*pcmdpriv
)
30 init_completion(&pcmdpriv
->cmd_queue_comp
);
31 init_completion(&pcmdpriv
->terminate_cmdthread_comp
);
33 _rtw_init_queue(&pcmdpriv
->cmd_queue
);
40 * rtw_enqueue_cmd can only be called between kernel thread,
41 * since only spin_lock is used.
43 * ISR/Call-Back functions can't call this sub-function.
46 static int _rtw_enqueue_cmd(struct __queue
*queue
, struct cmd_obj
*obj
)
53 spin_lock_irqsave(&queue
->lock
, irqL
);
55 list_add_tail(&obj
->list
, &queue
->queue
);
57 spin_unlock_irqrestore(&queue
->lock
, irqL
);
64 struct cmd_obj
*rtw_dequeue_cmd(struct __queue
*queue
)
69 spin_lock_irqsave(&queue
->lock
, irqL
);
70 obj
= list_first_entry_or_null(&queue
->queue
, struct cmd_obj
, list
);
72 list_del_init(&obj
->list
);
73 spin_unlock_irqrestore(&queue
->lock
, irqL
);
78 static int rtw_cmd_filter(struct cmd_priv
*pcmdpriv
, struct cmd_obj
*cmd_obj
)
80 u8 bAllow
= false; /* set to true to allow enqueuing cmd when hw_init_completed is false */
82 /* To decide allow or not */
83 if ((pcmdpriv
->padapter
->pwrctrlpriv
.bHWPwrPindetect
) &&
84 (!pcmdpriv
->padapter
->registrypriv
.usbss_enable
)) {
85 if (cmd_obj
->cmdcode
== _Set_Drv_Extra_CMD_
) {
86 struct drvextra_cmd_parm
*pdrvextra_cmd_parm
= (struct drvextra_cmd_parm
*)cmd_obj
->parmbuf
;
88 if (pdrvextra_cmd_parm
->ec_id
== POWER_SAVING_CTRL_WK_CID
)
93 if (cmd_obj
->cmdcode
== _SetChannelPlan_CMD_
)
96 if ((!pcmdpriv
->padapter
->hw_init_completed
&& !bAllow
) ||
97 !pcmdpriv
->cmdthd_running
) /* com_thread not running */
102 u32
rtw_enqueue_cmd(struct cmd_priv
*pcmdpriv
, struct cmd_obj
*cmd_obj
)
105 struct adapter
*padapter
= pcmdpriv
->padapter
;
110 cmd_obj
->padapter
= padapter
;
112 res
= rtw_cmd_filter(pcmdpriv
, cmd_obj
);
114 rtw_free_cmd_obj(cmd_obj
);
118 res
= _rtw_enqueue_cmd(&pcmdpriv
->cmd_queue
, cmd_obj
);
121 complete(&pcmdpriv
->cmd_queue_comp
);
128 void rtw_free_cmd_obj(struct cmd_obj
*pcmd
)
130 if ((pcmd
->cmdcode
!= _JoinBss_CMD_
) && (pcmd
->cmdcode
!= _CreateBss_CMD_
)) {
131 /* free parmbuf in cmd_obj */
132 kfree(pcmd
->parmbuf
);
136 if (pcmd
->rspsz
!= 0) {
137 /* free rsp in cmd_obj */
146 int rtw_cmd_thread(void *context
)
149 struct cmd_obj
*pcmd
;
150 u8 (*cmd_hdl
)(struct adapter
*padapter
, u8
*pbuf
);
151 void (*pcmd_callback
)(struct adapter
*dev
, struct cmd_obj
*pcmd
);
152 struct adapter
*padapter
= context
;
153 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
155 allow_signal(SIGTERM
);
157 pcmdpriv
->cmdthd_running
= true;
158 complete(&pcmdpriv
->terminate_cmdthread_comp
);
160 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_info_
,
161 ("start r871x %s !!!!\n", __func__
));
164 if (wait_for_completion_interruptible(&pcmdpriv
->cmd_queue_comp
))
167 if (padapter
->bDriverStopped
||
168 padapter
->bSurpriseRemoved
) {
169 DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n",
170 __func__
, padapter
->bDriverStopped
, padapter
->bSurpriseRemoved
, __LINE__
);
174 if (padapter
->bDriverStopped
||
175 padapter
->bSurpriseRemoved
) {
176 DBG_88E("%s: DriverStopped(%d) SurpriseRemoved(%d) break at line %d\n",
177 __func__
, padapter
->bDriverStopped
, padapter
->bSurpriseRemoved
, __LINE__
);
181 pcmd
= rtw_dequeue_cmd(&pcmdpriv
->cmd_queue
);
185 if (rtw_cmd_filter(pcmdpriv
, pcmd
) == _FAIL
) {
186 pcmd
->res
= H2C_DROPPED
;
188 if (pcmd
->cmdcode
< ARRAY_SIZE(wlancmds
)) {
189 cmd_hdl
= wlancmds
[pcmd
->cmdcode
].h2cfuns
;
192 ret
= cmd_hdl(pcmd
->padapter
, pcmd
->parmbuf
);
196 pcmd
->res
= H2C_PARAMETERS_ERROR
;
202 /* call callback function for post-processed */
203 if (pcmd
->cmdcode
< ARRAY_SIZE(rtw_cmd_callback
)) {
204 pcmd_callback
= rtw_cmd_callback
[pcmd
->cmdcode
].callback
;
205 if (!pcmd_callback
) {
206 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_info_
, ("mlme_cmd_hdl(): pcmd_callback = 0x%p, cmdcode = 0x%x\n", pcmd_callback
, pcmd
->cmdcode
));
207 rtw_free_cmd_obj(pcmd
);
209 /* todo: !!! fill rsp_buf to pcmd->rsp if (pcmd->rsp!= NULL) */
210 pcmd_callback(pcmd
->padapter
, pcmd
);/* need conider that free cmd_obj in rtw_cmd_callback */
213 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("%s: cmdcode = 0x%x callback not defined!\n", __func__
, pcmd
->cmdcode
));
214 rtw_free_cmd_obj(pcmd
);
217 if (signal_pending(current
))
218 flush_signals(current
);
222 pcmdpriv
->cmdthd_running
= false;
224 /* free all cmd_obj resources */
225 while ((pcmd
= rtw_dequeue_cmd(&pcmdpriv
->cmd_queue
))) {
226 /* DBG_88E("%s: leaving... drop cmdcode:%u\n", __func__, pcmd->cmdcode); */
228 rtw_free_cmd_obj(pcmd
);
231 complete(&pcmdpriv
->terminate_cmdthread_comp
);
233 complete_and_exit(NULL
, 0);
237 * rtw_sitesurvey_cmd(~)
238 * ### NOTE:#### (!!!!)
239 * MUST TAKE CARE THAT BEFORE CALLING THIS FUNC, YOU SHOULD HAVE
240 * LOCKED pmlmepriv->lock
242 u8
rtw_sitesurvey_cmd(struct adapter
*padapter
, struct ndis_802_11_ssid
*ssid
, int ssid_num
,
243 struct rtw_ieee80211_channel
*ch
, int ch_num
)
246 struct cmd_obj
*ph2c
;
247 struct sitesurvey_parm
*psurveyPara
;
248 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
249 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
251 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true)
252 rtw_lps_ctrl_wk_cmd(padapter
, LPS_CTRL_SCAN
, 1);
254 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
258 psurveyPara
= kzalloc(sizeof(struct sitesurvey_parm
), GFP_ATOMIC
);
264 rtw_free_network_queue(padapter
, false);
266 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_info_
, ("%s: flush network queue\n", __func__
));
268 init_h2fwcmd_w_parm_no_rsp(ph2c
, psurveyPara
, _SiteSurvey_CMD_
);
270 /* psurveyPara->bsslimit = 48; */
271 psurveyPara
->scan_mode
= pmlmepriv
->scan_mode
;
273 /* prepare ssid list */
277 for (i
= 0; i
< ssid_num
&& i
< RTW_SSID_SCAN_AMOUNT
; i
++) {
278 if (ssid
[i
].SsidLength
) {
279 memcpy(&psurveyPara
->ssid
[i
], &ssid
[i
], sizeof(struct ndis_802_11_ssid
));
280 psurveyPara
->ssid_num
++;
285 /* prepare channel list */
289 for (i
= 0; i
< ch_num
&& i
< RTW_CHANNEL_SCAN_AMOUNT
; i
++) {
290 if (ch
[i
].hw_value
&& !(ch
[i
].flags
& RTW_IEEE80211_CHAN_DISABLED
)) {
291 memcpy(&psurveyPara
->ch
[i
], &ch
[i
], sizeof(struct rtw_ieee80211_channel
));
292 psurveyPara
->ch_num
++;
297 set_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
);
299 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
301 if (res
== _SUCCESS
) {
302 mod_timer(&pmlmepriv
->scan_to_timer
,
303 jiffies
+ msecs_to_jiffies(SCANNING_TIMEOUT
));
305 LedControl8188eu(padapter
, LED_CTL_SITE_SURVEY
);
307 pmlmepriv
->scan_interval
= SCAN_INTERVAL
;/* 30*2 sec = 60sec */
309 _clr_fwstate_(pmlmepriv
, _FW_UNDER_SURVEY
);
315 void rtw_readtssi_cmdrsp_callback(struct adapter
*padapter
, struct cmd_obj
*pcmd
)
317 kfree(pcmd
->parmbuf
);
321 u8
rtw_createbss_cmd(struct adapter
*padapter
)
323 struct cmd_obj
*pcmd
;
324 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
325 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
326 struct wlan_bssid_ex
*pdev_network
= &padapter
->registrypriv
.dev_network
;
329 LedControl8188eu(padapter
, LED_CTL_START_TO_LINK
);
331 if (pmlmepriv
->assoc_ssid
.SsidLength
== 0)
332 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_info_
, (" createbss for Any SSid:%s\n", pmlmepriv
->assoc_ssid
.Ssid
));
334 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_info_
, (" createbss for SSid:%s\n", pmlmepriv
->assoc_ssid
.Ssid
));
336 pcmd
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
342 INIT_LIST_HEAD(&pcmd
->list
);
343 pcmd
->cmdcode
= _CreateBss_CMD_
;
344 pcmd
->parmbuf
= (unsigned char *)pdev_network
;
345 pcmd
->cmdsz
= get_wlan_bssid_ex_sz((struct wlan_bssid_ex
*)pdev_network
);
348 pdev_network
->Length
= pcmd
->cmdsz
;
349 res
= rtw_enqueue_cmd(pcmdpriv
, pcmd
);
355 u8
rtw_joinbss_cmd(struct adapter
*padapter
, struct wlan_network
*pnetwork
)
359 struct wlan_bssid_ex
*psecnetwork
;
360 struct cmd_obj
*pcmd
;
361 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
362 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
363 struct qos_priv
*pqospriv
= &pmlmepriv
->qospriv
;
364 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
365 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
366 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
367 enum ndis_802_11_network_infra ndis_network_mode
= pnetwork
->network
.InfrastructureMode
;
368 struct mlme_ext_priv
*pmlmeext
= &padapter
->mlmeextpriv
;
369 struct mlme_ext_info
*pmlmeinfo
= &pmlmeext
->mlmext_info
;
371 LedControl8188eu(padapter
, LED_CTL_START_TO_LINK
);
373 if (pmlmepriv
->assoc_ssid
.SsidLength
== 0)
374 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_info_
, ("+Join cmd: Any SSid\n"));
376 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_notice_
, ("+Join cmd: SSid =[%s]\n", pmlmepriv
->assoc_ssid
.Ssid
));
378 pcmd
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
383 /* for IEs is fix buf size */
384 t_len
= sizeof(struct wlan_bssid_ex
);
386 /* for hidden ap to set fw_state here */
387 if (!check_fwstate(pmlmepriv
, WIFI_STATION_STATE
| WIFI_ADHOC_STATE
)) {
388 switch (ndis_network_mode
) {
390 set_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
);
392 case Ndis802_11Infrastructure
:
393 set_fwstate(pmlmepriv
, WIFI_STATION_STATE
);
395 case Ndis802_11APMode
:
396 case Ndis802_11AutoUnknown
:
397 case Ndis802_11InfrastructureMax
:
402 psecnetwork
= (struct wlan_bssid_ex
*)&psecuritypriv
->sec_bss
;
408 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
,
409 ("%s :psecnetwork == NULL!!!\n", __func__
));
414 memset(psecnetwork
, 0, t_len
);
416 memcpy(psecnetwork
, &pnetwork
->network
, get_wlan_bssid_ex_sz(&pnetwork
->network
));
418 psecuritypriv
->authenticator_ie
[0] = (unsigned char)psecnetwork
->IELength
;
420 if ((psecnetwork
->IELength
-12) < (256-1))
421 memcpy(&psecuritypriv
->authenticator_ie
[1], &psecnetwork
->IEs
[12], psecnetwork
->IELength
-12);
423 memcpy(&psecuritypriv
->authenticator_ie
[1], &psecnetwork
->IEs
[12], (256-1));
425 psecnetwork
->IELength
= 0;
426 /* Added by Albert 2009/02/18 */
427 /* If the driver wants to use the bssid to create the connection. */
428 /* If not, we have to copy the connecting AP's MAC address to it so that */
429 /* the driver just has the bssid information for PMKIDList searching. */
431 if (!pmlmepriv
->assoc_by_bssid
)
432 memcpy(&pmlmepriv
->assoc_bssid
[0], &pnetwork
->network
.MacAddress
[0], ETH_ALEN
);
434 psecnetwork
->IELength
= rtw_restruct_sec_ie(padapter
, &pnetwork
->network
.IEs
[0], &psecnetwork
->IEs
[0], pnetwork
->network
.IELength
);
436 pqospriv
->qos_option
= 0;
438 if (pregistrypriv
->wmm_enable
) {
441 tmp_len
= rtw_restruct_wmm_ie(padapter
, &pnetwork
->network
.IEs
[0], &psecnetwork
->IEs
[0], pnetwork
->network
.IELength
, psecnetwork
->IELength
);
443 if (psecnetwork
->IELength
!= tmp_len
) {
444 psecnetwork
->IELength
= tmp_len
;
445 pqospriv
->qos_option
= 1; /* There is WMM IE in this corresp. beacon */
447 pqospriv
->qos_option
= 0;/* There is no WMM IE in this corresp. beacon */
451 phtpriv
->ht_option
= false;
452 if (pregistrypriv
->ht_enable
) {
454 * Added by Albert 2010/06/23
455 * For the WEP mode, we will use the bg mode to do
456 * the connection to avoid some IOT issue.
457 * Especially for Realtek 8192u SoftAP.
459 if ((padapter
->securitypriv
.dot11PrivacyAlgrthm
!= _WEP40_
) &&
460 (padapter
->securitypriv
.dot11PrivacyAlgrthm
!= _WEP104_
) &&
461 (padapter
->securitypriv
.dot11PrivacyAlgrthm
!= _TKIP_
)) {
462 /* rtw_restructure_ht_ie */
463 rtw_restructure_ht_ie(padapter
, &pnetwork
->network
.IEs
[0], &psecnetwork
->IEs
[0],
464 pnetwork
->network
.IELength
, &psecnetwork
->IELength
);
468 pmlmeinfo
->assoc_AP_vendor
= check_assoc_AP(pnetwork
->network
.IEs
, pnetwork
->network
.IELength
);
470 if (pmlmeinfo
->assoc_AP_vendor
== HT_IOT_PEER_TENDA
)
471 padapter
->pwrctrlpriv
.smart_ps
= 0;
473 padapter
->pwrctrlpriv
.smart_ps
= padapter
->registrypriv
.smart_ps
;
475 DBG_88E("%s: smart_ps =%d\n", __func__
, padapter
->pwrctrlpriv
.smart_ps
);
477 pcmd
->cmdsz
= get_wlan_bssid_ex_sz(psecnetwork
);/* get cmdsz before endian conversion */
479 INIT_LIST_HEAD(&pcmd
->list
);
480 pcmd
->cmdcode
= _JoinBss_CMD_
;
481 pcmd
->parmbuf
= (unsigned char *)psecnetwork
;
485 res
= rtw_enqueue_cmd(pcmdpriv
, pcmd
);
492 u8
rtw_disassoc_cmd(struct adapter
*padapter
, u32 deauth_timeout_ms
, bool enqueue
) /* for sta_mode */
494 struct cmd_obj
*cmdobj
= NULL
;
495 struct disconnect_parm
*param
= NULL
;
496 struct cmd_priv
*cmdpriv
= &padapter
->cmdpriv
;
499 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_notice_
, ("+%s\n", __func__
));
501 /* prepare cmd parameter */
502 param
= kzalloc(sizeof(*param
), GFP_KERNEL
);
507 param
->deauth_timeout_ms
= deauth_timeout_ms
;
510 /* need enqueue, prepare cmd_obj and enqueue */
511 cmdobj
= kzalloc(sizeof(*cmdobj
), GFP_KERNEL
);
517 init_h2fwcmd_w_parm_no_rsp(cmdobj
, param
, _DisConnect_CMD_
);
518 res
= rtw_enqueue_cmd(cmdpriv
, cmdobj
);
520 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */
521 if (disconnect_hdl(padapter
, (u8
*)param
) != H2C_SUCCESS
)
531 u8
rtw_setopmode_cmd(struct adapter
*padapter
, enum ndis_802_11_network_infra networktype
)
533 struct cmd_obj
*ph2c
;
534 struct setopmode_parm
*psetop
;
536 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
538 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
539 psetop
= kzalloc(sizeof(struct setopmode_parm
), GFP_KERNEL
);
540 if (!ph2c
|| !psetop
) {
546 init_h2fwcmd_w_parm_no_rsp(ph2c
, psetop
, _SetOpMode_CMD_
);
547 psetop
->mode
= (u8
)networktype
;
549 return rtw_enqueue_cmd(pcmdpriv
, ph2c
);
552 u8
rtw_setstakey_cmd(struct adapter
*padapter
, u8
*psta
, u8 unicast_key
)
554 struct cmd_obj
*ph2c
;
555 struct set_stakey_parm
*psetstakey_para
;
556 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
557 struct set_stakey_rsp
*psetstakey_rsp
= NULL
;
559 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
560 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
561 struct sta_info
*sta
= (struct sta_info
*)psta
;
563 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
564 psetstakey_para
= kzalloc(sizeof(struct set_stakey_parm
), GFP_KERNEL
);
565 psetstakey_rsp
= kzalloc(sizeof(struct set_stakey_rsp
), GFP_KERNEL
);
567 if (!ph2c
|| !psetstakey_para
|| !psetstakey_rsp
) {
569 kfree(psetstakey_para
);
570 kfree(psetstakey_rsp
);
574 init_h2fwcmd_w_parm_no_rsp(ph2c
, psetstakey_para
, _SetStaKey_CMD_
);
575 ph2c
->rsp
= (u8
*)psetstakey_rsp
;
576 ph2c
->rspsz
= sizeof(struct set_stakey_rsp
);
578 ether_addr_copy(psetstakey_para
->addr
, sta
->hwaddr
);
580 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
))
581 psetstakey_para
->algorithm
= (unsigned char)psecuritypriv
->dot11PrivacyAlgrthm
;
583 GET_ENCRY_ALGO(psecuritypriv
, sta
, psetstakey_para
->algorithm
, false);
586 memcpy(&psetstakey_para
->key
, &sta
->dot118021x_UncstKey
, 16);
588 memcpy(&psetstakey_para
->key
, &psecuritypriv
->dot118021XGrpKey
[psecuritypriv
->dot118021XGrpKeyid
].skey
, 16);
590 /* jeff: set this because at least sw key is ready */
591 padapter
->securitypriv
.busetkipkey
= true;
593 return rtw_enqueue_cmd(pcmdpriv
, ph2c
);
596 u8
rtw_clearstakey_cmd(struct adapter
*padapter
, u8
*psta
, u8 entry
, u8 enqueue
)
598 struct cmd_obj
*ph2c
;
599 struct set_stakey_parm
*psetstakey_para
;
600 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
601 struct set_stakey_rsp
*psetstakey_rsp
= NULL
;
602 struct sta_info
*sta
= (struct sta_info
*)psta
;
606 clear_cam_entry(padapter
, entry
);
608 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
614 psetstakey_para
= kzalloc(sizeof(struct set_stakey_parm
), GFP_ATOMIC
);
615 if (!psetstakey_para
) {
621 psetstakey_rsp
= kzalloc(sizeof(struct set_stakey_rsp
), GFP_ATOMIC
);
622 if (!psetstakey_rsp
) {
624 kfree(psetstakey_para
);
629 init_h2fwcmd_w_parm_no_rsp(ph2c
, psetstakey_para
, _SetStaKey_CMD_
);
630 ph2c
->rsp
= (u8
*)psetstakey_rsp
;
631 ph2c
->rspsz
= sizeof(struct set_stakey_rsp
);
633 ether_addr_copy(psetstakey_para
->addr
, sta
->hwaddr
);
635 psetstakey_para
->algorithm
= _NO_PRIVACY_
;
637 psetstakey_para
->id
= entry
;
639 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
646 u8
rtw_addbareq_cmd(struct adapter
*padapter
, u8 tid
, u8
*addr
)
648 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
649 struct cmd_obj
*ph2c
;
650 struct addBaReq_parm
*paddbareq_parm
;
653 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
659 paddbareq_parm
= kzalloc(sizeof(struct addBaReq_parm
), GFP_ATOMIC
);
660 if (!paddbareq_parm
) {
666 paddbareq_parm
->tid
= tid
;
667 memcpy(paddbareq_parm
->addr
, addr
, ETH_ALEN
);
669 init_h2fwcmd_w_parm_no_rsp(ph2c
, paddbareq_parm
, _AddBAReq_CMD_
);
671 /* DBG_88E("rtw_addbareq_cmd, tid =%d\n", tid); */
673 /* rtw_enqueue_cmd(pcmdpriv, ph2c); */
674 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
681 u8
rtw_dynamic_chk_wk_cmd(struct adapter
*padapter
)
683 struct cmd_obj
*ph2c
;
684 struct drvextra_cmd_parm
*pdrvextra_cmd_parm
;
685 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
688 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
694 pdrvextra_cmd_parm
= kzalloc(sizeof(struct drvextra_cmd_parm
), GFP_ATOMIC
);
695 if (!pdrvextra_cmd_parm
) {
701 pdrvextra_cmd_parm
->ec_id
= DYNAMIC_CHK_WK_CID
;
702 pdrvextra_cmd_parm
->type_size
= 0;
703 pdrvextra_cmd_parm
->pbuf
= (u8
*)padapter
;
705 init_h2fwcmd_w_parm_no_rsp(ph2c
, pdrvextra_cmd_parm
, _Set_Drv_Extra_CMD_
);
707 /* rtw_enqueue_cmd(pcmdpriv, ph2c); */
708 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
713 u8
rtw_set_chplan_cmd(struct adapter
*padapter
, u8 chplan
, u8 enqueue
)
715 struct cmd_obj
*pcmdobj
;
716 struct SetChannelPlan_param
*setChannelPlan_param
;
717 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
721 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_notice_
, ("+%s\n", __func__
));
723 /* check input parameter */
724 if (!rtw_is_channel_plan_valid(chplan
)) {
729 /* prepare cmd parameter */
730 setChannelPlan_param
= kzalloc(sizeof(struct SetChannelPlan_param
), GFP_KERNEL
);
731 if (!setChannelPlan_param
) {
735 setChannelPlan_param
->channel_plan
= chplan
;
738 /* need enqueue, prepare cmd_obj and enqueue */
739 pcmdobj
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
741 kfree(setChannelPlan_param
);
746 init_h2fwcmd_w_parm_no_rsp(pcmdobj
, setChannelPlan_param
, _SetChannelPlan_CMD_
);
747 res
= rtw_enqueue_cmd(pcmdpriv
, pcmdobj
);
749 /* no need to enqueue, do the cmd hdl directly and free cmd parameter */
750 if (set_chplan_hdl(padapter
, (unsigned char *)setChannelPlan_param
) != H2C_SUCCESS
)
753 kfree(setChannelPlan_param
);
756 /* do something based on res... */
758 padapter
->mlmepriv
.ChannelPlan
= chplan
;
765 static void traffic_status_watchdog(struct adapter
*padapter
)
768 u8 bBusyTraffic
= false, bTxBusyTraffic
= false, bRxBusyTraffic
= false;
769 u8 bHigherBusyTraffic
= false, bHigherBusyRxTraffic
= false, bHigherBusyTxTraffic
= false;
770 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
773 /* Determine if our traffic is busy now */
775 if (check_fwstate(pmlmepriv
, _FW_LINKED
)) {
776 if (pmlmepriv
->LinkDetectInfo
.NumRxOkInPeriod
> 100 ||
777 pmlmepriv
->LinkDetectInfo
.NumTxOkInPeriod
> 100) {
780 if (pmlmepriv
->LinkDetectInfo
.NumRxOkInPeriod
> pmlmepriv
->LinkDetectInfo
.NumTxOkInPeriod
)
781 bRxBusyTraffic
= true;
783 bTxBusyTraffic
= true;
786 /* Higher Tx/Rx data. */
787 if (pmlmepriv
->LinkDetectInfo
.NumRxOkInPeriod
> 4000 ||
788 pmlmepriv
->LinkDetectInfo
.NumTxOkInPeriod
> 4000) {
789 bHigherBusyTraffic
= true;
791 if (pmlmepriv
->LinkDetectInfo
.NumRxOkInPeriod
> pmlmepriv
->LinkDetectInfo
.NumTxOkInPeriod
)
792 bHigherBusyRxTraffic
= true;
794 bHigherBusyTxTraffic
= true;
797 /* check traffic for powersaving. */
798 if (((pmlmepriv
->LinkDetectInfo
.NumRxUnicastOkInPeriod
+ pmlmepriv
->LinkDetectInfo
.NumTxOkInPeriod
) > 8) ||
799 (pmlmepriv
->LinkDetectInfo
.NumRxUnicastOkInPeriod
> 2))
804 /* LeisurePS only work in infra mode. */
813 pmlmepriv
->LinkDetectInfo
.NumRxOkInPeriod
= 0;
814 pmlmepriv
->LinkDetectInfo
.NumTxOkInPeriod
= 0;
815 pmlmepriv
->LinkDetectInfo
.NumRxUnicastOkInPeriod
= 0;
816 pmlmepriv
->LinkDetectInfo
.bBusyTraffic
= bBusyTraffic
;
817 pmlmepriv
->LinkDetectInfo
.bTxBusyTraffic
= bTxBusyTraffic
;
818 pmlmepriv
->LinkDetectInfo
.bRxBusyTraffic
= bRxBusyTraffic
;
819 pmlmepriv
->LinkDetectInfo
.bHigherBusyTraffic
= bHigherBusyTraffic
;
820 pmlmepriv
->LinkDetectInfo
.bHigherBusyRxTraffic
= bHigherBusyRxTraffic
;
821 pmlmepriv
->LinkDetectInfo
.bHigherBusyTxTraffic
= bHigherBusyTxTraffic
;
824 static void dynamic_chk_wk_hdl(struct adapter
*padapter
, u8
*pbuf
, int sz
)
826 struct mlme_priv
*pmlmepriv
;
828 padapter
= (struct adapter
*)pbuf
;
829 pmlmepriv
= &padapter
->mlmepriv
;
831 #ifdef CONFIG_88EU_AP_MODE
832 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) == true)
833 expire_timeout_chk(padapter
);
836 linked_status_chk(padapter
);
837 traffic_status_watchdog(padapter
);
839 rtw_hal_dm_watchdog(padapter
);
842 static void lps_ctrl_wk_hdl(struct adapter
*padapter
, u8 lps_ctrl_type
)
844 struct pwrctrl_priv
*pwrpriv
= &padapter
->pwrctrlpriv
;
845 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
848 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
) == true) ||
849 (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) == true))
852 switch (lps_ctrl_type
) {
854 if (check_fwstate(pmlmepriv
, _FW_LINKED
) == true) {
859 case LPS_CTRL_JOINBSS
:
862 case LPS_CTRL_CONNECT
:
863 mstatus
= 1;/* connect */
864 /* Reset LPS Setting */
865 padapter
->pwrctrlpriv
.LpsIdleCount
= 0;
866 rtw_hal_set_hwreg(padapter
, HW_VAR_H2C_FW_JOINBSSRPT
, (u8
*)(&mstatus
));
868 case LPS_CTRL_DISCONNECT
:
869 mstatus
= 0;/* disconnect */
871 rtw_hal_set_hwreg(padapter
, HW_VAR_H2C_FW_JOINBSSRPT
, (u8
*)(&mstatus
));
873 case LPS_CTRL_SPECIAL_PACKET
:
874 /* DBG_88E("LPS_CTRL_SPECIAL_PACKET\n"); */
875 pwrpriv
->DelayLPSLastTimeStamp
= jiffies
;
886 u8
rtw_lps_ctrl_wk_cmd(struct adapter
*padapter
, u8 lps_ctrl_type
, u8 enqueue
)
888 struct cmd_obj
*ph2c
;
889 struct drvextra_cmd_parm
*pdrvextra_cmd_parm
;
890 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
891 /* struct pwrctrl_priv *pwrctrlpriv = &padapter->pwrctrlpriv; */
895 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
901 pdrvextra_cmd_parm
= kzalloc(sizeof(struct drvextra_cmd_parm
), GFP_ATOMIC
);
902 if (!pdrvextra_cmd_parm
) {
908 pdrvextra_cmd_parm
->ec_id
= LPS_CTRL_WK_CID
;
909 pdrvextra_cmd_parm
->type_size
= lps_ctrl_type
;
910 pdrvextra_cmd_parm
->pbuf
= NULL
;
912 init_h2fwcmd_w_parm_no_rsp(ph2c
, pdrvextra_cmd_parm
, _Set_Drv_Extra_CMD_
);
914 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
916 lps_ctrl_wk_hdl(padapter
, lps_ctrl_type
);
924 static void rpt_timer_setting_wk_hdl(struct adapter
*padapter
, u16 min_time
)
926 rtw_hal_set_hwreg(padapter
, HW_VAR_RPT_TIMER_SETTING
, (u8
*)(&min_time
));
929 u8
rtw_rpt_timer_cfg_cmd(struct adapter
*padapter
, u16 min_time
)
931 struct cmd_obj
*ph2c
;
932 struct drvextra_cmd_parm
*pdrvextra_cmd_parm
;
933 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
937 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
943 pdrvextra_cmd_parm
= kzalloc(sizeof(struct drvextra_cmd_parm
), GFP_ATOMIC
);
944 if (!pdrvextra_cmd_parm
) {
950 pdrvextra_cmd_parm
->ec_id
= RTP_TIMER_CFG_WK_CID
;
951 pdrvextra_cmd_parm
->type_size
= min_time
;
952 pdrvextra_cmd_parm
->pbuf
= NULL
;
953 init_h2fwcmd_w_parm_no_rsp(ph2c
, pdrvextra_cmd_parm
, _Set_Drv_Extra_CMD_
);
954 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
960 static void antenna_select_wk_hdl(struct adapter
*padapter
, u8 antenna
)
962 rtw_hal_set_hwreg(padapter
, HW_VAR_ANTENNA_DIVERSITY_SELECT
, (u8
*)(&antenna
));
965 u8
rtw_antenna_select_cmd(struct adapter
*padapter
, u8 antenna
, u8 enqueue
)
967 struct cmd_obj
*ph2c
;
968 struct drvextra_cmd_parm
*pdrvextra_cmd_parm
;
969 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
973 rtw_hal_get_def_var(padapter
, HAL_DEF_IS_SUPPORT_ANT_DIV
, &support_ant_div
);
974 if (!support_ant_div
)
978 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
984 pdrvextra_cmd_parm
= kzalloc(sizeof(struct drvextra_cmd_parm
), GFP_KERNEL
);
985 if (!pdrvextra_cmd_parm
) {
991 pdrvextra_cmd_parm
->ec_id
= ANT_SELECT_WK_CID
;
992 pdrvextra_cmd_parm
->type_size
= antenna
;
993 pdrvextra_cmd_parm
->pbuf
= NULL
;
994 init_h2fwcmd_w_parm_no_rsp(ph2c
, pdrvextra_cmd_parm
, _Set_Drv_Extra_CMD_
);
996 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
998 antenna_select_wk_hdl(padapter
, antenna
);
1005 u8
rtw_ps_cmd(struct adapter
*padapter
)
1007 struct cmd_obj
*ppscmd
;
1008 struct drvextra_cmd_parm
*pdrvextra_cmd_parm
;
1009 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
1011 ppscmd
= kzalloc(sizeof(struct cmd_obj
), GFP_ATOMIC
);
1012 pdrvextra_cmd_parm
= kzalloc(sizeof(struct drvextra_cmd_parm
), GFP_ATOMIC
);
1013 if (!ppscmd
|| !pdrvextra_cmd_parm
) {
1015 kfree(pdrvextra_cmd_parm
);
1019 pdrvextra_cmd_parm
->ec_id
= POWER_SAVING_CTRL_WK_CID
;
1020 pdrvextra_cmd_parm
->pbuf
= NULL
;
1021 init_h2fwcmd_w_parm_no_rsp(ppscmd
, pdrvextra_cmd_parm
, _Set_Drv_Extra_CMD_
);
1023 return rtw_enqueue_cmd(pcmdpriv
, ppscmd
);
1026 #ifdef CONFIG_88EU_AP_MODE
1028 static void rtw_chk_hi_queue_hdl(struct adapter
*padapter
)
1031 struct sta_info
*psta_bmc
;
1032 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1034 psta_bmc
= rtw_get_bcmc_stainfo(padapter
);
1038 if (psta_bmc
->sleepq_len
== 0) {
1041 /* while ((rtw_read32(padapter, 0x414)&0x00ffff00)!= 0) */
1042 /* while ((rtw_read32(padapter, 0x414)&0x0000ff00)!= 0) */
1044 rtw_hal_get_hwreg(padapter
, HW_VAR_CHK_HI_QUEUE_EMPTY
, &val
);
1054 rtw_hal_get_hwreg(padapter
, HW_VAR_CHK_HI_QUEUE_EMPTY
, &val
);
1058 pstapriv
->tim_bitmap
&= ~BIT(0);
1059 pstapriv
->sta_dz_bitmap
&= ~BIT(0);
1061 update_beacon(padapter
, _TIM_IE_
, NULL
, false);
1062 } else { /* re check again */
1063 rtw_chk_hi_queue_cmd(padapter
);
1068 u8
rtw_chk_hi_queue_cmd(struct adapter
*padapter
)
1070 struct cmd_obj
*ph2c
;
1071 struct drvextra_cmd_parm
*pdrvextra_cmd_parm
;
1072 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
1075 ph2c
= kzalloc(sizeof(struct cmd_obj
), GFP_KERNEL
);
1081 pdrvextra_cmd_parm
= kzalloc(sizeof(struct drvextra_cmd_parm
), GFP_KERNEL
);
1082 if (!pdrvextra_cmd_parm
) {
1088 pdrvextra_cmd_parm
->ec_id
= CHECK_HIQ_WK_CID
;
1089 pdrvextra_cmd_parm
->type_size
= 0;
1090 pdrvextra_cmd_parm
->pbuf
= NULL
;
1092 init_h2fwcmd_w_parm_no_rsp(ph2c
, pdrvextra_cmd_parm
, _Set_Drv_Extra_CMD_
);
1094 res
= rtw_enqueue_cmd(pcmdpriv
, ph2c
);
1100 u8
rtw_drvextra_cmd_hdl(struct adapter
*padapter
, unsigned char *pbuf
)
1102 struct drvextra_cmd_parm
*pdrvextra_cmd
;
1105 return H2C_PARAMETERS_ERROR
;
1107 pdrvextra_cmd
= (struct drvextra_cmd_parm
*)pbuf
;
1109 switch (pdrvextra_cmd
->ec_id
) {
1110 case DYNAMIC_CHK_WK_CID
:
1111 dynamic_chk_wk_hdl(padapter
, pdrvextra_cmd
->pbuf
, pdrvextra_cmd
->type_size
);
1113 case POWER_SAVING_CTRL_WK_CID
:
1114 rtw_ps_processor(padapter
);
1116 case LPS_CTRL_WK_CID
:
1117 lps_ctrl_wk_hdl(padapter
, (u8
)pdrvextra_cmd
->type_size
);
1119 case RTP_TIMER_CFG_WK_CID
:
1120 rpt_timer_setting_wk_hdl(padapter
, pdrvextra_cmd
->type_size
);
1122 case ANT_SELECT_WK_CID
:
1123 antenna_select_wk_hdl(padapter
, pdrvextra_cmd
->type_size
);
1125 #ifdef CONFIG_88EU_AP_MODE
1126 case CHECK_HIQ_WK_CID
:
1127 rtw_chk_hi_queue_hdl(padapter
);
1129 #endif /* CONFIG_88EU_AP_MODE */
1134 if (pdrvextra_cmd
->pbuf
&& pdrvextra_cmd
->type_size
> 0)
1135 kfree(pdrvextra_cmd
->pbuf
);
1140 void rtw_survey_cmd_callback(struct adapter
*padapter
, struct cmd_obj
*pcmd
)
1142 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1144 if (pcmd
->res
== H2C_DROPPED
) {
1145 /* TODO: cancel timer and do timeout handler directly... */
1146 /* need to make timeout handlerOS independent */
1147 mod_timer(&pmlmepriv
->scan_to_timer
,
1148 jiffies
+ msecs_to_jiffies(1));
1149 } else if (pcmd
->res
!= H2C_SUCCESS
) {
1150 mod_timer(&pmlmepriv
->scan_to_timer
,
1151 jiffies
+ msecs_to_jiffies(1));
1152 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("\n ********Error: MgntActrtw_set_802_11_bssid_LIST_SCAN Fail ************\n\n."));
1156 rtw_free_cmd_obj(pcmd
);
1159 void rtw_disassoc_cmd_callback(struct adapter
*padapter
, struct cmd_obj
*pcmd
)
1161 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1163 if (pcmd
->res
!= H2C_SUCCESS
) {
1164 spin_lock_bh(&pmlmepriv
->lock
);
1165 set_fwstate(pmlmepriv
, _FW_LINKED
);
1166 spin_unlock_bh(&pmlmepriv
->lock
);
1168 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("\n ***Error: disconnect_cmd_callback Fail ***\n."));
1173 rtw_free_cmd_obj(pcmd
);
1176 void rtw_joinbss_cmd_callback(struct adapter
*padapter
, struct cmd_obj
*pcmd
)
1178 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1180 if (pcmd
->res
== H2C_DROPPED
) {
1181 /* TODO: cancel timer and do timeout handler directly... */
1182 /* need to make timeout handlerOS independent */
1183 mod_timer(&pmlmepriv
->assoc_timer
,
1184 jiffies
+ msecs_to_jiffies(1));
1185 } else if (pcmd
->res
!= H2C_SUCCESS
) {
1186 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("********Error:rtw_select_and_join_from_scanned_queue Wait Sema Fail ************\n"));
1187 mod_timer(&pmlmepriv
->assoc_timer
,
1188 jiffies
+ msecs_to_jiffies(1));
1191 rtw_free_cmd_obj(pcmd
);
1194 void rtw_createbss_cmd_callback(struct adapter
*padapter
, struct cmd_obj
*pcmd
)
1196 struct sta_info
*psta
= NULL
;
1197 struct wlan_network
*pwlan
= NULL
;
1198 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1199 struct wlan_bssid_ex
*pnetwork
= (struct wlan_bssid_ex
*)pcmd
->parmbuf
;
1200 struct wlan_network
*tgt_network
= &pmlmepriv
->cur_network
;
1202 if (pcmd
->res
!= H2C_SUCCESS
) {
1203 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
,
1204 ("\n **** Error: %s Fail ****\n\n.", __func__
));
1205 mod_timer(&pmlmepriv
->assoc_timer
,
1206 jiffies
+ msecs_to_jiffies(1));
1209 del_timer_sync(&pmlmepriv
->assoc_timer
);
1211 spin_lock_bh(&pmlmepriv
->lock
);
1213 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
)) {
1214 psta
= rtw_get_stainfo(&padapter
->stapriv
, pnetwork
->MacAddress
);
1216 psta
= rtw_alloc_stainfo(&padapter
->stapriv
, pnetwork
->MacAddress
);
1218 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("\nCan't alloc sta_info when createbss_cmd_callback\n"));
1219 goto createbss_cmd_fail
;
1223 rtw_indicate_connect(padapter
);
1225 pwlan
= _rtw_alloc_network(pmlmepriv
);
1226 spin_lock_bh(&pmlmepriv
->scanned_queue
.lock
);
1228 pwlan
= rtw_get_oldest_wlan_network(&pmlmepriv
->scanned_queue
);
1230 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("\n Error: can't get pwlan in rtw_joinbss_event_callback\n"));
1231 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1232 goto createbss_cmd_fail
;
1234 pwlan
->last_scanned
= jiffies
;
1236 list_add_tail(&pwlan
->list
,
1237 &pmlmepriv
->scanned_queue
.queue
);
1240 pnetwork
->Length
= get_wlan_bssid_ex_sz(pnetwork
);
1241 memcpy(&pwlan
->network
, pnetwork
, pnetwork
->Length
);
1243 memcpy(&tgt_network
->network
, pnetwork
, (get_wlan_bssid_ex_sz(pnetwork
)));
1245 _clr_fwstate_(pmlmepriv
, _FW_UNDER_LINKING
);
1247 spin_unlock_bh(&pmlmepriv
->scanned_queue
.lock
);
1248 /* we will set _FW_LINKED when there is one more sat to
1249 * join us (rtw_stassoc_event_callback)
1255 spin_unlock_bh(&pmlmepriv
->lock
);
1257 rtw_free_cmd_obj(pcmd
);
1260 void rtw_setstaKey_cmdrsp_callback(struct adapter
*padapter
, struct cmd_obj
*pcmd
)
1262 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1263 struct set_stakey_rsp
*psetstakey_rsp
= (struct set_stakey_rsp
*)(pcmd
->rsp
);
1264 struct sta_info
*psta
= rtw_get_stainfo(pstapriv
, psetstakey_rsp
->addr
);
1267 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("\nERROR: %s => can't get sta_info\n\n", __func__
));
1271 rtw_free_cmd_obj(pcmd
);
1274 void rtw_setassocsta_cmdrsp_callback(struct adapter
*padapter
, struct cmd_obj
*pcmd
)
1276 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1277 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
1278 struct set_assocsta_parm
*passocsta_parm
= (struct set_assocsta_parm
*)(pcmd
->parmbuf
);
1279 struct set_assocsta_rsp
*passocsta_rsp
= (struct set_assocsta_rsp
*)(pcmd
->rsp
);
1280 struct sta_info
*psta
= rtw_get_stainfo(pstapriv
, passocsta_parm
->addr
);
1283 RT_TRACE(_module_rtl871x_cmd_c_
, _drv_err_
, ("\nERROR: %s => can't get sta_info\n\n", __func__
));
1287 psta
->aid
= passocsta_rsp
->cam_id
;
1288 psta
->mac_id
= passocsta_rsp
->cam_id
;
1290 spin_lock_bh(&pmlmepriv
->lock
);
1292 set_fwstate(pmlmepriv
, _FW_LINKED
);
1293 spin_unlock_bh(&pmlmepriv
->lock
);
1296 rtw_free_cmd_obj(pcmd
);