iwlwifi: fix scan_cmd_size allocation
authorDavid Spinadel <david.spinadel@intel.com>
Fri, 11 May 2012 08:53:15 +0000 (10:53 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 16 May 2012 17:08:17 +0000 (13:08 -0400)
Allocate scan command with dynamic size based on uCode capability
and num of channels.
This isn't an important fix as the previous allocation was always
too large as it added the scan command size but later subtracted
it (which meant it was supposed to be part of the max scan size.)

Signed-off-by: David Spinadel <david.spinadel@intel.com>
Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-scan.c

index 2813a0a89ed65c6654ffc3efb7b27429a96140e8..9af6a239b3843d0081dcc0fd7498d66258dbce5f 100644 (file)
@@ -2278,7 +2278,6 @@ struct iwl_ssid_ie {
 #define IWL_GOOD_CRC_TH_DISABLED       0
 #define IWL_GOOD_CRC_TH_DEFAULT                cpu_to_le16(1)
 #define IWL_GOOD_CRC_TH_NEVER          cpu_to_le16(0xffff)
-#define IWL_MAX_SCAN_SIZE 1024
 #define IWL_MAX_CMD_SIZE 4096
 
 /*
index a8437a6bc18e41d83d36e7208c166e28d56f0da4..6f221de5a76a31e953669168a4cad334368823e6 100644 (file)
@@ -52,6 +52,7 @@
 #define IWL_PASSIVE_DWELL_TIME_52   (10)
 #define IWL_PASSIVE_DWELL_BASE      (100)
 #define IWL_CHANNEL_TUNE_TIME       5
+#define MAX_SCAN_CHANNEL           50
 
 static int iwl_send_scan_abort(struct iwl_priv *priv)
 {
@@ -679,6 +680,13 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        u8 active_chains;
        u8 scan_tx_antennas = priv->hw_params.valid_tx_ant;
        int ret;
+       int scan_cmd_size = sizeof(struct iwl_scan_cmd) +
+                           MAX_SCAN_CHANNEL * sizeof(struct iwl_scan_channel) +
+                           priv->fw->ucode_capa.max_probe_length;
+
+       if (WARN_ON_ONCE(priv->scan_request &&
+                        priv->scan_request->n_channels > MAX_SCAN_CHANNEL))
+               return -EINVAL;
 
        lockdep_assert_held(&priv->mutex);
 
@@ -686,8 +694,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
                ctx = iwl_rxon_ctx_from_vif(vif);
 
        if (!priv->scan_cmd) {
-               priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) +
-                                        IWL_MAX_SCAN_SIZE, GFP_KERNEL);
+               priv->scan_cmd = kmalloc(scan_cmd_size, GFP_KERNEL);
                if (!priv->scan_cmd) {
                        IWL_DEBUG_SCAN(priv,
                                       "fail to allocate memory for scan\n");
@@ -695,7 +702,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
                }
        }
        scan = priv->scan_cmd;
-       memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);
+       memset(scan, 0, scan_cmd_size);
 
        scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
        scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
@@ -883,7 +890,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
                                        vif->addr,
                                        priv->scan_request->ie,
                                        priv->scan_request->ie_len,
-                                       IWL_MAX_SCAN_SIZE - sizeof(*scan));
+                                       scan_cmd_size - sizeof(*scan));
                break;
        case IWL_SCAN_RADIO_RESET:
        case IWL_SCAN_ROC:
@@ -891,7 +898,7 @@ static int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
                cmd_len = iwl_fill_probe_req(
                                        (struct ieee80211_mgmt *)scan->data,
                                        iwl_bcast_addr, NULL, 0,
-                                       IWL_MAX_SCAN_SIZE - sizeof(*scan));
+                                       scan_cmd_size - sizeof(*scan));
                break;
        default:
                BUG();