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>
20 * @brief This function handles disconnect event. it
21 * reports disconnect to upper layer, clean tx/rx packets,
22 * reset link state etc.
24 * @param priv A pointer to wlan_private structure
27 void libertas_mac_event_disconnected(wlan_private
* priv
)
29 wlan_adapter
*adapter
= priv
->adapter
;
30 union iwreq_data wrqu
;
32 if (adapter
->connect_status
!= libertas_connected
)
35 lbs_deb_cmd("Handles disconnect event.\n");
37 memset(wrqu
.ap_addr
.sa_data
, 0x00, ETH_ALEN
);
38 wrqu
.ap_addr
.sa_family
= ARPHRD_ETHER
;
41 * Cisco AP sends EAP failure and de-auth in less than 0.5 ms.
42 * It causes problem in the Supplicant
45 msleep_interruptible(1000);
46 wireless_send_event(priv
->wlan_dev
.netdev
, SIOCGIWAP
, &wrqu
, NULL
);
48 /* Free Tx and Rx packets */
49 kfree_skb(priv
->adapter
->currenttxskb
);
50 priv
->adapter
->currenttxskb
= NULL
;
52 /* report disconnect to upper layer */
53 netif_stop_queue(priv
->wlan_dev
.netdev
);
54 netif_carrier_off(priv
->wlan_dev
.netdev
);
56 /* reset SNR/NF/RSSI values */
57 memset(adapter
->SNR
, 0x00, sizeof(adapter
->SNR
));
58 memset(adapter
->NF
, 0x00, sizeof(adapter
->NF
));
59 memset(adapter
->RSSI
, 0x00, sizeof(adapter
->RSSI
));
60 memset(adapter
->rawSNR
, 0x00, sizeof(adapter
->rawSNR
));
61 memset(adapter
->rawNF
, 0x00, sizeof(adapter
->rawNF
));
62 adapter
->nextSNRNF
= 0;
63 adapter
->numSNRNF
= 0;
64 adapter
->rxpd_rate
= 0;
65 lbs_deb_cmd("Current SSID=%s, ssid length=%u\n",
66 adapter
->curbssparams
.ssid
.ssid
,
67 adapter
->curbssparams
.ssid
.ssidlength
);
68 lbs_deb_cmd("Previous SSID=%s, ssid length=%u\n",
69 adapter
->previousssid
.ssid
, adapter
->previousssid
.ssidlength
);
71 /* reset internal flags */
72 adapter
->secinfo
.WPAenabled
= 0;
73 adapter
->secinfo
.WPA2enabled
= 0;
74 adapter
->wpa_ie_len
= 0;
76 adapter
->connect_status
= libertas_disconnected
;
79 * memorize the previous SSID and BSSID
80 * it could be used for re-assoc
82 memcpy(&adapter
->previousssid
,
83 &adapter
->curbssparams
.ssid
, sizeof(struct WLAN_802_11_SSID
));
84 memcpy(adapter
->previousbssid
,
85 adapter
->curbssparams
.bssid
, ETH_ALEN
);
87 /* need to erase the current SSID and BSSID info */
88 adapter
->pattemptedbssdesc
= NULL
;
89 memset(&adapter
->curbssparams
, 0, sizeof(adapter
->curbssparams
));
91 if (adapter
->psstate
!= PS_STATE_FULL_POWER
) {
92 /* make firmware to exit PS mode */
93 lbs_deb_cmd("Disconnected, so exit PS mode.\n");
94 libertas_ps_wakeup(priv
, 0);
99 * @brief This function handles MIC failure event.
101 * @param priv A pointer to wlan_private structure
102 * @para event the event id
105 static void handle_mic_failureevent(wlan_private
* priv
, u32 event
)
109 memset(buf
, 0, sizeof(buf
));
111 sprintf(buf
, "%s", "MLME-MICHAELMICFAILURE.indication ");
113 if (event
== MACREG_INT_CODE_MIC_ERR_UNICAST
) {
114 strcat(buf
, "unicast ");
116 strcat(buf
, "multicast ");
119 libertas_send_iwevcustom_event(priv
, buf
);
122 static int wlan_ret_reg_access(wlan_private
* priv
,
123 u16 type
, struct cmd_ds_command
*resp
)
126 wlan_adapter
*adapter
= priv
->adapter
;
128 lbs_deb_enter(LBS_DEB_CMD
);
131 case cmd_ret_mac_reg_access
:
133 struct cmd_ds_mac_reg_access
*reg
;
136 (struct cmd_ds_mac_reg_access
*)&resp
->params
.
139 adapter
->offsetvalue
.offset
= reg
->offset
;
140 adapter
->offsetvalue
.value
= reg
->value
;
144 case cmd_ret_bbp_reg_access
:
146 struct cmd_ds_bbp_reg_access
*reg
;
148 (struct cmd_ds_bbp_reg_access
*)&resp
->params
.
151 adapter
->offsetvalue
.offset
= reg
->offset
;
152 adapter
->offsetvalue
.value
= reg
->value
;
156 case cmd_ret_rf_reg_access
:
158 struct cmd_ds_rf_reg_access
*reg
;
160 (struct cmd_ds_rf_reg_access
*)&resp
->params
.
163 adapter
->offsetvalue
.offset
= reg
->offset
;
164 adapter
->offsetvalue
.value
= reg
->value
;
172 lbs_deb_enter_args(LBS_DEB_CMD
, "ret %d", ret
);
176 static int wlan_ret_get_hw_spec(wlan_private
* priv
,
177 struct cmd_ds_command
*resp
)
180 struct cmd_ds_get_hw_spec
*hwspec
= &resp
->params
.hwspec
;
181 wlan_adapter
*adapter
= priv
->adapter
;
184 lbs_deb_enter(LBS_DEB_CMD
);
186 adapter
->fwcapinfo
= le32_to_cpu(hwspec
->fwcapinfo
);
188 adapter
->fwreleasenumber
= hwspec
->fwreleasenumber
;
190 lbs_deb_cmd("GET_HW_SPEC: FWReleaseVersion- 0x%X\n",
191 adapter
->fwreleasenumber
);
192 lbs_deb_cmd("GET_HW_SPEC: Permanent addr- %2x:%2x:%2x:%2x:%2x:%2x\n",
193 hwspec
->permanentaddr
[0], hwspec
->permanentaddr
[1],
194 hwspec
->permanentaddr
[2], hwspec
->permanentaddr
[3],
195 hwspec
->permanentaddr
[4], hwspec
->permanentaddr
[5]);
196 lbs_deb_cmd("GET_HW_SPEC: hwifversion=0x%X version=0x%X\n",
197 hwspec
->hwifversion
, hwspec
->version
);
199 adapter
->regioncode
= le16_to_cpu(hwspec
->regioncode
);
201 for (i
= 0; i
< MRVDRV_MAX_REGION_CODE
; i
++) {
202 /* use the region code to search for the index */
203 if (adapter
->regioncode
== libertas_region_code_to_index
[i
]) {
204 adapter
->regiontableindex
= (u16
) i
;
209 /* if it's unidentified region code, use the default (USA) */
210 if (i
>= MRVDRV_MAX_REGION_CODE
) {
211 adapter
->regioncode
= 0x10;
212 adapter
->regiontableindex
= 0;
214 "unidentified region code, use the default (USA)\n");
217 if (adapter
->current_addr
[0] == 0xff) {
218 memmove(adapter
->current_addr
, hwspec
->permanentaddr
,
222 memcpy(priv
->wlan_dev
.netdev
->dev_addr
, adapter
->current_addr
, ETH_ALEN
);
224 memcpy(priv
->mesh_dev
->dev_addr
, adapter
->current_addr
,
227 if (libertas_set_regiontable(priv
, adapter
->regioncode
, 0)) {
232 if (libertas_set_universaltable(priv
, 0)) {
238 lbs_deb_enter_args(LBS_DEB_CMD
, "ret %d", ret
);
242 static int wlan_ret_802_11_sleep_params(wlan_private
* priv
,
243 struct cmd_ds_command
*resp
)
245 struct cmd_ds_802_11_sleep_params
*sp
= &resp
->params
.sleep_params
;
246 wlan_adapter
*adapter
= priv
->adapter
;
248 lbs_deb_enter(LBS_DEB_CMD
);
250 lbs_deb_cmd("error=%x offset=%x stabletime=%x calcontrol=%x\n"
251 " extsleepclk=%x\n", sp
->error
, sp
->offset
,
252 sp
->stabletime
, sp
->calcontrol
, sp
->externalsleepclk
);
253 adapter
->sp
.sp_error
= le16_to_cpu(sp
->error
);
254 adapter
->sp
.sp_offset
= le16_to_cpu(sp
->offset
);
255 adapter
->sp
.sp_stabletime
= le16_to_cpu(sp
->stabletime
);
256 adapter
->sp
.sp_calcontrol
= le16_to_cpu(sp
->calcontrol
);
257 adapter
->sp
.sp_extsleepclk
= le16_to_cpu(sp
->externalsleepclk
);
258 adapter
->sp
.sp_reserved
= le16_to_cpu(sp
->reserved
);
260 lbs_deb_enter(LBS_DEB_CMD
);
264 static int wlan_ret_802_11_stat(wlan_private
* priv
,
265 struct cmd_ds_command
*resp
)
267 /* currently adapter->wlan802_11Stat is unused
269 struct cmd_ds_802_11_get_stat *p11Stat = &resp->params.gstat;
270 wlan_adapter *adapter = priv->adapter;
272 // TODO Convert it to Big endian befor copy
273 memcpy(&adapter->wlan802_11Stat,
274 p11Stat, sizeof(struct cmd_ds_802_11_get_stat));
279 static int wlan_ret_802_11_snmp_mib(wlan_private
* priv
,
280 struct cmd_ds_command
*resp
)
282 struct cmd_ds_802_11_snmp_mib
*smib
= &resp
->params
.smib
;
283 u16 oid
= le16_to_cpu(smib
->oid
);
284 u16 querytype
= le16_to_cpu(smib
->querytype
);
286 lbs_deb_enter(LBS_DEB_CMD
);
288 lbs_deb_cmd("SNMP_RESP: value of the oid = %x, querytype=%x\n", oid
,
290 lbs_deb_cmd("SNMP_RESP: Buf size = %x\n",
291 le16_to_cpu(smib
->bufsize
));
293 if (querytype
== cmd_act_get
) {
296 priv
->adapter
->fragthsd
=
298 ((unsigned short *)(smib
->value
)));
299 lbs_deb_cmd("SNMP_RESP: fragthsd =%u\n",
300 priv
->adapter
->fragthsd
);
303 priv
->adapter
->rtsthsd
=
305 ((unsigned short *)(smib
->value
)));
306 lbs_deb_cmd("SNMP_RESP: rtsthsd =%u\n",
307 priv
->adapter
->rtsthsd
);
309 case short_retrylim_i
:
310 priv
->adapter
->txretrycount
=
312 ((unsigned short *)(smib
->value
)));
313 lbs_deb_cmd("SNMP_RESP: txretrycount =%u\n",
314 priv
->adapter
->rtsthsd
);
321 lbs_deb_enter(LBS_DEB_CMD
);
325 static int wlan_ret_802_11_key_material(wlan_private
* priv
,
326 struct cmd_ds_command
*resp
)
328 struct cmd_ds_802_11_key_material
*pkeymaterial
=
329 &resp
->params
.keymaterial
;
330 wlan_adapter
*adapter
= priv
->adapter
;
331 u16 action
= le16_to_cpu(pkeymaterial
->action
);
333 lbs_deb_enter(LBS_DEB_CMD
);
335 /* Copy the returned key to driver private data */
336 if (action
== cmd_act_get
) {
337 u8
* buf_ptr
= (u8
*) &pkeymaterial
->keyParamSet
;
338 u8
* resp_end
= (u8
*) (resp
+ le16_to_cpu(resp
->size
));
340 while (buf_ptr
< resp_end
) {
341 struct MrvlIEtype_keyParamSet
* pkeyparamset
=
342 (struct MrvlIEtype_keyParamSet
*) buf_ptr
;
343 struct WLAN_802_11_KEY
* pkey
;
344 u16 key_info
= le16_to_cpu(pkeyparamset
->keyinfo
);
345 u16 param_set_len
= le16_to_cpu(pkeyparamset
->length
);
347 u16 key_len
= le16_to_cpu(pkeyparamset
->keylen
);
349 end
= (u8
*) pkeyparamset
+ sizeof (pkeyparamset
->type
)
350 + sizeof (pkeyparamset
->length
)
352 /* Make sure we don't access past the end of the IEs */
356 if (key_info
& KEY_INFO_WPA_UNICAST
)
357 pkey
= &adapter
->wpa_unicast_key
;
358 else if (key_info
& KEY_INFO_WPA_MCAST
)
359 pkey
= &adapter
->wpa_mcast_key
;
363 /* Copy returned key into driver */
364 memset(pkey
, 0, sizeof(struct WLAN_802_11_KEY
));
365 if (key_len
> sizeof(pkey
->key
))
367 pkey
->type
= le16_to_cpu(pkeyparamset
->keytypeid
);
368 pkey
->flags
= le16_to_cpu(pkeyparamset
->keyinfo
);
369 pkey
->len
= le16_to_cpu(pkeyparamset
->keylen
);
370 memcpy(pkey
->key
, pkeyparamset
->key
, pkey
->len
);
376 lbs_deb_enter(LBS_DEB_CMD
);
380 static int wlan_ret_802_11_mac_address(wlan_private
* priv
,
381 struct cmd_ds_command
*resp
)
383 struct cmd_ds_802_11_mac_address
*macadd
= &resp
->params
.macadd
;
384 wlan_adapter
*adapter
= priv
->adapter
;
386 lbs_deb_enter(LBS_DEB_CMD
);
388 memcpy(adapter
->current_addr
, macadd
->macadd
, ETH_ALEN
);
390 lbs_deb_enter(LBS_DEB_CMD
);
394 static int wlan_ret_802_11_rf_tx_power(wlan_private
* priv
,
395 struct cmd_ds_command
*resp
)
397 struct cmd_ds_802_11_rf_tx_power
*rtp
= &resp
->params
.txp
;
398 wlan_adapter
*adapter
= priv
->adapter
;
400 lbs_deb_enter(LBS_DEB_CMD
);
402 adapter
->txpowerlevel
= le16_to_cpu(rtp
->currentlevel
);
404 lbs_deb_cmd("Current TxPower Level = %d\n", adapter
->txpowerlevel
);
406 lbs_deb_enter(LBS_DEB_CMD
);
410 static int wlan_ret_802_11_rf_antenna(wlan_private
* priv
,
411 struct cmd_ds_command
*resp
)
413 struct cmd_ds_802_11_rf_antenna
*pAntenna
= &resp
->params
.rant
;
414 wlan_adapter
*adapter
= priv
->adapter
;
415 u16 action
= le16_to_cpu(pAntenna
->action
);
417 if (action
== cmd_act_get_rx
)
418 adapter
->rxantennamode
=
419 le16_to_cpu(pAntenna
->antennamode
);
421 if (action
== cmd_act_get_tx
)
422 adapter
->txantennamode
=
423 le16_to_cpu(pAntenna
->antennamode
);
425 lbs_deb_cmd("RF_ANT_RESP: action = 0x%x, mode = 0x%04x\n",
426 action
, le16_to_cpu(pAntenna
->antennamode
));
431 static int wlan_ret_802_11_rate_adapt_rateset(wlan_private
* priv
,
432 struct cmd_ds_command
*resp
)
434 struct cmd_ds_802_11_rate_adapt_rateset
*rates
=
435 &resp
->params
.rateset
;
436 wlan_adapter
*adapter
= priv
->adapter
;
438 lbs_deb_enter(LBS_DEB_CMD
);
440 if (rates
->action
== cmd_act_get
) {
441 adapter
->enablehwauto
= rates
->enablehwauto
;
442 adapter
->ratebitmap
= rates
->bitmap
;
445 lbs_deb_enter(LBS_DEB_CMD
);
449 static int wlan_ret_802_11_data_rate(wlan_private
* priv
,
450 struct cmd_ds_command
*resp
)
452 struct cmd_ds_802_11_data_rate
*pdatarate
= &resp
->params
.drate
;
453 wlan_adapter
*adapter
= priv
->adapter
;
456 lbs_deb_enter(LBS_DEB_CMD
);
458 lbs_dbg_hex("DATA_RATE_RESP: data_rate- ",
459 (u8
*) pdatarate
, sizeof(struct cmd_ds_802_11_data_rate
));
461 dot11datarate
= pdatarate
->datarate
[0];
462 if (pdatarate
->action
== cmd_act_get_tx_rate
) {
463 memcpy(adapter
->libertas_supported_rates
, pdatarate
->datarate
,
464 sizeof(adapter
->libertas_supported_rates
));
466 adapter
->datarate
= libertas_index_to_data_rate(dot11datarate
);
468 lbs_deb_enter(LBS_DEB_CMD
);
472 static int wlan_ret_802_11_rf_channel(wlan_private
* priv
,
473 struct cmd_ds_command
*resp
)
475 struct cmd_ds_802_11_rf_channel
*rfchannel
=
476 &resp
->params
.rfchannel
;
477 wlan_adapter
*adapter
= priv
->adapter
;
478 u16 action
= le16_to_cpu(rfchannel
->action
);
479 u16 newchannel
= le16_to_cpu(rfchannel
->currentchannel
);
481 lbs_deb_enter(LBS_DEB_CMD
);
483 if (action
== cmd_opt_802_11_rf_channel_get
484 && adapter
->curbssparams
.channel
!= newchannel
) {
485 lbs_deb_cmd("channel Switch: %d to %d\n",
486 adapter
->curbssparams
.channel
, newchannel
);
488 /* Update the channel again */
489 adapter
->curbssparams
.channel
= newchannel
;
492 lbs_deb_enter(LBS_DEB_CMD
);
496 static int wlan_ret_802_11_rssi(wlan_private
* priv
,
497 struct cmd_ds_command
*resp
)
499 struct cmd_ds_802_11_rssi_rsp
*rssirsp
= &resp
->params
.rssirsp
;
500 wlan_adapter
*adapter
= priv
->adapter
;
502 /* store the non average value */
503 adapter
->SNR
[TYPE_BEACON
][TYPE_NOAVG
] = le16_to_cpu(rssirsp
->SNR
);
504 adapter
->NF
[TYPE_BEACON
][TYPE_NOAVG
] =
505 le16_to_cpu(rssirsp
->noisefloor
);
507 adapter
->SNR
[TYPE_BEACON
][TYPE_AVG
] = le16_to_cpu(rssirsp
->avgSNR
);
508 adapter
->NF
[TYPE_BEACON
][TYPE_AVG
] =
509 le16_to_cpu(rssirsp
->avgnoisefloor
);
511 adapter
->RSSI
[TYPE_BEACON
][TYPE_NOAVG
] =
512 CAL_RSSI(adapter
->SNR
[TYPE_BEACON
][TYPE_NOAVG
],
513 adapter
->NF
[TYPE_BEACON
][TYPE_NOAVG
]);
515 adapter
->RSSI
[TYPE_BEACON
][TYPE_AVG
] =
516 CAL_RSSI(adapter
->SNR
[TYPE_BEACON
][TYPE_AVG
] / AVG_SCALE
,
517 adapter
->NF
[TYPE_BEACON
][TYPE_AVG
] / AVG_SCALE
);
519 lbs_deb_cmd("Beacon RSSI value = 0x%x\n",
520 adapter
->RSSI
[TYPE_BEACON
][TYPE_AVG
]);
525 static int wlan_ret_802_11_eeprom_access(wlan_private
* priv
,
526 struct cmd_ds_command
*resp
)
528 wlan_adapter
*adapter
= priv
->adapter
;
529 struct wlan_ioctl_regrdwr
*pbuf
;
530 pbuf
= (struct wlan_ioctl_regrdwr
*) adapter
->prdeeprom
;
532 lbs_deb_cmd("eeprom read len=%x\n",
533 le16_to_cpu(resp
->params
.rdeeprom
.bytecount
));
534 if (pbuf
->NOB
< le16_to_cpu(resp
->params
.rdeeprom
.bytecount
)) {
536 lbs_deb_cmd("eeprom read return length is too big\n");
539 pbuf
->NOB
= le16_to_cpu(resp
->params
.rdeeprom
.bytecount
);
542 memcpy(&pbuf
->value
, (u8
*) & resp
->params
.rdeeprom
.value
,
543 le16_to_cpu(resp
->params
.rdeeprom
.bytecount
));
544 lbs_dbg_hex("adapter", (char *)&pbuf
->value
,
545 le16_to_cpu(resp
->params
.rdeeprom
.bytecount
));
550 static int wlan_ret_get_log(wlan_private
* priv
,
551 struct cmd_ds_command
*resp
)
553 struct cmd_ds_802_11_get_log
*logmessage
=
554 (struct cmd_ds_802_11_get_log
*)&resp
->params
.glog
;
555 wlan_adapter
*adapter
= priv
->adapter
;
557 lbs_deb_enter(LBS_DEB_CMD
);
559 /* TODO Convert it to Big Endian before copy */
560 memcpy(&adapter
->logmsg
, logmessage
,
561 sizeof(struct cmd_ds_802_11_get_log
));
563 lbs_deb_enter(LBS_DEB_CMD
);
567 static inline int handle_cmd_response(u16 respcmd
,
568 struct cmd_ds_command
*resp
,
573 wlan_adapter
*adapter
= priv
->adapter
;
576 case cmd_ret_mac_reg_access
:
577 case cmd_ret_bbp_reg_access
:
578 case cmd_ret_rf_reg_access
:
579 ret
= wlan_ret_reg_access(priv
, respcmd
, resp
);
582 case cmd_ret_hw_spec_info
:
583 ret
= wlan_ret_get_hw_spec(priv
, resp
);
586 case cmd_ret_802_11_scan
:
587 ret
= libertas_ret_80211_scan(priv
, resp
);
590 case cmd_ret_802_11_get_log
:
591 ret
= wlan_ret_get_log(priv
, resp
);
594 case cmd_ret_802_11_associate
:
595 case cmd_ret_802_11_reassociate
:
596 ret
= libertas_ret_80211_associate(priv
, resp
);
599 case cmd_ret_802_11_disassociate
:
600 case cmd_ret_802_11_deauthenticate
:
601 ret
= libertas_ret_80211_disassociate(priv
, resp
);
604 case cmd_ret_802_11_ad_hoc_start
:
605 case cmd_ret_802_11_ad_hoc_join
:
606 ret
= libertas_ret_80211_ad_hoc_start(priv
, resp
);
609 case cmd_ret_802_11_stat
:
610 ret
= wlan_ret_802_11_stat(priv
, resp
);
613 case cmd_ret_802_11_snmp_mib
:
614 ret
= wlan_ret_802_11_snmp_mib(priv
, resp
);
617 case cmd_ret_802_11_rf_tx_power
:
618 ret
= wlan_ret_802_11_rf_tx_power(priv
, resp
);
621 case cmd_ret_802_11_set_afc
:
622 case cmd_ret_802_11_get_afc
:
623 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
624 memmove(adapter
->cur_cmd
->pdata_buf
,
626 sizeof(struct cmd_ds_802_11_afc
));
627 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
630 case cmd_ret_802_11_rf_antenna
:
631 ret
= wlan_ret_802_11_rf_antenna(priv
, resp
);
634 case cmd_ret_mac_multicast_adr
:
635 case cmd_ret_mac_control
:
636 case cmd_ret_802_11_set_wep
:
637 case cmd_ret_802_11_reset
:
638 case cmd_ret_802_11_authenticate
:
639 case cmd_ret_802_11_radio_control
:
640 case cmd_ret_802_11_beacon_stop
:
641 case cmd_ret_802_11_enable_rsn
:
644 case cmd_ret_802_11_data_rate
:
645 ret
= wlan_ret_802_11_data_rate(priv
, resp
);
647 case cmd_ret_802_11_rate_adapt_rateset
:
648 ret
= wlan_ret_802_11_rate_adapt_rateset(priv
, resp
);
650 case cmd_ret_802_11_rf_channel
:
651 ret
= wlan_ret_802_11_rf_channel(priv
, resp
);
654 case cmd_ret_802_11_rssi
:
655 ret
= wlan_ret_802_11_rssi(priv
, resp
);
658 case cmd_ret_802_11_mac_address
:
659 ret
= wlan_ret_802_11_mac_address(priv
, resp
);
662 case cmd_ret_802_11_ad_hoc_stop
:
663 ret
= libertas_ret_80211_ad_hoc_stop(priv
, resp
);
666 case cmd_ret_802_11_key_material
:
667 lbs_deb_cmd("CMD_RESP: KEY_MATERIAL command response\n");
668 ret
= wlan_ret_802_11_key_material(priv
, resp
);
671 case cmd_ret_802_11_eeprom_access
:
672 ret
= wlan_ret_802_11_eeprom_access(priv
, resp
);
675 case cmd_ret_802_11d_domain_info
:
676 ret
= libertas_ret_802_11d_domain_info(priv
, resp
);
679 case cmd_ret_802_11_sleep_params
:
680 ret
= wlan_ret_802_11_sleep_params(priv
, resp
);
682 case cmd_ret_802_11_inactivity_timeout
:
683 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
684 *((u16
*) adapter
->cur_cmd
->pdata_buf
) =
685 le16_to_cpu(resp
->params
.inactivity_timeout
.timeout
);
686 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
689 case cmd_ret_802_11_tpc_cfg
:
690 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
691 memmove(adapter
->cur_cmd
->pdata_buf
,
692 &resp
->params
.tpccfg
,
693 sizeof(struct cmd_ds_802_11_tpc_cfg
));
694 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
696 case cmd_ret_802_11_led_gpio_ctrl
:
697 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
698 memmove(adapter
->cur_cmd
->pdata_buf
,
699 &resp
->params
.ledgpio
,
700 sizeof(struct cmd_ds_802_11_led_ctrl
));
701 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
703 case cmd_ret_802_11_pwr_cfg
:
704 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
705 memmove(adapter
->cur_cmd
->pdata_buf
,
706 &resp
->params
.pwrcfg
,
707 sizeof(struct cmd_ds_802_11_pwr_cfg
));
708 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
712 case cmd_ret_get_tsf
:
713 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
714 memcpy(priv
->adapter
->cur_cmd
->pdata_buf
,
715 &resp
->params
.gettsf
.tsfvalue
, sizeof(u64
));
716 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
718 case cmd_ret_bt_access
:
719 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
720 if (adapter
->cur_cmd
->pdata_buf
)
721 memcpy(adapter
->cur_cmd
->pdata_buf
,
722 &resp
->params
.bt
.addr1
, 2 * ETH_ALEN
);
723 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
725 case cmd_ret_fwt_access
:
726 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
727 if (adapter
->cur_cmd
->pdata_buf
)
728 memcpy(adapter
->cur_cmd
->pdata_buf
,
730 sizeof(resp
->params
.fwt
));
731 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
733 case cmd_ret_mesh_access
:
734 if (adapter
->cur_cmd
->pdata_buf
)
735 memcpy(adapter
->cur_cmd
->pdata_buf
,
737 sizeof(resp
->params
.mesh
));
739 case cmd_rte_802_11_tx_rate_query
:
740 priv
->adapter
->txrate
= resp
->params
.txrate
.txrate
;
743 lbs_deb_cmd("CMD_RESP: Unknown command response %#x\n",
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_CMD
);
761 lbs_deb_cmd("CMD_RESP: @ %lu\n", jiffies
);
763 /* Now we got response from FW, cancel the command timer */
764 del_timer(&adapter
->command_timer
);
766 mutex_lock(&adapter
->lock
);
767 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
769 if (!adapter
->cur_cmd
) {
770 lbs_deb_cmd("CMD_RESP: NULL cur_cmd=%p\n", adapter
->cur_cmd
);
772 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
775 resp
= (struct cmd_ds_command
*)(adapter
->cur_cmd
->bufvirtualaddr
);
777 lbs_dbg_hex("CMD_RESP:", adapter
->cur_cmd
->bufvirtualaddr
,
778 priv
->wlan_dev
.upld_len
);
780 respcmd
= le16_to_cpu(resp
->command
);
782 result
= le16_to_cpu(resp
->result
);
784 lbs_deb_cmd("CMD_RESP: %x result: %d length: %d\n", respcmd
,
785 result
, priv
->wlan_dev
.upld_len
);
787 if (!(respcmd
& 0x8000)) {
788 lbs_deb_cmd("Invalid response to command!");
789 adapter
->cur_cmd_retcode
= -1;
790 __libertas_cleanup_and_insert_cmd(priv
, adapter
->cur_cmd
);
791 adapter
->nr_cmd_pending
--;
792 adapter
->cur_cmd
= NULL
;
793 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
798 /* Store the response code to cur_cmd_retcode. */
799 adapter
->cur_cmd_retcode
= le16_to_cpu(resp
->result
);
801 if (respcmd
== cmd_ret_802_11_ps_mode
) {
802 struct cmd_ds_802_11_ps_mode
*psmode
;
804 psmode
= &resp
->params
.psmode
;
806 "CMD_RESP: PS_MODE cmd reply result=%#x action=0x%X\n",
807 resp
->result
, psmode
->action
);
808 psmode
->action
= cpu_to_le16(psmode
->action
);
811 lbs_deb_cmd("CMD_RESP: PS command failed- %#x \n",
813 if (adapter
->mode
== IW_MODE_ADHOC
) {
815 * We should not re-try enter-ps command in
816 * ad-hoc mode. It takes place in
817 * libertas_execute_next_command().
819 if (psmode
->action
== cmd_subcmd_enter_ps
)
821 wlan802_11powermodecam
;
823 } else if (psmode
->action
== cmd_subcmd_enter_ps
) {
824 adapter
->needtowakeup
= 0;
825 adapter
->psstate
= PS_STATE_AWAKE
;
827 lbs_deb_cmd("CMD_RESP: Enter_PS command response\n");
828 if (adapter
->connect_status
!= libertas_connected
) {
830 * When Deauth Event received before Enter_PS command
831 * response, We need to wake up the firmware.
834 "Disconnected, Going to invoke libertas_ps_wakeup\n");
836 mutex_unlock(&adapter
->lock
);
837 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
838 libertas_ps_wakeup(priv
, 0);
839 mutex_lock(&adapter
->lock
);
840 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
842 } else if (psmode
->action
== cmd_subcmd_exit_ps
) {
843 adapter
->needtowakeup
= 0;
844 adapter
->psstate
= PS_STATE_FULL_POWER
;
845 lbs_deb_cmd("CMD_RESP: Exit_PS command response\n");
847 lbs_deb_cmd("CMD_RESP: PS- action=0x%X\n",
851 __libertas_cleanup_and_insert_cmd(priv
, adapter
->cur_cmd
);
852 adapter
->nr_cmd_pending
--;
853 adapter
->cur_cmd
= NULL
;
854 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
860 if (adapter
->cur_cmd
->cmdflags
& CMD_F_HOSTCMD
) {
861 /* Copy the response back to response buffer */
862 memcpy(adapter
->cur_cmd
->pdata_buf
, resp
, resp
->size
);
864 adapter
->cur_cmd
->cmdflags
&= ~CMD_F_HOSTCMD
;
867 /* If the command is not successful, cleanup and return failure */
868 if ((result
!= 0 || !(respcmd
& 0x8000))) {
869 lbs_deb_cmd("CMD_RESP: command reply %#x result=%#x\n",
870 resp
->command
, resp
->result
);
872 * Handling errors here
875 case cmd_ret_hw_spec_info
:
876 case cmd_ret_802_11_reset
:
877 lbs_deb_cmd("CMD_RESP: Reset command failed\n");
882 __libertas_cleanup_and_insert_cmd(priv
, adapter
->cur_cmd
);
883 adapter
->nr_cmd_pending
--;
884 adapter
->cur_cmd
= NULL
;
885 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
891 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
893 ret
= handle_cmd_response(respcmd
, resp
, priv
);
895 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
896 if (adapter
->cur_cmd
) {
897 /* Clean up and Put current command back to cmdfreeq */
898 __libertas_cleanup_and_insert_cmd(priv
, adapter
->cur_cmd
);
899 adapter
->nr_cmd_pending
--;
900 WARN_ON(adapter
->nr_cmd_pending
> 128);
901 adapter
->cur_cmd
= NULL
;
903 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
906 mutex_unlock(&adapter
->lock
);
907 lbs_deb_enter_args(LBS_DEB_CMD
, "ret %d", ret
);
911 int libertas_process_event(wlan_private
* priv
)
914 wlan_adapter
*adapter
= priv
->adapter
;
917 spin_lock_irq(&adapter
->driver_lock
);
918 eventcause
= adapter
->eventcause
;
919 spin_unlock_irq(&adapter
->driver_lock
);
921 lbs_deb_enter(LBS_DEB_CMD
);
923 lbs_deb_cmd("EVENT Cause %x\n", eventcause
);
925 switch (eventcause
>> SBI_EVENT_CAUSE_SHIFT
) {
926 case MACREG_INT_CODE_LINK_SENSED
:
927 lbs_deb_cmd("EVENT: MACREG_INT_CODE_LINK_SENSED\n");
930 case MACREG_INT_CODE_DEAUTHENTICATED
:
931 lbs_deb_cmd("EVENT: Deauthenticated\n");
932 libertas_mac_event_disconnected(priv
);
935 case MACREG_INT_CODE_DISASSOCIATED
:
936 lbs_deb_cmd("EVENT: Disassociated\n");
937 libertas_mac_event_disconnected(priv
);
940 case MACREG_INT_CODE_LINK_LOSE_NO_SCAN
:
941 lbs_deb_cmd("EVENT: Link lost\n");
942 libertas_mac_event_disconnected(priv
);
945 case MACREG_INT_CODE_PS_SLEEP
:
946 lbs_deb_cmd("EVENT: SLEEP\n");
949 /* handle unexpected PS SLEEP event */
950 if (adapter
->psstate
== PS_STATE_FULL_POWER
) {
952 "EVENT: In FULL POWER mode - ignore PS SLEEP\n");
955 adapter
->psstate
= PS_STATE_PRE_SLEEP
;
957 libertas_ps_confirm_sleep(priv
, (u16
) adapter
->psmode
);
961 case MACREG_INT_CODE_PS_AWAKE
:
962 lbs_deb_cmd("EVENT: AWAKE \n");
965 /* handle unexpected PS AWAKE event */
966 if (adapter
->psstate
== PS_STATE_FULL_POWER
) {
968 "EVENT: In FULL POWER mode - ignore PS AWAKE\n");
972 adapter
->psstate
= PS_STATE_AWAKE
;
974 if (adapter
->needtowakeup
) {
976 * wait for the command processing to finish
977 * before resuming sending
978 * adapter->needtowakeup will be set to FALSE
979 * in libertas_ps_wakeup()
981 lbs_deb_cmd("Waking up...\n");
982 libertas_ps_wakeup(priv
, 0);
986 case MACREG_INT_CODE_MIC_ERR_UNICAST
:
987 lbs_deb_cmd("EVENT: UNICAST MIC ERROR\n");
988 handle_mic_failureevent(priv
, MACREG_INT_CODE_MIC_ERR_UNICAST
);
991 case MACREG_INT_CODE_MIC_ERR_MULTICAST
:
992 lbs_deb_cmd("EVENT: MULTICAST MIC ERROR\n");
993 handle_mic_failureevent(priv
, MACREG_INT_CODE_MIC_ERR_MULTICAST
);
995 case MACREG_INT_CODE_MIB_CHANGED
:
996 case MACREG_INT_CODE_INIT_DONE
:
999 case MACREG_INT_CODE_ADHOC_BCN_LOST
:
1000 lbs_deb_cmd("EVENT: HWAC - ADHOC BCN LOST\n");
1003 case MACREG_INT_CODE_RSSI_LOW
:
1004 lbs_pr_alert( "EVENT: RSSI_LOW\n");
1006 case MACREG_INT_CODE_SNR_LOW
:
1007 lbs_pr_alert( "EVENT: SNR_LOW\n");
1009 case MACREG_INT_CODE_MAX_FAIL
:
1010 lbs_pr_alert( "EVENT: MAX_FAIL\n");
1012 case MACREG_INT_CODE_RSSI_HIGH
:
1013 lbs_pr_alert( "EVENT: RSSI_HIGH\n");
1015 case MACREG_INT_CODE_SNR_HIGH
:
1016 lbs_pr_alert( "EVENT: SNR_HIGH\n");
1020 lbs_pr_alert( "EVENT: unknown event id: %#x\n",
1021 eventcause
>> SBI_EVENT_CAUSE_SHIFT
);
1025 spin_lock_irq(&adapter
->driver_lock
);
1026 adapter
->eventcause
= 0;
1027 spin_unlock_irq(&adapter
->driver_lock
);
1029 lbs_deb_enter_args(LBS_DEB_CMD
, "ret %d", ret
);