1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
5 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
6 * Linux device driver for RTL8192SU
8 * Modifications for inclusion into the Linux staging tree are
9 * Copyright(c) 2010 Larry Finger. All rights reserved.
11 * Contact information:
15 ******************************************************************************/
17 #define _RTL871X_CMD_C_
19 #include <linux/compiler.h>
20 #include <linux/kernel.h>
21 #include <linux/errno.h>
22 #include <linux/slab.h>
23 #include <linux/module.h>
24 #include <linux/kref.h>
25 #include <linux/netdevice.h>
26 #include <linux/skbuff.h>
27 #include <linux/usb.h>
28 #include <linux/usb/ch9.h>
29 #include <linux/circ_buf.h>
30 #include <linux/uaccess.h>
31 #include <asm/byteorder.h>
32 #include <linux/atomic.h>
33 #include <linux/semaphore.h>
34 #include <linux/rtnetlink.h>
36 #include "osdep_service.h"
37 #include "drv_types.h"
38 #include "recv_osdep.h"
39 #include "mlme_osdep.h"
42 * Caller and the r8712_cmd_thread can protect cmd_q by spin_lock.
43 * No irqsave is necessary.
46 static sint _init_cmd_priv(struct cmd_priv *pcmdpriv)
48 init_completion(&pcmdpriv->cmd_queue_comp);
49 init_completion(&pcmdpriv->terminate_cmdthread_comp);
51 _init_queue(&(pcmdpriv->cmd_queue));
53 /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
54 pcmdpriv->cmd_seq = 1;
55 pcmdpriv->cmd_allocated_buf = kmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ,
57 if (!pcmdpriv->cmd_allocated_buf)
59 pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ -
60 ((addr_t)(pcmdpriv->cmd_allocated_buf) &
61 (CMDBUFF_ALIGN_SZ - 1));
62 pcmdpriv->rsp_allocated_buf = kmalloc(MAX_RSPSZ + 4, GFP_ATOMIC);
63 if (!pcmdpriv->rsp_allocated_buf) {
64 kfree(pcmdpriv->cmd_allocated_buf);
65 pcmdpriv->cmd_allocated_buf = NULL;
68 pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 -
69 ((addr_t)(pcmdpriv->rsp_allocated_buf) & 3);
70 pcmdpriv->cmd_issued_cnt = 0;
71 pcmdpriv->cmd_done_cnt = 0;
72 pcmdpriv->rsp_cnt = 0;
76 static sint _init_evt_priv(struct evt_priv *pevtpriv)
78 /* allocate DMA-able/Non-Page memory for cmd_buf and rsp_buf */
79 pevtpriv->event_seq = 0;
80 pevtpriv->evt_allocated_buf = kmalloc(MAX_EVTSZ + 4, GFP_ATOMIC);
82 if (!pevtpriv->evt_allocated_buf)
84 pevtpriv->evt_buf = pevtpriv->evt_allocated_buf + 4 -
85 ((addr_t)(pevtpriv->evt_allocated_buf) & 3);
86 pevtpriv->evt_done_cnt = 0;
90 static void _free_evt_priv(struct evt_priv *pevtpriv)
92 kfree(pevtpriv->evt_allocated_buf);
95 static void _free_cmd_priv(struct cmd_priv *pcmdpriv)
98 kfree(pcmdpriv->cmd_allocated_buf);
99 kfree(pcmdpriv->rsp_allocated_buf);
106 * _enqueue_cmd can only be called between kernel thread,
107 * since only spin_lock is used.
109 * ISR/Call-Back functions can't call this sub-function.
113 static sint _enqueue_cmd(struct __queue *queue, struct cmd_obj *obj)
119 spin_lock_irqsave(&queue->lock, irqL);
120 list_add_tail(&obj->list, &queue->queue);
121 spin_unlock_irqrestore(&queue->lock, irqL);
125 static struct cmd_obj *_dequeue_cmd(struct __queue *queue)
130 spin_lock_irqsave(&queue->lock, irqL);
131 obj = list_first_entry_or_null(&queue->queue,
132 struct cmd_obj, list);
134 list_del_init(&obj->list);
135 spin_unlock_irqrestore(&queue->lock, irqL);
139 u32 r8712_init_cmd_priv(struct cmd_priv *pcmdpriv)
141 return _init_cmd_priv(pcmdpriv);
144 u32 r8712_init_evt_priv(struct evt_priv *pevtpriv)
146 return _init_evt_priv(pevtpriv);
149 void r8712_free_evt_priv(struct evt_priv *pevtpriv)
151 _free_evt_priv(pevtpriv);
154 void r8712_free_cmd_priv(struct cmd_priv *pcmdpriv)
156 _free_cmd_priv(pcmdpriv);
159 u32 r8712_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *obj)
163 if (pcmdpriv->padapter->eeprompriv.bautoload_fail_flag)
165 res = _enqueue_cmd(&pcmdpriv->cmd_queue, obj);
166 complete(&pcmdpriv->cmd_queue_comp);
170 u32 r8712_enqueue_cmd_ex(struct cmd_priv *pcmdpriv, struct cmd_obj *obj)
173 struct __queue *queue;
177 if (pcmdpriv->padapter->eeprompriv.bautoload_fail_flag)
179 queue = &pcmdpriv->cmd_queue;
180 spin_lock_irqsave(&queue->lock, irqL);
181 list_add_tail(&obj->list, &queue->queue);
182 spin_unlock_irqrestore(&queue->lock, irqL);
183 complete(&pcmdpriv->cmd_queue_comp);
187 struct cmd_obj *r8712_dequeue_cmd(struct __queue *queue)
189 return _dequeue_cmd(queue);
192 void r8712_free_cmd_obj(struct cmd_obj *pcmd)
194 if ((pcmd->cmdcode != _JoinBss_CMD_) &&
195 (pcmd->cmdcode != _CreateBss_CMD_))
196 kfree(pcmd->parmbuf);
197 if (pcmd->rsp != NULL) {
198 if (pcmd->rspsz != 0)
205 * r8712_sitesurvey_cmd(~)
206 * ### NOTE:#### (!!!!)
207 * MUST TAKE CARE THAT BEFORE CALLING THIS FUNC,
208 * YOU SHOULD HAVE LOCKED pmlmepriv->lock
210 u8 r8712_sitesurvey_cmd(struct _adapter *padapter,
211 struct ndis_802_11_ssid *pssid)
213 struct cmd_obj *ph2c;
214 struct sitesurvey_parm *psurveyPara;
215 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
216 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
218 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
221 psurveyPara = kmalloc(sizeof(*psurveyPara), GFP_ATOMIC);
226 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara,
227 GEN_CMD_CODE(_SiteSurvey));
228 psurveyPara->bsslimit = cpu_to_le32(48);
229 psurveyPara->passive_mode = cpu_to_le32(pmlmepriv->passive_mode);
230 psurveyPara->ss_ssidlen = 0;
231 memset(psurveyPara->ss_ssid, 0, IW_ESSID_MAX_SIZE + 1);
232 if ((pssid != NULL) && (pssid->SsidLength)) {
233 memcpy(psurveyPara->ss_ssid, pssid->Ssid, pssid->SsidLength);
234 psurveyPara->ss_ssidlen = cpu_to_le32(pssid->SsidLength);
236 set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
237 r8712_enqueue_cmd(pcmdpriv, ph2c);
238 mod_timer(&pmlmepriv->scan_to_timer,
239 jiffies + msecs_to_jiffies(SCANNING_TIMEOUT));
240 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_SITE_SURVEY);
241 padapter->blnEnableRxFF0Filter = 0;
245 u8 r8712_setdatarate_cmd(struct _adapter *padapter, u8 *rateset)
247 struct cmd_obj *ph2c;
248 struct setdatarate_parm *pbsetdataratepara;
249 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
251 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
254 pbsetdataratepara = kmalloc(sizeof(*pbsetdataratepara), GFP_ATOMIC);
255 if (!pbsetdataratepara) {
259 init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara,
260 GEN_CMD_CODE(_SetDataRate));
261 pbsetdataratepara->mac_id = 5;
262 memcpy(pbsetdataratepara->datarates, rateset, NumRates);
263 r8712_enqueue_cmd(pcmdpriv, ph2c);
267 u8 r8712_set_chplan_cmd(struct _adapter *padapter, int chplan)
269 struct cmd_obj *ph2c;
270 struct SetChannelPlan_param *psetchplanpara;
271 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
273 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
276 psetchplanpara = kmalloc(sizeof(*psetchplanpara), GFP_ATOMIC);
277 if (!psetchplanpara) {
281 init_h2fwcmd_w_parm_no_rsp(ph2c, psetchplanpara,
282 GEN_CMD_CODE(_SetChannelPlan));
283 psetchplanpara->ChannelPlan = chplan;
284 r8712_enqueue_cmd(pcmdpriv, ph2c);
288 u8 r8712_setbasicrate_cmd(struct _adapter *padapter, u8 *rateset)
290 struct cmd_obj *ph2c;
291 struct setbasicrate_parm *pssetbasicratepara;
292 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
294 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
297 pssetbasicratepara = kmalloc(sizeof(*pssetbasicratepara), GFP_ATOMIC);
298 if (!pssetbasicratepara) {
302 init_h2fwcmd_w_parm_no_rsp(ph2c, pssetbasicratepara,
304 memcpy(pssetbasicratepara->basicrates, rateset, NumRates);
305 r8712_enqueue_cmd(pcmdpriv, ph2c);
309 u8 r8712_setfwdig_cmd(struct _adapter *padapter, u8 type)
311 struct cmd_obj *ph2c;
312 struct writePTM_parm *pwriteptmparm;
313 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
315 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
318 pwriteptmparm = kmalloc(sizeof(*pwriteptmparm), GFP_ATOMIC);
319 if (!pwriteptmparm) {
323 init_h2fwcmd_w_parm_no_rsp(ph2c, pwriteptmparm, GEN_CMD_CODE(_SetDIG));
324 pwriteptmparm->type = type;
325 r8712_enqueue_cmd(pcmdpriv, ph2c);
329 u8 r8712_setfwra_cmd(struct _adapter *padapter, u8 type)
331 struct cmd_obj *ph2c;
332 struct writePTM_parm *pwriteptmparm;
333 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
335 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
338 pwriteptmparm = kmalloc(sizeof(*pwriteptmparm), GFP_ATOMIC);
339 if (!pwriteptmparm) {
343 init_h2fwcmd_w_parm_no_rsp(ph2c, pwriteptmparm, GEN_CMD_CODE(_SetRA));
344 pwriteptmparm->type = type;
345 r8712_enqueue_cmd(pcmdpriv, ph2c);
349 u8 r8712_setrfreg_cmd(struct _adapter *padapter, u8 offset, u32 val)
351 struct cmd_obj *ph2c;
352 struct writeRF_parm *pwriterfparm;
353 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
355 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
358 pwriterfparm = kmalloc(sizeof(*pwriterfparm), GFP_ATOMIC);
363 init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg));
364 pwriterfparm->offset = offset;
365 pwriterfparm->value = val;
366 r8712_enqueue_cmd(pcmdpriv, ph2c);
370 u8 r8712_getrfreg_cmd(struct _adapter *padapter, u8 offset, u8 *pval)
372 struct cmd_obj *ph2c;
373 struct readRF_parm *prdrfparm;
374 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
376 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
379 prdrfparm = kmalloc(sizeof(*prdrfparm), GFP_ATOMIC);
384 INIT_LIST_HEAD(&ph2c->list);
385 ph2c->cmdcode = GEN_CMD_CODE(_GetRFReg);
386 ph2c->parmbuf = (unsigned char *)prdrfparm;
387 ph2c->cmdsz = sizeof(struct readRF_parm);
389 ph2c->rspsz = sizeof(struct readRF_rsp);
390 prdrfparm->offset = offset;
391 r8712_enqueue_cmd(pcmdpriv, ph2c);
395 void r8712_getbbrfreg_cmdrsp_callback(struct _adapter *padapter,
396 struct cmd_obj *pcmd)
398 kfree(pcmd->parmbuf);
400 padapter->mppriv.workparam.bcompleted = true;
403 void r8712_readtssi_cmdrsp_callback(struct _adapter *padapter,
404 struct cmd_obj *pcmd)
406 kfree(pcmd->parmbuf);
409 padapter->mppriv.workparam.bcompleted = true;
412 u8 r8712_createbss_cmd(struct _adapter *padapter)
414 struct cmd_obj *pcmd;
415 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
416 struct wlan_bssid_ex *pdev_network =
417 &padapter->registrypriv.dev_network;
419 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_START_TO_LINK);
420 pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC);
423 INIT_LIST_HEAD(&pcmd->list);
424 pcmd->cmdcode = _CreateBss_CMD_;
425 pcmd->parmbuf = (unsigned char *)pdev_network;
426 pcmd->cmdsz = r8712_get_wlan_bssid_ex_sz(pdev_network);
429 /* notes: translate IELength & Length after assign to cmdsz; */
430 pdev_network->Length = pcmd->cmdsz;
431 pdev_network->IELength = pdev_network->IELength;
432 pdev_network->Ssid.SsidLength = pdev_network->Ssid.SsidLength;
433 r8712_enqueue_cmd(pcmdpriv, pcmd);
437 u8 r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork)
439 struct wlan_bssid_ex *psecnetwork;
440 struct cmd_obj *pcmd;
441 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
442 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
443 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
444 struct security_priv *psecuritypriv = &padapter->securitypriv;
445 struct registry_priv *pregistrypriv = &padapter->registrypriv;
446 enum NDIS_802_11_NETWORK_INFRASTRUCTURE ndis_network_mode =
447 pnetwork->network.InfrastructureMode;
449 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_START_TO_LINK);
450 pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC);
454 /* for hidden ap to set fw_state here */
455 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) !=
457 switch (ndis_network_mode) {
459 pmlmepriv->fw_state |= WIFI_ADHOC_STATE;
461 case Ndis802_11Infrastructure:
462 pmlmepriv->fw_state |= WIFI_STATION_STATE;
464 case Ndis802_11APMode:
465 case Ndis802_11AutoUnknown:
466 case Ndis802_11InfrastructureMax:
470 psecnetwork = &psecuritypriv->sec_bss;
475 memcpy(psecnetwork, &pnetwork->network, sizeof(*psecnetwork));
476 psecuritypriv->authenticator_ie[0] = (unsigned char)
477 psecnetwork->IELength;
478 if ((psecnetwork->IELength - 12) < (256 - 1))
479 memcpy(&psecuritypriv->authenticator_ie[1],
480 &psecnetwork->IEs[12], psecnetwork->IELength - 12);
482 memcpy(&psecuritypriv->authenticator_ie[1],
483 &psecnetwork->IEs[12], (256 - 1));
484 psecnetwork->IELength = 0;
486 * If the driver wants to use the bssid to create the connection.
487 * If not, we copy the connecting AP's MAC address to it so that
488 * the driver just has the bssid information for PMKIDList searching.
490 if (!pmlmepriv->assoc_by_bssid)
491 ether_addr_copy(&pmlmepriv->assoc_bssid[0],
492 &pnetwork->network.MacAddress[0]);
493 psecnetwork->IELength = r8712_restruct_sec_ie(padapter,
494 &pnetwork->network.IEs[0],
495 &psecnetwork->IEs[0],
496 pnetwork->network.IELength);
497 pqospriv->qos_option = 0;
498 if (pregistrypriv->wmm_enable) {
501 tmp_len = r8712_restruct_wmm_ie(padapter,
502 &pnetwork->network.IEs[0],
503 &psecnetwork->IEs[0],
504 pnetwork->network.IELength,
505 psecnetwork->IELength);
506 if (psecnetwork->IELength != tmp_len) {
507 psecnetwork->IELength = tmp_len;
508 pqospriv->qos_option = 1; /* WMM IE in beacon */
510 pqospriv->qos_option = 0; /* no WMM IE in beacon */
513 if (pregistrypriv->ht_enable) {
515 * For WEP mode, we will use the bg mode to do the connection
516 * to avoid some IOT issues, especially for Realtek 8192u
519 if ((padapter->securitypriv.PrivacyAlgrthm != _WEP40_) &&
520 (padapter->securitypriv.PrivacyAlgrthm != _WEP104_)) {
521 /* restructure_ht_ie */
522 r8712_restructure_ht_ie(padapter,
523 &pnetwork->network.IEs[0],
524 &psecnetwork->IEs[0],
525 pnetwork->network.IELength,
526 &psecnetwork->IELength);
529 psecuritypriv->supplicant_ie[0] = (u8)psecnetwork->IELength;
530 if (psecnetwork->IELength < 255)
531 memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0],
532 psecnetwork->IELength);
534 memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0],
536 /* get cmdsz before endian conversion */
537 pcmd->cmdsz = r8712_get_wlan_bssid_ex_sz(psecnetwork);
539 /* wlan_network endian conversion */
540 psecnetwork->Length = cpu_to_le32(psecnetwork->Length);
541 psecnetwork->Ssid.SsidLength = cpu_to_le32(
542 psecnetwork->Ssid.SsidLength);
543 psecnetwork->Privacy = cpu_to_le32(psecnetwork->Privacy);
544 psecnetwork->Rssi = cpu_to_le32(psecnetwork->Rssi);
545 psecnetwork->NetworkTypeInUse = cpu_to_le32(
546 psecnetwork->NetworkTypeInUse);
547 psecnetwork->Configuration.ATIMWindow = cpu_to_le32(
548 psecnetwork->Configuration.ATIMWindow);
549 psecnetwork->Configuration.BeaconPeriod = cpu_to_le32(
550 psecnetwork->Configuration.BeaconPeriod);
551 psecnetwork->Configuration.DSConfig = cpu_to_le32(
552 psecnetwork->Configuration.DSConfig);
553 psecnetwork->Configuration.FHConfig.DwellTime = cpu_to_le32(
554 psecnetwork->Configuration.FHConfig.DwellTime);
555 psecnetwork->Configuration.FHConfig.HopPattern = cpu_to_le32(
556 psecnetwork->Configuration.FHConfig.HopPattern);
557 psecnetwork->Configuration.FHConfig.HopSet = cpu_to_le32(
558 psecnetwork->Configuration.FHConfig.HopSet);
559 psecnetwork->Configuration.FHConfig.Length = cpu_to_le32(
560 psecnetwork->Configuration.FHConfig.Length);
561 psecnetwork->Configuration.Length = cpu_to_le32(
562 psecnetwork->Configuration.Length);
563 psecnetwork->InfrastructureMode = cpu_to_le32(
564 psecnetwork->InfrastructureMode);
565 psecnetwork->IELength = cpu_to_le32(psecnetwork->IELength);
567 INIT_LIST_HEAD(&pcmd->list);
568 pcmd->cmdcode = _JoinBss_CMD_;
569 pcmd->parmbuf = (unsigned char *)psecnetwork;
572 r8712_enqueue_cmd(pcmdpriv, pcmd);
576 u8 r8712_disassoc_cmd(struct _adapter *padapter) /* for sta_mode */
578 struct cmd_obj *pdisconnect_cmd;
579 struct disconnect_parm *pdisconnect;
580 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
582 pdisconnect_cmd = kmalloc(sizeof(*pdisconnect_cmd), GFP_ATOMIC);
583 if (!pdisconnect_cmd)
585 pdisconnect = kmalloc(sizeof(*pdisconnect), GFP_ATOMIC);
587 kfree(pdisconnect_cmd);
590 init_h2fwcmd_w_parm_no_rsp(pdisconnect_cmd, pdisconnect,
592 r8712_enqueue_cmd(pcmdpriv, pdisconnect_cmd);
596 u8 r8712_setopmode_cmd(struct _adapter *padapter,
597 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)
599 struct cmd_obj *ph2c;
600 struct setopmode_parm *psetop;
602 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
604 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
607 psetop = kmalloc(sizeof(*psetop), GFP_ATOMIC);
612 init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_);
613 psetop->mode = (u8)networktype;
614 r8712_enqueue_cmd(pcmdpriv, ph2c);
618 u8 r8712_setstakey_cmd(struct _adapter *padapter, u8 *psta, u8 unicast_key)
620 struct cmd_obj *ph2c;
621 struct set_stakey_parm *psetstakey_para;
622 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
623 struct set_stakey_rsp *psetstakey_rsp = NULL;
624 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
625 struct security_priv *psecuritypriv = &padapter->securitypriv;
626 struct sta_info *sta = (struct sta_info *)psta;
628 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
631 psetstakey_para = kmalloc(sizeof(*psetstakey_para), GFP_ATOMIC);
632 if (!psetstakey_para) {
636 psetstakey_rsp = kmalloc(sizeof(*psetstakey_rsp), GFP_ATOMIC);
637 if (!psetstakey_rsp) {
639 kfree(psetstakey_para);
642 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
643 ph2c->rsp = (u8 *) psetstakey_rsp;
644 ph2c->rspsz = sizeof(struct set_stakey_rsp);
645 ether_addr_copy(psetstakey_para->addr, sta->hwaddr);
646 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
647 psetstakey_para->algorithm = (unsigned char)
648 psecuritypriv->PrivacyAlgrthm;
650 GET_ENCRY_ALGO(psecuritypriv, sta,
651 psetstakey_para->algorithm, false);
653 memcpy(&psetstakey_para->key, &sta->x_UncstKey, 16);
655 memcpy(&psetstakey_para->key,
656 &psecuritypriv->XGrpKey[
657 psecuritypriv->XGrpKeyid - 1]. skey, 16);
658 r8712_enqueue_cmd(pcmdpriv, ph2c);
662 u8 r8712_setrfintfs_cmd(struct _adapter *padapter, u8 mode)
664 struct cmd_obj *ph2c;
665 struct setrfintfs_parm *psetrfintfsparm;
666 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
668 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
671 psetrfintfsparm = kmalloc(sizeof(*psetrfintfsparm), GFP_ATOMIC);
672 if (!psetrfintfsparm) {
676 init_h2fwcmd_w_parm_no_rsp(ph2c, psetrfintfsparm,
677 GEN_CMD_CODE(_SetRFIntFs));
678 psetrfintfsparm->rfintfs = mode;
679 r8712_enqueue_cmd(pcmdpriv, ph2c);
683 u8 r8712_setrttbl_cmd(struct _adapter *padapter,
684 struct setratable_parm *prate_table)
686 struct cmd_obj *ph2c;
687 struct setratable_parm *psetrttblparm;
688 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
690 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
693 psetrttblparm = kmalloc(sizeof(*psetrttblparm), GFP_ATOMIC);
694 if (!psetrttblparm) {
698 init_h2fwcmd_w_parm_no_rsp(ph2c, psetrttblparm,
699 GEN_CMD_CODE(_SetRaTable));
700 memcpy(psetrttblparm, prate_table, sizeof(struct setratable_parm));
701 r8712_enqueue_cmd(pcmdpriv, ph2c);
705 u8 r8712_setMacAddr_cmd(struct _adapter *padapter, u8 *mac_addr)
707 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
708 struct cmd_obj *ph2c;
709 struct SetMacAddr_param *psetMacAddr_para;
711 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
714 psetMacAddr_para = kmalloc(sizeof(*psetMacAddr_para), GFP_ATOMIC);
715 if (!psetMacAddr_para) {
719 init_h2fwcmd_w_parm_no_rsp(ph2c, psetMacAddr_para,
720 _SetMacAddress_CMD_);
721 ether_addr_copy(psetMacAddr_para->MacAddr, mac_addr);
722 r8712_enqueue_cmd(pcmdpriv, ph2c);
726 u8 r8712_setassocsta_cmd(struct _adapter *padapter, u8 *mac_addr)
728 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
729 struct cmd_obj *ph2c;
730 struct set_assocsta_parm *psetassocsta_para;
731 struct set_assocsta_rsp *psetassocsta_rsp = NULL;
733 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
736 psetassocsta_para = kmalloc(sizeof(*psetassocsta_para), GFP_ATOMIC);
737 if (!psetassocsta_para) {
741 psetassocsta_rsp = kmalloc(sizeof(*psetassocsta_rsp), GFP_ATOMIC);
742 if (!psetassocsta_rsp) {
744 kfree(psetassocsta_para);
747 init_h2fwcmd_w_parm_no_rsp(ph2c, psetassocsta_para, _SetAssocSta_CMD_);
748 ph2c->rsp = (u8 *) psetassocsta_rsp;
749 ph2c->rspsz = sizeof(struct set_assocsta_rsp);
750 ether_addr_copy(psetassocsta_para->addr, mac_addr);
751 r8712_enqueue_cmd(pcmdpriv, ph2c);
755 u8 r8712_addbareq_cmd(struct _adapter *padapter, u8 tid)
757 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
758 struct cmd_obj *ph2c;
759 struct addBaReq_parm *paddbareq_parm;
761 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
764 paddbareq_parm = kmalloc(sizeof(*paddbareq_parm), GFP_ATOMIC);
765 if (!paddbareq_parm) {
769 paddbareq_parm->tid = tid;
770 init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm,
771 GEN_CMD_CODE(_AddBAReq));
772 r8712_enqueue_cmd_ex(pcmdpriv, ph2c);
776 u8 r8712_wdg_wk_cmd(struct _adapter *padapter)
778 struct cmd_obj *ph2c;
779 struct drvint_cmd_parm *pdrvintcmd_param;
780 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
782 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
785 pdrvintcmd_param = kmalloc(sizeof(*pdrvintcmd_param), GFP_ATOMIC);
786 if (!pdrvintcmd_param) {
790 pdrvintcmd_param->i_cid = WDG_WK_CID;
791 pdrvintcmd_param->sz = 0;
792 pdrvintcmd_param->pbuf = NULL;
793 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvintcmd_param, _DRV_INT_CMD_);
794 r8712_enqueue_cmd_ex(pcmdpriv, ph2c);
798 void r8712_survey_cmd_callback(struct _adapter *padapter, struct cmd_obj *pcmd)
800 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
802 if (pcmd->res != H2C_SUCCESS)
803 clr_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
804 r8712_free_cmd_obj(pcmd);
807 void r8712_disassoc_cmd_callback(struct _adapter *padapter,
808 struct cmd_obj *pcmd)
811 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
813 if (pcmd->res != H2C_SUCCESS) {
814 spin_lock_irqsave(&pmlmepriv->lock, irqL);
815 set_fwstate(pmlmepriv, _FW_LINKED);
816 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
819 r8712_free_cmd_obj(pcmd);
822 void r8712_joinbss_cmd_callback(struct _adapter *padapter, struct cmd_obj *pcmd)
824 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
826 if (pcmd->res != H2C_SUCCESS)
827 mod_timer(&pmlmepriv->assoc_timer,
828 jiffies + msecs_to_jiffies(1));
829 r8712_free_cmd_obj(pcmd);
832 void r8712_createbss_cmd_callback(struct _adapter *padapter,
833 struct cmd_obj *pcmd)
836 struct sta_info *psta = NULL;
837 struct wlan_network *pwlan = NULL;
838 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
839 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)pcmd->parmbuf;
840 struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
842 if (pcmd->res != H2C_SUCCESS)
843 mod_timer(&pmlmepriv->assoc_timer,
844 jiffies + msecs_to_jiffies(1));
845 del_timer(&pmlmepriv->assoc_timer);
848 pnetwork->Length = le32_to_cpu(pnetwork->Length);
849 pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength);
850 pnetwork->Privacy = le32_to_cpu(pnetwork->Privacy);
851 pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi);
852 pnetwork->NetworkTypeInUse = le32_to_cpu(pnetwork->NetworkTypeInUse);
853 pnetwork->Configuration.ATIMWindow =
854 le32_to_cpu(pnetwork->Configuration.ATIMWindow);
855 pnetwork->Configuration.DSConfig =
856 le32_to_cpu(pnetwork->Configuration.DSConfig);
857 pnetwork->Configuration.FHConfig.DwellTime =
858 le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime);
859 pnetwork->Configuration.FHConfig.HopPattern =
860 le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern);
861 pnetwork->Configuration.FHConfig.HopSet =
862 le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet);
863 pnetwork->Configuration.FHConfig.Length =
864 le32_to_cpu(pnetwork->Configuration.FHConfig.Length);
865 pnetwork->Configuration.Length =
866 le32_to_cpu(pnetwork->Configuration.Length);
867 pnetwork->InfrastructureMode =
868 le32_to_cpu(pnetwork->InfrastructureMode);
869 pnetwork->IELength = le32_to_cpu(pnetwork->IELength);
871 spin_lock_irqsave(&pmlmepriv->lock, irqL);
872 if ((pmlmepriv->fw_state) & WIFI_AP_STATE) {
873 psta = r8712_get_stainfo(&padapter->stapriv,
874 pnetwork->MacAddress);
876 psta = r8712_alloc_stainfo(&padapter->stapriv,
877 pnetwork->MacAddress);
879 goto createbss_cmd_fail;
881 r8712_indicate_connect(padapter);
883 pwlan = _r8712_alloc_network(pmlmepriv);
885 pwlan = r8712_get_oldest_wlan_network(
886 &pmlmepriv->scanned_queue);
888 goto createbss_cmd_fail;
889 pwlan->last_scanned = jiffies;
891 list_add_tail(&(pwlan->list),
892 &pmlmepriv->scanned_queue.queue);
894 pnetwork->Length = r8712_get_wlan_bssid_ex_sz(pnetwork);
895 memcpy(&(pwlan->network), pnetwork, pnetwork->Length);
897 memcpy(&tgt_network->network, pnetwork,
898 (r8712_get_wlan_bssid_ex_sz(pnetwork)));
899 if (pmlmepriv->fw_state & _FW_UNDER_LINKING)
900 pmlmepriv->fw_state ^= _FW_UNDER_LINKING;
902 * we will set _FW_LINKED when there is one more sat to
903 * join us (stassoc_event_callback)
907 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
908 r8712_free_cmd_obj(pcmd);
911 void r8712_setstaKey_cmdrsp_callback(struct _adapter *padapter,
912 struct cmd_obj *pcmd)
914 struct sta_priv *pstapriv = &padapter->stapriv;
915 struct set_stakey_rsp *psetstakey_rsp = (struct set_stakey_rsp *)
917 struct sta_info *psta = r8712_get_stainfo(pstapriv,
918 psetstakey_rsp->addr);
922 psta->aid = psta->mac_id = psetstakey_rsp->keyid; /*CAM_ID(CAM_ENTRY)*/
924 r8712_free_cmd_obj(pcmd);
927 void r8712_setassocsta_cmdrsp_callback(struct _adapter *padapter,
928 struct cmd_obj *pcmd)
931 struct sta_priv *pstapriv = &padapter->stapriv;
932 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
933 struct set_assocsta_parm *passocsta_parm =
934 (struct set_assocsta_parm *)(pcmd->parmbuf);
935 struct set_assocsta_rsp *passocsta_rsp =
936 (struct set_assocsta_rsp *) (pcmd->rsp);
937 struct sta_info *psta = r8712_get_stainfo(pstapriv,
938 passocsta_parm->addr);
942 psta->aid = psta->mac_id = passocsta_rsp->cam_id;
943 spin_lock_irqsave(&pmlmepriv->lock, irqL);
944 if ((check_fwstate(pmlmepriv, WIFI_MP_STATE)) &&
945 (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)))
946 pmlmepriv->fw_state ^= _FW_UNDER_LINKING;
947 set_fwstate(pmlmepriv, _FW_LINKED);
948 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
949 r8712_free_cmd_obj(pcmd);
952 u8 r8712_disconnectCtrlEx_cmd(struct _adapter *adapter, u32 enableDrvCtrl,
953 u32 tryPktCnt, u32 tryPktInterval, u32 firstStageTO)
955 struct cmd_obj *ph2c;
956 struct DisconnectCtrlEx_param *param;
957 struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
959 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
962 param = kzalloc(sizeof(*param), GFP_ATOMIC);
968 param->EnableDrvCtrl = (unsigned char)enableDrvCtrl;
969 param->TryPktCnt = (unsigned char)tryPktCnt;
970 param->TryPktInterval = (unsigned char)tryPktInterval;
971 param->FirstStageTO = (unsigned int)firstStageTO;
973 init_h2fwcmd_w_parm_no_rsp(ph2c, param,
974 GEN_CMD_CODE(_DisconnectCtrlEx));
975 r8712_enqueue_cmd(pcmdpriv, ph2c);