aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis R. Rodriguez <mcgrof@do-not-panic.com>2012-12-19 13:53:02 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-01-03 07:01:37 -0500
commit3ebfa6e76beab01e644e1facd5fdb84d4274043e (patch)
tree7324fb5171326d8ce0af3eb22c2d50a9f5531573
parentad2d223aa900179031feb40273881e212941573d (diff)
cfg80211: do not process beacon hints if one is already queued
Regulatory beacon hints are used to help with world roaming and as it is right now we learn from a beacon hint processed on one wiphy to all other wiphys. The processing of beacon hints however is scheduled and if we have a lot of interfaces we may hit the case that we'll queue a the same beacon hint many times until its processed. To avoid this do a lookup on the queued up beacon hints prior to adding a new beacon hint. If the beacon hint is removed from the pending reg beacon hint list then it would be processed and we'd ensure all wiphys would have learned from it, if its on the pending reg beacon list we'd now find it prior to it being processed. Tested-by: Ben Greear <greearb@candelatech.com> Reported-by: Ben Greear <greearb@candelatech.com> Reported-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Luis R. Rodriguez <mcgrof@do-not-panic.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/wireless/reg.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index fd53d975c0bc..2a3ae4d1001d 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1925,11 +1925,23 @@ static bool freq_is_chan_12_13_14(u16 freq)
1925 return false; 1925 return false;
1926} 1926}
1927 1927
1928static bool pending_reg_beacon(struct ieee80211_channel *beacon_chan)
1929{
1930 struct reg_beacon *pending_beacon;
1931
1932 list_for_each_entry(pending_beacon, &reg_pending_beacons, list)
1933 if (beacon_chan->center_freq ==
1934 pending_beacon->chan.center_freq)
1935 return true;
1936 return false;
1937}
1938
1928int regulatory_hint_found_beacon(struct wiphy *wiphy, 1939int regulatory_hint_found_beacon(struct wiphy *wiphy,
1929 struct ieee80211_channel *beacon_chan, 1940 struct ieee80211_channel *beacon_chan,
1930 gfp_t gfp) 1941 gfp_t gfp)
1931{ 1942{
1932 struct reg_beacon *reg_beacon; 1943 struct reg_beacon *reg_beacon;
1944 bool processing;
1933 1945
1934 if (beacon_chan->beacon_found || 1946 if (beacon_chan->beacon_found ||
1935 beacon_chan->flags & IEEE80211_CHAN_RADAR || 1947 beacon_chan->flags & IEEE80211_CHAN_RADAR ||
@@ -1937,6 +1949,13 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy,
1937 !freq_is_chan_12_13_14(beacon_chan->center_freq))) 1949 !freq_is_chan_12_13_14(beacon_chan->center_freq)))
1938 return 0; 1950 return 0;
1939 1951
1952 spin_lock_bh(&reg_pending_beacons_lock);
1953 processing = pending_reg_beacon(beacon_chan);
1954 spin_unlock_bh(&reg_pending_beacons_lock);
1955
1956 if (processing)
1957 return 0;
1958
1940 reg_beacon = kzalloc(sizeof(struct reg_beacon), gfp); 1959 reg_beacon = kzalloc(sizeof(struct reg_beacon), gfp);
1941 if (!reg_beacon) 1960 if (!reg_beacon)
1942 return -ENOMEM; 1961 return -ENOMEM;