aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2013-03-01 13:52:03 -0500
committerJohn W. Linville <linville@tuxdriver.com>2013-03-01 13:52:03 -0500
commit98b7ff9a4977e4f4f451c30288b197ad79e5ab7f (patch)
treeb0aae5739f08a2c3fd822e2b86dd1a369fd2e0a2 /net
parent32fcafbcd1c9f6c7013016a22a5369b4acb93577 (diff)
parent466026989f112e0546ca39ab00a759af82dbe83a (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c12
-rw-r--r--net/mac80211/iface.c2
-rw-r--r--net/mac80211/tx.c77
-rw-r--r--net/wireless/nl80211.c61
4 files changed, 62 insertions, 90 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 09d96a8f6c2c..808f5fcd1ced 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -3285,13 +3285,19 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
3285 struct cfg80211_chan_def *chandef) 3285 struct cfg80211_chan_def *chandef)
3286{ 3286{
3287 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); 3287 struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
3288 struct ieee80211_local *local = wiphy_priv(wiphy);
3288 struct ieee80211_chanctx_conf *chanctx_conf; 3289 struct ieee80211_chanctx_conf *chanctx_conf;
3289 int ret = -ENODATA; 3290 int ret = -ENODATA;
3290 3291
3291 rcu_read_lock(); 3292 rcu_read_lock();
3292 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); 3293 if (local->use_chanctx) {
3293 if (chanctx_conf) { 3294 chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
3294 *chandef = chanctx_conf->def; 3295 if (chanctx_conf) {
3296 *chandef = chanctx_conf->def;
3297 ret = 0;
3298 }
3299 } else if (local->open_count == local->monitors) {
3300 *chandef = local->monitor_chandef;
3295 ret = 0; 3301 ret = 0;
3296 } 3302 }
3297 rcu_read_unlock(); 3303 rcu_read_unlock();
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 2c059e54e885..640afab304d7 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -107,7 +107,7 @@ void ieee80211_recalc_idle(struct ieee80211_local *local)
107 107
108 lockdep_assert_held(&local->mtx); 108 lockdep_assert_held(&local->mtx);
109 109
110 active = !list_empty(&local->chanctx_list); 110 active = !list_empty(&local->chanctx_list) || local->monitors;
111 111
112 if (!local->ops->remain_on_channel) { 112 if (!local->ops->remain_on_channel) {
113 list_for_each_entry(roc, &local->roc_list, list) { 113 list_for_each_entry(roc, &local->roc_list, list) {
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 5b9602b62405..c592a413bad9 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1231,34 +1231,40 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local,
1231 if (local->queue_stop_reasons[q] || 1231 if (local->queue_stop_reasons[q] ||
1232 (!txpending && !skb_queue_empty(&local->pending[q]))) { 1232 (!txpending && !skb_queue_empty(&local->pending[q]))) {
1233 if (unlikely(info->flags & 1233 if (unlikely(info->flags &
1234 IEEE80211_TX_INTFL_OFFCHAN_TX_OK && 1234 IEEE80211_TX_INTFL_OFFCHAN_TX_OK)) {
1235 local->queue_stop_reasons[q] & 1235 if (local->queue_stop_reasons[q] &
1236 ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL))) { 1236 ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL)) {
1237 /*
1238 * Drop off-channel frames if queues
1239 * are stopped for any reason other
1240 * than off-channel operation. Never
1241 * queue them.
1242 */
1243 spin_unlock_irqrestore(
1244 &local->queue_stop_reason_lock,
1245 flags);
1246 ieee80211_purge_tx_queue(&local->hw,
1247 skbs);
1248 return true;
1249 }
1250 } else {
1251
1237 /* 1252 /*
1238 * Drop off-channel frames if queues are stopped 1253 * Since queue is stopped, queue up frames for
1239 * for any reason other than off-channel 1254 * later transmission from the tx-pending
1240 * operation. Never queue them. 1255 * tasklet when the queue is woken again.
1241 */ 1256 */
1242 spin_unlock_irqrestore( 1257 if (txpending)
1243 &local->queue_stop_reason_lock, flags); 1258 skb_queue_splice_init(skbs,
1244 ieee80211_purge_tx_queue(&local->hw, skbs); 1259 &local->pending[q]);
1245 return true; 1260 else
1261 skb_queue_splice_tail_init(skbs,
1262 &local->pending[q]);
1263
1264 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
1265 flags);
1266 return false;
1246 } 1267 }
1247
1248 /*
1249 * Since queue is stopped, queue up frames for later
1250 * transmission from the tx-pending tasklet when the
1251 * queue is woken again.
1252 */
1253 if (txpending)
1254 skb_queue_splice_init(skbs, &local->pending[q]);
1255 else
1256 skb_queue_splice_tail_init(skbs,
1257 &local->pending[q]);
1258
1259 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
1260 flags);
1261 return false;
1262 } 1268 }
1263 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 1269 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
1264 1270
@@ -1844,9 +1850,24 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1844 } 1850 }
1845 1851
1846 if (!is_multicast_ether_addr(skb->data)) { 1852 if (!is_multicast_ether_addr(skb->data)) {
1853 struct sta_info *next_hop;
1854 bool mpp_lookup = true;
1855
1847 mpath = mesh_path_lookup(sdata, skb->data); 1856 mpath = mesh_path_lookup(sdata, skb->data);
1848 if (!mpath) 1857 if (mpath) {
1858 mpp_lookup = false;
1859 next_hop = rcu_dereference(mpath->next_hop);
1860 if (!next_hop ||
1861 !(mpath->flags & (MESH_PATH_ACTIVE |
1862 MESH_PATH_RESOLVING)))
1863 mpp_lookup = true;
1864 }
1865
1866 if (mpp_lookup)
1849 mppath = mpp_path_lookup(sdata, skb->data); 1867 mppath = mpp_path_lookup(sdata, skb->data);
1868
1869 if (mppath && mpath)
1870 mesh_path_del(mpath->sdata, mpath->dst);
1850 } 1871 }
1851 1872
1852 /* 1873 /*
@@ -2360,9 +2381,9 @@ static int ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,
2360 if (local->tim_in_locked_section) { 2381 if (local->tim_in_locked_section) {
2361 __ieee80211_beacon_add_tim(sdata, ps, skb); 2382 __ieee80211_beacon_add_tim(sdata, ps, skb);
2362 } else { 2383 } else {
2363 spin_lock(&local->tim_lock); 2384 spin_lock_bh(&local->tim_lock);
2364 __ieee80211_beacon_add_tim(sdata, ps, skb); 2385 __ieee80211_beacon_add_tim(sdata, ps, skb);
2365 spin_unlock(&local->tim_lock); 2386 spin_unlock_bh(&local->tim_lock);
2366 } 2387 }
2367 2388
2368 return 0; 2389 return 0;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 35545ccc30fd..e652d05ff712 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -554,16 +554,9 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
554 if ((chan->flags & IEEE80211_CHAN_NO_IBSS) && 554 if ((chan->flags & IEEE80211_CHAN_NO_IBSS) &&
555 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS)) 555 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS))
556 goto nla_put_failure; 556 goto nla_put_failure;
557 if (chan->flags & IEEE80211_CHAN_RADAR) { 557 if ((chan->flags & IEEE80211_CHAN_RADAR) &&
558 u32 time = elapsed_jiffies_msecs(chan->dfs_state_entered); 558 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR))
559 if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR)) 559 goto nla_put_failure;
560 goto nla_put_failure;
561 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE,
562 chan->dfs_state))
563 goto nla_put_failure;
564 if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME, time))
565 goto nla_put_failure;
566 }
567 if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) && 560 if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) &&
568 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS)) 561 nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS))
569 goto nla_put_failure; 562 goto nla_put_failure;
@@ -900,9 +893,6 @@ static int nl80211_put_iface_combinations(struct wiphy *wiphy,
900 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM, 893 nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM,
901 c->max_interfaces)) 894 c->max_interfaces))
902 goto nla_put_failure; 895 goto nla_put_failure;
903 if (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
904 c->radar_detect_widths))
905 goto nla_put_failure;
906 896
907 nla_nest_end(msg, nl_combi); 897 nla_nest_end(msg, nl_combi);
908 } 898 }
@@ -914,48 +904,6 @@ nla_put_failure:
914 return -ENOBUFS; 904 return -ENOBUFS;
915} 905}
916 906
917#ifdef CONFIG_PM
918static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev,
919 struct sk_buff *msg)
920{
921 const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan.tcp;
922 struct nlattr *nl_tcp;
923
924 if (!tcp)
925 return 0;
926
927 nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION);
928 if (!nl_tcp)
929 return -ENOBUFS;
930
931 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
932 tcp->data_payload_max))
933 return -ENOBUFS;
934
935 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD,
936 tcp->data_payload_max))
937 return -ENOBUFS;
938
939 if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ))
940 return -ENOBUFS;
941
942 if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN,
943 sizeof(*tcp->tok), tcp->tok))
944 return -ENOBUFS;
945
946 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL,
947 tcp->data_interval_max))
948 return -ENOBUFS;
949
950 if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD,
951 tcp->wake_payload_max))
952 return -ENOBUFS;
953
954 nla_nest_end(msg, nl_tcp);
955 return 0;
956}
957#endif
958
959static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flags, 907static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flags,
960 struct cfg80211_registered_device *dev) 908 struct cfg80211_registered_device *dev)
961{ 909{
@@ -1330,9 +1278,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag
1330 goto nla_put_failure; 1278 goto nla_put_failure;
1331 } 1279 }
1332 1280
1333 if (nl80211_send_wowlan_tcp_caps(dev, msg))
1334 goto nla_put_failure;
1335
1336 nla_nest_end(msg, nl_wowlan); 1281 nla_nest_end(msg, nl_wowlan);
1337 } 1282 }
1338#endif 1283#endif