mac80211: fix channel context related warnings when using wds ap mode (fixes #12585)
authorFelix Fietkau <nbd@openwrt.org>
Mon, 10 Dec 2012 18:29:17 +0000 (18:29 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Mon, 10 Dec 2012 18:29:17 +0000 (18:29 +0000)
SVN-Revision: 34610

package/mac80211/patches/300-pending_work.patch
package/mac80211/patches/310-ap_scan.patch
package/mac80211/patches/513-mac80211_reduce_txqueuelen.patch
package/mac80211/patches/520-mac80211_cur_txpower.patch
package/mac80211/patches/523-mac80211_configure_antenna_gain.patch
package/mac80211/patches/530-ath9k_extra_leds.patch
package/mac80211/patches/540-mac80211_optimize_mcs_rate_mask.patch

index f90ae21..9905a57 100644 (file)
        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);
  
  
        /*
         * 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;
  }
  
  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;
                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);
index 958c7fd..8177310 100644 (file)
@@ -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)
                 */
index 0b1caa7..bb72e8e 100644 (file)
@@ -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);
index 48ded53..cc049f7 100644 (file)
@@ -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);
  
index e1f17ff..844d453 100644 (file)
  };
  
  /* 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;
 +
 +              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,
index bd428d0..9435122 100644 (file)
  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 */
index a80a46f..adf8e1b 100644 (file)
@@ -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++) {