2 * This file contains the handling of command
3 * responses as well as events generated by firmware.
5 #include <linux/delay.h>
6 #include <linux/if_arp.h>
7 #include <linux/netdevice.h>
9 #include <net/iw_handler.h>
19 * @brief This function handles disconnect event. it
20 * reports disconnect to upper layer, clean tx/rx packets,
21 * reset link state etc.
23 * @param priv A pointer to wlan_private structure
26 void libertas_mac_event_disconnected(wlan_private * priv)
28 wlan_adapter *adapter = priv->adapter;
29 union iwreq_data wrqu;
31 if (adapter->connect_status != LIBERTAS_CONNECTED)
34 lbs_deb_enter(LBS_DEB_CMD);
36 memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN);
37 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
40 * Cisco AP sends EAP failure and de-auth in less than 0.5 ms.
41 * It causes problem in the Supplicant
44 msleep_interruptible(1000);
45 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
47 /* Free Tx and Rx packets */
48 kfree_skb(priv->adapter->currenttxskb);
49 priv->adapter->currenttxskb = NULL;
51 /* report disconnect to upper layer */
52 netif_stop_queue(priv->dev);
53 netif_carrier_off(priv->dev);
55 /* reset SNR/NF/RSSI values */
56 memset(adapter->SNR, 0x00, sizeof(adapter->SNR));
57 memset(adapter->NF, 0x00, sizeof(adapter->NF));
58 memset(adapter->RSSI, 0x00, sizeof(adapter->RSSI));
59 memset(adapter->rawSNR, 0x00, sizeof(adapter->rawSNR));
60 memset(adapter->rawNF, 0x00, sizeof(adapter->rawNF));
61 adapter->nextSNRNF = 0;
62 adapter->numSNRNF = 0;
63 adapter->rxpd_rate = 0;
64 lbs_deb_cmd("current SSID '%s', length %u\n",
65 escape_essid(adapter->curbssparams.ssid,
66 adapter->curbssparams.ssid_len),
67 adapter->curbssparams.ssid_len);
68 lbs_deb_cmd("previous SSID '%s', length %u\n",
69 escape_essid(adapter->prev_ssid, adapter->prev_ssid_len),
70 adapter->prev_ssid_len);
72 adapter->connect_status = LIBERTAS_DISCONNECTED;
74 /* Save previous SSID and BSSID for possible reassociation */
75 memcpy(&adapter->prev_ssid, &adapter->curbssparams.ssid,
77 adapter->prev_ssid_len = adapter->curbssparams.ssid_len;
78 memcpy(adapter->prev_bssid, adapter->curbssparams.bssid, ETH_ALEN);
80 /* Clear out associated SSID and BSSID since connection is
83 memset(&adapter->curbssparams.bssid, 0, ETH_ALEN);
84 memset(&adapter->curbssparams.ssid, 0, IW_ESSID_MAX_SIZE);
85 adapter->curbssparams.ssid_len = 0;
87 if (adapter->psstate != PS_STATE_FULL_POWER) {
88 /* make firmware to exit PS mode */
89 lbs_deb_cmd("disconnected, so exit PS mode\n");
90 libertas_ps_wakeup(priv, 0);
92 lbs_deb_leave(LBS_DEB_CMD);
96 * @brief This function handles MIC failure event.
98 * @param priv A pointer to wlan_private structure
99 * @para event the event id
102 static void handle_mic_failureevent(wlan_private * priv, u32 event)
106 lbs_deb_enter(LBS_DEB_CMD);
107 memset(buf, 0, sizeof(buf));
109 sprintf(buf, "%s", "MLME-MICHAELMICFAILURE.indication ");
111 if (event == MACREG_INT_CODE_MIC_ERR_UNICAST) {
112 strcat(buf, "unicast ");
114 strcat(buf, "multicast ");
117 libertas_send_iwevcustom_event(priv, buf);
118 lbs_deb_leave(LBS_DEB_CMD);
121 static int wlan_ret_reg_access(wlan_private * priv,
122 u16 type, struct cmd_ds_command *resp)
125 wlan_adapter *adapter = priv->adapter;
127 lbs_deb_enter(LBS_DEB_CMD);
130 case CMD_RET(CMD_MAC_REG_ACCESS):
132 struct cmd_ds_mac_reg_access *reg = &resp->params.macreg;
134 adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
135 adapter->offsetvalue.value = le32_to_cpu(reg->value);
139 case CMD_RET(CMD_BBP_REG_ACCESS):
141 struct cmd_ds_bbp_reg_access *reg = &resp->params.bbpreg;
143 adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
144 adapter->offsetvalue.value = reg->value;
148 case CMD_RET(CMD_RF_REG_ACCESS):
150 struct cmd_ds_rf_reg_access *reg = &resp->params.rfreg;
152 adapter->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
153 adapter->offsetvalue.value = reg->value;
161 lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret);
165 static int wlan_ret_get_hw_spec(wlan_private * priv,
166 struct cmd_ds_command *resp)
169 struct cmd_ds_get_hw_spec *hwspec = &resp->params.hwspec;
170 wlan_adapter *adapter = priv->adapter;
173 lbs_deb_enter(LBS_DEB_CMD);
175 adapter->fwcapinfo = le32_to_cpu(hwspec->fwcapinfo);
177 memcpy(adapter->fwreleasenumber, hwspec->fwreleasenumber, 4);
179 lbs_deb_cmd("GET_HW_SPEC: firmware release %u.%u.%up%u\n",
180 adapter->fwreleasenumber[2], adapter->fwreleasenumber[1],
181 adapter->fwreleasenumber[0], adapter->fwreleasenumber[3]);
182 lbs_deb_cmd("GET_HW_SPEC: MAC addr " MAC_FMT "\n",
183 MAC_ARG(hwspec->permanentaddr));
184 lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
185 hwspec->hwifversion, hwspec->version);
187 adapter->regioncode = le16_to_cpu(hwspec->regioncode);
189 for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
190 /* use the region code to search for the index */
191 if (adapter->regioncode == libertas_region_code_to_index[i]) {
192 adapter->regiontableindex = (u16) i;
197 /* if it's unidentified region code, use the default (USA) */
198 if (i >= MRVDRV_MAX_REGION_CODE) {
199 adapter->regioncode = 0x10;
200 adapter->regiontableindex = 0;
201 lbs_pr_info("unidentified region code; using the default (USA)\n");
204 if (adapter->current_addr[0] == 0xff)
205 memmove(adapter->current_addr, hwspec->permanentaddr, ETH_ALEN);
207 memcpy(priv->dev->dev_addr, adapter->current_addr, ETH_ALEN);
209 memcpy(priv->mesh_dev->dev_addr, adapter->current_addr, ETH_ALEN);
211 if (libertas_set_regiontable(priv, adapter->regioncode, 0)) {
216 if (libertas_set_universaltable(priv, 0)) {
222 lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret);
226 static int wlan_ret_802_11_sleep_params(wlan_private * priv,
227 struct cmd_ds_command *resp)
229 struct cmd_ds_802_11_sleep_params *sp = &resp->params.sleep_params;
230 wlan_adapter *adapter = priv->adapter;
232 lbs_deb_enter(LBS_DEB_CMD);
234 lbs_deb_cmd("error 0x%x, offset 0x%x, stabletime 0x%x, calcontrol 0x%x "
235 "extsleepclk 0x%x\n", le16_to_cpu(sp->error),
236 le16_to_cpu(sp->offset), le16_to_cpu(sp->stabletime),
237 sp->calcontrol, sp->externalsleepclk);
239 adapter->sp.sp_error = le16_to_cpu(sp->error);
240 adapter->sp.sp_offset = le16_to_cpu(sp->offset);
241 adapter->sp.sp_stabletime = le16_to_cpu(sp->stabletime);
242 adapter->sp.sp_calcontrol = sp->calcontrol;
243 adapter->sp.sp_extsleepclk = sp->externalsleepclk;
244 adapter->sp.sp_reserved = le16_to_cpu(sp->reserved);
246 lbs_deb_enter(LBS_DEB_CMD);
250 static int wlan_ret_802_11_stat(wlan_private * priv,
251 struct cmd_ds_command *resp)
253 lbs_deb_enter(LBS_DEB_CMD);
254 /* currently adapter->wlan802_11Stat is unused
256 struct cmd_ds_802_11_get_stat *p11Stat = &resp->params.gstat;
257 wlan_adapter *adapter = priv->adapter;
259 // TODO Convert it to Big endian befor copy
260 memcpy(&adapter->wlan802_11Stat,
261 p11Stat, sizeof(struct cmd_ds_802_11_get_stat));
263 lbs_deb_leave(LBS_DEB_CMD);
267 static int wlan_ret_802_11_snmp_mib(wlan_private * priv,
268 struct cmd_ds_command *resp)
270 struct cmd_ds_802_11_snmp_mib *smib = &resp->params.smib;
271 u16 oid = le16_to_cpu(smib->oid);
272 u16 querytype = le16_to_cpu(smib->querytype);
274 lbs_deb_enter(LBS_DEB_CMD);
276 lbs_deb_cmd("SNMP_RESP: oid 0x%x, querytype 0x%x\n", oid,
278 lbs_deb_cmd("SNMP_RESP: Buf size %d\n", le16_to_cpu(smib->bufsize));
280 if (querytype == CMD_ACT_GET) {
283 priv->adapter->fragthsd =
284 le16_to_cpu(*((__le16 *)(smib->value)));
285 lbs_deb_cmd("SNMP_RESP: frag threshold %u\n",
286 priv->adapter->fragthsd);
289 priv->adapter->rtsthsd =
290 le16_to_cpu(*((__le16 *)(smib->value)));
291 lbs_deb_cmd("SNMP_RESP: rts threshold %u\n",
292 priv->adapter->rtsthsd);
294 case SHORT_RETRYLIM_I:
295 priv->adapter->txretrycount =
296 le16_to_cpu(*((__le16 *)(smib->value)));
297 lbs_deb_cmd("SNMP_RESP: tx retry count %u\n",
298 priv->adapter->rtsthsd);
305 lbs_deb_enter(LBS_DEB_CMD);
309 static int wlan_ret_802_11_key_material(wlan_private * priv,
310 struct cmd_ds_command *resp)
312 struct cmd_ds_802_11_key_material *pkeymaterial =
313 &resp->params.keymaterial;
314 wlan_adapter *adapter = priv->adapter;
315 u16 action = le16_to_cpu(pkeymaterial->action);
317 lbs_deb_enter(LBS_DEB_CMD);
319 /* Copy the returned key to driver private data */
320 if (action == CMD_ACT_GET) {
321 u8 * buf_ptr = (u8 *) &pkeymaterial->keyParamSet;
322 u8 * resp_end = (u8 *) (resp + le16_to_cpu(resp->size));
324 while (buf_ptr < resp_end) {
325 struct MrvlIEtype_keyParamSet * pkeyparamset =
326 (struct MrvlIEtype_keyParamSet *) buf_ptr;
327 struct enc_key * pkey;
328 u16 param_set_len = le16_to_cpu(pkeyparamset->length);
329 u16 key_len = le16_to_cpu(pkeyparamset->keylen);
330 u16 key_flags = le16_to_cpu(pkeyparamset->keyinfo);
331 u16 key_type = le16_to_cpu(pkeyparamset->keytypeid);
334 end = (u8 *) pkeyparamset + sizeof (pkeyparamset->type)
335 + sizeof (pkeyparamset->length)
337 /* Make sure we don't access past the end of the IEs */
341 if (key_flags & KEY_INFO_WPA_UNICAST)
342 pkey = &adapter->wpa_unicast_key;
343 else if (key_flags & KEY_INFO_WPA_MCAST)
344 pkey = &adapter->wpa_mcast_key;
348 /* Copy returned key into driver */
349 memset(pkey, 0, sizeof(struct enc_key));
350 if (key_len > sizeof(pkey->key))
352 pkey->type = key_type;
353 pkey->flags = key_flags;
355 memcpy(pkey->key, pkeyparamset->key, pkey->len);
361 lbs_deb_enter(LBS_DEB_CMD);
365 static int wlan_ret_802_11_mac_address(wlan_private * priv,
366 struct cmd_ds_command *resp)
368 struct cmd_ds_802_11_mac_address *macadd = &resp->params.macadd;
369 wlan_adapter *adapter = priv->adapter;
371 lbs_deb_enter(LBS_DEB_CMD);
373 memcpy(adapter->current_addr, macadd->macadd, ETH_ALEN);
375 lbs_deb_enter(LBS_DEB_CMD);
379 static int wlan_ret_802_11_rf_tx_power(wlan_private * priv,
380 struct cmd_ds_command *resp)
382 struct cmd_ds_802_11_rf_tx_power *rtp = &resp->params.txp;
383 wlan_adapter *adapter = priv->adapter;
385 lbs_deb_enter(LBS_DEB_CMD);
387 adapter->txpowerlevel = le16_to_cpu(rtp->currentlevel);
389 lbs_deb_cmd("TX power currently %d\n", adapter->txpowerlevel);
391 lbs_deb_leave(LBS_DEB_CMD);
395 static int wlan_ret_802_11_rf_antenna(wlan_private * priv,
396 struct cmd_ds_command *resp)
398 struct cmd_ds_802_11_rf_antenna *pAntenna = &resp->params.rant;
399 wlan_adapter *adapter = priv->adapter;
400 u16 action = le16_to_cpu(pAntenna->action);
402 lbs_deb_enter(LBS_DEB_CMD);
403 if (action == CMD_ACT_GET_RX)
404 adapter->rxantennamode = le16_to_cpu(pAntenna->antennamode);
406 if (action == CMD_ACT_GET_TX)
407 adapter->txantennamode = le16_to_cpu(pAntenna->antennamode);
409 lbs_deb_cmd("RF_ANT_RESP: action 0x%x, mode 0x%04x\n",
410 action, le16_to_cpu(pAntenna->antennamode));
412 lbs_deb_leave(LBS_DEB_CMD);
416 static int wlan_ret_802_11_rate_adapt_rateset(wlan_private * priv,
417 struct cmd_ds_command *resp)
419 struct cmd_ds_802_11_rate_adapt_rateset *rates = &resp->params.rateset;
420 wlan_adapter *adapter = priv->adapter;
422 lbs_deb_enter(LBS_DEB_CMD);
424 if (rates->action == CMD_ACT_GET) {
425 adapter->enablehwauto = le16_to_cpu(rates->enablehwauto);
426 adapter->ratebitmap = le16_to_cpu(rates->bitmap);
429 lbs_deb_leave(LBS_DEB_CMD);
433 static int wlan_ret_802_11_data_rate(wlan_private * priv,
434 struct cmd_ds_command *resp)
436 struct cmd_ds_802_11_data_rate *pdatarate = &resp->params.drate;
437 wlan_adapter *adapter = priv->adapter;
439 lbs_deb_enter(LBS_DEB_CMD);
441 lbs_deb_hex(LBS_DEB_CMD, "DATA_RATE_RESP", (u8 *) pdatarate,
442 sizeof(struct cmd_ds_802_11_data_rate));
444 /* FIXME: get actual rates FW can do if this command actually returns
445 * all data rates supported.
447 adapter->cur_rate = libertas_fw_index_to_data_rate(pdatarate->rates[0]);
448 lbs_deb_cmd("DATA_RATE: current rate 0x%02x\n", adapter->cur_rate);
450 lbs_deb_leave(LBS_DEB_CMD);
454 static int wlan_ret_802_11_rf_channel(wlan_private * priv,
455 struct cmd_ds_command *resp)
457 struct cmd_ds_802_11_rf_channel *rfchannel = &resp->params.rfchannel;
458 wlan_adapter *adapter = priv->adapter;
459 u16 action = le16_to_cpu(rfchannel->action);
460 u16 newchannel = le16_to_cpu(rfchannel->currentchannel);
462 lbs_deb_enter(LBS_DEB_CMD);
464 if (action == CMD_OPT_802_11_RF_CHANNEL_GET
465 && adapter->curbssparams.channel != newchannel) {
466 lbs_deb_cmd("channel switch from %d to %d\n",
467 adapter->curbssparams.channel, newchannel);
469 /* Update the channel again */
470 adapter->curbssparams.channel = newchannel;
473 lbs_deb_enter(LBS_DEB_CMD);
477 static int wlan_ret_802_11_rssi(wlan_private * priv,
478 struct cmd_ds_command *resp)
480 struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp;
481 wlan_adapter *adapter = priv->adapter;
483 lbs_deb_enter(LBS_DEB_CMD);
485 /* store the non average value */
486 adapter->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR);
487 adapter->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor);
489 adapter->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR);
490 adapter->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor);
492 adapter->RSSI[TYPE_BEACON][TYPE_NOAVG] =
493 CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG],
494 adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
496 adapter->RSSI[TYPE_BEACON][TYPE_AVG] =
497 CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE,
498 adapter->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE);
500 lbs_deb_cmd("RSSI: beacon %d, avg %d\n",
501 adapter->RSSI[TYPE_BEACON][TYPE_NOAVG],
502 adapter->RSSI[TYPE_BEACON][TYPE_AVG]);
504 lbs_deb_leave(LBS_DEB_CMD);
508 static int wlan_ret_802_11_eeprom_access(wlan_private * priv,
509 struct cmd_ds_command *resp)
511 wlan_adapter *adapter = priv->adapter;
512 struct wlan_ioctl_regrdwr *pbuf;
513 pbuf = (struct wlan_ioctl_regrdwr *) adapter->prdeeprom;
515 lbs_deb_enter_args(LBS_DEB_CMD, "len %d",
516 le16_to_cpu(resp->params.rdeeprom.bytecount));
517 if (pbuf->NOB < le16_to_cpu(resp->params.rdeeprom.bytecount)) {
519 lbs_deb_cmd("EEPROM read length too big\n");
522 pbuf->NOB = le16_to_cpu(resp->params.rdeeprom.bytecount);
525 memcpy(&pbuf->value, (u8 *) & resp->params.rdeeprom.value,
526 le16_to_cpu(resp->params.rdeeprom.bytecount));
527 lbs_deb_hex(LBS_DEB_CMD, "EEPROM", (char *)&pbuf->value,
528 le16_to_cpu(resp->params.rdeeprom.bytecount));
530 lbs_deb_leave(LBS_DEB_CMD);
534 static int wlan_ret_get_log(wlan_private * priv,
535 struct cmd_ds_command *resp)
537 struct cmd_ds_802_11_get_log *logmessage = &resp->params.glog;
538 wlan_adapter *adapter = priv->adapter;
540 lbs_deb_enter(LBS_DEB_CMD);
542 /* Stored little-endian */
543 memcpy(&adapter->logmsg, logmessage, sizeof(struct cmd_ds_802_11_get_log));
545 lbs_deb_leave(LBS_DEB_CMD);
549 static int libertas_ret_802_11_enable_rsn(wlan_private * priv,
550 struct cmd_ds_command *resp)
552 struct cmd_ds_802_11_enable_rsn *enable_rsn = &resp->params.enbrsn;
553 wlan_adapter *adapter = priv->adapter;
554 u32 * pdata_buf = adapter->cur_cmd->pdata_buf;
556 lbs_deb_enter(LBS_DEB_CMD);
558 if (enable_rsn->action == cpu_to_le16(CMD_ACT_GET)) {
560 *pdata_buf = (u32) le16_to_cpu(enable_rsn->enable);
563 lbs_deb_leave(LBS_DEB_CMD);
567 static inline int handle_cmd_response(u16 respcmd,
568 struct cmd_ds_command *resp,
573 wlan_adapter *adapter = priv->adapter;
575 lbs_deb_enter(LBS_DEB_HOST);
578 case CMD_RET(CMD_MAC_REG_ACCESS):
579 case CMD_RET(CMD_BBP_REG_ACCESS):
580 case CMD_RET(CMD_RF_REG_ACCESS):
581 ret = wlan_ret_reg_access(priv, respcmd, resp);
584 case CMD_RET(CMD_GET_HW_SPEC):
585 ret = wlan_ret_get_hw_spec(priv, resp);
588 case CMD_RET(CMD_802_11_SCAN):
589 ret = libertas_ret_80211_scan(priv, resp);
592 case CMD_RET(CMD_802_11_GET_LOG):
593 ret = wlan_ret_get_log(priv, resp);
596 case CMD_RET_802_11_ASSOCIATE:
597 case CMD_RET(CMD_802_11_ASSOCIATE):
598 case CMD_RET(CMD_802_11_REASSOCIATE):
599 ret = libertas_ret_80211_associate(priv, resp);
602 case CMD_RET(CMD_802_11_DISASSOCIATE):
603 case CMD_RET(CMD_802_11_DEAUTHENTICATE):
604 ret = libertas_ret_80211_disassociate(priv, resp);
607 case CMD_RET(CMD_802_11_AD_HOC_START):
608 case CMD_RET(CMD_802_11_AD_HOC_JOIN):
609 ret = libertas_ret_80211_ad_hoc_start(priv, resp);
612 case CMD_RET(CMD_802_11_GET_STAT):
613 ret = wlan_ret_802_11_stat(priv, resp);
616 case CMD_RET(CMD_802_11_SNMP_MIB):
617 ret = wlan_ret_802_11_snmp_mib(priv, resp);
620 case CMD_RET(CMD_802_11_RF_TX_POWER):
621 ret = wlan_ret_802_11_rf_tx_power(priv, resp);
624 case CMD_RET(CMD_802_11_SET_AFC):
625 case CMD_RET(CMD_802_11_GET_AFC):
626 spin_lock_irqsave(&adapter->driver_lock, flags);
627 memmove(adapter->cur_cmd->pdata_buf, &resp->params.afc,
628 sizeof(struct cmd_ds_802_11_afc));
629 spin_unlock_irqrestore(&adapter->driver_lock, flags);
632 case CMD_RET(CMD_802_11_RF_ANTENNA):
633 ret = wlan_ret_802_11_rf_antenna(priv, resp);
636 case CMD_RET(CMD_MAC_MULTICAST_ADR):
637 case CMD_RET(CMD_MAC_CONTROL):
638 case CMD_RET(CMD_802_11_SET_WEP):
639 case CMD_RET(CMD_802_11_RESET):
640 case CMD_RET(CMD_802_11_AUTHENTICATE):
641 case CMD_RET(CMD_802_11_RADIO_CONTROL):
642 case CMD_RET(CMD_802_11_BEACON_STOP):
645 case CMD_RET(CMD_802_11_ENABLE_RSN):
646 ret = libertas_ret_802_11_enable_rsn(priv, resp);
649 case CMD_RET(CMD_802_11_DATA_RATE):
650 ret = wlan_ret_802_11_data_rate(priv, resp);
652 case CMD_RET(CMD_802_11_RATE_ADAPT_RATESET):
653 ret = wlan_ret_802_11_rate_adapt_rateset(priv, resp);
655 case CMD_RET(CMD_802_11_RF_CHANNEL):
656 ret = wlan_ret_802_11_rf_channel(priv, resp);
659 case CMD_RET(CMD_802_11_RSSI):
660 ret = wlan_ret_802_11_rssi(priv, resp);
663 case CMD_RET(CMD_802_11_MAC_ADDRESS):
664 ret = wlan_ret_802_11_mac_address(priv, resp);
667 case CMD_RET(CMD_802_11_AD_HOC_STOP):
668 ret = libertas_ret_80211_ad_hoc_stop(priv, resp);
671 case CMD_RET(CMD_802_11_KEY_MATERIAL):
672 ret = wlan_ret_802_11_key_material(priv, resp);
675 case CMD_RET(CMD_802_11_EEPROM_ACCESS):
676 ret = wlan_ret_802_11_eeprom_access(priv, resp);
679 case CMD_RET(CMD_802_11D_DOMAIN_INFO):
680 ret = libertas_ret_802_11d_domain_info(priv, resp);
683 case CMD_RET(CMD_802_11_SLEEP_PARAMS):
684 ret = wlan_ret_802_11_sleep_params(priv, resp);
686 case CMD_RET(CMD_802_11_INACTIVITY_TIMEOUT):
687 spin_lock_irqsave(&adapter->driver_lock, flags);
688 *((u16 *) adapter->cur_cmd->pdata_buf) =
689 le16_to_cpu(resp->params.inactivity_timeout.timeout);
690 spin_unlock_irqrestore(&adapter->driver_lock, flags);
693 case CMD_RET(CMD_802_11_TPC_CFG):
694 spin_lock_irqsave(&adapter->driver_lock, flags);
695 memmove(adapter->cur_cmd->pdata_buf, &resp->params.tpccfg,
696 sizeof(struct cmd_ds_802_11_tpc_cfg));
697 spin_unlock_irqrestore(&adapter->driver_lock, flags);
699 case CMD_RET(CMD_802_11_LED_GPIO_CTRL):
700 spin_lock_irqsave(&adapter->driver_lock, flags);
701 memmove(adapter->cur_cmd->pdata_buf, &resp->params.ledgpio,
702 sizeof(struct cmd_ds_802_11_led_ctrl));
703 spin_unlock_irqrestore(&adapter->driver_lock, flags);
705 case CMD_RET(CMD_802_11_PWR_CFG):
706 spin_lock_irqsave(&adapter->driver_lock, flags);
707 memmove(adapter->cur_cmd->pdata_buf, &resp->params.pwrcfg,
708 sizeof(struct cmd_ds_802_11_pwr_cfg));
709 spin_unlock_irqrestore(&adapter->driver_lock, flags);
713 case CMD_RET(CMD_GET_TSF):
714 spin_lock_irqsave(&adapter->driver_lock, flags);
715 memcpy(priv->adapter->cur_cmd->pdata_buf,
716 &resp->params.gettsf.tsfvalue, sizeof(u64));
717 spin_unlock_irqrestore(&adapter->driver_lock, flags);
719 case CMD_RET(CMD_BT_ACCESS):
720 spin_lock_irqsave(&adapter->driver_lock, flags);
721 if (adapter->cur_cmd->pdata_buf)
722 memcpy(adapter->cur_cmd->pdata_buf,
723 &resp->params.bt.addr1, 2 * ETH_ALEN);
724 spin_unlock_irqrestore(&adapter->driver_lock, flags);
726 case CMD_RET(CMD_FWT_ACCESS):
727 spin_lock_irqsave(&adapter->driver_lock, flags);
728 if (adapter->cur_cmd->pdata_buf)
729 memcpy(adapter->cur_cmd->pdata_buf, &resp->params.fwt,
730 sizeof(resp->params.fwt));
731 spin_unlock_irqrestore(&adapter->driver_lock, flags);
733 case CMD_RET(CMD_MESH_ACCESS):
734 if (adapter->cur_cmd->pdata_buf)
735 memcpy(adapter->cur_cmd->pdata_buf, &resp->params.mesh,
736 sizeof(resp->params.mesh));
738 case CMD_RET(CMD_802_11_TX_RATE_QUERY):
739 priv->adapter->txrate = resp->params.txrate.txrate;
742 lbs_deb_host("CMD_RESP: unknown cmd response 0x%04x\n",
746 lbs_deb_leave(LBS_DEB_HOST);
750 int libertas_process_rx_command(wlan_private * priv)
753 struct cmd_ds_command *resp;
754 wlan_adapter *adapter = priv->adapter;
759 lbs_deb_enter(LBS_DEB_HOST);
761 /* Now we got response from FW, cancel the command timer */
762 del_timer(&adapter->command_timer);
764 mutex_lock(&adapter->lock);
765 spin_lock_irqsave(&adapter->driver_lock, flags);
767 if (!adapter->cur_cmd) {
768 lbs_deb_host("CMD_RESP: cur_cmd is NULL\n");
770 spin_unlock_irqrestore(&adapter->driver_lock, flags);
773 resp = (struct cmd_ds_command *)(adapter->cur_cmd->bufvirtualaddr);
775 respcmd = le16_to_cpu(resp->command);
776 result = le16_to_cpu(resp->result);
778 lbs_deb_host("CMD_RESP: response 0x%04x, size %d, jiffies %lu\n",
779 respcmd, priv->upld_len, jiffies);
780 lbs_deb_hex(LBS_DEB_HOST, "CMD_RESP", adapter->cur_cmd->bufvirtualaddr,
783 if (!(respcmd & 0x8000)) {
784 lbs_deb_host("invalid response!\n");
785 adapter->cur_cmd_retcode = -1;
786 __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
787 adapter->nr_cmd_pending--;
788 adapter->cur_cmd = NULL;
789 spin_unlock_irqrestore(&adapter->driver_lock, flags);
794 /* Store the response code to cur_cmd_retcode. */
795 adapter->cur_cmd_retcode = result;;
797 if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) {
798 struct cmd_ds_802_11_ps_mode *psmode = &resp->params.psmode;
799 u16 action = le16_to_cpu(psmode->action);
802 "CMD_RESP: PS_MODE cmd reply result 0x%x, action 0x%x\n",
806 lbs_deb_host("CMD_RESP: PS command failed with 0x%x\n",
809 * We should not re-try enter-ps command in
810 * ad-hoc mode. It takes place in
811 * libertas_execute_next_command().
813 if (adapter->mode == IW_MODE_ADHOC &&
814 action == CMD_SUBCMD_ENTER_PS)
815 adapter->psmode = WLAN802_11POWERMODECAM;
816 } else if (action == CMD_SUBCMD_ENTER_PS) {
817 adapter->needtowakeup = 0;
818 adapter->psstate = PS_STATE_AWAKE;
820 lbs_deb_host("CMD_RESP: ENTER_PS command response\n");
821 if (adapter->connect_status != LIBERTAS_CONNECTED) {
823 * When Deauth Event received before Enter_PS command
824 * response, We need to wake up the firmware.
827 "disconnected, invoking libertas_ps_wakeup\n");
829 spin_unlock_irqrestore(&adapter->driver_lock, flags);
830 mutex_unlock(&adapter->lock);
831 libertas_ps_wakeup(priv, 0);
832 mutex_lock(&adapter->lock);
833 spin_lock_irqsave(&adapter->driver_lock, flags);
835 } else if (action == CMD_SUBCMD_EXIT_PS) {
836 adapter->needtowakeup = 0;
837 adapter->psstate = PS_STATE_FULL_POWER;
838 lbs_deb_host("CMD_RESP: EXIT_PS command response\n");
840 lbs_deb_host("CMD_RESP: PS action 0x%X\n", action);
843 __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
844 adapter->nr_cmd_pending--;
845 adapter->cur_cmd = NULL;
846 spin_unlock_irqrestore(&adapter->driver_lock, flags);
852 if (adapter->cur_cmd->cmdflags & CMD_F_HOSTCMD) {
853 /* Copy the response back to response buffer */
854 memcpy(adapter->cur_cmd->pdata_buf, resp, resp->size);
856 adapter->cur_cmd->cmdflags &= ~CMD_F_HOSTCMD;
859 /* If the command is not successful, cleanup and return failure */
860 if ((result != 0 || !(respcmd & 0x8000))) {
861 lbs_deb_host("CMD_RESP: error 0x%04x in command reply 0x%04x\n",
864 * Handling errors here
867 case CMD_RET(CMD_GET_HW_SPEC):
868 case CMD_RET(CMD_802_11_RESET):
869 lbs_deb_host("CMD_RESP: reset failed\n");
874 __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
875 adapter->nr_cmd_pending--;
876 adapter->cur_cmd = NULL;
877 spin_unlock_irqrestore(&adapter->driver_lock, flags);
883 spin_unlock_irqrestore(&adapter->driver_lock, flags);
885 ret = handle_cmd_response(respcmd, resp, priv);
887 spin_lock_irqsave(&adapter->driver_lock, flags);
888 if (adapter->cur_cmd) {
889 /* Clean up and Put current command back to cmdfreeq */
890 __libertas_cleanup_and_insert_cmd(priv, adapter->cur_cmd);
891 adapter->nr_cmd_pending--;
892 WARN_ON(adapter->nr_cmd_pending > 128);
893 adapter->cur_cmd = NULL;
895 spin_unlock_irqrestore(&adapter->driver_lock, flags);
898 mutex_unlock(&adapter->lock);
899 lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
903 int libertas_process_event(wlan_private * priv)
906 wlan_adapter *adapter = priv->adapter;
909 spin_lock_irq(&adapter->driver_lock);
910 eventcause = adapter->eventcause;
911 spin_unlock_irq(&adapter->driver_lock);
913 lbs_deb_enter(LBS_DEB_CMD);
915 lbs_deb_cmd("event cause 0x%x\n", eventcause);
917 switch (eventcause >> SBI_EVENT_CAUSE_SHIFT) {
918 case MACREG_INT_CODE_LINK_SENSED:
919 lbs_deb_cmd("EVENT: MACREG_INT_CODE_LINK_SENSED\n");
922 case MACREG_INT_CODE_DEAUTHENTICATED:
923 lbs_deb_cmd("EVENT: deauthenticated\n");
924 libertas_mac_event_disconnected(priv);
927 case MACREG_INT_CODE_DISASSOCIATED:
928 lbs_deb_cmd("EVENT: disassociated\n");
929 libertas_mac_event_disconnected(priv);
932 case MACREG_INT_CODE_LINK_LOSE_NO_SCAN:
933 lbs_deb_cmd("EVENT: link lost\n");
934 libertas_mac_event_disconnected(priv);
937 case MACREG_INT_CODE_PS_SLEEP:
938 lbs_deb_cmd("EVENT: sleep\n");
940 /* handle unexpected PS SLEEP event */
941 if (adapter->psstate == PS_STATE_FULL_POWER) {
943 "EVENT: in FULL POWER mode, ignoreing PS_SLEEP\n");
946 adapter->psstate = PS_STATE_PRE_SLEEP;
948 libertas_ps_confirm_sleep(priv, (u16) adapter->psmode);
952 case MACREG_INT_CODE_PS_AWAKE:
953 lbs_deb_cmd("EVENT: awake\n");
955 /* handle unexpected PS AWAKE event */
956 if (adapter->psstate == PS_STATE_FULL_POWER) {
958 "EVENT: In FULL POWER mode - ignore PS AWAKE\n");
962 adapter->psstate = PS_STATE_AWAKE;
964 if (adapter->needtowakeup) {
966 * wait for the command processing to finish
967 * before resuming sending
968 * adapter->needtowakeup will be set to FALSE
969 * in libertas_ps_wakeup()
971 lbs_deb_cmd("waking up ...\n");
972 libertas_ps_wakeup(priv, 0);
976 case MACREG_INT_CODE_MIC_ERR_UNICAST:
977 lbs_deb_cmd("EVENT: UNICAST MIC ERROR\n");
978 handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_UNICAST);
981 case MACREG_INT_CODE_MIC_ERR_MULTICAST:
982 lbs_deb_cmd("EVENT: MULTICAST MIC ERROR\n");
983 handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_MULTICAST);
985 case MACREG_INT_CODE_MIB_CHANGED:
986 case MACREG_INT_CODE_INIT_DONE:
989 case MACREG_INT_CODE_ADHOC_BCN_LOST:
990 lbs_deb_cmd("EVENT: ADHOC beacon lost\n");
993 case MACREG_INT_CODE_RSSI_LOW:
994 lbs_pr_alert("EVENT: rssi low\n");
996 case MACREG_INT_CODE_SNR_LOW:
997 lbs_pr_alert("EVENT: snr low\n");
999 case MACREG_INT_CODE_MAX_FAIL:
1000 lbs_pr_alert("EVENT: max fail\n");
1002 case MACREG_INT_CODE_RSSI_HIGH:
1003 lbs_pr_alert("EVENT: rssi high\n");
1005 case MACREG_INT_CODE_SNR_HIGH:
1006 lbs_pr_alert("EVENT: snr high\n");
1009 case MACREG_INT_CODE_MESH_AUTO_STARTED:
1010 lbs_pr_alert("EVENT: MESH_AUTO_STARTED\n");
1011 adapter->connect_status = LIBERTAS_CONNECTED ;
1012 if (priv->mesh_open == 1) {
1013 netif_wake_queue(priv->mesh_dev) ;
1014 netif_carrier_on(priv->mesh_dev) ;
1016 adapter->mode = IW_MODE_ADHOC ;
1017 schedule_work(&priv->sync_channel);
1021 lbs_pr_alert("EVENT: unknown event id 0x%04x\n",
1022 eventcause >> SBI_EVENT_CAUSE_SHIFT);
1026 spin_lock_irq(&adapter->driver_lock);
1027 adapter->eventcause = 0;
1028 spin_unlock_irq(&adapter->driver_lock);
1030 lbs_deb_enter_args(LBS_DEB_CMD, "ret %d", ret);