mwifiex: store mwifiex_ds_misc_subsc_evt in mwifiex_private
authorJeff Disher <disher@chromium.org>
Fri, 31 Aug 2012 01:20:55 +0000 (18:20 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 7 Sep 2012 19:03:44 +0000 (15:03 -0400)
Since mwifiex_ds_misc_subsc_evt is used in an asynchronous case,
store the structure in the long-lived mwifiex_private instead of
on the calling stack.

This fixes a problem where the response of the asynchronous
operation would corrupt a stack frame potentially in use by
a different thread.

Signed-off-by: Jeff Disher <disher@chromium.org>
Reviewed-by: Sam Leffler <sleffler@chromium.org>
Tested-by: Jeff Disher <disher@chromium.org>
Acked-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/sta_cmdresp.c

index ede0c65dcb9649343f25bd46a9010dd144065adf..bb753903259e6ee059ef20507fccb4132ea37f68 100644 (file)
@@ -484,6 +484,7 @@ struct mwifiex_private {
        s32 cqm_rssi_thold;
        u32 cqm_rssi_hyst;
        u8 subsc_evt_rssi_state;
+       struct mwifiex_ds_misc_subsc_evt async_subsc_evt_storage;
        struct mwifiex_ie mgmt_ie[MAX_MGMT_IE_INDEX];
        u16 beacon_idx;
        u16 proberesp_idx;
index 62223ab662ce3386c27ee1cac5bdcd729775ef2c..675c00bbe7d33d5ff15cce5760eb851499e932ee 100644 (file)
@@ -123,7 +123,8 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv,
 {
        struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp =
                                                &resp->params.rssi_info_rsp;
-       struct mwifiex_ds_misc_subsc_evt subsc_evt;
+       struct mwifiex_ds_misc_subsc_evt *subsc_evt =
+                                               &priv->async_subsc_evt_storage;
 
        priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last);
        priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last);
@@ -140,26 +141,27 @@ static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv,
        if (priv->subsc_evt_rssi_state == EVENT_HANDLED)
                return 0;
 
+       memset(subsc_evt, 0x00, sizeof(struct mwifiex_ds_misc_subsc_evt));
+
        /* Resubscribe low and high rssi events with new thresholds */
-       memset(&subsc_evt, 0x00, sizeof(struct mwifiex_ds_misc_subsc_evt));
-       subsc_evt.events = BITMASK_BCN_RSSI_LOW | BITMASK_BCN_RSSI_HIGH;
-       subsc_evt.action = HostCmd_ACT_BITWISE_SET;
+       subsc_evt->events = BITMASK_BCN_RSSI_LOW | BITMASK_BCN_RSSI_HIGH;
+       subsc_evt->action = HostCmd_ACT_BITWISE_SET;
        if (priv->subsc_evt_rssi_state == RSSI_LOW_RECVD) {
-               subsc_evt.bcn_l_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg -
+               subsc_evt->bcn_l_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg -
                                priv->cqm_rssi_hyst);
-               subsc_evt.bcn_h_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold);
+               subsc_evt->bcn_h_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold);
        } else if (priv->subsc_evt_rssi_state == RSSI_HIGH_RECVD) {
-               subsc_evt.bcn_l_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold);
-               subsc_evt.bcn_h_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg +
+               subsc_evt->bcn_l_rssi_cfg.abs_value = abs(priv->cqm_rssi_thold);
+               subsc_evt->bcn_h_rssi_cfg.abs_value = abs(priv->bcn_rssi_avg +
                                priv->cqm_rssi_hyst);
        }
-       subsc_evt.bcn_l_rssi_cfg.evt_freq = 1;
-       subsc_evt.bcn_h_rssi_cfg.evt_freq = 1;
+       subsc_evt->bcn_l_rssi_cfg.evt_freq = 1;
+       subsc_evt->bcn_h_rssi_cfg.evt_freq = 1;
 
        priv->subsc_evt_rssi_state = EVENT_HANDLED;
 
        mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SUBSCRIBE_EVENT,
-                              0, 0, &subsc_evt);
+                              0, 0, subsc_evt);
 
        return 0;
 }