From: Felix Fietkau <nbd@openwrt.org>
Date: Mon, 10 Dec 2012 18:29:17 +0000 (+0000)
Subject: mac80211: fix channel context related warnings when using wds ap mode (fixes #12585)
X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=b8757c644f02ae75e23bfd231682453d5a75f30f;p=openwrt%2Fstaging%2Fthess.git

mac80211: fix channel context related warnings when using wds ap mode (fixes #12585)

SVN-Revision: 34610
---

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);
diff --git a/package/mac80211/patches/310-ap_scan.patch b/package/mac80211/patches/310-ap_scan.patch
index 958c7fd20b..8177310564 100644
--- a/package/mac80211/patches/310-ap_scan.patch
+++ b/package/mac80211/patches/310-ap_scan.patch
@@ -1,6 +1,6 @@
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -1916,7 +1916,7 @@ static int ieee80211_scan(struct wiphy *
+@@ -1925,7 +1925,7 @@ static int ieee80211_scan(struct wiphy *
  		 * the  frames sent while scanning on other channel will be
  		 * lost)
  		 */
diff --git a/package/mac80211/patches/513-mac80211_reduce_txqueuelen.patch b/package/mac80211/patches/513-mac80211_reduce_txqueuelen.patch
index 0b1caa769c..bb72e8e2d4 100644
--- a/package/mac80211/patches/513-mac80211_reduce_txqueuelen.patch
+++ b/package/mac80211/patches/513-mac80211_reduce_txqueuelen.patch
@@ -1,6 +1,6 @@
 --- a/net/mac80211/iface.c
 +++ b/net/mac80211/iface.c
-@@ -1039,6 +1039,7 @@ static const struct net_device_ops ieee8
+@@ -1046,6 +1046,7 @@ static const struct net_device_ops ieee8
  static void ieee80211_if_setup(struct net_device *dev)
  {
  	ether_setup(dev);
diff --git a/package/mac80211/patches/520-mac80211_cur_txpower.patch b/package/mac80211/patches/520-mac80211_cur_txpower.patch
index 48ded53dd8..cc049f7c99 100644
--- a/package/mac80211/patches/520-mac80211_cur_txpower.patch
+++ b/package/mac80211/patches/520-mac80211_cur_txpower.patch
@@ -10,7 +10,7 @@
  };
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -2096,7 +2096,9 @@ static int ieee80211_get_tx_power(struct
+@@ -2105,7 +2105,9 @@ static int ieee80211_get_tx_power(struct
  	struct ieee80211_local *local = wiphy_priv(wiphy);
  	struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
  
diff --git a/package/mac80211/patches/523-mac80211_configure_antenna_gain.patch b/package/mac80211/patches/523-mac80211_configure_antenna_gain.patch
index e1f17ff1d1..844d4537b4 100644
--- a/package/mac80211/patches/523-mac80211_configure_antenna_gain.patch
+++ b/package/mac80211/patches/523-mac80211_configure_antenna_gain.patch
@@ -47,11 +47,10 @@
  };
  
  /* policy for the key attributes */
-@@ -1651,6 +1652,22 @@ static int nl80211_set_wiphy(struct sk_b
- 		if (result)
+@@ -1652,6 +1653,22 @@ static int nl80211_set_wiphy(struct sk_b
  			goto bad_res;
  	}
-+
+ 
 +	if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_GAIN]) {
 +		int idx, dbi = 0;
 +
@@ -67,12 +66,13 @@
 +		if (result)
 +			goto bad_res;
 +	}
- 
++
  	if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
  	    info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
+ 		u32 tx_ant, rx_ant;
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -2118,6 +2118,19 @@ static int ieee80211_get_tx_power(struct
+@@ -2127,6 +2127,19 @@ static int ieee80211_get_tx_power(struct
  	return 0;
  }
  
@@ -92,7 +92,7 @@
  static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
  				  const u8 *addr)
  {
-@@ -3241,6 +3254,7 @@ struct cfg80211_ops mac80211_config_ops
+@@ -3250,6 +3263,7 @@ struct cfg80211_ops mac80211_config_ops 
  	.set_wiphy_params = ieee80211_set_wiphy_params,
  	.set_tx_power = ieee80211_set_tx_power,
  	.get_tx_power = ieee80211_get_tx_power,
diff --git a/package/mac80211/patches/530-ath9k_extra_leds.patch b/package/mac80211/patches/530-ath9k_extra_leds.patch
index bd428d0b23..9435122484 100644
--- a/package/mac80211/patches/530-ath9k_extra_leds.patch
+++ b/package/mac80211/patches/530-ath9k_extra_leds.patch
@@ -162,7 +162,7 @@
  void ath_fill_led_pin(struct ath_softc *sc)
 --- a/drivers/net/wireless/ath/ath9k/init.c
 +++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -878,7 +878,7 @@ int ath9k_init_device(u16 devid, struct
+@@ -878,7 +878,7 @@ int ath9k_init_device(u16 devid, struct 
  
  #ifdef CONFIG_MAC80211_LEDS
  	/* must be initialized before ieee80211_register_hw */
diff --git a/package/mac80211/patches/540-mac80211_optimize_mcs_rate_mask.patch b/package/mac80211/patches/540-mac80211_optimize_mcs_rate_mask.patch
index a80a46f014..adf8e1b721 100644
--- a/package/mac80211/patches/540-mac80211_optimize_mcs_rate_mask.patch
+++ b/package/mac80211/patches/540-mac80211_optimize_mcs_rate_mask.patch
@@ -11,7 +11,7 @@
  	union {
 --- a/net/mac80211/cfg.c
 +++ b/net/mac80211/cfg.c
-@@ -2291,9 +2291,20 @@ static int ieee80211_set_bitrate_mask(st
+@@ -2300,9 +2300,20 @@ static int ieee80211_set_bitrate_mask(st
  	}
  
  	for (i = 0; i < IEEE80211_NUM_BANDS; i++) {