forked from Minki/linux
[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>
This commit is contained in:
parent
023384faf6
commit
c7c466763d
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user