aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/cmdresp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/libertas/cmdresp.c')
-rw-r--r--drivers/net/wireless/libertas/cmdresp.c138
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 */
27void lbs_mac_event_disconnected(struct lbs_private *priv) 29void 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 */
88static 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
107static int lbs_ret_reg_access(struct lbs_private *priv, 77static 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
150static 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
180static 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
197static inline int handle_cmd_response(struct lbs_private *priv, 120static 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: