diff options
| author | Tomas Winkler <tomas.winkler@intel.com> | 2007-10-17 20:04:15 -0400 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2007-10-18 15:56:11 -0400 |
| commit | c7c466763d70059ead7ed990e2e9766a0caf9509 (patch) | |
| tree | 1d9cab3ea20e2d01bfbecd89d73a6828836af515 /drivers/net | |
| parent | 023384faf6a6cb44b5d4a265a7c58279ff810de1 (diff) | |
[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/net')
| -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 a1d2716556be..83019d1d7ccc 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) | |||
| 1747 | * return : set the bit for each supported rate insert in ie | 1747 | * return : set the bit for each supported rate insert in ie |
| 1748 | */ | 1748 | */ |
| 1749 | static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate, | 1749 | static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate, |
| 1750 | u16 basic_rate, int max_count) | 1750 | u16 basic_rate, int *left) |
| 1751 | { | 1751 | { |
| 1752 | u16 ret_rates = 0, bit; | 1752 | u16 ret_rates = 0, bit; |
| 1753 | int i; | 1753 | int i; |
| 1754 | u8 *rates; | 1754 | u8 *cnt = ie; |
| 1755 | 1755 | u8 *rates = ie + 1; | |
| 1756 | rates = &(ie[1]); | ||
| 1757 | 1756 | ||
| 1758 | for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) { | 1757 | for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) { |
| 1759 | if (bit & supported_rate) { | 1758 | if (bit & supported_rate) { |
| 1760 | ret_rates |= bit; | 1759 | ret_rates |= bit; |
| 1761 | rates[*ie] = iwl_rates[i].ieee | | 1760 | rates[*cnt] = iwl_rates[i].ieee | |
| 1762 | ((bit & basic_rate) ? 0x80 : 0x00); | 1761 | ((bit & basic_rate) ? 0x80 : 0x00); |
| 1763 | *ie = *ie + 1; | 1762 | (*cnt)++; |
| 1764 | if (*ie >= max_count) | 1763 | (*left)--; |
| 1764 | if ((*left <= 0) || | ||
| 1765 | (*cnt >= IWL_SUPPORTED_RATES_IE_LEN)) | ||
| 1765 | break; | 1766 | break; |
| 1766 | } | 1767 | } |
| 1767 | } | 1768 | } |
| @@ -1778,7 +1779,7 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, | |||
| 1778 | { | 1779 | { |
| 1779 | int len = 0; | 1780 | int len = 0; |
| 1780 | u8 *pos = NULL; | 1781 | u8 *pos = NULL; |
| 1781 | u16 ret_rates; | 1782 | u16 active_rates, ret_rates, cck_rates; |
| 1782 | 1783 | ||
| 1783 | /* Make sure there is enough space for the probe request, | 1784 | /* Make sure there is enough space for the probe request, |
| 1784 | * two mandatory IEs and the data */ | 1785 | * two mandatory IEs and the data */ |
| @@ -1823,19 +1824,27 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, | |||
| 1823 | left -= 2; | 1824 | left -= 2; |
| 1824 | if (left < 0) | 1825 | if (left < 0) |
| 1825 | return 0; | 1826 | return 0; |
| 1827 | |||
| 1826 | /* ... fill it in... */ | 1828 | /* ... fill it in... */ |
| 1827 | *pos++ = WLAN_EID_SUPP_RATES; | 1829 | *pos++ = WLAN_EID_SUPP_RATES; |
| 1828 | *pos = 0; | 1830 | *pos = 0; |
| 1829 | ret_rates = priv->active_rate = priv->rates_mask; | 1831 | |
| 1832 | priv->active_rate = priv->rates_mask; | ||
| 1833 | active_rates = priv->active_rate; | ||
| 1830 | priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; | 1834 | priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; |
| 1831 | 1835 | ||
| 1832 | iwl_supported_rate_to_ie(pos, priv->active_rate, | 1836 | cck_rates = IWL_CCK_RATES_MASK & active_rates; |
| 1833 | priv->active_rate_basic, left); | 1837 | ret_rates = iwl_supported_rate_to_ie(pos, cck_rates, |
| 1838 | priv->active_rate_basic, &left); | ||
| 1839 | active_rates &= ~ret_rates; | ||
| 1840 | |||
| 1841 | ret_rates = iwl_supported_rate_to_ie(pos, active_rates, | ||
| 1842 | priv->active_rate_basic, &left); | ||
| 1843 | active_rates &= ~ret_rates; | ||
| 1844 | |||
| 1834 | len += 2 + *pos; | 1845 | len += 2 + *pos; |
| 1835 | pos += (*pos) + 1; | 1846 | pos += (*pos) + 1; |
| 1836 | ret_rates = ~ret_rates & priv->active_rate; | 1847 | if (active_rates == 0) |
| 1837 | |||
| 1838 | if (ret_rates == 0) | ||
| 1839 | goto fill_end; | 1848 | goto fill_end; |
| 1840 | 1849 | ||
| 1841 | /* fill in supported extended rate */ | 1850 | /* fill in supported extended rate */ |
| @@ -1846,7 +1855,8 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, | |||
| 1846 | /* ... fill it in... */ | 1855 | /* ... fill it in... */ |
| 1847 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | 1856 | *pos++ = WLAN_EID_EXT_SUPP_RATES; |
| 1848 | *pos = 0; | 1857 | *pos = 0; |
| 1849 | iwl_supported_rate_to_ie(pos, ret_rates, priv->active_rate_basic, left); | 1858 | iwl_supported_rate_to_ie(pos, active_rates, |
| 1859 | priv->active_rate_basic, &left); | ||
| 1850 | if (*pos > 0) | 1860 | if (*pos > 0) |
| 1851 | len += 2 + *pos; | 1861 | len += 2 + *pos; |
| 1852 | 1862 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index acdf5507d3d0..5e1279263b22 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) | |||
| 1800 | * return : set the bit for each supported rate insert in ie | 1800 | * return : set the bit for each supported rate insert in ie |
| 1801 | */ | 1801 | */ |
| 1802 | static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate, | 1802 | static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate, |
| 1803 | u16 basic_rate, int max_count) | 1803 | u16 basic_rate, int *left) |
| 1804 | { | 1804 | { |
| 1805 | u16 ret_rates = 0, bit; | 1805 | u16 ret_rates = 0, bit; |
| 1806 | int i; | 1806 | int i; |
| 1807 | u8 *rates; | 1807 | u8 *cnt = ie; |
| 1808 | 1808 | u8 *rates = ie + 1; | |
| 1809 | rates = &(ie[1]); | ||
| 1810 | 1809 | ||
| 1811 | for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) { | 1810 | for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) { |
| 1812 | if (bit & supported_rate) { | 1811 | if (bit & supported_rate) { |
| 1813 | ret_rates |= bit; | 1812 | ret_rates |= bit; |
| 1814 | rates[*ie] = iwl_rates[i].ieee | | 1813 | rates[*cnt] = iwl_rates[i].ieee | |
| 1815 | ((bit & basic_rate) ? 0x80 : 0x00); | 1814 | ((bit & basic_rate) ? 0x80 : 0x00); |
| 1816 | *ie = *ie + 1; | 1815 | (*cnt)++; |
| 1817 | if (*ie >= max_count) | 1816 | (*left)--; |
| 1817 | if ((*left <= 0) || | ||
| 1818 | (*cnt >= IWL_SUPPORTED_RATES_IE_LEN)) | ||
| 1818 | break; | 1819 | break; |
| 1819 | } | 1820 | } |
| 1820 | } | 1821 | } |
| @@ -1837,7 +1838,7 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, | |||
| 1837 | { | 1838 | { |
| 1838 | int len = 0; | 1839 | int len = 0; |
| 1839 | u8 *pos = NULL; | 1840 | u8 *pos = NULL; |
| 1840 | u16 ret_rates; | 1841 | u16 active_rates, ret_rates, cck_rates; |
| 1841 | 1842 | ||
| 1842 | /* Make sure there is enough space for the probe request, | 1843 | /* Make sure there is enough space for the probe request, |
| 1843 | * two mandatory IEs and the data */ | 1844 | * two mandatory IEs and the data */ |
| @@ -1882,19 +1883,27 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, | |||
| 1882 | left -= 2; | 1883 | left -= 2; |
| 1883 | if (left < 0) | 1884 | if (left < 0) |
| 1884 | return 0; | 1885 | return 0; |
| 1886 | |||
| 1885 | /* ... fill it in... */ | 1887 | /* ... fill it in... */ |
| 1886 | *pos++ = WLAN_EID_SUPP_RATES; | 1888 | *pos++ = WLAN_EID_SUPP_RATES; |
| 1887 | *pos = 0; | 1889 | *pos = 0; |
| 1888 | ret_rates = priv->active_rate = priv->rates_mask; | 1890 | |
| 1891 | priv->active_rate = priv->rates_mask; | ||
| 1892 | active_rates = priv->active_rate; | ||
| 1889 | priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; | 1893 | priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK; |
| 1890 | 1894 | ||
| 1891 | iwl_supported_rate_to_ie(pos, priv->active_rate, | 1895 | cck_rates = IWL_CCK_RATES_MASK & active_rates; |
| 1892 | priv->active_rate_basic, left); | 1896 | ret_rates = iwl_supported_rate_to_ie(pos, cck_rates, |
| 1897 | priv->active_rate_basic, &left); | ||
| 1898 | active_rates &= ~ret_rates; | ||
| 1899 | |||
| 1900 | ret_rates = iwl_supported_rate_to_ie(pos, active_rates, | ||
| 1901 | priv->active_rate_basic, &left); | ||
| 1902 | active_rates &= ~ret_rates; | ||
| 1903 | |||
| 1893 | len += 2 + *pos; | 1904 | len += 2 + *pos; |
| 1894 | pos += (*pos) + 1; | 1905 | pos += (*pos) + 1; |
| 1895 | ret_rates = ~ret_rates & priv->active_rate; | 1906 | if (active_rates == 0) |
| 1896 | |||
| 1897 | if (ret_rates == 0) | ||
| 1898 | goto fill_end; | 1907 | goto fill_end; |
| 1899 | 1908 | ||
| 1900 | /* fill in supported extended rate */ | 1909 | /* fill in supported extended rate */ |
| @@ -1905,7 +1914,8 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv, | |||
| 1905 | /* ... fill it in... */ | 1914 | /* ... fill it in... */ |
| 1906 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | 1915 | *pos++ = WLAN_EID_EXT_SUPP_RATES; |
| 1907 | *pos = 0; | 1916 | *pos = 0; |
| 1908 | iwl_supported_rate_to_ie(pos, ret_rates, priv->active_rate_basic, left); | 1917 | iwl_supported_rate_to_ie(pos, active_rates, |
| 1918 | priv->active_rate_basic, &left); | ||
| 1909 | if (*pos > 0) | 1919 | if (*pos > 0) |
| 1910 | len += 2 + *pos; | 1920 | len += 2 + *pos; |
| 1911 | 1921 | ||
