0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #define _RTL871X_CMD_C_
0018
0019 #include <linux/compiler.h>
0020 #include <linux/kernel.h>
0021 #include <linux/errno.h>
0022 #include <linux/slab.h>
0023 #include <linux/module.h>
0024 #include <linux/kref.h>
0025 #include <linux/netdevice.h>
0026 #include <linux/skbuff.h>
0027 #include <linux/usb.h>
0028 #include <linux/usb/ch9.h>
0029 #include <linux/circ_buf.h>
0030 #include <linux/uaccess.h>
0031 #include <asm/byteorder.h>
0032 #include <linux/atomic.h>
0033 #include <linux/semaphore.h>
0034 #include <linux/rtnetlink.h>
0035
0036 #include "osdep_service.h"
0037 #include "drv_types.h"
0038 #include "recv_osdep.h"
0039 #include "mlme_osdep.h"
0040
0041
0042
0043
0044
0045
0046 int r8712_init_cmd_priv(struct cmd_priv *pcmdpriv)
0047 {
0048 init_completion(&pcmdpriv->cmd_queue_comp);
0049 init_completion(&pcmdpriv->terminate_cmdthread_comp);
0050
0051 _init_queue(&(pcmdpriv->cmd_queue));
0052
0053
0054 pcmdpriv->cmd_seq = 1;
0055 pcmdpriv->cmd_allocated_buf = kmalloc(MAX_CMDSZ + CMDBUFF_ALIGN_SZ,
0056 GFP_ATOMIC);
0057 if (!pcmdpriv->cmd_allocated_buf)
0058 return -ENOMEM;
0059 pcmdpriv->cmd_buf = pcmdpriv->cmd_allocated_buf + CMDBUFF_ALIGN_SZ -
0060 ((addr_t)(pcmdpriv->cmd_allocated_buf) &
0061 (CMDBUFF_ALIGN_SZ - 1));
0062 pcmdpriv->rsp_allocated_buf = kmalloc(MAX_RSPSZ + 4, GFP_ATOMIC);
0063 if (!pcmdpriv->rsp_allocated_buf) {
0064 kfree(pcmdpriv->cmd_allocated_buf);
0065 pcmdpriv->cmd_allocated_buf = NULL;
0066 return -ENOMEM;
0067 }
0068 pcmdpriv->rsp_buf = pcmdpriv->rsp_allocated_buf + 4 -
0069 ((addr_t)(pcmdpriv->rsp_allocated_buf) & 3);
0070 pcmdpriv->cmd_issued_cnt = 0;
0071 pcmdpriv->cmd_done_cnt = 0;
0072 pcmdpriv->rsp_cnt = 0;
0073 return 0;
0074 }
0075
0076 int r8712_init_evt_priv(struct evt_priv *pevtpriv)
0077 {
0078
0079 pevtpriv->event_seq = 0;
0080 pevtpriv->evt_allocated_buf = kmalloc(MAX_EVTSZ + 4, GFP_ATOMIC);
0081
0082 if (!pevtpriv->evt_allocated_buf)
0083 return -ENOMEM;
0084 pevtpriv->evt_buf = pevtpriv->evt_allocated_buf + 4 -
0085 ((addr_t)(pevtpriv->evt_allocated_buf) & 3);
0086 pevtpriv->evt_done_cnt = 0;
0087 return 0;
0088 }
0089
0090 void r8712_free_evt_priv(struct evt_priv *pevtpriv)
0091 {
0092 kfree(pevtpriv->evt_allocated_buf);
0093 }
0094
0095 void r8712_free_cmd_priv(struct cmd_priv *pcmdpriv)
0096 {
0097 if (pcmdpriv) {
0098 kfree(pcmdpriv->cmd_allocated_buf);
0099 kfree(pcmdpriv->rsp_allocated_buf);
0100 }
0101 }
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113 void r8712_enqueue_cmd(struct cmd_priv *pcmdpriv, struct cmd_obj *obj)
0114 {
0115 struct __queue *queue;
0116 unsigned long irqL;
0117
0118 if (pcmdpriv->padapter->eeprompriv.bautoload_fail_flag)
0119 return;
0120 if (!obj)
0121 return;
0122 queue = &pcmdpriv->cmd_queue;
0123 spin_lock_irqsave(&queue->lock, irqL);
0124 list_add_tail(&obj->list, &queue->queue);
0125 spin_unlock_irqrestore(&queue->lock, irqL);
0126 complete(&pcmdpriv->cmd_queue_comp);
0127 }
0128
0129 struct cmd_obj *r8712_dequeue_cmd(struct __queue *queue)
0130 {
0131 unsigned long irqL;
0132 struct cmd_obj *obj;
0133
0134 spin_lock_irqsave(&queue->lock, irqL);
0135 obj = list_first_entry_or_null(&queue->queue,
0136 struct cmd_obj, list);
0137 if (obj)
0138 list_del_init(&obj->list);
0139 spin_unlock_irqrestore(&queue->lock, irqL);
0140 return obj;
0141 }
0142
0143 void r8712_enqueue_cmd_ex(struct cmd_priv *pcmdpriv, struct cmd_obj *obj)
0144 {
0145 unsigned long irqL;
0146 struct __queue *queue;
0147
0148 if (!obj)
0149 return;
0150 if (pcmdpriv->padapter->eeprompriv.bautoload_fail_flag)
0151 return;
0152 queue = &pcmdpriv->cmd_queue;
0153 spin_lock_irqsave(&queue->lock, irqL);
0154 list_add_tail(&obj->list, &queue->queue);
0155 spin_unlock_irqrestore(&queue->lock, irqL);
0156 complete(&pcmdpriv->cmd_queue_comp);
0157 }
0158
0159 void r8712_free_cmd_obj(struct cmd_obj *pcmd)
0160 {
0161 if ((pcmd->cmdcode != _JoinBss_CMD_) &&
0162 (pcmd->cmdcode != _CreateBss_CMD_))
0163 kfree(pcmd->parmbuf);
0164 if (pcmd->rsp) {
0165 if (pcmd->rspsz != 0)
0166 kfree(pcmd->rsp);
0167 }
0168 kfree(pcmd);
0169 }
0170
0171 u8 r8712_sitesurvey_cmd(struct _adapter *padapter,
0172 struct ndis_802_11_ssid *pssid)
0173 __must_hold(&padapter->mlmepriv.lock)
0174 {
0175 struct cmd_obj *ph2c;
0176 struct sitesurvey_parm *psurveyPara;
0177 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
0178 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
0179
0180 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
0181 if (!ph2c)
0182 return _FAIL;
0183 psurveyPara = kmalloc(sizeof(*psurveyPara), GFP_ATOMIC);
0184 if (!psurveyPara) {
0185 kfree(ph2c);
0186 return _FAIL;
0187 }
0188 init_h2fwcmd_w_parm_no_rsp(ph2c, psurveyPara,
0189 GEN_CMD_CODE(_SiteSurvey));
0190 psurveyPara->bsslimit = cpu_to_le32(48);
0191 psurveyPara->passive_mode = cpu_to_le32(pmlmepriv->passive_mode);
0192 psurveyPara->ss_ssidlen = 0;
0193 memset(psurveyPara->ss_ssid, 0, IW_ESSID_MAX_SIZE + 1);
0194 if (pssid && pssid->SsidLength) {
0195 int len = min_t(int, pssid->SsidLength, IW_ESSID_MAX_SIZE);
0196
0197 memcpy(psurveyPara->ss_ssid, pssid->Ssid, len);
0198 psurveyPara->ss_ssidlen = cpu_to_le32(len);
0199 }
0200 set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
0201 r8712_enqueue_cmd(pcmdpriv, ph2c);
0202 mod_timer(&pmlmepriv->scan_to_timer,
0203 jiffies + msecs_to_jiffies(SCANNING_TIMEOUT));
0204 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_SITE_SURVEY);
0205 complete(&padapter->rx_filter_ready);
0206 return _SUCCESS;
0207 }
0208
0209 int r8712_setdatarate_cmd(struct _adapter *padapter, u8 *rateset)
0210 {
0211 struct cmd_obj *ph2c;
0212 struct setdatarate_parm *pbsetdataratepara;
0213 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
0214
0215 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
0216 if (!ph2c)
0217 return -ENOMEM;
0218 pbsetdataratepara = kmalloc(sizeof(*pbsetdataratepara), GFP_ATOMIC);
0219 if (!pbsetdataratepara) {
0220 kfree(ph2c);
0221 return -ENOMEM;
0222 }
0223 init_h2fwcmd_w_parm_no_rsp(ph2c, pbsetdataratepara,
0224 GEN_CMD_CODE(_SetDataRate));
0225 pbsetdataratepara->mac_id = 5;
0226 memcpy(pbsetdataratepara->datarates, rateset, NumRates);
0227 r8712_enqueue_cmd(pcmdpriv, ph2c);
0228 return 0;
0229 }
0230
0231 void r8712_set_chplan_cmd(struct _adapter *padapter, int chplan)
0232 {
0233 struct cmd_obj *ph2c;
0234 struct SetChannelPlan_param *psetchplanpara;
0235 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
0236
0237 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
0238 if (!ph2c)
0239 return;
0240 psetchplanpara = kmalloc(sizeof(*psetchplanpara), GFP_ATOMIC);
0241 if (!psetchplanpara) {
0242 kfree(ph2c);
0243 return;
0244 }
0245 init_h2fwcmd_w_parm_no_rsp(ph2c, psetchplanpara,
0246 GEN_CMD_CODE(_SetChannelPlan));
0247 psetchplanpara->ChannelPlan = chplan;
0248 r8712_enqueue_cmd(pcmdpriv, ph2c);
0249 }
0250
0251 int r8712_setrfreg_cmd(struct _adapter *padapter, u8 offset, u32 val)
0252 {
0253 struct cmd_obj *ph2c;
0254 struct writeRF_parm *pwriterfparm;
0255 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
0256
0257 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
0258 if (!ph2c)
0259 return -ENOMEM;
0260 pwriterfparm = kmalloc(sizeof(*pwriterfparm), GFP_ATOMIC);
0261 if (!pwriterfparm) {
0262 kfree(ph2c);
0263 return -ENOMEM;
0264 }
0265 init_h2fwcmd_w_parm_no_rsp(ph2c, pwriterfparm, GEN_CMD_CODE(_SetRFReg));
0266 pwriterfparm->offset = offset;
0267 pwriterfparm->value = val;
0268 r8712_enqueue_cmd(pcmdpriv, ph2c);
0269 return 0;
0270 }
0271
0272 int r8712_getrfreg_cmd(struct _adapter *padapter, u8 offset, u8 *pval)
0273 {
0274 struct cmd_obj *ph2c;
0275 struct readRF_parm *prdrfparm;
0276 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
0277
0278 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
0279 if (!ph2c)
0280 return -ENOMEM;
0281 prdrfparm = kmalloc(sizeof(*prdrfparm), GFP_ATOMIC);
0282 if (!prdrfparm) {
0283 kfree(ph2c);
0284 return -ENOMEM;
0285 }
0286 INIT_LIST_HEAD(&ph2c->list);
0287 ph2c->cmdcode = GEN_CMD_CODE(_GetRFReg);
0288 ph2c->parmbuf = (unsigned char *)prdrfparm;
0289 ph2c->cmdsz = sizeof(struct readRF_parm);
0290 ph2c->rsp = pval;
0291 ph2c->rspsz = sizeof(struct readRF_rsp);
0292 prdrfparm->offset = offset;
0293 r8712_enqueue_cmd(pcmdpriv, ph2c);
0294 return 0;
0295 }
0296
0297 void r8712_getbbrfreg_cmdrsp_callback(struct _adapter *padapter,
0298 struct cmd_obj *pcmd)
0299 {
0300 kfree(pcmd->parmbuf);
0301 kfree(pcmd);
0302 padapter->mppriv.workparam.bcompleted = true;
0303 }
0304
0305 void r8712_readtssi_cmdrsp_callback(struct _adapter *padapter,
0306 struct cmd_obj *pcmd)
0307 {
0308 kfree(pcmd->parmbuf);
0309 kfree(pcmd);
0310
0311 padapter->mppriv.workparam.bcompleted = true;
0312 }
0313
0314 int r8712_createbss_cmd(struct _adapter *padapter)
0315 {
0316 struct cmd_obj *pcmd;
0317 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
0318 struct wlan_bssid_ex *pdev_network =
0319 &padapter->registrypriv.dev_network;
0320
0321 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_START_TO_LINK);
0322 pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC);
0323 if (!pcmd)
0324 return -ENOMEM;
0325 INIT_LIST_HEAD(&pcmd->list);
0326 pcmd->cmdcode = _CreateBss_CMD_;
0327 pcmd->parmbuf = (unsigned char *)pdev_network;
0328 pcmd->cmdsz = r8712_get_wlan_bssid_ex_sz(pdev_network);
0329 pcmd->rsp = NULL;
0330 pcmd->rspsz = 0;
0331
0332 pdev_network->Length = pcmd->cmdsz;
0333 pdev_network->IELength = pdev_network->IELength;
0334 pdev_network->Ssid.SsidLength = pdev_network->Ssid.SsidLength;
0335 r8712_enqueue_cmd(pcmdpriv, pcmd);
0336 return 0;
0337 }
0338
0339 int r8712_joinbss_cmd(struct _adapter *padapter, struct wlan_network *pnetwork)
0340 {
0341 struct wlan_bssid_ex *psecnetwork;
0342 struct cmd_obj *pcmd;
0343 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
0344 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
0345 struct qos_priv *pqospriv = &pmlmepriv->qospriv;
0346 struct security_priv *psecuritypriv = &padapter->securitypriv;
0347 struct registry_priv *pregistrypriv = &padapter->registrypriv;
0348 enum NDIS_802_11_NETWORK_INFRASTRUCTURE ndis_network_mode =
0349 pnetwork->network.InfrastructureMode;
0350
0351 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_START_TO_LINK);
0352 pcmd = kmalloc(sizeof(*pcmd), GFP_ATOMIC);
0353 if (!pcmd)
0354 return -ENOMEM;
0355
0356
0357 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) !=
0358 true) {
0359 switch (ndis_network_mode) {
0360 case Ndis802_11IBSS:
0361 pmlmepriv->fw_state |= WIFI_ADHOC_STATE;
0362 break;
0363 case Ndis802_11Infrastructure:
0364 pmlmepriv->fw_state |= WIFI_STATION_STATE;
0365 break;
0366 case Ndis802_11APMode:
0367 case Ndis802_11AutoUnknown:
0368 case Ndis802_11InfrastructureMax:
0369 break;
0370 }
0371 }
0372 psecnetwork = &psecuritypriv->sec_bss;
0373 memcpy(psecnetwork, &pnetwork->network, sizeof(*psecnetwork));
0374 psecuritypriv->authenticator_ie[0] = (unsigned char)
0375 psecnetwork->IELength;
0376 if ((psecnetwork->IELength - 12) < (256 - 1))
0377 memcpy(&psecuritypriv->authenticator_ie[1],
0378 &psecnetwork->IEs[12], psecnetwork->IELength - 12);
0379 else
0380 memcpy(&psecuritypriv->authenticator_ie[1],
0381 &psecnetwork->IEs[12], (256 - 1));
0382 psecnetwork->IELength = 0;
0383
0384
0385
0386
0387
0388 if (!pmlmepriv->assoc_by_bssid)
0389 ether_addr_copy(&pmlmepriv->assoc_bssid[0],
0390 &pnetwork->network.MacAddress[0]);
0391 psecnetwork->IELength = r8712_restruct_sec_ie(padapter,
0392 &pnetwork->network.IEs[0],
0393 &psecnetwork->IEs[0],
0394 pnetwork->network.IELength);
0395 pqospriv->qos_option = 0;
0396 if (pregistrypriv->wmm_enable) {
0397 u32 tmp_len;
0398
0399 tmp_len = r8712_restruct_wmm_ie(padapter,
0400 &pnetwork->network.IEs[0],
0401 &psecnetwork->IEs[0],
0402 pnetwork->network.IELength,
0403 psecnetwork->IELength);
0404 if (psecnetwork->IELength != tmp_len) {
0405 psecnetwork->IELength = tmp_len;
0406 pqospriv->qos_option = 1;
0407 } else {
0408 pqospriv->qos_option = 0;
0409 }
0410 }
0411 if (pregistrypriv->ht_enable) {
0412
0413
0414
0415
0416
0417 if ((padapter->securitypriv.PrivacyAlgrthm != _WEP40_) &&
0418 (padapter->securitypriv.PrivacyAlgrthm != _WEP104_)) {
0419
0420 r8712_restructure_ht_ie(padapter,
0421 &pnetwork->network.IEs[0],
0422 &psecnetwork->IEs[0],
0423 pnetwork->network.IELength,
0424 &psecnetwork->IELength);
0425 }
0426 }
0427 psecuritypriv->supplicant_ie[0] = (u8)psecnetwork->IELength;
0428 if (psecnetwork->IELength < 255)
0429 memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0],
0430 psecnetwork->IELength);
0431 else
0432 memcpy(&psecuritypriv->supplicant_ie[1], &psecnetwork->IEs[0],
0433 255);
0434
0435 pcmd->cmdsz = r8712_get_wlan_bssid_ex_sz(psecnetwork);
0436 #ifdef __BIG_ENDIAN
0437
0438 psecnetwork->Length = cpu_to_le32(psecnetwork->Length);
0439 psecnetwork->Ssid.SsidLength = cpu_to_le32(
0440 psecnetwork->Ssid.SsidLength);
0441 psecnetwork->Privacy = cpu_to_le32(psecnetwork->Privacy);
0442 psecnetwork->Rssi = cpu_to_le32(psecnetwork->Rssi);
0443 psecnetwork->NetworkTypeInUse = cpu_to_le32(
0444 psecnetwork->NetworkTypeInUse);
0445 psecnetwork->Configuration.ATIMWindow = cpu_to_le32(
0446 psecnetwork->Configuration.ATIMWindow);
0447 psecnetwork->Configuration.BeaconPeriod = cpu_to_le32(
0448 psecnetwork->Configuration.BeaconPeriod);
0449 psecnetwork->Configuration.DSConfig = cpu_to_le32(
0450 psecnetwork->Configuration.DSConfig);
0451 psecnetwork->Configuration.FHConfig.DwellTime = cpu_to_le32(
0452 psecnetwork->Configuration.FHConfig.DwellTime);
0453 psecnetwork->Configuration.FHConfig.HopPattern = cpu_to_le32(
0454 psecnetwork->Configuration.FHConfig.HopPattern);
0455 psecnetwork->Configuration.FHConfig.HopSet = cpu_to_le32(
0456 psecnetwork->Configuration.FHConfig.HopSet);
0457 psecnetwork->Configuration.FHConfig.Length = cpu_to_le32(
0458 psecnetwork->Configuration.FHConfig.Length);
0459 psecnetwork->Configuration.Length = cpu_to_le32(
0460 psecnetwork->Configuration.Length);
0461 psecnetwork->InfrastructureMode = cpu_to_le32(
0462 psecnetwork->InfrastructureMode);
0463 psecnetwork->IELength = cpu_to_le32(psecnetwork->IELength);
0464 #endif
0465 INIT_LIST_HEAD(&pcmd->list);
0466 pcmd->cmdcode = _JoinBss_CMD_;
0467 pcmd->parmbuf = (unsigned char *)psecnetwork;
0468 pcmd->rsp = NULL;
0469 pcmd->rspsz = 0;
0470 r8712_enqueue_cmd(pcmdpriv, pcmd);
0471 return 0;
0472 }
0473
0474 void r8712_disassoc_cmd(struct _adapter *padapter)
0475 {
0476 struct cmd_obj *pdisconnect_cmd;
0477 struct disconnect_parm *pdisconnect;
0478 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
0479
0480 pdisconnect_cmd = kmalloc(sizeof(*pdisconnect_cmd), GFP_ATOMIC);
0481 if (!pdisconnect_cmd)
0482 return;
0483 pdisconnect = kmalloc(sizeof(*pdisconnect), GFP_ATOMIC);
0484 if (!pdisconnect) {
0485 kfree(pdisconnect_cmd);
0486 return;
0487 }
0488 init_h2fwcmd_w_parm_no_rsp(pdisconnect_cmd, pdisconnect,
0489 _DisConnect_CMD_);
0490 r8712_enqueue_cmd(pcmdpriv, pdisconnect_cmd);
0491 }
0492
0493 void r8712_setopmode_cmd(struct _adapter *padapter,
0494 enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype)
0495 {
0496 struct cmd_obj *ph2c;
0497 struct setopmode_parm *psetop;
0498
0499 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
0500
0501 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
0502 if (!ph2c)
0503 return;
0504 psetop = kmalloc(sizeof(*psetop), GFP_ATOMIC);
0505 if (!psetop) {
0506 kfree(ph2c);
0507 return;
0508 }
0509 init_h2fwcmd_w_parm_no_rsp(ph2c, psetop, _SetOpMode_CMD_);
0510 psetop->mode = (u8)networktype;
0511 r8712_enqueue_cmd(pcmdpriv, ph2c);
0512 }
0513
0514 void r8712_setstakey_cmd(struct _adapter *padapter, u8 *psta, u8 unicast_key)
0515 {
0516 struct cmd_obj *ph2c;
0517 struct set_stakey_parm *psetstakey_para;
0518 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
0519 struct set_stakey_rsp *psetstakey_rsp = NULL;
0520 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
0521 struct security_priv *psecuritypriv = &padapter->securitypriv;
0522 struct sta_info *sta = (struct sta_info *)psta;
0523
0524 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
0525 if (!ph2c)
0526 return;
0527 psetstakey_para = kmalloc(sizeof(*psetstakey_para), GFP_ATOMIC);
0528 if (!psetstakey_para) {
0529 kfree(ph2c);
0530 return;
0531 }
0532 psetstakey_rsp = kmalloc(sizeof(*psetstakey_rsp), GFP_ATOMIC);
0533 if (!psetstakey_rsp) {
0534 kfree(ph2c);
0535 kfree(psetstakey_para);
0536 return;
0537 }
0538 init_h2fwcmd_w_parm_no_rsp(ph2c, psetstakey_para, _SetStaKey_CMD_);
0539 ph2c->rsp = (u8 *)psetstakey_rsp;
0540 ph2c->rspsz = sizeof(struct set_stakey_rsp);
0541 ether_addr_copy(psetstakey_para->addr, sta->hwaddr);
0542 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
0543 psetstakey_para->algorithm = (unsigned char)
0544 psecuritypriv->PrivacyAlgrthm;
0545 else
0546 GET_ENCRY_ALGO(psecuritypriv, sta,
0547 psetstakey_para->algorithm, false);
0548 if (unicast_key)
0549 memcpy(&psetstakey_para->key, &sta->x_UncstKey, 16);
0550 else
0551 memcpy(&psetstakey_para->key,
0552 &psecuritypriv->XGrpKey[
0553 psecuritypriv->XGrpKeyid - 1]. skey, 16);
0554 r8712_enqueue_cmd(pcmdpriv, ph2c);
0555 }
0556
0557 void r8712_setMacAddr_cmd(struct _adapter *padapter, const u8 *mac_addr)
0558 {
0559 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
0560 struct cmd_obj *ph2c;
0561 struct SetMacAddr_param *psetMacAddr_para;
0562
0563 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
0564 if (!ph2c)
0565 return;
0566 psetMacAddr_para = kmalloc(sizeof(*psetMacAddr_para), GFP_ATOMIC);
0567 if (!psetMacAddr_para) {
0568 kfree(ph2c);
0569 return;
0570 }
0571 init_h2fwcmd_w_parm_no_rsp(ph2c, psetMacAddr_para,
0572 _SetMacAddress_CMD_);
0573 ether_addr_copy(psetMacAddr_para->MacAddr, mac_addr);
0574 r8712_enqueue_cmd(pcmdpriv, ph2c);
0575 }
0576
0577 void r8712_addbareq_cmd(struct _adapter *padapter, u8 tid)
0578 {
0579 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
0580 struct cmd_obj *ph2c;
0581 struct addBaReq_parm *paddbareq_parm;
0582
0583 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
0584 if (!ph2c)
0585 return;
0586 paddbareq_parm = kmalloc(sizeof(*paddbareq_parm), GFP_ATOMIC);
0587 if (!paddbareq_parm) {
0588 kfree(ph2c);
0589 return;
0590 }
0591 paddbareq_parm->tid = tid;
0592 init_h2fwcmd_w_parm_no_rsp(ph2c, paddbareq_parm,
0593 GEN_CMD_CODE(_AddBAReq));
0594 r8712_enqueue_cmd_ex(pcmdpriv, ph2c);
0595 }
0596
0597 void r8712_wdg_wk_cmd(struct _adapter *padapter)
0598 {
0599 struct cmd_obj *ph2c;
0600 struct drvint_cmd_parm *pdrvintcmd_param;
0601 struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
0602
0603 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
0604 if (!ph2c)
0605 return;
0606 pdrvintcmd_param = kmalloc(sizeof(*pdrvintcmd_param), GFP_ATOMIC);
0607 if (!pdrvintcmd_param) {
0608 kfree(ph2c);
0609 return;
0610 }
0611 pdrvintcmd_param->i_cid = WDG_WK_CID;
0612 pdrvintcmd_param->sz = 0;
0613 pdrvintcmd_param->pbuf = NULL;
0614 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvintcmd_param, _DRV_INT_CMD_);
0615 r8712_enqueue_cmd_ex(pcmdpriv, ph2c);
0616 }
0617
0618 void r8712_survey_cmd_callback(struct _adapter *padapter, struct cmd_obj *pcmd)
0619 {
0620 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
0621
0622 if (pcmd->res != H2C_SUCCESS)
0623 clr_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
0624 r8712_free_cmd_obj(pcmd);
0625 }
0626
0627 void r8712_disassoc_cmd_callback(struct _adapter *padapter,
0628 struct cmd_obj *pcmd)
0629 {
0630 unsigned long irqL;
0631 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
0632
0633 if (pcmd->res != H2C_SUCCESS) {
0634 spin_lock_irqsave(&pmlmepriv->lock, irqL);
0635 set_fwstate(pmlmepriv, _FW_LINKED);
0636 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
0637 return;
0638 }
0639 r8712_free_cmd_obj(pcmd);
0640 }
0641
0642 void r8712_joinbss_cmd_callback(struct _adapter *padapter, struct cmd_obj *pcmd)
0643 {
0644 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
0645
0646 if (pcmd->res != H2C_SUCCESS)
0647 mod_timer(&pmlmepriv->assoc_timer,
0648 jiffies + msecs_to_jiffies(1));
0649 r8712_free_cmd_obj(pcmd);
0650 }
0651
0652 void r8712_createbss_cmd_callback(struct _adapter *padapter,
0653 struct cmd_obj *pcmd)
0654 {
0655 unsigned long irqL;
0656 struct sta_info *psta = NULL;
0657 struct wlan_network *pwlan = NULL;
0658 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
0659 struct wlan_bssid_ex *pnetwork = (struct wlan_bssid_ex *)pcmd->parmbuf;
0660 struct wlan_network *tgt_network = &(pmlmepriv->cur_network);
0661
0662 if (pcmd->res != H2C_SUCCESS)
0663 mod_timer(&pmlmepriv->assoc_timer,
0664 jiffies + msecs_to_jiffies(1));
0665 del_timer(&pmlmepriv->assoc_timer);
0666 #ifdef __BIG_ENDIAN
0667
0668 pnetwork->Length = le32_to_cpu(pnetwork->Length);
0669 pnetwork->Ssid.SsidLength = le32_to_cpu(pnetwork->Ssid.SsidLength);
0670 pnetwork->Privacy = le32_to_cpu(pnetwork->Privacy);
0671 pnetwork->Rssi = le32_to_cpu(pnetwork->Rssi);
0672 pnetwork->NetworkTypeInUse = le32_to_cpu(pnetwork->NetworkTypeInUse);
0673 pnetwork->Configuration.ATIMWindow =
0674 le32_to_cpu(pnetwork->Configuration.ATIMWindow);
0675 pnetwork->Configuration.DSConfig =
0676 le32_to_cpu(pnetwork->Configuration.DSConfig);
0677 pnetwork->Configuration.FHConfig.DwellTime =
0678 le32_to_cpu(pnetwork->Configuration.FHConfig.DwellTime);
0679 pnetwork->Configuration.FHConfig.HopPattern =
0680 le32_to_cpu(pnetwork->Configuration.FHConfig.HopPattern);
0681 pnetwork->Configuration.FHConfig.HopSet =
0682 le32_to_cpu(pnetwork->Configuration.FHConfig.HopSet);
0683 pnetwork->Configuration.FHConfig.Length =
0684 le32_to_cpu(pnetwork->Configuration.FHConfig.Length);
0685 pnetwork->Configuration.Length =
0686 le32_to_cpu(pnetwork->Configuration.Length);
0687 pnetwork->InfrastructureMode =
0688 le32_to_cpu(pnetwork->InfrastructureMode);
0689 pnetwork->IELength = le32_to_cpu(pnetwork->IELength);
0690 #endif
0691 spin_lock_irqsave(&pmlmepriv->lock, irqL);
0692 if ((pmlmepriv->fw_state) & WIFI_AP_STATE) {
0693 psta = r8712_get_stainfo(&padapter->stapriv,
0694 pnetwork->MacAddress);
0695 if (!psta) {
0696 psta = r8712_alloc_stainfo(&padapter->stapriv,
0697 pnetwork->MacAddress);
0698 if (!psta)
0699 goto createbss_cmd_fail;
0700 }
0701 r8712_indicate_connect(padapter);
0702 } else {
0703 pwlan = _r8712_alloc_network(pmlmepriv);
0704 if (!pwlan) {
0705 pwlan = r8712_get_oldest_wlan_network(
0706 &pmlmepriv->scanned_queue);
0707 if (!pwlan)
0708 goto createbss_cmd_fail;
0709 pwlan->last_scanned = jiffies;
0710 } else {
0711 list_add_tail(&(pwlan->list),
0712 &pmlmepriv->scanned_queue.queue);
0713 }
0714 pnetwork->Length = r8712_get_wlan_bssid_ex_sz(pnetwork);
0715 memcpy(&(pwlan->network), pnetwork, pnetwork->Length);
0716 pwlan->fixed = true;
0717 memcpy(&tgt_network->network, pnetwork,
0718 (r8712_get_wlan_bssid_ex_sz(pnetwork)));
0719 if (pmlmepriv->fw_state & _FW_UNDER_LINKING)
0720 pmlmepriv->fw_state ^= _FW_UNDER_LINKING;
0721
0722
0723
0724
0725 }
0726 createbss_cmd_fail:
0727 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
0728 r8712_free_cmd_obj(pcmd);
0729 }
0730
0731 void r8712_setstaKey_cmdrsp_callback(struct _adapter *padapter,
0732 struct cmd_obj *pcmd)
0733 {
0734 struct sta_priv *pstapriv = &padapter->stapriv;
0735 struct set_stakey_rsp *psetstakey_rsp = (struct set_stakey_rsp *)
0736 (pcmd->rsp);
0737 struct sta_info *psta = r8712_get_stainfo(pstapriv,
0738 psetstakey_rsp->addr);
0739
0740 if (!psta)
0741 goto exit;
0742 psta->aid = psta->mac_id = psetstakey_rsp->keyid;
0743 exit:
0744 r8712_free_cmd_obj(pcmd);
0745 }
0746
0747 void r8712_setassocsta_cmdrsp_callback(struct _adapter *padapter,
0748 struct cmd_obj *pcmd)
0749 {
0750 unsigned long irqL;
0751 struct sta_priv *pstapriv = &padapter->stapriv;
0752 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
0753 struct set_assocsta_parm *passocsta_parm =
0754 (struct set_assocsta_parm *)(pcmd->parmbuf);
0755 struct set_assocsta_rsp *passocsta_rsp =
0756 (struct set_assocsta_rsp *) (pcmd->rsp);
0757 struct sta_info *psta = r8712_get_stainfo(pstapriv,
0758 passocsta_parm->addr);
0759
0760 if (!psta)
0761 return;
0762 psta->aid = psta->mac_id = passocsta_rsp->cam_id;
0763 spin_lock_irqsave(&pmlmepriv->lock, irqL);
0764 if ((check_fwstate(pmlmepriv, WIFI_MP_STATE)) &&
0765 (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)))
0766 pmlmepriv->fw_state ^= _FW_UNDER_LINKING;
0767 set_fwstate(pmlmepriv, _FW_LINKED);
0768 spin_unlock_irqrestore(&pmlmepriv->lock, irqL);
0769 r8712_free_cmd_obj(pcmd);
0770 }
0771
0772 void r8712_disconnectCtrlEx_cmd(struct _adapter *adapter, u32 enableDrvCtrl,
0773 u32 tryPktCnt, u32 tryPktInterval, u32 firstStageTO)
0774 {
0775 struct cmd_obj *ph2c;
0776 struct DisconnectCtrlEx_param *param;
0777 struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
0778
0779 ph2c = kmalloc(sizeof(*ph2c), GFP_ATOMIC);
0780 if (!ph2c)
0781 return;
0782 param = kzalloc(sizeof(*param), GFP_ATOMIC);
0783 if (!param) {
0784 kfree(ph2c);
0785 return;
0786 }
0787
0788 param->EnableDrvCtrl = (unsigned char)enableDrvCtrl;
0789 param->TryPktCnt = (unsigned char)tryPktCnt;
0790 param->TryPktInterval = (unsigned char)tryPktInterval;
0791 param->FirstStageTO = (unsigned int)firstStageTO;
0792
0793 init_h2fwcmd_w_parm_no_rsp(ph2c, param,
0794 GEN_CMD_CODE(_DisconnectCtrlEx));
0795 r8712_enqueue_cmd(pcmdpriv, ph2c);
0796 }