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_cmd("Handles disconnect event.\n");
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', ssid 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', ssid 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);
95 * @brief This function handles MIC failure event.
97 * @param priv A pointer to wlan_private structure
98 * @para event the event id
101 static void handle_mic_failureevent(wlan_private
* priv
, u32 event
)
105 memset(buf
, 0, sizeof(buf
));
107 sprintf(buf
, "%s", "MLME-MICHAELMICFAILURE.indication ");
109 if (event
== MACREG_INT_CODE_MIC_ERR_UNICAST
) {
110 strcat(buf
, "unicast ");
112 strcat(buf
, "multicast ");
115 libertas_send_iwevcustom_event(priv
, buf
);
118 static int wlan_ret_reg_access(wlan_private
* priv
,
119 u16 type
, struct cmd_ds_command
*resp
)
122 wlan_adapter
*adapter
= priv
->adapter
;
124 lbs_deb_enter(LBS_DEB_CMD
);
127 case cmd_ret_mac_reg_access
:
129 struct cmd_ds_mac_reg_access
*reg
= &resp
->params
.macreg
;
131 adapter
->offsetvalue
.offset
= (u32
)le16_to_cpu(reg
->offset
);
132 adapter
->offsetvalue
.value
= le32_to_cpu(reg
->value
);
136 case cmd_ret_bbp_reg_access
:
138 struct cmd_ds_bbp_reg_access
*reg
= &resp
->params
.bbpreg
;
140 adapter
->offsetvalue
.offset
= (u32
)le16_to_cpu(reg
->offset
);
141 adapter
->offsetvalue
.value
= reg
->value
;
145 case cmd_ret_rf_reg_access
:
147 struct cmd_ds_rf_reg_access
*reg
= &resp
->params
.rfreg
;
149 adapter
->offsetvalue
.offset
= (u32
)le16_to_cpu(reg
->offset
);
150 adapter
->offsetvalue
.value
= reg
->value
;
158 lbs_deb_enter_args(LBS_DEB_CMD
, "ret %d", ret
);
162 static int wlan_ret_get_hw_spec(wlan_private
* priv
,
163 struct cmd_ds_command
*resp
)
166 struct cmd_ds_get_hw_spec
*hwspec
= &resp
->params
.hwspec
;
167 wlan_adapter
*adapter
= priv
->adapter
;
170 lbs_deb_enter(LBS_DEB_CMD
);
172 adapter
->fwcapinfo
= le32_to_cpu(hwspec
->fwcapinfo
);
174 memcpy(adapter
->fwreleasenumber
, hwspec
->fwreleasenumber
, 4);
176 lbs_deb_cmd("GET_HW_SPEC: FWReleaseVersion- %u.%u.%u.p%u\n",
177 adapter
->fwreleasenumber
[2], adapter
->fwreleasenumber
[1],
178 adapter
->fwreleasenumber
[0], adapter
->fwreleasenumber
[3]);
179 lbs_deb_cmd("GET_HW_SPEC: Permanent addr- %2x:%2x:%2x:%2x:%2x:%2x\n",
180 hwspec
->permanentaddr
[0], hwspec
->permanentaddr
[1],
181 hwspec
->permanentaddr
[2], hwspec
->permanentaddr
[3],
182 hwspec
->permanentaddr
[4], hwspec
->permanentaddr
[5]);
183 lbs_deb_cmd("GET_HW_SPEC: hwifversion=0x%X version=0x%X\n",
184 hwspec
->hwifversion
, hwspec
->version
);
186 adapter
->regioncode
= le16_to_cpu(hwspec
->regioncode
);
188 for (i
= 0; i
< MRVDRV_MAX_REGION_CODE
; i
++) {
189 /* use the region code to search for the index */
190 if (adapter
->regioncode
== libertas_region_code_to_index
[i
]) {
191 adapter
->regiontableindex
= (u16
) i
;
196 /* if it's unidentified region code, use the default (USA) */
197 if (i
>= MRVDRV_MAX_REGION_CODE
) {
198 adapter
->regioncode
= 0x10;
199 adapter
->regiontableindex
= 0;
200 lbs_pr_info("unidentified region code; using the default (USA)\n");
203 if (adapter
->current_addr
[0] == 0xff)
204 memmove(adapter
->current_addr
, hwspec
->permanentaddr
, ETH_ALEN
);
206 memcpy(priv
->dev
->dev_addr
, adapter
->current_addr
, ETH_ALEN
);
208 memcpy(priv
->mesh_dev
->dev_addr
, adapter
->current_addr
, ETH_ALEN
);
210 if (libertas_set_regiontable(priv
, adapter
->regioncode
, 0)) {
215 if (libertas_set_universaltable(priv
, 0)) {
221 lbs_deb_enter_args(LBS_DEB_CMD
, "ret %d", ret
);
225 static int wlan_ret_802_11_sleep_params(wlan_private
* priv
,
226 struct cmd_ds_command
*resp
)
228 struct cmd_ds_802_11_sleep_params
*sp
= &resp
->params
.sleep_params
;
229 wlan_adapter
*adapter
= priv
->adapter
;
231 lbs_deb_enter(LBS_DEB_CMD
);
233 lbs_deb_cmd("error=%x offset=%x stabletime=%x calcontrol=%x\n"
234 " extsleepclk=%x\n", le16_to_cpu(sp
->error
),
235 le16_to_cpu(sp
->offset
), le16_to_cpu(sp
->stabletime
),
236 sp
->calcontrol
, sp
->externalsleepclk
);
238 adapter
->sp
.sp_error
= le16_to_cpu(sp
->error
);
239 adapter
->sp
.sp_offset
= le16_to_cpu(sp
->offset
);
240 adapter
->sp
.sp_stabletime
= le16_to_cpu(sp
->stabletime
);
241 adapter
->sp
.sp_calcontrol
= sp
->calcontrol
;
242 adapter
->sp
.sp_extsleepclk
= sp
->externalsleepclk
;
243 adapter
->sp
.sp_reserved
= le16_to_cpu(sp
->reserved
);
245 lbs_deb_enter(LBS_DEB_CMD
);
249 static int wlan_ret_802_11_stat(wlan_private
* priv
,
250 struct cmd_ds_command
*resp
)
252 /* currently adapter->wlan802_11Stat is unused
254 struct cmd_ds_802_11_get_stat *p11Stat = &resp->params.gstat;
255 wlan_adapter *adapter = priv->adapter;
257 // TODO Convert it to Big endian befor copy
258 memcpy(&adapter->wlan802_11Stat,
259 p11Stat, sizeof(struct cmd_ds_802_11_get_stat));
264 static int wlan_ret_802_11_snmp_mib(wlan_private
* priv
,
265 struct cmd_ds_command
*resp
)
267 struct cmd_ds_802_11_snmp_mib
*smib
= &resp
->params
.smib
;
268 u16 oid
= le16_to_cpu(smib
->oid
);
269 u16 querytype
= le16_to_cpu(smib
->querytype
);
271 lbs_deb_enter(LBS_DEB_CMD
);
273 lbs_deb_cmd("SNMP_RESP: value of the oid = %x, querytype=%x\n", oid
,
275 lbs_deb_cmd("SNMP_RESP: Buf size = %x\n", le16_to_cpu(smib
->bufsize
));
277 if (querytype
== cmd_act_get
) {
280 priv
->adapter
->fragthsd
=
281 le16_to_cpu(*((__le16
*)(smib
->value
)));
282 lbs_deb_cmd("SNMP_RESP: fragthsd =%u\n",
283 priv
->adapter
->fragthsd
);
286 priv
->adapter
->rtsthsd
=
287 le16_to_cpu(*((__le16
*)(smib
->value
)));
288 lbs_deb_cmd("SNMP_RESP: rtsthsd =%u\n",
289 priv
->adapter
->rtsthsd
);
291 case short_retrylim_i
:
292 priv
->adapter
->txretrycount
=
293 le16_to_cpu(*((__le16
*)(smib
->value
)));
294 lbs_deb_cmd("SNMP_RESP: txretrycount =%u\n",
295 priv
->adapter
->rtsthsd
);
302 lbs_deb_enter(LBS_DEB_CMD
);
306 static int wlan_ret_802_11_key_material(wlan_private
* priv
,
307 struct cmd_ds_command
*resp
)
309 struct cmd_ds_802_11_key_material
*pkeymaterial
=
310 &resp
->params
.keymaterial
;
311 wlan_adapter
*adapter
= priv
->adapter
;
312 u16 action
= le16_to_cpu(pkeymaterial
->action
);
314 lbs_deb_enter(LBS_DEB_CMD
);
316 /* Copy the returned key to driver private data */
317 if (action
== cmd_act_get
) {
318 u8
* buf_ptr
= (u8
*) &pkeymaterial
->keyParamSet
;
319 u8
* resp_end
= (u8
*) (resp
+ le16_to_cpu(resp
->size
));
321 while (buf_ptr
< resp_end
) {
322 struct MrvlIEtype_keyParamSet
* pkeyparamset
=
323 (struct MrvlIEtype_keyParamSet
*) buf_ptr
;
324 struct enc_key
* pkey
;
325 u16 param_set_len
= le16_to_cpu(pkeyparamset
->length
);
326 u16 key_len
= le16_to_cpu(pkeyparamset
->keylen
);
327 u16 key_flags
= le16_to_cpu(pkeyparamset
->keyinfo
);
328 u16 key_type
= le16_to_cpu(pkeyparamset
->keytypeid
);
331 end
= (u8
*) pkeyparamset
+ sizeof (pkeyparamset
->type
)
332 + sizeof (pkeyparamset
->length
)
334 /* Make sure we don't access past the end of the IEs */
338 if (key_flags
& KEY_INFO_WPA_UNICAST
)
339 pkey
= &adapter
->wpa_unicast_key
;
340 else if (key_flags
& KEY_INFO_WPA_MCAST
)
341 pkey
= &adapter
->wpa_mcast_key
;
345 /* Copy returned key into driver */
346 memset(pkey
, 0, sizeof(struct enc_key
));
347 if (key_len
> sizeof(pkey
->key
))
349 pkey
->type
= key_type
;
350 pkey
->flags
= key_flags
;
352 memcpy(pkey
->key
, pkeyparamset
->key
, pkey
->len
);
358 lbs_deb_enter(LBS_DEB_CMD
);
362 static int wlan_ret_802_11_mac_address(wlan_private
* priv
,
363 struct cmd_ds_command
*resp
)
365 struct cmd_ds_802_11_mac_address
*macadd
= &resp
->params
.macadd
;
366 wlan_adapter
*adapter
= priv
->adapter
;
368 lbs_deb_enter(LBS_DEB_CMD
);
370 memcpy(adapter
->current_addr
, macadd
->macadd
, ETH_ALEN
);
372 lbs_deb_enter(LBS_DEB_CMD
);
376 static int wlan_ret_802_11_rf_tx_power(wlan_private
* priv
,
377 struct cmd_ds_command
*resp
)
379 struct cmd_ds_802_11_rf_tx_power
*rtp
= &resp
->params
.txp
;
380 wlan_adapter
*adapter
= priv
->adapter
;
382 lbs_deb_enter(LBS_DEB_CMD
);
384 adapter
->txpowerlevel
= le16_to_cpu(rtp
->currentlevel
);
386 lbs_deb_cmd("Current TxPower Level = %d\n", adapter
->txpowerlevel
);
388 lbs_deb_enter(LBS_DEB_CMD
);
392 static int wlan_ret_802_11_rf_antenna(wlan_private
* priv
,
393 struct cmd_ds_command
*resp
)
395 struct cmd_ds_802_11_rf_antenna
*pAntenna
= &resp
->params
.rant
;
396 wlan_adapter
*adapter
= priv
->adapter
;
397 u16 action
= le16_to_cpu(pAntenna
->action
);
399 if (action
== cmd_act_get_rx
)
400 adapter
->rxantennamode
= le16_to_cpu(pAntenna
->antennamode
);
402 if (action
== cmd_act_get_tx
)
403 adapter
->txantennamode
= le16_to_cpu(pAntenna
->antennamode
);
405 lbs_deb_cmd("RF_ANT_RESP: action = 0x%x, mode = 0x%04x\n",
406 action
, le16_to_cpu(pAntenna
->antennamode
));
411 static int wlan_ret_802_11_rate_adapt_rateset(wlan_private
* priv
,
412 struct cmd_ds_command
*resp
)
414 struct cmd_ds_802_11_rate_adapt_rateset
*rates
= &resp
->params
.rateset
;
415 wlan_adapter
*adapter
= priv
->adapter
;
417 lbs_deb_enter(LBS_DEB_CMD
);
419 if (rates
->action
== cmd_act_get
) {
420 adapter
->enablehwauto
= le16_to_cpu(rates
->enablehwauto
);
421 adapter
->ratebitmap
= le16_to_cpu(rates
->bitmap
);
424 lbs_deb_enter(LBS_DEB_CMD
);
428 static int wlan_ret_802_11_data_rate(wlan_private
* priv
,
429 struct cmd_ds_command
*resp
)
431 struct cmd_ds_802_11_data_rate
*pdatarate
= &resp
->params
.drate
;
432 wlan_adapter
*adapter
= priv
->adapter
;
435 lbs_deb_enter(LBS_DEB_CMD
);
437 lbs_dbg_hex("DATA_RATE_RESP: data_rate- ",
438 (u8
*) pdatarate
, sizeof(struct cmd_ds_802_11_data_rate
));
440 dot11datarate
= pdatarate
->datarate
[0];
441 if (pdatarate
->action
== cpu_to_le16(cmd_act_get_tx_rate
)) {
442 memcpy(adapter
->libertas_supported_rates
, pdatarate
->datarate
,
443 sizeof(adapter
->libertas_supported_rates
));
445 adapter
->datarate
= libertas_index_to_data_rate(dot11datarate
);
447 lbs_deb_enter(LBS_DEB_CMD
);
451 static int wlan_ret_802_11_rf_channel(wlan_private
* priv
,
452 struct cmd_ds_command
*resp
)
454 struct cmd_ds_802_11_rf_channel
*rfchannel
= &resp
->params
.rfchannel
;
455 wlan_adapter
*adapter
= priv
->adapter
;
456 u16 action
= le16_to_cpu(rfchannel
->action
);
457 u16 newchannel
= le16_to_cpu(rfchannel
->currentchannel
);
459 lbs_deb_enter(LBS_DEB_CMD
);
461 if (action
== cmd_opt_802_11_rf_channel_get
462 && adapter
->curbssparams
.channel
!= newchannel
) {
463 lbs_deb_cmd("channel Switch: %d to %d\n",
464 adapter
->curbssparams
.channel
, newchannel
);
466 /* Update the channel again */
467 adapter
->curbssparams
.channel
= newchannel
;
470 lbs_deb_enter(LBS_DEB_CMD
);
474 static int wlan_ret_802_11_rssi(wlan_private
* priv
,
475 struct cmd_ds_command
*resp
)
477 struct cmd_ds_802_11_rssi_rsp
*rssirsp
= &resp
->params
.rssirsp
;
478 wlan_adapter
*adapter
= priv
->adapter
;
480 /* store the non average value */
481 adapter
->SNR
[TYPE_BEACON
][TYPE_NOAVG
] = le16_to_cpu(rssirsp
->SNR
);
482 adapter
->NF
[TYPE_BEACON
][TYPE_NOAVG
] = le16_to_cpu(rssirsp
->noisefloor
);
484 adapter
->SNR
[TYPE_BEACON
][TYPE_AVG
] = le16_to_cpu(rssirsp
->avgSNR
);
485 adapter
->NF
[TYPE_BEACON
][TYPE_AVG
] = le16_to_cpu(rssirsp
->avgnoisefloor
);
487 adapter
->RSSI
[TYPE_BEACON
][TYPE_NOAVG
] =
488 CAL_RSSI(adapter
->SNR
[TYPE_BEACON
][TYPE_NOAVG
],
489 adapter
->NF
[TYPE_BEACON
][TYPE_NOAVG
]);
491 adapter
->RSSI
[TYPE_BEACON
][TYPE_AVG
] =
492 CAL_RSSI(adapter
->SNR
[TYPE_BEACON
][TYPE_AVG
] / AVG_SCALE
,
493 adapter
->NF
[TYPE_BEACON
][TYPE_AVG
] / AVG_SCALE
);
495 lbs_deb_cmd("Beacon RSSI value = 0x%x\n",
496 adapter
->RSSI
[TYPE_BEACON
][TYPE_AVG
]);
501 static int wlan_ret_802_11_eeprom_access(wlan_private
* priv
,
502 struct cmd_ds_command
*resp
)
504 wlan_adapter
*adapter
= priv
->adapter
;
505 struct wlan_ioctl_regrdwr
*pbuf
;
506 pbuf
= (struct wlan_ioctl_regrdwr
*) adapter
->prdeeprom
;
508 lbs_deb_cmd("eeprom read len=%x\n",
509 le16_to_cpu(resp
->params
.rdeeprom
.bytecount
));
510 if (pbuf
->NOB
< le16_to_cpu(resp
->params
.rdeeprom
.bytecount
)) {
512 lbs_deb_cmd("eeprom read return length is too big\n");
515 pbuf
->NOB
= le16_to_cpu(resp
->params
.rdeeprom
.bytecount
);
518 memcpy(&pbuf
->value
, (u8
*) & resp
->params
.rdeeprom
.value
,
519 le16_to_cpu(resp
->params
.rdeeprom
.bytecount
));
520 lbs_dbg_hex("adapter", (char *)&pbuf
->value
,
521 le16_to_cpu(resp
->params
.rdeeprom
.bytecount
));
526 static int wlan_ret_get_log(wlan_private
* priv
,
527 struct cmd_ds_command
*resp
)
529 struct cmd_ds_802_11_get_log
*logmessage
= &resp
->params
.glog
;
530 wlan_adapter
*adapter
= priv
->adapter
;
532 lbs_deb_enter(LBS_DEB_CMD
);
534 /* Stored little-endian */
535 memcpy(&adapter
->logmsg
, logmessage
, sizeof(struct cmd_ds_802_11_get_log
));
537 lbs_deb_enter(LBS_DEB_CMD
);
541 static int libertas_ret_802_11_enable_rsn(wlan_private
* priv
,
542 struct cmd_ds_command
*resp
)
544 struct cmd_ds_802_11_enable_rsn
*enable_rsn
= &resp
->params
.enbrsn
;
545 wlan_adapter
*adapter
= priv
->adapter
;
546 u32
* pdata_buf
= adapter
->cur_cmd
->pdata_buf
;
548 lbs_deb_enter(LBS_DEB_CMD
);
550 if (enable_rsn
->action
== cpu_to_le16(cmd_act_get
)) {
552 *pdata_buf
= (u32
) le16_to_cpu(enable_rsn
->enable
);
555 lbs_deb_enter(LBS_DEB_CMD
);
559 static inline int handle_cmd_response(u16 respcmd
,
560 struct cmd_ds_command
*resp
,
565 wlan_adapter
*adapter
= priv
->adapter
;
568 case cmd_ret_mac_reg_access
:
569 case cmd_ret_bbp_reg_access
:
570 case cmd_ret_rf_reg_access
:
571 ret
= wlan_ret_reg_access(priv
, respcmd
, resp
);
574 case cmd_ret_hw_spec_info
:
575 ret
= wlan_ret_get_hw_spec(priv
, resp
);
578 case cmd_ret_802_11_scan
:
579 ret
= libertas_ret_80211_scan(priv
, resp
);
582 case cmd_ret_802_11_get_log
:
583 ret
= wlan_ret_get_log(priv
, resp
);
586 case cmd_ret_802_11_associate
:
587 case cmd_ret_802_11_reassociate
:
588 ret
= libertas_ret_80211_associate(priv
, resp
);
591 case cmd_ret_802_11_disassociate
:
592 case cmd_ret_802_11_deauthenticate
:
593 ret
= libertas_ret_80211_disassociate(priv
, resp
);
596 case cmd_ret_802_11_ad_hoc_start
:
597 case cmd_ret_802_11_ad_hoc_join
:
598 ret
= libertas_ret_80211_ad_hoc_start(priv
, resp
);
601 case cmd_ret_802_11_stat
:
602 ret
= wlan_ret_802_11_stat(priv
, resp
);
605 case cmd_ret_802_11_snmp_mib
:
606 ret
= wlan_ret_802_11_snmp_mib(priv
, resp
);
609 case cmd_ret_802_11_rf_tx_power
:
610 ret
= wlan_ret_802_11_rf_tx_power(priv
, resp
);
613 case cmd_ret_802_11_set_afc
:
614 case cmd_ret_802_11_get_afc
:
615 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
616 memmove(adapter
->cur_cmd
->pdata_buf
, &resp
->params
.afc
,
617 sizeof(struct cmd_ds_802_11_afc
));
618 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
621 case cmd_ret_802_11_rf_antenna
:
622 ret
= wlan_ret_802_11_rf_antenna(priv
, resp
);
625 case cmd_ret_mac_multicast_adr
:
626 case cmd_ret_mac_control
:
627 case cmd_ret_802_11_set_wep
:
628 case cmd_ret_802_11_reset
:
629 case cmd_ret_802_11_authenticate
:
630 case cmd_ret_802_11_radio_control
:
631 case cmd_ret_802_11_beacon_stop
:
634 case cmd_ret_802_11_enable_rsn
:
635 ret
= libertas_ret_802_11_enable_rsn(priv
, resp
);
638 case cmd_ret_802_11_data_rate
:
639 ret
= wlan_ret_802_11_data_rate(priv
, resp
);
641 case cmd_ret_802_11_rate_adapt_rateset
:
642 ret
= wlan_ret_802_11_rate_adapt_rateset(priv
, resp
);
644 case cmd_ret_802_11_rf_channel
:
645 ret
= wlan_ret_802_11_rf_channel(priv
, resp
);
648 case cmd_ret_802_11_rssi
:
649 ret
= wlan_ret_802_11_rssi(priv
, resp
);
652 case cmd_ret_802_11_mac_address
:
653 ret
= wlan_ret_802_11_mac_address(priv
, resp
);
656 case cmd_ret_802_11_ad_hoc_stop
:
657 ret
= libertas_ret_80211_ad_hoc_stop(priv
, resp
);
660 case cmd_ret_802_11_key_material
:
661 lbs_deb_cmd("CMD_RESP: KEY_MATERIAL command response\n");
662 ret
= wlan_ret_802_11_key_material(priv
, resp
);
665 case cmd_ret_802_11_eeprom_access
:
666 ret
= wlan_ret_802_11_eeprom_access(priv
, resp
);
669 case cmd_ret_802_11d_domain_info
:
670 ret
= libertas_ret_802_11d_domain_info(priv
, resp
);
673 case cmd_ret_802_11_sleep_params
:
674 ret
= wlan_ret_802_11_sleep_params(priv
, resp
);
676 case cmd_ret_802_11_inactivity_timeout
:
677 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
678 *((u16
*) adapter
->cur_cmd
->pdata_buf
) =
679 le16_to_cpu(resp
->params
.inactivity_timeout
.timeout
);
680 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
683 case cmd_ret_802_11_tpc_cfg
:
684 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
685 memmove(adapter
->cur_cmd
->pdata_buf
, &resp
->params
.tpccfg
,
686 sizeof(struct cmd_ds_802_11_tpc_cfg
));
687 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
689 case cmd_ret_802_11_led_gpio_ctrl
:
690 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
691 memmove(adapter
->cur_cmd
->pdata_buf
, &resp
->params
.ledgpio
,
692 sizeof(struct cmd_ds_802_11_led_ctrl
));
693 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
695 case cmd_ret_802_11_pwr_cfg
:
696 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
697 memmove(adapter
->cur_cmd
->pdata_buf
, &resp
->params
.pwrcfg
,
698 sizeof(struct cmd_ds_802_11_pwr_cfg
));
699 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
703 case cmd_ret_get_tsf
:
704 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
705 memcpy(priv
->adapter
->cur_cmd
->pdata_buf
,
706 &resp
->params
.gettsf
.tsfvalue
, sizeof(u64
));
707 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
709 case cmd_ret_bt_access
:
710 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
711 if (adapter
->cur_cmd
->pdata_buf
)
712 memcpy(adapter
->cur_cmd
->pdata_buf
,
713 &resp
->params
.bt
.addr1
, 2 * ETH_ALEN
);
714 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
716 case cmd_ret_fwt_access
:
717 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
718 if (adapter
->cur_cmd
->pdata_buf
)
719 memcpy(adapter
->cur_cmd
->pdata_buf
, &resp
->params
.fwt
,
720 sizeof(resp
->params
.fwt
));
721 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
723 case cmd_ret_mesh_access
:
724 if (adapter
->cur_cmd
->pdata_buf
)
725 memcpy(adapter
->cur_cmd
->pdata_buf
, &resp
->params
.mesh
,
726 sizeof(resp
->params
.mesh
));
728 case cmd_rte_802_11_tx_rate_query
:
729 priv
->adapter
->txrate
= resp
->params
.txrate
.txrate
;
732 lbs_deb_cmd("CMD_RESP: Unknown command response %#x\n",
739 int libertas_process_rx_command(wlan_private
* priv
)
742 struct cmd_ds_command
*resp
;
743 wlan_adapter
*adapter
= priv
->adapter
;
748 lbs_deb_enter(LBS_DEB_CMD
);
750 lbs_deb_cmd("CMD_RESP: @ %lu\n", jiffies
);
752 /* Now we got response from FW, cancel the command timer */
753 del_timer(&adapter
->command_timer
);
755 mutex_lock(&adapter
->lock
);
756 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
758 if (!adapter
->cur_cmd
) {
759 lbs_deb_cmd("CMD_RESP: NULL cur_cmd=%p\n", adapter
->cur_cmd
);
761 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
764 resp
= (struct cmd_ds_command
*)(adapter
->cur_cmd
->bufvirtualaddr
);
766 lbs_dbg_hex("CMD_RESP:", adapter
->cur_cmd
->bufvirtualaddr
,
769 respcmd
= le16_to_cpu(resp
->command
);
771 result
= le16_to_cpu(resp
->result
);
773 lbs_deb_cmd("CMD_RESP: %x result: %d length: %d\n", respcmd
,
774 result
, priv
->upld_len
);
776 if (!(respcmd
& 0x8000)) {
777 lbs_deb_cmd("Invalid response to command!");
778 adapter
->cur_cmd_retcode
= -1;
779 __libertas_cleanup_and_insert_cmd(priv
, adapter
->cur_cmd
);
780 adapter
->nr_cmd_pending
--;
781 adapter
->cur_cmd
= NULL
;
782 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
787 /* Store the response code to cur_cmd_retcode. */
788 adapter
->cur_cmd_retcode
= result
;;
790 if (respcmd
== cmd_ret_802_11_ps_mode
) {
791 struct cmd_ds_802_11_ps_mode
*psmode
= &resp
->params
.psmode
;
792 u16 action
= le16_to_cpu(psmode
->action
);
795 "CMD_RESP: PS_MODE cmd reply result=%#x action=0x%X\n",
799 lbs_deb_cmd("CMD_RESP: PS command failed- %#x \n",
802 * We should not re-try enter-ps command in
803 * ad-hoc mode. It takes place in
804 * libertas_execute_next_command().
806 if (adapter
->mode
== IW_MODE_ADHOC
&&
807 action
== cmd_subcmd_enter_ps
)
808 adapter
->psmode
= wlan802_11powermodecam
;
809 } else if (action
== cmd_subcmd_enter_ps
) {
810 adapter
->needtowakeup
= 0;
811 adapter
->psstate
= PS_STATE_AWAKE
;
813 lbs_deb_cmd("CMD_RESP: Enter_PS command response\n");
814 if (adapter
->connect_status
!= libertas_connected
) {
816 * When Deauth Event received before Enter_PS command
817 * response, We need to wake up the firmware.
820 "Disconnected, Going to invoke libertas_ps_wakeup\n");
822 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
823 mutex_unlock(&adapter
->lock
);
824 libertas_ps_wakeup(priv
, 0);
825 mutex_lock(&adapter
->lock
);
826 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
828 } else if (action
== cmd_subcmd_exit_ps
) {
829 adapter
->needtowakeup
= 0;
830 adapter
->psstate
= PS_STATE_FULL_POWER
;
831 lbs_deb_cmd("CMD_RESP: Exit_PS command response\n");
833 lbs_deb_cmd("CMD_RESP: PS- action=0x%X\n", action
);
836 __libertas_cleanup_and_insert_cmd(priv
, adapter
->cur_cmd
);
837 adapter
->nr_cmd_pending
--;
838 adapter
->cur_cmd
= NULL
;
839 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
845 if (adapter
->cur_cmd
->cmdflags
& CMD_F_HOSTCMD
) {
846 /* Copy the response back to response buffer */
847 memcpy(adapter
->cur_cmd
->pdata_buf
, resp
, resp
->size
);
849 adapter
->cur_cmd
->cmdflags
&= ~CMD_F_HOSTCMD
;
852 /* If the command is not successful, cleanup and return failure */
853 if ((result
!= 0 || !(respcmd
& 0x8000))) {
854 lbs_deb_cmd("CMD_RESP: command reply %#x result=%#x\n",
857 * Handling errors here
860 case cmd_ret_hw_spec_info
:
861 case cmd_ret_802_11_reset
:
862 lbs_deb_cmd("CMD_RESP: Reset command failed\n");
867 __libertas_cleanup_and_insert_cmd(priv
, adapter
->cur_cmd
);
868 adapter
->nr_cmd_pending
--;
869 adapter
->cur_cmd
= NULL
;
870 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
876 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
878 ret
= handle_cmd_response(respcmd
, resp
, priv
);
880 spin_lock_irqsave(&adapter
->driver_lock
, flags
);
881 if (adapter
->cur_cmd
) {
882 /* Clean up and Put current command back to cmdfreeq */
883 __libertas_cleanup_and_insert_cmd(priv
, adapter
->cur_cmd
);
884 adapter
->nr_cmd_pending
--;
885 WARN_ON(adapter
->nr_cmd_pending
> 128);
886 adapter
->cur_cmd
= NULL
;
888 spin_unlock_irqrestore(&adapter
->driver_lock
, flags
);
891 mutex_unlock(&adapter
->lock
);
892 lbs_deb_enter_args(LBS_DEB_CMD
, "ret %d", ret
);
896 int libertas_process_event(wlan_private
* priv
)
899 wlan_adapter
*adapter
= priv
->adapter
;
902 spin_lock_irq(&adapter
->driver_lock
);
903 eventcause
= adapter
->eventcause
;
904 spin_unlock_irq(&adapter
->driver_lock
);
906 lbs_deb_enter(LBS_DEB_CMD
);
908 lbs_deb_cmd("EVENT Cause %x\n", eventcause
);
910 switch (eventcause
>> SBI_EVENT_CAUSE_SHIFT
) {
911 case MACREG_INT_CODE_LINK_SENSED
:
912 lbs_deb_cmd("EVENT: MACREG_INT_CODE_LINK_SENSED\n");
915 case MACREG_INT_CODE_DEAUTHENTICATED
:
916 lbs_deb_cmd("EVENT: Deauthenticated\n");
917 libertas_mac_event_disconnected(priv
);
920 case MACREG_INT_CODE_DISASSOCIATED
:
921 lbs_deb_cmd("EVENT: Disassociated\n");
922 libertas_mac_event_disconnected(priv
);
925 case MACREG_INT_CODE_LINK_LOSE_NO_SCAN
:
926 lbs_deb_cmd("EVENT: Link lost\n");
927 libertas_mac_event_disconnected(priv
);
930 case MACREG_INT_CODE_PS_SLEEP
:
931 lbs_deb_cmd("EVENT: SLEEP\n");
934 /* handle unexpected PS SLEEP event */
935 if (adapter
->psstate
== PS_STATE_FULL_POWER
) {
937 "EVENT: In FULL POWER mode - ignore PS SLEEP\n");
940 adapter
->psstate
= PS_STATE_PRE_SLEEP
;
942 libertas_ps_confirm_sleep(priv
, (u16
) adapter
->psmode
);
946 case MACREG_INT_CODE_PS_AWAKE
:
947 lbs_deb_cmd("EVENT: AWAKE \n");
950 /* handle unexpected PS AWAKE event */
951 if (adapter
->psstate
== PS_STATE_FULL_POWER
) {
953 "EVENT: In FULL POWER mode - ignore PS AWAKE\n");
957 adapter
->psstate
= PS_STATE_AWAKE
;
959 if (adapter
->needtowakeup
) {
961 * wait for the command processing to finish
962 * before resuming sending
963 * adapter->needtowakeup will be set to FALSE
964 * in libertas_ps_wakeup()
966 lbs_deb_cmd("Waking up...\n");
967 libertas_ps_wakeup(priv
, 0);
971 case MACREG_INT_CODE_MIC_ERR_UNICAST
:
972 lbs_deb_cmd("EVENT: UNICAST MIC ERROR\n");
973 handle_mic_failureevent(priv
, MACREG_INT_CODE_MIC_ERR_UNICAST
);
976 case MACREG_INT_CODE_MIC_ERR_MULTICAST
:
977 lbs_deb_cmd("EVENT: MULTICAST MIC ERROR\n");
978 handle_mic_failureevent(priv
, MACREG_INT_CODE_MIC_ERR_MULTICAST
);
980 case MACREG_INT_CODE_MIB_CHANGED
:
981 case MACREG_INT_CODE_INIT_DONE
:
984 case MACREG_INT_CODE_ADHOC_BCN_LOST
:
985 lbs_deb_cmd("EVENT: HWAC - ADHOC BCN LOST\n");
988 case MACREG_INT_CODE_RSSI_LOW
:
989 lbs_pr_alert( "EVENT: RSSI_LOW\n");
991 case MACREG_INT_CODE_SNR_LOW
:
992 lbs_pr_alert( "EVENT: SNR_LOW\n");
994 case MACREG_INT_CODE_MAX_FAIL
:
995 lbs_pr_alert( "EVENT: MAX_FAIL\n");
997 case MACREG_INT_CODE_RSSI_HIGH
:
998 lbs_pr_alert( "EVENT: RSSI_HIGH\n");
1000 case MACREG_INT_CODE_SNR_HIGH
:
1001 lbs_pr_alert( "EVENT: SNR_HIGH\n");
1004 case MACREG_INT_CODE_MESH_AUTO_STARTED
:
1005 lbs_pr_alert( "EVENT: MESH_AUTO_STARTED\n");
1006 adapter
->connect_status
= libertas_connected
;
1007 if (priv
->mesh_open
== 1) {
1008 netif_wake_queue(priv
->mesh_dev
) ;
1009 netif_carrier_on(priv
->mesh_dev
) ;
1011 adapter
->mode
= IW_MODE_ADHOC
;
1012 schedule_work(&priv
->sync_channel
);
1016 lbs_pr_alert( "EVENT: unknown event id: %#x\n",
1017 eventcause
>> SBI_EVENT_CAUSE_SHIFT
);
1021 spin_lock_irq(&adapter
->driver_lock
);
1022 adapter
->eventcause
= 0;
1023 spin_unlock_irq(&adapter
->driver_lock
);
1025 lbs_deb_enter_args(LBS_DEB_CMD
, "ret %d", ret
);