diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2008-05-27 10:50:51 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-06-03 15:00:16 -0400 |
commit | 747cf5e924a469a15a454b88a813236460b30975 (patch) | |
tree | 561ebdf183e01b54bce155e4ab5998f7e21b3d8f | |
parent | 20ad4fd56255b455beb677dc097eb108d15f1d63 (diff) |
mac80211: fix ieee80211_get_buffered_bc
fix bss not initialized in ieee80211_get_buffered_bc
and unbalanced locking
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | net/mac80211/tx.c | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index dac44cbd036f..16af30811f98 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1947,7 +1947,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
1947 | struct ieee80211_vif *vif) | 1947 | struct ieee80211_vif *vif) |
1948 | { | 1948 | { |
1949 | struct ieee80211_local *local = hw_to_local(hw); | 1949 | struct ieee80211_local *local = hw_to_local(hw); |
1950 | struct sk_buff *skb; | 1950 | struct sk_buff *skb = NULL; |
1951 | struct sta_info *sta; | 1951 | struct sta_info *sta; |
1952 | ieee80211_tx_handler *handler; | 1952 | ieee80211_tx_handler *handler; |
1953 | struct ieee80211_tx_data tx; | 1953 | struct ieee80211_tx_data tx; |
@@ -1960,7 +1960,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
1960 | 1960 | ||
1961 | sdata = vif_to_sdata(vif); | 1961 | sdata = vif_to_sdata(vif); |
1962 | bdev = sdata->dev; | 1962 | bdev = sdata->dev; |
1963 | 1963 | bss = &sdata->u.ap; | |
1964 | 1964 | ||
1965 | if (!bss) | 1965 | if (!bss) |
1966 | return NULL; | 1966 | return NULL; |
@@ -1968,19 +1968,16 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
1968 | rcu_read_lock(); | 1968 | rcu_read_lock(); |
1969 | beacon = rcu_dereference(bss->beacon); | 1969 | beacon = rcu_dereference(bss->beacon); |
1970 | 1970 | ||
1971 | if (sdata->vif.type != IEEE80211_IF_TYPE_AP || !beacon || | 1971 | if (sdata->vif.type != IEEE80211_IF_TYPE_AP || !beacon || !beacon->head) |
1972 | !beacon->head) { | 1972 | goto out; |
1973 | rcu_read_unlock(); | ||
1974 | return NULL; | ||
1975 | } | ||
1976 | 1973 | ||
1977 | if (bss->dtim_count != 0) | 1974 | if (bss->dtim_count != 0) |
1978 | return NULL; /* send buffered bc/mc only after DTIM beacon */ | 1975 | goto out; /* send buffered bc/mc only after DTIM beacon */ |
1979 | 1976 | ||
1980 | while (1) { | 1977 | while (1) { |
1981 | skb = skb_dequeue(&bss->ps_bc_buf); | 1978 | skb = skb_dequeue(&bss->ps_bc_buf); |
1982 | if (!skb) | 1979 | if (!skb) |
1983 | return NULL; | 1980 | goto out; |
1984 | local->total_ps_buffered--; | 1981 | local->total_ps_buffered--; |
1985 | 1982 | ||
1986 | if (!skb_queue_empty(&bss->ps_bc_buf) && skb->len >= 2) { | 1983 | if (!skb_queue_empty(&bss->ps_bc_buf) && skb->len >= 2) { |
@@ -2023,6 +2020,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
2023 | skb = NULL; | 2020 | skb = NULL; |
2024 | } | 2021 | } |
2025 | 2022 | ||
2023 | out: | ||
2026 | rcu_read_unlock(); | 2024 | rcu_read_unlock(); |
2027 | 2025 | ||
2028 | return skb; | 2026 | return skb; |