From 3d534485d14551d757a1527ff2d2ce49b84f71d6 Mon Sep 17 00:00:00 2001 From: nbd Date: Mon, 10 Dec 2012 18:29:17 +0000 Subject: mac80211: fix channel context related warnings when using wds ap mode (fixes #12585) git-svn-id: svn://svn.openwrt.org/openwrt/trunk@34610 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/mac80211/patches/300-pending_work.patch | 142 +++++++++++++++++++++++- 1 file changed, 138 insertions(+), 4 deletions(-) (limited to 'package/mac80211/patches/300-pending_work.patch') diff --git a/package/mac80211/patches/300-pending_work.patch b/package/mac80211/patches/300-pending_work.patch index f90ae21b6f..9905a57d54 100644 --- a/package/mac80211/patches/300-pending_work.patch +++ b/package/mac80211/patches/300-pending_work.patch @@ -119,15 +119,36 @@ ieee80211_bss_info_change_notify(sdata, bss_change); --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c -@@ -510,7 +510,6 @@ int ieee80211_do_open(struct wireless_de +@@ -508,9 +508,9 @@ static void ieee80211_del_virtual_monito + int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) + { struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); ++ struct ieee80211_sub_if_data *ap_sdata; struct net_device *dev = wdev->netdev; struct ieee80211_local *local = sdata->local; - struct sta_info *sta; u32 changed = 0; int res; u32 hw_reconf_flags = 0; -@@ -665,30 +664,8 @@ int ieee80211_do_open(struct wireless_de +@@ -587,10 +587,14 @@ int ieee80211_do_open(struct wireless_de + switch (sdata->vif.type) { + case NL80211_IFTYPE_AP_VLAN: + /* no need to tell driver, but set carrier */ +- if (rtnl_dereference(sdata->bss->beacon)) +- netif_carrier_on(dev); +- else ++ if (!rtnl_dereference(sdata->bss->beacon)) { + netif_carrier_off(dev); ++ break; ++ } ++ ++ ap_sdata = get_bss_sdata(sdata); ++ ieee80211_vif_copy_channel(sdata, ap_sdata); ++ netif_carrier_on(dev); + break; + case NL80211_IFTYPE_MONITOR: + if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) { +@@ -665,30 +669,8 @@ int ieee80211_do_open(struct wireless_de set_bit(SDATA_STATE_RUNNING, &sdata->state); @@ -159,7 +180,16 @@ /* * set_multicast_list will be invoked by the networking core -@@ -1072,6 +1049,72 @@ static void ieee80211_if_setup(struct ne +@@ -844,6 +826,8 @@ static void ieee80211_do_stop(struct iee + switch (sdata->vif.type) { + case NL80211_IFTYPE_AP_VLAN: + list_del(&sdata->u.vlan.list); ++ netif_carrier_off(sdata->dev); ++ ieee80211_vif_release_channel(sdata); + /* no need to tell driver */ + break; + case NL80211_IFTYPE_MONITOR: +@@ -1072,6 +1056,72 @@ static void ieee80211_if_setup(struct ne dev->destructor = free_netdev; } @@ -232,7 +262,7 @@ static void ieee80211_iface_work(struct work_struct *work) { struct ieee80211_sub_if_data *sdata = -@@ -1176,6 +1219,9 @@ static void ieee80211_iface_work(struct +@@ -1176,6 +1226,9 @@ static void ieee80211_iface_work(struct break; ieee80211_mesh_rx_queued_mgmt(sdata, skb); break; @@ -692,3 +722,107 @@ err = 0; goto out; } +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -915,6 +915,12 @@ static int ieee80211_start_ap(struct wip + if (err) + return err; + ++ list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { ++ err = ieee80211_vif_copy_channel(vlan, sdata); ++ if (err) ++ return err; ++ } ++ + /* + * Apply control port protocol, this allows us to + * not encrypt dynamic WEP control frames. +@@ -998,8 +1004,11 @@ static int ieee80211_stop_ap(struct wiph + old_probe_resp = rtnl_dereference(sdata->u.ap.probe_resp); + + /* turn off carrier for this interface and dependent VLANs */ +- list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) ++ list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { ++ sta_info_flush(local, vlan); + netif_carrier_off(vlan->dev); ++ ieee80211_vif_release_channel(vlan); ++ } + netif_carrier_off(dev); + + /* remove beacon and probe response */ +--- a/net/mac80211/chan.c ++++ b/net/mac80211/chan.c +@@ -119,14 +119,17 @@ static int ieee80211_assign_vif_chanctx( + + lockdep_assert_held(&local->chanctx_mtx); + +- ret = drv_assign_vif_chanctx(local, sdata, ctx); +- if (ret) +- return ret; ++ if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN) { ++ ret = drv_assign_vif_chanctx(local, sdata, ctx); ++ if (ret) ++ return ret; ++ } + + rcu_assign_pointer(sdata->vif.chanctx_conf, &ctx->conf); + ctx->refcount++; + +- ieee80211_recalc_txpower(sdata); ++ if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN) ++ ieee80211_recalc_txpower(sdata); + + return 0; + } +@@ -174,7 +177,8 @@ static void ieee80211_unassign_vif_chanc + ctx->refcount--; + rcu_assign_pointer(sdata->vif.chanctx_conf, NULL); + +- drv_unassign_vif_chanctx(local, sdata, ctx); ++ if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN) ++ drv_unassign_vif_chanctx(local, sdata, ctx); + + if (ctx->refcount > 0) { + ieee80211_recalc_chanctx_chantype(sdata->local, ctx); +@@ -285,6 +289,30 @@ void ieee80211_recalc_smps_chanctx(struc + drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS); + } + ++int ieee80211_vif_copy_channel(struct ieee80211_sub_if_data *sdata, ++ struct ieee80211_sub_if_data *parent) ++{ ++ struct ieee80211_local *local = sdata->local; ++ struct ieee80211_chanctx_conf *conf; ++ struct ieee80211_chanctx *ctx; ++ ++ int ret; ++ ++ mutex_lock(&local->chanctx_mtx); ++ conf = rcu_dereference_protected(parent->vif.chanctx_conf, ++ lockdep_is_held(&local->chanctx_mtx)); ++ if (!conf) { ++ ret = -ENOENT; ++ goto out; ++ } ++ ++ ctx = container_of(conf, struct ieee80211_chanctx, conf); ++ ret = ieee80211_assign_vif_chanctx(sdata, ctx); ++out: ++ mutex_unlock(&local->chanctx_mtx); ++ return ret; ++} ++ + int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, + const struct cfg80211_chan_def *chandef, + enum ieee80211_chanctx_mode mode) +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1633,6 +1633,8 @@ ieee80211_vif_use_channel(struct ieee802 + const struct cfg80211_chan_def *chandef, + enum ieee80211_chanctx_mode mode); + void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); ++int ieee80211_vif_copy_channel(struct ieee80211_sub_if_data *sdata, ++ struct ieee80211_sub_if_data *parent); + + void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, + struct ieee80211_chanctx *chanctx); -- cgit v1.2.3