diff options
Diffstat (limited to 'drivers/net/wireless/libertas/cmdresp.c')
-rw-r--r-- | drivers/net/wireless/libertas/cmdresp.c | 138 |
1 files changed, 20 insertions, 118 deletions
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 23f684337fdd..88f7131d66e9 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * This file contains the handling of command | 2 | * This file contains the handling of command |
3 | * responses as well as events generated by firmware. | 3 | * responses as well as events generated by firmware. |
4 | */ | 4 | */ |
5 | #include <linux/slab.h> | ||
5 | #include <linux/delay.h> | 6 | #include <linux/delay.h> |
6 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
7 | #include <linux/if_arp.h> | 8 | #include <linux/if_arp.h> |
@@ -11,6 +12,7 @@ | |||
11 | 12 | ||
12 | #include "host.h" | 13 | #include "host.h" |
13 | #include "decl.h" | 14 | #include "decl.h" |
15 | #include "cmd.h" | ||
14 | #include "defs.h" | 16 | #include "defs.h" |
15 | #include "dev.h" | 17 | #include "dev.h" |
16 | #include "assoc.h" | 18 | #include "assoc.h" |
@@ -26,23 +28,17 @@ | |||
26 | */ | 28 | */ |
27 | void lbs_mac_event_disconnected(struct lbs_private *priv) | 29 | void lbs_mac_event_disconnected(struct lbs_private *priv) |
28 | { | 30 | { |
29 | union iwreq_data wrqu; | ||
30 | |||
31 | if (priv->connect_status != LBS_CONNECTED) | 31 | if (priv->connect_status != LBS_CONNECTED) |
32 | return; | 32 | return; |
33 | 33 | ||
34 | lbs_deb_enter(LBS_DEB_ASSOC); | 34 | lbs_deb_enter(LBS_DEB_ASSOC); |
35 | 35 | ||
36 | memset(wrqu.ap_addr.sa_data, 0x00, ETH_ALEN); | ||
37 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; | ||
38 | |||
39 | /* | 36 | /* |
40 | * Cisco AP sends EAP failure and de-auth in less than 0.5 ms. | 37 | * Cisco AP sends EAP failure and de-auth in less than 0.5 ms. |
41 | * It causes problem in the Supplicant | 38 | * It causes problem in the Supplicant |
42 | */ | 39 | */ |
43 | |||
44 | msleep_interruptible(1000); | 40 | msleep_interruptible(1000); |
45 | wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); | 41 | lbs_send_disconnect_notification(priv); |
46 | 42 | ||
47 | /* report disconnect to upper layer */ | 43 | /* report disconnect to upper layer */ |
48 | netif_stop_queue(priv->dev); | 44 | netif_stop_queue(priv->dev); |
@@ -67,7 +63,7 @@ void lbs_mac_event_disconnected(struct lbs_private *priv) | |||
67 | * no longer valid. | 63 | * no longer valid. |
68 | */ | 64 | */ |
69 | memset(&priv->curbssparams.bssid, 0, ETH_ALEN); | 65 | memset(&priv->curbssparams.bssid, 0, ETH_ALEN); |
70 | memset(&priv->curbssparams.ssid, 0, IW_ESSID_MAX_SIZE); | 66 | memset(&priv->curbssparams.ssid, 0, IEEE80211_MAX_SSID_LEN); |
71 | priv->curbssparams.ssid_len = 0; | 67 | priv->curbssparams.ssid_len = 0; |
72 | 68 | ||
73 | if (priv->psstate != PS_STATE_FULL_POWER) { | 69 | if (priv->psstate != PS_STATE_FULL_POWER) { |
@@ -78,32 +74,6 @@ void lbs_mac_event_disconnected(struct lbs_private *priv) | |||
78 | lbs_deb_leave(LBS_DEB_ASSOC); | 74 | lbs_deb_leave(LBS_DEB_ASSOC); |
79 | } | 75 | } |
80 | 76 | ||
81 | /** | ||
82 | * @brief This function handles MIC failure event. | ||
83 | * | ||
84 | * @param priv A pointer to struct lbs_private structure | ||
85 | * @para event the event id | ||
86 | * @return n/a | ||
87 | */ | ||
88 | static void handle_mic_failureevent(struct lbs_private *priv, u32 event) | ||
89 | { | ||
90 | char buf[50]; | ||
91 | |||
92 | lbs_deb_enter(LBS_DEB_CMD); | ||
93 | memset(buf, 0, sizeof(buf)); | ||
94 | |||
95 | sprintf(buf, "%s", "MLME-MICHAELMICFAILURE.indication "); | ||
96 | |||
97 | if (event == MACREG_INT_CODE_MIC_ERR_UNICAST) { | ||
98 | strcat(buf, "unicast "); | ||
99 | } else { | ||
100 | strcat(buf, "multicast "); | ||
101 | } | ||
102 | |||
103 | lbs_send_iwevcustom_event(priv, buf); | ||
104 | lbs_deb_leave(LBS_DEB_CMD); | ||
105 | } | ||
106 | |||
107 | static int lbs_ret_reg_access(struct lbs_private *priv, | 77 | static int lbs_ret_reg_access(struct lbs_private *priv, |
108 | u16 type, struct cmd_ds_command *resp) | 78 | u16 type, struct cmd_ds_command *resp) |
109 | { | 79 | { |
@@ -147,53 +117,6 @@ static int lbs_ret_reg_access(struct lbs_private *priv, | |||
147 | return ret; | 117 | return ret; |
148 | } | 118 | } |
149 | 119 | ||
150 | static int lbs_ret_802_11_rssi(struct lbs_private *priv, | ||
151 | struct cmd_ds_command *resp) | ||
152 | { | ||
153 | struct cmd_ds_802_11_rssi_rsp *rssirsp = &resp->params.rssirsp; | ||
154 | |||
155 | lbs_deb_enter(LBS_DEB_CMD); | ||
156 | |||
157 | /* store the non average value */ | ||
158 | priv->SNR[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->SNR); | ||
159 | priv->NF[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->noisefloor); | ||
160 | |||
161 | priv->SNR[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgSNR); | ||
162 | priv->NF[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgnoisefloor); | ||
163 | |||
164 | priv->RSSI[TYPE_BEACON][TYPE_NOAVG] = | ||
165 | CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG], | ||
166 | priv->NF[TYPE_BEACON][TYPE_NOAVG]); | ||
167 | |||
168 | priv->RSSI[TYPE_BEACON][TYPE_AVG] = | ||
169 | CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_AVG] / AVG_SCALE, | ||
170 | priv->NF[TYPE_BEACON][TYPE_AVG] / AVG_SCALE); | ||
171 | |||
172 | lbs_deb_cmd("RSSI: beacon %d, avg %d\n", | ||
173 | priv->RSSI[TYPE_BEACON][TYPE_NOAVG], | ||
174 | priv->RSSI[TYPE_BEACON][TYPE_AVG]); | ||
175 | |||
176 | lbs_deb_leave(LBS_DEB_CMD); | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | static int lbs_ret_802_11_bcn_ctrl(struct lbs_private * priv, | ||
181 | struct cmd_ds_command *resp) | ||
182 | { | ||
183 | struct cmd_ds_802_11_beacon_control *bcn_ctrl = | ||
184 | &resp->params.bcn_ctrl; | ||
185 | |||
186 | lbs_deb_enter(LBS_DEB_CMD); | ||
187 | |||
188 | if (bcn_ctrl->action == CMD_ACT_GET) { | ||
189 | priv->beacon_enable = (u8) le16_to_cpu(bcn_ctrl->beacon_enable); | ||
190 | priv->beacon_period = le16_to_cpu(bcn_ctrl->beacon_period); | ||
191 | } | ||
192 | |||
193 | lbs_deb_enter(LBS_DEB_CMD); | ||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | static inline int handle_cmd_response(struct lbs_private *priv, | 120 | static inline int handle_cmd_response(struct lbs_private *priv, |
198 | struct cmd_header *cmd_response) | 121 | struct cmd_header *cmd_response) |
199 | { | 122 | { |
@@ -227,29 +150,13 @@ static inline int handle_cmd_response(struct lbs_private *priv, | |||
227 | ret = lbs_ret_802_11_rssi(priv, resp); | 150 | ret = lbs_ret_802_11_rssi(priv, resp); |
228 | break; | 151 | break; |
229 | 152 | ||
230 | case CMD_RET(CMD_802_11D_DOMAIN_INFO): | ||
231 | ret = lbs_ret_802_11d_domain_info(resp); | ||
232 | break; | ||
233 | |||
234 | case CMD_RET(CMD_802_11_TPC_CFG): | 153 | case CMD_RET(CMD_802_11_TPC_CFG): |
235 | spin_lock_irqsave(&priv->driver_lock, flags); | 154 | spin_lock_irqsave(&priv->driver_lock, flags); |
236 | memmove((void *)priv->cur_cmd->callback_arg, &resp->params.tpccfg, | 155 | memmove((void *)priv->cur_cmd->callback_arg, &resp->params.tpccfg, |
237 | sizeof(struct cmd_ds_802_11_tpc_cfg)); | 156 | sizeof(struct cmd_ds_802_11_tpc_cfg)); |
238 | spin_unlock_irqrestore(&priv->driver_lock, flags); | 157 | spin_unlock_irqrestore(&priv->driver_lock, flags); |
239 | break; | 158 | break; |
240 | case CMD_RET(CMD_802_11_LED_GPIO_CTRL): | ||
241 | spin_lock_irqsave(&priv->driver_lock, flags); | ||
242 | memmove((void *)priv->cur_cmd->callback_arg, &resp->params.ledgpio, | ||
243 | sizeof(struct cmd_ds_802_11_led_ctrl)); | ||
244 | spin_unlock_irqrestore(&priv->driver_lock, flags); | ||
245 | break; | ||
246 | 159 | ||
247 | case CMD_RET(CMD_GET_TSF): | ||
248 | spin_lock_irqsave(&priv->driver_lock, flags); | ||
249 | memcpy((void *)priv->cur_cmd->callback_arg, | ||
250 | &resp->params.gettsf.tsfvalue, sizeof(u64)); | ||
251 | spin_unlock_irqrestore(&priv->driver_lock, flags); | ||
252 | break; | ||
253 | case CMD_RET(CMD_BT_ACCESS): | 160 | case CMD_RET(CMD_BT_ACCESS): |
254 | spin_lock_irqsave(&priv->driver_lock, flags); | 161 | spin_lock_irqsave(&priv->driver_lock, flags); |
255 | if (priv->cur_cmd->callback_arg) | 162 | if (priv->cur_cmd->callback_arg) |
@@ -334,11 +241,6 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len) | |||
334 | /* Now we got response from FW, cancel the command timer */ | 241 | /* Now we got response from FW, cancel the command timer */ |
335 | del_timer(&priv->command_timer); | 242 | del_timer(&priv->command_timer); |
336 | priv->cmd_timed_out = 0; | 243 | priv->cmd_timed_out = 0; |
337 | if (priv->nr_retries) { | ||
338 | lbs_pr_info("Received result %x to command %x after %d retries\n", | ||
339 | result, curcmd, priv->nr_retries); | ||
340 | priv->nr_retries = 0; | ||
341 | } | ||
342 | 244 | ||
343 | /* Store the response code to cur_cmd_retcode. */ | 245 | /* Store the response code to cur_cmd_retcode. */ |
344 | priv->cur_cmd_retcode = result; | 246 | priv->cur_cmd_retcode = result; |
@@ -505,9 +407,21 @@ int lbs_process_event(struct lbs_private *priv, u32 event) | |||
505 | 407 | ||
506 | case MACREG_INT_CODE_HOST_AWAKE: | 408 | case MACREG_INT_CODE_HOST_AWAKE: |
507 | lbs_deb_cmd("EVENT: host awake\n"); | 409 | lbs_deb_cmd("EVENT: host awake\n"); |
410 | if (priv->reset_deep_sleep_wakeup) | ||
411 | priv->reset_deep_sleep_wakeup(priv); | ||
412 | priv->is_deep_sleep = 0; | ||
508 | lbs_send_confirmwake(priv); | 413 | lbs_send_confirmwake(priv); |
509 | break; | 414 | break; |
510 | 415 | ||
416 | case MACREG_INT_CODE_DEEP_SLEEP_AWAKE: | ||
417 | if (priv->reset_deep_sleep_wakeup) | ||
418 | priv->reset_deep_sleep_wakeup(priv); | ||
419 | lbs_deb_cmd("EVENT: ds awake\n"); | ||
420 | priv->is_deep_sleep = 0; | ||
421 | priv->wakeup_dev_required = 0; | ||
422 | wake_up_interruptible(&priv->ds_awake_q); | ||
423 | break; | ||
424 | |||
511 | case MACREG_INT_CODE_PS_AWAKE: | 425 | case MACREG_INT_CODE_PS_AWAKE: |
512 | lbs_deb_cmd("EVENT: ps awake\n"); | 426 | lbs_deb_cmd("EVENT: ps awake\n"); |
513 | /* handle unexpected PS AWAKE event */ | 427 | /* handle unexpected PS AWAKE event */ |
@@ -533,12 +447,12 @@ int lbs_process_event(struct lbs_private *priv, u32 event) | |||
533 | 447 | ||
534 | case MACREG_INT_CODE_MIC_ERR_UNICAST: | 448 | case MACREG_INT_CODE_MIC_ERR_UNICAST: |
535 | lbs_deb_cmd("EVENT: UNICAST MIC ERROR\n"); | 449 | lbs_deb_cmd("EVENT: UNICAST MIC ERROR\n"); |
536 | handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_UNICAST); | 450 | lbs_send_mic_failureevent(priv, event); |
537 | break; | 451 | break; |
538 | 452 | ||
539 | case MACREG_INT_CODE_MIC_ERR_MULTICAST: | 453 | case MACREG_INT_CODE_MIC_ERR_MULTICAST: |
540 | lbs_deb_cmd("EVENT: MULTICAST MIC ERROR\n"); | 454 | lbs_deb_cmd("EVENT: MULTICAST MIC ERROR\n"); |
541 | handle_mic_failureevent(priv, MACREG_INT_CODE_MIC_ERR_MULTICAST); | 455 | lbs_send_mic_failureevent(priv, event); |
542 | break; | 456 | break; |
543 | 457 | ||
544 | case MACREG_INT_CODE_MIB_CHANGED: | 458 | case MACREG_INT_CODE_MIB_CHANGED: |
@@ -567,20 +481,8 @@ int lbs_process_event(struct lbs_private *priv, u32 event) | |||
567 | break; | 481 | break; |
568 | 482 | ||
569 | case MACREG_INT_CODE_MESH_AUTO_STARTED: | 483 | case MACREG_INT_CODE_MESH_AUTO_STARTED: |
570 | /* Ignore spurious autostart events if autostart is disabled */ | 484 | /* Ignore spurious autostart events */ |
571 | if (!priv->mesh_autostart_enabled) { | 485 | lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n"); |
572 | lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n"); | ||
573 | break; | ||
574 | } | ||
575 | lbs_pr_info("EVENT: MESH_AUTO_STARTED\n"); | ||
576 | priv->mesh_connect_status = LBS_CONNECTED; | ||
577 | if (priv->mesh_open) { | ||
578 | netif_carrier_on(priv->mesh_dev); | ||
579 | if (!priv->tx_pending_len) | ||
580 | netif_wake_queue(priv->mesh_dev); | ||
581 | } | ||
582 | priv->mode = IW_MODE_ADHOC; | ||
583 | schedule_work(&priv->sync_channel); | ||
584 | break; | 486 | break; |
585 | 487 | ||
586 | default: | 488 | default: |