diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2007-10-18 02:04:15 +0200 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2007-10-18 15:56:11 -0400 |
commit | c7c466763d70059ead7ed990e2e9766a0caf9509 (patch) | |
tree | 1d9cab3ea20e2d01bfbecd89d73a6828836af515 /drivers | |
parent | 023384faf6a6cb44b5d4a265a7c58279ff810de1 (diff) | |
download | op-kernel-dev-c7c466763d70059ead7ed990e2e9766a0caf9509.zip op-kernel-dev-c7c466763d70059ead7ed990e2e9766a0caf9509.tar.gz |
[PATCH] iwlwifi: Fix rate setting in probe request for HW sacn
This patch fixes setting of rates in probe request used in
HW scan. The bug was reported by Helmut Schaa <hschaa@suse.de>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 42 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 42 |
2 files changed, 52 insertions, 32 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index a1d2716..83019d1 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -1747,21 +1747,22 @@ static void iwl_unset_hw_setting(struct iwl_priv *priv) * return : set the bit for each supported rate insert in ie */ static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate, - u16 basic_rate, int max_count) + u16 basic_rate, int *left) { u16 ret_rates = 0, bit; int i; - u8 *rates; - - rates = &(ie[1]); + u8 *cnt = ie; + u8 *rates = ie + 1; for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) { if (bit & supported_rate) { ret_rates |= bit; - rates[*ie] = iwl_rates[i].ieee | - ((bit & basic_rate) ? 0x80 : 0x00); - *ie = *ie + 1; - if (*ie >= max_count) + rates[*cnt] = iwl_rates[i].ieee | + ((bit & basic_rate) ? 0x80 : 0x00); + (*cnt)++; + (*left)--; + if ((*left <= 0) || + (*cnt >= IWL_SUPPORTED_RATES_IE_LEN)) break; } } @@ -1778,7 +1779,7 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, { int len = 0; u8 *pos = NULL; - u16 ret_rates; + u16 active_rates, ret_rates, cck_rates; /* Make sure there is enough space for the probe request, * two mandatory IEs and the data */ @@ -1823,19 +1824,27 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, left -= 2; if (left < 0) return 0; + /* ... fill it in... */ *pos++ = WLAN_EID_SUPP_RATES; *pos = 0; - ret_rates = priv->active_rate = priv->rates_mask; + + priv->active_rate = priv->rates_mask; + active_rates = priv->active_rate; priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; - iwl_supported_rate_to_ie(pos, priv->active_rate, - priv->active_rate_basic, left); + cck_rates = IWL_CCK_RATES_MASK & active_rates; + ret_rates = iwl_supported_rate_to_ie(pos, cck_rates, + priv->active_rate_basic, &left); + active_rates &= ~ret_rates; + + ret_rates = iwl_supported_rate_to_ie(pos, active_rates, + priv->active_rate_basic, &left); + active_rates &= ~ret_rates; + len += 2 + *pos; pos += (*pos) + 1; - ret_rates = ~ret_rates & priv->active_rate; - - if (ret_rates == 0) + if (active_rates == 0) goto fill_end; /* fill in supported extended rate */ @@ -1846,7 +1855,8 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, /* ... fill it in... */ *pos++ = WLAN_EID_EXT_SUPP_RATES; *pos = 0; - iwl_supported_rate_to_ie(pos, ret_rates, priv->active_rate_basic, left); + iwl_supported_rate_to_ie(pos, active_rates, + priv->active_rate_basic, &left); if (*pos > 0) len += 2 + *pos; diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index acdf550..5e12792 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c @@ -1800,21 +1800,22 @@ static void iwl_unset_hw_setting(struct iwl_priv *priv) * return : set the bit for each supported rate insert in ie */ static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate, - u16 basic_rate, int max_count) + u16 basic_rate, int *left) { u16 ret_rates = 0, bit; int i; - u8 *rates; - - rates = &(ie[1]); + u8 *cnt = ie; + u8 *rates = ie + 1; for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) { if (bit & supported_rate) { ret_rates |= bit; - rates[*ie] = iwl_rates[i].ieee | - ((bit & basic_rate) ? 0x80 : 0x00); - *ie = *ie + 1; - if (*ie >= max_count) + rates[*cnt] = iwl_rates[i].ieee | + ((bit & basic_rate) ? 0x80 : 0x00); + (*cnt)++; + (*left)--; + if ((*left <= 0) || + (*cnt >= IWL_SUPPORTED_RATES_IE_LEN)) break; } } @@ -1837,7 +1838,7 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, { int len = 0; u8 *pos = NULL; - u16 ret_rates; + u16 active_rates, ret_rates, cck_rates; /* Make sure there is enough space for the probe request, * two mandatory IEs and the data */ @@ -1882,19 +1883,27 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, left -= 2; if (left < 0) return 0; + /* ... fill it in... */ *pos++ = WLAN_EID_SUPP_RATES; *pos = 0; - ret_rates = priv->active_rate = priv->rates_mask; + + priv->active_rate = priv->rates_mask; + active_rates = priv->active_rate; priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; - iwl_supported_rate_to_ie(pos, priv->active_rate, - priv->active_rate_basic, left); + cck_rates = IWL_CCK_RATES_MASK & active_rates; + ret_rates = iwl_supported_rate_to_ie(pos, cck_rates, + priv->active_rate_basic, &left); + active_rates &= ~ret_rates; + + ret_rates = iwl_supported_rate_to_ie(pos, active_rates, + priv->active_rate_basic, &left); + active_rates &= ~ret_rates; + len += 2 + *pos; pos += (*pos) + 1; - ret_rates = ~ret_rates & priv->active_rate; - - if (ret_rates == 0) + if (active_rates == 0) goto fill_end; /* fill in supported extended rate */ @@ -1905,7 +1914,8 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, /* ... fill it in... */ *pos++ = WLAN_EID_EXT_SUPP_RATES; *pos = 0; - iwl_supported_rate_to_ie(pos, ret_rates, priv->active_rate_basic, left); + iwl_supported_rate_to_ie(pos, active_rates, + priv->active_rate_basic, &left); if (*pos > 0) len += 2 + *pos; |