aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r--net/mac80211/tx.c48
1 files changed, 26 insertions, 22 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 33e314f3aab7..80f4343a3007 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -327,10 +327,8 @@ static void purge_old_ps_buffers(struct ieee80211_local *local)
327 } 327 }
328 total += skb_queue_len(&ap->ps_bc_buf); 328 total += skb_queue_len(&ap->ps_bc_buf);
329 } 329 }
330 rcu_read_unlock();
331 330
332 read_lock_bh(&local->sta_lock); 331 list_for_each_entry_rcu(sta, &local->sta_list, list) {
333 list_for_each_entry(sta, &local->sta_list, list) {
334 skb = skb_dequeue(&sta->ps_tx_buf); 332 skb = skb_dequeue(&sta->ps_tx_buf);
335 if (skb) { 333 if (skb) {
336 purged++; 334 purged++;
@@ -338,7 +336,8 @@ static void purge_old_ps_buffers(struct ieee80211_local *local)
338 } 336 }
339 total += skb_queue_len(&sta->ps_tx_buf); 337 total += skb_queue_len(&sta->ps_tx_buf);
340 } 338 }
341 read_unlock_bh(&local->sta_lock); 339
340 rcu_read_unlock();
342 341
343 local->total_ps_buffered = total; 342 local->total_ps_buffered = total;
344 printk(KERN_DEBUG "%s: PS buffers full - purged %d frames\n", 343 printk(KERN_DEBUG "%s: PS buffers full - purged %d frames\n",
@@ -1141,20 +1140,17 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1141 return 0; 1140 return 0;
1142 } 1141 }
1143 1142
1143 rcu_read_lock();
1144
1144 /* initialises tx */ 1145 /* initialises tx */
1145 res_prepare = __ieee80211_tx_prepare(&tx, skb, dev, control); 1146 res_prepare = __ieee80211_tx_prepare(&tx, skb, dev, control);
1146 1147
1147 if (res_prepare == TX_DROP) { 1148 if (res_prepare == TX_DROP) {
1148 dev_kfree_skb(skb); 1149 dev_kfree_skb(skb);
1150 rcu_read_unlock();
1149 return 0; 1151 return 0;
1150 } 1152 }
1151 1153
1152 /*
1153 * key references are protected using RCU and this requires that
1154 * we are in a read-site RCU section during receive processing
1155 */
1156 rcu_read_lock();
1157
1158 sta = tx.sta; 1154 sta = tx.sta;
1159 tx.channel = local->hw.conf.channel; 1155 tx.channel = local->hw.conf.channel;
1160 1156
@@ -1167,9 +1163,6 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1167 1163
1168 skb = tx.skb; /* handlers are allowed to change skb */ 1164 skb = tx.skb; /* handlers are allowed to change skb */
1169 1165
1170 if (sta)
1171 sta_info_put(sta);
1172
1173 if (unlikely(res == TX_DROP)) { 1166 if (unlikely(res == TX_DROP)) {
1174 I802_DEBUG_INC(local->tx_handlers_drop); 1167 I802_DEBUG_INC(local->tx_handlers_drop);
1175 goto drop; 1168 goto drop;
@@ -1489,11 +1482,11 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1489 * in AP mode) 1482 * in AP mode)
1490 */ 1483 */
1491 if (!is_multicast_ether_addr(hdr.addr1)) { 1484 if (!is_multicast_ether_addr(hdr.addr1)) {
1485 rcu_read_lock();
1492 sta = sta_info_get(local, hdr.addr1); 1486 sta = sta_info_get(local, hdr.addr1);
1493 if (sta) { 1487 if (sta)
1494 sta_flags = sta->flags; 1488 sta_flags = sta->flags;
1495 sta_info_put(sta); 1489 rcu_read_unlock();
1496 }
1497 } 1490 }
1498 1491
1499 /* receiver is QoS enabled, use a QoS type frame */ 1492 /* receiver is QoS enabled, use a QoS type frame */
@@ -1722,7 +1715,6 @@ static void ieee80211_beacon_add_tim(struct ieee80211_local *local,
1722 1715
1723 /* Generate bitmap for TIM only if there are any STAs in power save 1716 /* Generate bitmap for TIM only if there are any STAs in power save
1724 * mode. */ 1717 * mode. */
1725 read_lock_bh(&local->sta_lock);
1726 if (atomic_read(&bss->num_sta_ps) > 0) 1718 if (atomic_read(&bss->num_sta_ps) > 0)
1727 /* in the hope that this is faster than 1719 /* in the hope that this is faster than
1728 * checking byte-for-byte */ 1720 * checking byte-for-byte */
@@ -1773,7 +1765,6 @@ static void ieee80211_beacon_add_tim(struct ieee80211_local *local,
1773 *pos++ = aid0; /* Bitmap control */ 1765 *pos++ = aid0; /* Bitmap control */
1774 *pos++ = 0; /* Part Virt Bitmap */ 1766 *pos++ = 0; /* Part Virt Bitmap */
1775 } 1767 }
1776 read_unlock_bh(&local->sta_lock);
1777} 1768}
1778 1769
1779struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, 1770struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
@@ -1821,7 +1812,22 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1821 ieee80211_include_sequence(sdata, 1812 ieee80211_include_sequence(sdata,
1822 (struct ieee80211_hdr *)skb->data); 1813 (struct ieee80211_hdr *)skb->data);
1823 1814
1824 ieee80211_beacon_add_tim(local, ap, skb, beacon); 1815 /*
1816 * Not very nice, but we want to allow the driver to call
1817 * ieee80211_beacon_get() as a response to the set_tim()
1818 * callback. That, however, is already invoked under the
1819 * sta_lock to guarantee consistent and race-free update
1820 * of the tim bitmap in mac80211 and the driver.
1821 */
1822 if (local->tim_in_locked_section) {
1823 ieee80211_beacon_add_tim(local, ap, skb, beacon);
1824 } else {
1825 unsigned long flags;
1826
1827 spin_lock_irqsave(&local->sta_lock, flags);
1828 ieee80211_beacon_add_tim(local, ap, skb, beacon);
1829 spin_unlock_irqrestore(&local->sta_lock, flags);
1830 }
1825 1831
1826 if (beacon->tail) 1832 if (beacon->tail)
1827 memcpy(skb_put(skb, beacon->tail_len), 1833 memcpy(skb_put(skb, beacon->tail_len),
@@ -1965,7 +1971,6 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
1965 rcu_read_unlock(); 1971 rcu_read_unlock();
1966 return NULL; 1972 return NULL;
1967 } 1973 }
1968 rcu_read_unlock();
1969 1974
1970 if (bss->dtim_count != 0) 1975 if (bss->dtim_count != 0)
1971 return NULL; /* send buffered bc/mc only after DTIM beacon */ 1976 return NULL; /* send buffered bc/mc only after DTIM beacon */
@@ -2010,8 +2015,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
2010 skb = NULL; 2015 skb = NULL;
2011 } 2016 }
2012 2017
2013 if (sta) 2018 rcu_read_unlock();
2014 sta_info_put(sta);
2015 2019
2016 return skb; 2020 return skb;
2017} 2021}