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
master
Felix Fietkau 2012-12-10 18:29:17 +00:00
parent c88dfafb1e
commit 722553af77
7 changed files with 149 additions and 15 deletions

View File

@ -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);

View 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)
*/

View 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);

View 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);

View File

@ -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,

View File

@ -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 */

View 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++) {