aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2007-10-17 20:04:15 -0400
committerJohn W. Linville <linville@tuxdriver.com>2007-10-18 15:56:11 -0400
commitc7c466763d70059ead7ed990e2e9766a0caf9509 (patch)
tree1d9cab3ea20e2d01bfbecd89d73a6828836af515
parent023384faf6a6cb44b5d4a265a7c58279ff810de1 (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>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c42
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c42
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 */
1749static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate, 1749static 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 */
1802static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate, 1802static 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