1 /******************************************************************************
4 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
5 * Linux device driver for RTL8192SU
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 * Modifications for inclusion into the Linux staging tree are
21 * Copyright(c) 2010 Larry Finger. All rights reserved.
23 * Contact information:
24 * WLAN FAE <wlanfae@realtek.com>
25 * Larry Finger <Larry.Finger@lwfinger.net>
27 ******************************************************************************/
29 #define _RTL871X_CMD_C_
31 #include "osdep_service.h"
32 #include "drv_types.h"
33 #include "recv_osdep.h"
34 #include "mlme_osdep.h"
35 #include "rtl871x_byteorder.h"
38 Caller and the r8712_cmd_thread can protect cmd_q by spin_lock.
39 No irqsave is necessary.
42 static sint
_init_cmd_priv(struct cmd_priv
*pcmdpriv
)
44 sema_init(&(pcmdpriv
->cmd_queue_sema
), 0);
45 sema_init(&(pcmdpriv
->terminate_cmdthread_sema
), 0);
47 _init_queue(&(pcmdpriv
->cmd_queue
));
49 /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
50 pcmdpriv
->cmd_seq
= 1;
51 pcmdpriv
->cmd_allocated_buf
= _malloc(MAX_CMDSZ
+ CMDBUFF_ALIGN_SZ
);
52 if (pcmdpriv
->cmd_allocated_buf
== NULL
)
54 pcmdpriv
->cmd_buf
= pcmdpriv
->cmd_allocated_buf
+ CMDBUFF_ALIGN_SZ
-
55 ((addr_t
)(pcmdpriv
->cmd_allocated_buf
) &
56 (CMDBUFF_ALIGN_SZ
-1));
57 pcmdpriv
->rsp_allocated_buf
= _malloc(MAX_RSPSZ
+ 4);
58 if (pcmdpriv
->rsp_allocated_buf
== NULL
)
60 pcmdpriv
->rsp_buf
= pcmdpriv
->rsp_allocated_buf
+ 4 -
61 ((addr_t
)(pcmdpriv
->rsp_allocated_buf
) & 3);
62 pcmdpriv
->cmd_issued_cnt
= 0;
63 pcmdpriv
->cmd_done_cnt
= 0;
64 pcmdpriv
->rsp_cnt
= 0;
68 static sint
_init_evt_priv(struct evt_priv
*pevtpriv
)
70 /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
71 pevtpriv
->event_seq
= 0;
72 pevtpriv
->evt_allocated_buf
= _malloc(MAX_EVTSZ
+ 4);
74 if (pevtpriv
->evt_allocated_buf
== NULL
)
76 pevtpriv
->evt_buf
= pevtpriv
->evt_allocated_buf
+ 4 -
77 ((addr_t
)(pevtpriv
->evt_allocated_buf
) & 3);
78 pevtpriv
->evt_done_cnt
= 0;
82 static void _free_evt_priv(struct evt_priv
*pevtpriv
)
84 kfree(pevtpriv
->evt_allocated_buf
);
87 static void _free_cmd_priv(struct cmd_priv
*pcmdpriv
)
90 kfree(pcmdpriv
->cmd_allocated_buf
);
91 kfree(pcmdpriv
->rsp_allocated_buf
);
98 _enqueue_cmd can only be called between kernel thread,
99 since only spin_lock is used.
101 ISR/Call-Back functions can't call this sub-function.
105 static sint
_enqueue_cmd(struct __queue
*queue
, struct cmd_obj
*obj
)
111 spin_lock_irqsave(&queue
->lock
, irqL
);
112 list_insert_tail(&obj
->list
, &queue
->queue
);
113 spin_unlock_irqrestore(&queue
->lock
, irqL
);
117 static struct cmd_obj
*_dequeue_cmd(struct __queue
*queue
)
122 spin_lock_irqsave(&(queue
->lock
), irqL
);
123 if (is_list_empty(&(queue
->queue
)))
126 obj
= LIST_CONTAINOR(get_next(&(queue
->queue
)),
127 struct cmd_obj
, list
);
128 list_delete(&obj
->list
);
130 spin_unlock_irqrestore(&(queue
->lock
), irqL
);
134 u32
r8712_init_cmd_priv(struct cmd_priv
*pcmdpriv
)
136 return _init_cmd_priv(pcmdpriv
);
139 u32
r8712_init_evt_priv(struct evt_priv
*pevtpriv
)
141 return _init_evt_priv(pevtpriv
);
144 void r8712_free_evt_priv(struct evt_priv
*pevtpriv
)
146 _free_evt_priv(pevtpriv
);
149 void r8712_free_cmd_priv(struct cmd_priv
*pcmdpriv
)
151 _free_cmd_priv(pcmdpriv
);
154 u32
r8712_enqueue_cmd(struct cmd_priv
*pcmdpriv
, struct cmd_obj
*obj
)
158 if (pcmdpriv
->padapter
->eeprompriv
.bautoload_fail_flag
== true)
160 res
= _enqueue_cmd(&pcmdpriv
->cmd_queue
, obj
);
161 up(&pcmdpriv
->cmd_queue_sema
);
165 u32
r8712_enqueue_cmd_ex(struct cmd_priv
*pcmdpriv
, struct cmd_obj
*obj
)
168 struct __queue
*queue
;
172 if (pcmdpriv
->padapter
->eeprompriv
.bautoload_fail_flag
== true)
174 queue
= &pcmdpriv
->cmd_queue
;
175 spin_lock_irqsave(&queue
->lock
, irqL
);
176 list_insert_tail(&obj
->list
, &queue
->queue
);
177 spin_unlock_irqrestore(&queue
->lock
, irqL
);
178 up(&pcmdpriv
->cmd_queue_sema
);
182 struct cmd_obj
*r8712_dequeue_cmd(struct __queue
*queue
)
184 return _dequeue_cmd(queue
);
187 void r8712_free_cmd_obj(struct cmd_obj
*pcmd
)
189 if ((pcmd
->cmdcode
!= _JoinBss_CMD_
) &&
190 (pcmd
->cmdcode
!= _CreateBss_CMD_
))
191 kfree((unsigned char *)pcmd
->parmbuf
);
192 if (pcmd
->rsp
!= NULL
) {
193 if (pcmd
->rspsz
!= 0)
194 kfree((unsigned char *)pcmd
->rsp
);
196 kfree((unsigned char *)pcmd
);
200 r8712_sitesurvey_cmd(~)
202 MUST TAKE CARE THAT BEFORE CALLING THIS FUNC,
203 YOU SHOULD HAVE LOCKED pmlmepriv->lock
205 u8
r8712_sitesurvey_cmd(struct _adapter
*padapter
,
206 struct ndis_802_11_ssid
*pssid
)
208 struct cmd_obj
*ph2c
;
209 struct sitesurvey_parm
*psurveyPara
;
210 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
211 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
213 ph2c
= (struct cmd_obj
*)_malloc(sizeof(struct cmd_obj
));
216 psurveyPara
= (struct sitesurvey_parm
*)_malloc(
217 sizeof(struct sitesurvey_parm
));
218 if (psurveyPara
== NULL
) {
219 kfree((unsigned char *) ph2c
);
222 init_h2fwcmd_w_parm_no_rsp(ph2c
, psurveyPara
,
223 GEN_CMD_CODE(_SiteSurvey
));
224 psurveyPara
->bsslimit
= cpu_to_le32(48);
225 psurveyPara
->passive_mode
= cpu_to_le32(1);
226 psurveyPara
->ss_ssidlen
= 0;
227 memset(psurveyPara
->ss_ssid
, 0, IW_ESSID_MAX_SIZE
+ 1);
228 if ((pssid
!= NULL
) && (pssid
->SsidLength
)) {
229 memcpy(psurveyPara
->ss_ssid
, pssid
->Ssid
, pssid
->SsidLength
);
230 psurveyPara
->ss_ssidlen
= cpu_to_le32(pssid
->SsidLength
);
232 set_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
);
233 r8712_enqueue_cmd(pcmdpriv
, ph2c
);
234 _set_timer(&pmlmepriv
->scan_to_timer
, SCANNING_TIMEOUT
);
235 padapter
->ledpriv
.LedControlHandler(padapter
, LED_CTL_SITE_SURVEY
);
239 u8
r8712_setdatarate_cmd(struct _adapter
*padapter
, u8
*rateset
)
241 struct cmd_obj
*ph2c
;
242 struct setdatarate_parm
*pbsetdataratepara
;
243 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
245 ph2c
= (struct cmd_obj
*)_malloc(sizeof(struct cmd_obj
));
248 pbsetdataratepara
= (struct setdatarate_parm
*)_malloc(
249 sizeof(struct setdatarate_parm
));
250 if (pbsetdataratepara
== NULL
) {
254 init_h2fwcmd_w_parm_no_rsp(ph2c
, pbsetdataratepara
,
255 GEN_CMD_CODE(_SetDataRate
));
256 pbsetdataratepara
->mac_id
= 5;
257 memcpy(pbsetdataratepara
->datarates
, rateset
, NumRates
);
258 r8712_enqueue_cmd(pcmdpriv
, ph2c
);
262 u8
r8712_setbasicrate_cmd(struct _adapter
*padapter
, u8
*rateset
)
264 struct cmd_obj
*ph2c
;
265 struct setbasicrate_parm
*pssetbasicratepara
;
266 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
268 ph2c
= (struct cmd_obj
*)_malloc(sizeof(struct cmd_obj
));
271 pssetbasicratepara
= (struct setbasicrate_parm
*)_malloc(
272 sizeof(struct setbasicrate_parm
));
273 if (pssetbasicratepara
== NULL
) {
277 init_h2fwcmd_w_parm_no_rsp(ph2c
, pssetbasicratepara
,
279 memcpy(pssetbasicratepara
->basicrates
, rateset
, NumRates
);
280 r8712_enqueue_cmd(pcmdpriv
, ph2c
);
284 /* power tracking mechanism setting */
285 u8
r8712_setptm_cmd(struct _adapter
*padapter
, u8 type
)
287 struct cmd_obj
*ph2c
;
288 struct PT_param
*pptparm
;
289 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
291 ph2c
= (struct cmd_obj
*)_malloc(sizeof(struct cmd_obj
));
294 pptparm
= (struct PT_param
*)_malloc(sizeof(struct PT_param
));
295 if (pptparm
== NULL
) {
299 init_h2fwcmd_w_parm_no_rsp(ph2c
, pptparm
,
300 GEN_CMD_CODE(_SetPowerTracking
));
301 pptparm
->PT_En
= type
;
302 r8712_enqueue_cmd(pcmdpriv
, ph2c
);
306 u8
r8712_setrfreg_cmd(struct _adapter
*padapter
, u8 offset
, u32 val
)
308 struct cmd_obj
*ph2c
;
309 struct writeRF_parm
*pwriterfparm
;
310 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
312 ph2c
= (struct cmd_obj
*)_malloc(sizeof(struct cmd_obj
));
315 pwriterfparm
= (struct writeRF_parm
*)_malloc(
316 sizeof(struct writeRF_parm
));
317 if (pwriterfparm
== NULL
) {
321 init_h2fwcmd_w_parm_no_rsp(ph2c
, pwriterfparm
, GEN_CMD_CODE(_SetRFReg
));
322 pwriterfparm
->offset
= offset
;
323 pwriterfparm
->value
= val
;
324 r8712_enqueue_cmd(pcmdpriv
, ph2c
);
328 u8
r8712_getrfreg_cmd(struct _adapter
*padapter
, u8 offset
, u8
*pval
)
330 struct cmd_obj
*ph2c
;
331 struct readRF_parm
*prdrfparm
;
332 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
334 ph2c
= (struct cmd_obj
*)_malloc(sizeof(struct cmd_obj
));
337 prdrfparm
= (struct readRF_parm
*)_malloc(sizeof(struct readRF_parm
));
338 if (prdrfparm
== NULL
) {
342 _init_listhead(&ph2c
->list
);
343 ph2c
->cmdcode
= GEN_CMD_CODE(_GetRFReg
);
344 ph2c
->parmbuf
= (unsigned char *)prdrfparm
;
345 ph2c
->cmdsz
= sizeof(struct readRF_parm
);
347 ph2c
->rspsz
= sizeof(struct readRF_rsp
);
348 prdrfparm
->offset
= offset
;
349 r8712_enqueue_cmd(pcmdpriv
, ph2c
);
353 void r8712_getbbrfreg_cmdrsp_callback(struct _adapter
*padapter
,
354 struct cmd_obj
*pcmd
)
356 kfree((unsigned char *) pcmd
->parmbuf
);
357 kfree((unsigned char *) pcmd
);
358 padapter
->mppriv
.workparam
.bcompleted
= true;
361 u8
r8712_createbss_cmd(struct _adapter
*padapter
)
363 struct cmd_obj
*pcmd
;
364 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
365 struct wlan_bssid_ex
*pdev_network
=
366 &padapter
->registrypriv
.dev_network
;
368 padapter
->ledpriv
.LedControlHandler(padapter
, LED_CTL_START_TO_LINK
);
369 pcmd
= (struct cmd_obj
*)_malloc(sizeof(struct cmd_obj
));
372 _init_listhead(&pcmd
->list
);
373 pcmd
->cmdcode
= _CreateBss_CMD_
;
374 pcmd
->parmbuf
= (unsigned char *)pdev_network
;
375 pcmd
->cmdsz
= r8712_get_ndis_wlan_bssid_ex_sz((
376 struct ndis_wlan_bssid_ex
*)
380 /* notes: translate IELength & Length after assign to cmdsz; */
381 pdev_network
->Length
= cpu_to_le32(pcmd
->cmdsz
);
382 pdev_network
->IELength
= cpu_to_le32(pdev_network
->IELength
);
383 pdev_network
->Ssid
.SsidLength
= cpu_to_le32(
384 pdev_network
->Ssid
.SsidLength
);
385 r8712_enqueue_cmd(pcmdpriv
, pcmd
);
389 u8
r8712_joinbss_cmd(struct _adapter
*padapter
, struct wlan_network
*pnetwork
)
393 struct ndis_wlan_bssid_ex
*psecnetwork
;
394 struct cmd_obj
*pcmd
;
395 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
396 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
397 struct qos_priv
*pqospriv
= &pmlmepriv
->qospriv
;
398 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
399 struct registry_priv
*pregistrypriv
= &padapter
->registrypriv
;
400 enum NDIS_802_11_NETWORK_INFRASTRUCTURE ndis_network_mode
= pnetwork
->
401 network
.InfrastructureMode
;
403 padapter
->ledpriv
.LedControlHandler(padapter
, LED_CTL_START_TO_LINK
);
404 pcmd
= (struct cmd_obj
*)_malloc(sizeof(struct cmd_obj
));
407 t_len
= sizeof(u32
) + 6 * sizeof(unsigned char) + 2 +
408 sizeof(struct ndis_802_11_ssid
) + sizeof(u32
) +
410 sizeof(enum NDIS_802_11_NETWORK_TYPE
) +
411 sizeof(struct NDIS_802_11_CONFIGURATION
) +
412 sizeof(enum NDIS_802_11_NETWORK_INFRASTRUCTURE
) +
413 sizeof(NDIS_802_11_RATES_EX
) +
414 sizeof(u32
) + MAX_IE_SZ
;
416 /* for hidden ap to set fw_state here */
417 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
|WIFI_ADHOC_STATE
) !=
419 switch (ndis_network_mode
) {
421 pmlmepriv
->fw_state
|= WIFI_ADHOC_STATE
;
423 case Ndis802_11Infrastructure
:
424 pmlmepriv
->fw_state
|= WIFI_STATION_STATE
;
426 case Ndis802_11APMode
:
427 case Ndis802_11AutoUnknown
:
428 case Ndis802_11InfrastructureMax
:
432 psecnetwork
= (struct ndis_wlan_bssid_ex
*)&psecuritypriv
->sec_bss
;
433 if (psecnetwork
== NULL
) {
435 kfree((unsigned char *)pcmd
);
438 memset(psecnetwork
, 0, t_len
);
439 memcpy(psecnetwork
, &pnetwork
->network
, t_len
);
440 auth
= &psecuritypriv
->authenticator_ie
[0];
441 psecuritypriv
->authenticator_ie
[0] = (unsigned char)
442 psecnetwork
->IELength
;
443 if ((psecnetwork
->IELength
-12) < (256 - 1))
444 memcpy(&psecuritypriv
->authenticator_ie
[1],
445 &psecnetwork
->IEs
[12], psecnetwork
->IELength
-12);
447 memcpy(&psecuritypriv
->authenticator_ie
[1],
448 &psecnetwork
->IEs
[12], (256-1));
449 psecnetwork
->IELength
= 0;
450 /* If the the driver wants to use the bssid to create the connection.
451 * If not, we copy the connecting AP's MAC address to it so that
452 * the driver just has the bssid information for PMKIDList searching.
454 if (pmlmepriv
->assoc_by_bssid
== false)
455 memcpy(&pmlmepriv
->assoc_bssid
[0],
456 &pnetwork
->network
.MacAddress
[0], ETH_ALEN
);
457 psecnetwork
->IELength
= r8712_restruct_sec_ie(padapter
,
458 &pnetwork
->network
.IEs
[0],
459 &psecnetwork
->IEs
[0],
460 pnetwork
->network
.IELength
);
461 pqospriv
->qos_option
= 0;
462 if (pregistrypriv
->wmm_enable
) {
465 tmp_len
= r8712_restruct_wmm_ie(padapter
,
466 &pnetwork
->network
.IEs
[0],
467 &psecnetwork
->IEs
[0],
468 pnetwork
->network
.IELength
,
469 psecnetwork
->IELength
);
470 if (psecnetwork
->IELength
!= tmp_len
) {
471 psecnetwork
->IELength
= tmp_len
;
472 pqospriv
->qos_option
= 1; /* WMM IE in beacon */
474 pqospriv
->qos_option
= 0; /* no WMM IE in beacon */
476 if (pregistrypriv
->ht_enable
) {
477 /* For WEP mode, we will use the bg mode to do the connection
478 * to avoid some IOT issues, especially for Realtek 8192u
481 if ((padapter
->securitypriv
.PrivacyAlgrthm
!= _WEP40_
) &&
482 (padapter
->securitypriv
.PrivacyAlgrthm
!= _WEP104_
)) {
483 /* restructure_ht_ie */
484 r8712_restructure_ht_ie(padapter
,
485 &pnetwork
->network
.IEs
[0],
486 &psecnetwork
->IEs
[0],
487 pnetwork
->network
.IELength
,
488 &psecnetwork
->IELength
);
489 if (check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
))
490 r8712_add_ht_addt_info(padapter
,
491 &pnetwork
->network
.IEs
[0],
492 &psecnetwork
->IEs
[0],
493 pnetwork
->network
.IELength
,
494 &psecnetwork
->IELength
);
497 psecuritypriv
->supplicant_ie
[0] = (u8
)psecnetwork
->IELength
;
498 if (psecnetwork
->IELength
< 255)
499 memcpy(&psecuritypriv
->supplicant_ie
[1], &psecnetwork
->IEs
[0],
500 psecnetwork
->IELength
);
502 memcpy(&psecuritypriv
->supplicant_ie
[1], &psecnetwork
->IEs
[0],
504 /* get cmdsz before endian conversion */
505 pcmd
->cmdsz
= r8712_get_ndis_wlan_bssid_ex_sz(psecnetwork
);
507 /* wlan_network endian conversion */
508 psecnetwork
->Length
= cpu_to_le32(psecnetwork
->Length
);
509 psecnetwork
->Ssid
.SsidLength
= cpu_to_le32(
510 psecnetwork
->Ssid
.SsidLength
);
511 psecnetwork
->Privacy
= cpu_to_le32(psecnetwork
->Privacy
);
512 psecnetwork
->Rssi
= cpu_to_le32(psecnetwork
->Rssi
);
513 psecnetwork
->NetworkTypeInUse
= cpu_to_le32(
514 psecnetwork
->NetworkTypeInUse
);
515 psecnetwork
->Configuration
.ATIMWindow
= cpu_to_le32(
516 psecnetwork
->Configuration
.ATIMWindow
);
517 psecnetwork
->Configuration
.BeaconPeriod
= cpu_to_le32(
518 psecnetwork
->Configuration
.BeaconPeriod
);
519 psecnetwork
->Configuration
.DSConfig
= cpu_to_le32(
520 psecnetwork
->Configuration
.DSConfig
);
521 psecnetwork
->Configuration
.FHConfig
.DwellTime
= cpu_to_le32(
522 psecnetwork
->Configuration
.FHConfig
.DwellTime
);
523 psecnetwork
->Configuration
.FHConfig
.HopPattern
= cpu_to_le32(
524 psecnetwork
->Configuration
.FHConfig
.HopPattern
);
525 psecnetwork
->Configuration
.FHConfig
.HopSet
= cpu_to_le32(
526 psecnetwork
->Configuration
.FHConfig
.HopSet
);
527 psecnetwork
->Configuration
.FHConfig
.Length
= cpu_to_le32(
528 psecnetwork
->Configuration
.FHConfig
.Length
);
529 psecnetwork
->Configuration
.Length
= cpu_to_le32(
530 psecnetwork
->Configuration
.Length
);
531 psecnetwork
->InfrastructureMode
= cpu_to_le32(
532 psecnetwork
->InfrastructureMode
);
533 psecnetwork
->IELength
= cpu_to_le32(psecnetwork
->IELength
);
535 _init_listhead(&pcmd
->list
);
536 pcmd
->cmdcode
= _JoinBss_CMD_
;
537 pcmd
->parmbuf
= (unsigned char *)psecnetwork
;
540 r8712_enqueue_cmd(pcmdpriv
, pcmd
);
544 u8
r8712_disassoc_cmd(struct _adapter
*padapter
) /* for sta_mode */
546 struct cmd_obj
*pdisconnect_cmd
;
547 struct disconnect_parm
*pdisconnect
;
548 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
550 pdisconnect_cmd
= (struct cmd_obj
*)_malloc(sizeof(struct cmd_obj
));
551 if (pdisconnect_cmd
== NULL
)
553 pdisconnect
= (struct disconnect_parm
*)_malloc(
554 sizeof(struct disconnect_parm
));
555 if (pdisconnect
== NULL
) {
556 kfree((u8
*)pdisconnect_cmd
);
559 init_h2fwcmd_w_parm_no_rsp(pdisconnect_cmd
, pdisconnect
,
561 r8712_enqueue_cmd(pcmdpriv
, pdisconnect_cmd
);
565 u8
r8712_setopmode_cmd(struct _adapter
*padapter
,
566 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype
)
568 struct cmd_obj
*ph2c
;
569 struct setopmode_parm
*psetop
;
571 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
573 ph2c
= (struct cmd_obj
*)_malloc(sizeof(struct cmd_obj
));
576 psetop
= (struct setopmode_parm
*)_malloc(
577 sizeof(struct setopmode_parm
));
578 if (psetop
== NULL
) {
582 init_h2fwcmd_w_parm_no_rsp(ph2c
, psetop
, _SetOpMode_CMD_
);
583 psetop
->mode
= (u8
)networktype
;
584 r8712_enqueue_cmd(pcmdpriv
, ph2c
);
588 u8
r8712_setstakey_cmd(struct _adapter
*padapter
, u8
*psta
, u8 unicast_key
)
590 struct cmd_obj
*ph2c
;
591 struct set_stakey_parm
*psetstakey_para
;
592 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
593 struct set_stakey_rsp
*psetstakey_rsp
= NULL
;
594 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
595 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
596 struct sta_info
*sta
= (struct sta_info
*)psta
;
598 ph2c
= (struct cmd_obj
*)_malloc(sizeof(struct cmd_obj
));
601 psetstakey_para
= (struct set_stakey_parm
*)_malloc(
602 sizeof(struct set_stakey_parm
));
603 if (psetstakey_para
== NULL
) {
607 psetstakey_rsp
= (struct set_stakey_rsp
*)_malloc(
608 sizeof(struct set_stakey_rsp
));
609 if (psetstakey_rsp
== NULL
) {
611 kfree((u8
*) psetstakey_para
);
614 init_h2fwcmd_w_parm_no_rsp(ph2c
, psetstakey_para
, _SetStaKey_CMD_
);
615 ph2c
->rsp
= (u8
*) psetstakey_rsp
;
616 ph2c
->rspsz
= sizeof(struct set_stakey_rsp
);
617 memcpy(psetstakey_para
->addr
, sta
->hwaddr
, ETH_ALEN
);
618 if (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
))
619 psetstakey_para
->algorithm
= (unsigned char)
620 psecuritypriv
->PrivacyAlgrthm
;
622 GET_ENCRY_ALGO(psecuritypriv
, sta
,
623 psetstakey_para
->algorithm
, false);
624 if (unicast_key
== true)
625 memcpy(&psetstakey_para
->key
, &sta
->x_UncstKey
, 16);
627 memcpy(&psetstakey_para
->key
,
628 &psecuritypriv
->XGrpKey
[
629 psecuritypriv
->XGrpKeyid
- 1]. skey
, 16);
630 r8712_enqueue_cmd(pcmdpriv
, ph2c
);
634 u8
r8712_setrfintfs_cmd(struct _adapter
*padapter
, u8 mode
)
636 struct cmd_obj
*ph2c
;
637 struct setrfintfs_parm
*psetrfintfsparm
;
638 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
640 ph2c
= (struct cmd_obj
*)_malloc(sizeof(struct cmd_obj
));
643 psetrfintfsparm
= (struct setrfintfs_parm
*)_malloc(
644 sizeof(struct setrfintfs_parm
));
645 if (psetrfintfsparm
== NULL
) {
646 kfree((unsigned char *) ph2c
);
649 init_h2fwcmd_w_parm_no_rsp(ph2c
, psetrfintfsparm
,
650 GEN_CMD_CODE(_SetRFIntFs
));
651 psetrfintfsparm
->rfintfs
= mode
;
652 r8712_enqueue_cmd(pcmdpriv
, ph2c
);
656 u8
r8712_setrttbl_cmd(struct _adapter
*padapter
,
657 struct setratable_parm
*prate_table
)
659 struct cmd_obj
*ph2c
;
660 struct setratable_parm
*psetrttblparm
;
661 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
663 ph2c
= (struct cmd_obj
*)_malloc(sizeof(struct cmd_obj
));
666 psetrttblparm
= (struct setratable_parm
*)_malloc(
667 sizeof(struct setratable_parm
));
668 if (psetrttblparm
== NULL
) {
669 kfree((unsigned char *)ph2c
);
672 init_h2fwcmd_w_parm_no_rsp(ph2c
, psetrttblparm
,
673 GEN_CMD_CODE(_SetRaTable
));
674 memcpy(psetrttblparm
, prate_table
, sizeof(struct setratable_parm
));
675 r8712_enqueue_cmd(pcmdpriv
, ph2c
);
679 u8
r8712_setMacAddr_cmd(struct _adapter
*padapter
, u8
*mac_addr
)
681 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
682 struct cmd_obj
*ph2c
;
683 struct SetMacAddr_param
*psetMacAddr_para
;
685 ph2c
= (struct cmd_obj
*)_malloc(sizeof(struct cmd_obj
));
688 psetMacAddr_para
= (struct SetMacAddr_param
*)_malloc(
689 sizeof(struct SetMacAddr_param
));
690 if (psetMacAddr_para
== NULL
) {
694 init_h2fwcmd_w_parm_no_rsp(ph2c
, psetMacAddr_para
,
695 _SetMacAddress_CMD_
);
696 memcpy(psetMacAddr_para
->MacAddr
, mac_addr
, ETH_ALEN
);
697 r8712_enqueue_cmd(pcmdpriv
, ph2c
);
701 u8
r8712_setassocsta_cmd(struct _adapter
*padapter
, u8
*mac_addr
)
703 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
704 struct cmd_obj
*ph2c
;
705 struct set_assocsta_parm
*psetassocsta_para
;
706 struct set_stakey_rsp
*psetassocsta_rsp
= NULL
;
708 ph2c
= (struct cmd_obj
*)_malloc(sizeof(struct cmd_obj
));
711 psetassocsta_para
= (struct set_assocsta_parm
*)
712 _malloc(sizeof(struct set_assocsta_parm
));
713 if (psetassocsta_para
== NULL
) {
717 psetassocsta_rsp
= (struct set_stakey_rsp
*)_malloc(
718 sizeof(struct set_assocsta_rsp
));
719 if (psetassocsta_rsp
== NULL
) {
721 kfree((u8
*)psetassocsta_para
);
724 init_h2fwcmd_w_parm_no_rsp(ph2c
, psetassocsta_para
, _SetAssocSta_CMD_
);
725 ph2c
->rsp
= (u8
*) psetassocsta_rsp
;
726 ph2c
->rspsz
= sizeof(struct set_assocsta_rsp
);
727 memcpy(psetassocsta_para
->addr
, mac_addr
, ETH_ALEN
);
728 r8712_enqueue_cmd(pcmdpriv
, ph2c
);
732 u8
r8712_addbareq_cmd(struct _adapter
*padapter
, u8 tid
)
734 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
735 struct cmd_obj
*ph2c
;
736 struct addBaReq_parm
*paddbareq_parm
;
738 ph2c
= (struct cmd_obj
*)_malloc(sizeof(struct cmd_obj
));
741 paddbareq_parm
= (struct addBaReq_parm
*)_malloc(
742 sizeof(struct addBaReq_parm
));
743 if (paddbareq_parm
== NULL
) {
744 kfree((unsigned char *)ph2c
);
747 paddbareq_parm
->tid
= tid
;
748 init_h2fwcmd_w_parm_no_rsp(ph2c
, paddbareq_parm
,
749 GEN_CMD_CODE(_AddBAReq
));
750 r8712_enqueue_cmd_ex(pcmdpriv
, ph2c
);
754 u8
r8712_wdg_wk_cmd(struct _adapter
*padapter
)
756 struct cmd_obj
*ph2c
;
757 struct drvint_cmd_parm
*pdrvintcmd_param
;
758 struct cmd_priv
*pcmdpriv
= &padapter
->cmdpriv
;
760 ph2c
= (struct cmd_obj
*)_malloc(sizeof(struct cmd_obj
));
763 pdrvintcmd_param
= (struct drvint_cmd_parm
*)_malloc(
764 sizeof(struct drvint_cmd_parm
));
765 if (pdrvintcmd_param
== NULL
) {
766 kfree((unsigned char *)ph2c
);
769 pdrvintcmd_param
->i_cid
= WDG_WK_CID
;
770 pdrvintcmd_param
->sz
= 0;
771 pdrvintcmd_param
->pbuf
= NULL
;
772 init_h2fwcmd_w_parm_no_rsp(ph2c
, pdrvintcmd_param
, _DRV_INT_CMD_
);
773 r8712_enqueue_cmd_ex(pcmdpriv
, ph2c
);
777 void r8712_survey_cmd_callback(struct _adapter
*padapter
, struct cmd_obj
*pcmd
)
779 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
781 if (pcmd
->res
!= H2C_SUCCESS
)
782 clr_fwstate(pmlmepriv
, _FW_UNDER_SURVEY
);
783 r8712_free_cmd_obj(pcmd
);
786 void r8712_disassoc_cmd_callback(struct _adapter
*padapter
,
787 struct cmd_obj
*pcmd
)
790 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
792 if (pcmd
->res
!= H2C_SUCCESS
) {
793 spin_lock_irqsave(&pmlmepriv
->lock
, irqL
);
794 set_fwstate(pmlmepriv
, _FW_LINKED
);
795 spin_unlock_irqrestore(&pmlmepriv
->lock
, irqL
);
798 r8712_free_cmd_obj(pcmd
);
801 void r8712_joinbss_cmd_callback(struct _adapter
*padapter
, struct cmd_obj
*pcmd
)
803 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
805 if ((pcmd
->res
!= H2C_SUCCESS
))
806 _set_timer(&pmlmepriv
->assoc_timer
, 1);
807 r8712_free_cmd_obj(pcmd
);
810 void r8712_createbss_cmd_callback(struct _adapter
*padapter
,
811 struct cmd_obj
*pcmd
)
815 struct sta_info
*psta
= NULL
;
816 struct wlan_network
*pwlan
= NULL
;
817 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
818 struct ndis_wlan_bssid_ex
*pnetwork
= (struct ndis_wlan_bssid_ex
*)
820 struct wlan_network
*tgt_network
= &(pmlmepriv
->cur_network
);
822 if ((pcmd
->res
!= H2C_SUCCESS
))
823 _set_timer(&pmlmepriv
->assoc_timer
, 1);
824 _cancel_timer(&pmlmepriv
->assoc_timer
, &timer_cancelled
);
827 pnetwork
->Length
= le32_to_cpu(pnetwork
->Length
);
828 pnetwork
->Ssid
.SsidLength
= le32_to_cpu(pnetwork
->Ssid
.SsidLength
);
829 pnetwork
->Privacy
= le32_to_cpu(pnetwork
->Privacy
);
830 pnetwork
->Rssi
= le32_to_cpu(pnetwork
->Rssi
);
831 pnetwork
->NetworkTypeInUse
= le32_to_cpu(pnetwork
->NetworkTypeInUse
);
832 pnetwork
->Configuration
.ATIMWindow
= le32_to_cpu(pnetwork
->
833 Configuration
.ATIMWindow
);
834 pnetwork
->Configuration
.DSConfig
= le32_to_cpu(pnetwork
->
835 Configuration
.DSConfig
);
836 pnetwork
->Configuration
.FHConfig
.DwellTime
= le32_to_cpu(pnetwork
->
837 Configuration
.FHConfig
.DwellTime
);
838 pnetwork
->Configuration
.FHConfig
.HopPattern
= le32_to_cpu(pnetwork
->
839 Configuration
.FHConfig
.HopPattern
);
840 pnetwork
->Configuration
.FHConfig
.HopSet
= le32_to_cpu(pnetwork
->
841 Configuration
.FHConfig
.HopSet
);
842 pnetwork
->Configuration
.FHConfig
.Length
= le32_to_cpu(pnetwork
->
843 Configuration
.FHConfig
.Length
);
844 pnetwork
->Configuration
.Length
= le32_to_cpu(pnetwork
->
845 Configuration
.Length
);
846 pnetwork
->InfrastructureMode
= le32_to_cpu(pnetwork
->
848 pnetwork
->IELength
= le32_to_cpu(pnetwork
->IELength
);
850 spin_lock_irqsave(&pmlmepriv
->lock
, irqL
);
851 if ((pmlmepriv
->fw_state
) & WIFI_AP_STATE
) {
852 psta
= r8712_get_stainfo(&padapter
->stapriv
,
853 pnetwork
->MacAddress
);
855 psta
= r8712_alloc_stainfo(&padapter
->stapriv
,
856 pnetwork
->MacAddress
);
858 goto createbss_cmd_fail
;
860 r8712_indicate_connect(padapter
);
862 pwlan
= _r8712_alloc_network(pmlmepriv
);
864 pwlan
= r8712_get_oldest_wlan_network(
865 &pmlmepriv
->scanned_queue
);
867 goto createbss_cmd_fail
;
868 pwlan
->last_scanned
= jiffies
;
870 list_insert_tail(&(pwlan
->list
),
871 &pmlmepriv
->scanned_queue
.queue
);
872 pnetwork
->Length
= r8712_get_ndis_wlan_bssid_ex_sz(pnetwork
);
873 memcpy(&(pwlan
->network
), pnetwork
, pnetwork
->Length
);
875 memcpy(&tgt_network
->network
, pnetwork
,
876 (r8712_get_ndis_wlan_bssid_ex_sz(pnetwork
)));
877 if (pmlmepriv
->fw_state
& _FW_UNDER_LINKING
)
878 pmlmepriv
->fw_state
^= _FW_UNDER_LINKING
;
879 /* we will set _FW_LINKED when there is one more sat to
880 * join us (stassoc_event_callback) */
883 spin_unlock_irqrestore(&pmlmepriv
->lock
, irqL
);
884 r8712_free_cmd_obj(pcmd
);
887 void r8712_setstaKey_cmdrsp_callback(struct _adapter
*padapter
,
888 struct cmd_obj
*pcmd
)
890 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
891 struct set_stakey_rsp
*psetstakey_rsp
= (struct set_stakey_rsp
*)
893 struct sta_info
*psta
= r8712_get_stainfo(pstapriv
,
894 psetstakey_rsp
->addr
);
898 psta
->aid
= psta
->mac_id
= psetstakey_rsp
->keyid
; /*CAM_ID(CAM_ENTRY)*/
900 r8712_free_cmd_obj(pcmd
);
903 void r8712_setassocsta_cmdrsp_callback(struct _adapter
*padapter
,
904 struct cmd_obj
*pcmd
)
907 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
908 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
909 struct set_assocsta_parm
*passocsta_parm
=
910 (struct set_assocsta_parm
*)(pcmd
->parmbuf
);
911 struct set_assocsta_rsp
*passocsta_rsp
=
912 (struct set_assocsta_rsp
*) (pcmd
->rsp
);
913 struct sta_info
*psta
= r8712_get_stainfo(pstapriv
,
914 passocsta_parm
->addr
);
918 psta
->aid
= psta
->mac_id
= passocsta_rsp
->cam_id
;
919 spin_lock_irqsave(&pmlmepriv
->lock
, irqL
);
920 if ((check_fwstate(pmlmepriv
, WIFI_MP_STATE
)) &&
921 (check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
)))
922 pmlmepriv
->fw_state
^= _FW_UNDER_LINKING
;
923 set_fwstate(pmlmepriv
, _FW_LINKED
);
924 spin_unlock_irqrestore(&pmlmepriv
->lock
, irqL
);
925 r8712_free_cmd_obj(pcmd
);