]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.fixes/iwlwifi-fix-rs_get_rate-oops.patch
Reenabled linux-xen and xen-image build
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.fixes / iwlwifi-fix-rs_get_rate-oops.patch
CommitLineData
00e5a55c
BS
1From: Abbas, Mohamed <mohamed.abbas@intel.com>
2Subject: iwlwifi: fix rs_get_rate WARN_ON()
3Patch-mainline: not yet
4References: bnc#456002
5
6In ieee80211_sta structure there is u64 supp_rates[IEEE80211_NUM_BANDS]
7this is filled with all support rate from assoc_resp. If we associate
8with G-band AP only supp_rates of G-band will be set the other band
9supp_rates will be set to 0. If the user type this command
10this will cause mac80211 to set to new channel, mac80211
11does not disassociate in setting new channel, so the active
12band is now A-band. then in handling the new essid mac80211 will
13kick in the assoc steps which involve sending disassociation frame.
14in this mac80211 will WARN_ON sta->supp_rates[A_BAND] == 0.
15
16This fixes:
17http://www.intellinuxwireless.org/bugzilla/show_bug.cgi?id=1822
18http://www.kerneloops.org/searchweek.php?search=rs_get_rate
19
20Signed-off-by: mohamed abbas <mohamed.abbas@intel.com>
21Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
22Acked-by: Helmut Schaa <hschaa@suse.de>
23Acked-by: Jiri Benc <jbenc@suse.cz>
24
25---
26 drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 11 ++++++++---
27 drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 14 ++++++++++++--
28 2 files changed, 20 insertions(+), 5 deletions(-)
29
30--- linux-2.6.27.orig/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
31+++ linux-2.6.27/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
32@@ -652,7 +652,8 @@ static void rs_get_rate(void *priv_rate,
33 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
34 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
35 struct sta_info *sta;
36- u16 fc, rate_mask;
37+ u16 fc;
38+ u16 rate_mask = 0;
39 struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate;
40 DECLARE_MAC_BUF(mac);
41
42@@ -661,6 +662,8 @@ static void rs_get_rate(void *priv_rate,
43 rcu_read_lock();
44
45 sta = sta_info_get(local, hdr->addr1);
46+ if (sta)
47+ rate_mask = sta->supp_rates[sband->band];
48
49 /* Send management frames and broadcast/multicast data using lowest
50 * rate. */
51@@ -669,12 +672,14 @@ static void rs_get_rate(void *priv_rate,
52 is_multicast_ether_addr(hdr->addr1) ||
53 !sta || !sta->rate_ctrl_priv) {
54 IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
55- sel->rate_idx = rate_lowest_index(local, sband, sta);
56+ if (!rate_mask)
57+ sel->rate_idx = rate_lowest_index(local, sband, NULL);
58+ else
59+ sel->rate_idx = rate_lowest_index(local, sband, sta);
60 rcu_read_unlock();
61 return;
62 }
63
64- rate_mask = sta->supp_rates[sband->band];
65 index = min(sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1);
66
67 if (sband->band == IEEE80211_BAND_5GHZ)
68--- linux-2.6.27.orig/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
69+++ linux-2.6.27/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
70@@ -795,9 +795,12 @@ static void rs_tx_status(void *priv_rate
71 u8 active_index = 0;
72 __le16 fc = hdr->frame_control;
73 s32 tpt = 0;
74+ struct ieee80211_supported_band *sband;
75
76 IWL_DEBUG_RATE_LIMIT("get frame ack response, update rate scale window\n");
77
78+ sband = local->hw.wiphy->bands[info->band];
79+
80 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1))
81 return;
82
83@@ -965,7 +968,8 @@ static void rs_tx_status(void *priv_rate
84 }
85
86 /* See if there's a better rate or modulation mode to try. */
87- rs_rate_scale_perform(priv, dev, hdr, sta);
88+ if(sta && sta->supp_rates[sband->band])
89+ rs_rate_scale_perform(priv, dev, hdr, sta);
90 out:
91 rcu_read_unlock();
92 return;
93@@ -2090,19 +2094,25 @@ static void rs_get_rate(void *priv_rate,
94 __le16 fc;
95 struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
96 struct iwl_lq_sta *lq_sta;
97+ u64 mask_bit = 0;
98
99 IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
100
101 rcu_read_lock();
102
103 sta = sta_info_get(local, hdr->addr1);
104+ if (sta)
105+ mask_bit = sta->supp_rates[sband->band];
106
107 /* Send management frames and broadcast/multicast data using lowest
108 * rate. */
109 fc = hdr->frame_control;
110 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
111 !sta || !sta->rate_ctrl_priv) {
112- sel->rate_idx = rate_lowest_index(local, sband, sta);
113+ if (!mask_bit)
114+ sel->rate_idx = rate_lowest_index(local, sband, NULL);
115+ else
116+ sel->rate_idx = rate_lowest_index(local, sband, sta);
117 goto out;
118 }
119