2012-10-24 10:12:50

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 0/4] multi-channel/interface TX power handling

This was the remaining work I had to do in mac80211, but it
got a little larger because cfg80211 wasn't doing per-vif
TX power ...

I disallowed setting TX power per hardware now, we could in
theory do something like set all interfaces in that case, but
it seemed like a lot of work for very little gain. If someone
needs it, we can do it later :-)

johannes



2012-10-24 23:05:25

by Kelly Hogan

[permalink] [raw]
Subject: Is Multi-Vif (vaps) Different Channel Operation Supported?

Hi All,

We are utilizing current ath9k and mac80211 and are trying to discern if multi-channel support is possible on different Vifs, on the same phy.

Example:

Two Vifs running as masters, controlled via hostapd
One Vif running as a Station, controlled by wpa_supplicant
One Vif running as a mesh vap

We can run all the Vifs fine, but it appears that with shared hostapd/wpa_supplicant control files, that the master Vifs always have to follow the channel that the station is connected to. The mesh vap also seems to require being on the same channel of the station.

Any info on if this is supported, or what order to process creation, channel setting, etc to get them to simultaneously allow different channel support would be helpful, or save us the time of assuming that it can be done if it in fact can't.

TIA!

2012-10-24 10:12:52

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 3/4] mac80211: handle TX power per virtual interface

From: Johannes Berg <[email protected]>

Even before channel contexts/multi-channel, having a
single global TX power limit was already problematic,
in particular if two managed interfaces connected to
two APs with different power constraints. The channel
context introduction completely broke this though and
in fact I had disabled TX power tracking there (for
drivers using channel contexts.)

Change everything to track TX power per interface so
that different user settings and different channel
maxima are treated correctly.

Signed-off-by: Johannes Berg <[email protected]>
---
include/net/mac80211.h | 7 ++++++-
net/mac80211/cfg.c | 27 +++++++++------------------
net/mac80211/chan.c | 2 ++
net/mac80211/debugfs.c | 3 ---
net/mac80211/debugfs_netdev.c | 6 ++++++
net/mac80211/ieee80211_i.h | 11 ++++++++---
net/mac80211/iface.c | 38 ++++++++++++++++++++++++++++++++++++++
net/mac80211/main.c | 23 +++++++++++++----------
net/mac80211/mlme.c | 32 +++++++++++++++++---------------
net/mac80211/trace.h | 2 ++
net/mac80211/util.c | 3 ++-
11 files changed, 103 insertions(+), 51 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 00b7204..9318c66 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -207,6 +207,7 @@ struct ieee80211_chanctx_conf {
* @BSS_CHANGED_SSID: SSID changed for this BSS (AP mode)
* @BSS_CHANGED_AP_PROBE_RESP: Probe Response changed for this BSS (AP mode)
* @BSS_CHANGED_PS: PS changed for this BSS (STA mode)
+ * @BSS_CHANGED_TXPOWER: TX power setting changed for this interface
*/
enum ieee80211_bss_change {
BSS_CHANGED_ASSOC = 1<<0,
@@ -227,6 +228,7 @@ enum ieee80211_bss_change {
BSS_CHANGED_SSID = 1<<15,
BSS_CHANGED_AP_PROBE_RESP = 1<<16,
BSS_CHANGED_PS = 1<<17,
+ BSS_CHANGED_TXPOWER = 1<<18,

/* when adding here, make sure to change ieee80211_reconfig */
};
@@ -309,6 +311,7 @@ enum ieee80211_rssi_event {
* @ssid: The SSID of the current vif. Only valid in AP-mode.
* @ssid_len: Length of SSID given in @ssid.
* @hidden_ssid: The SSID of the current vif is hidden. Only valid in AP-mode.
+ * @txpower: TX power in dBm
*/
struct ieee80211_bss_conf {
const u8 *bssid;
@@ -341,6 +344,7 @@ struct ieee80211_bss_conf {
u8 ssid[IEEE80211_MAX_SSID_LEN];
size_t ssid_len;
bool hidden_ssid;
+ int txpower;
};

/**
@@ -884,7 +888,8 @@ enum ieee80211_smps_mode {
* powersave documentation below. This variable is valid only when
* the CONF_PS flag is set.
*
- * @power_level: requested transmit power (in dBm)
+ * @power_level: requested transmit power (in dBm), backward compatibility
+ * value only that is set to the minimum of all interfaces
*
* @channel: the channel to tune to
* @channel_type: the channel (HT) type
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 081169a..e880db6 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1974,34 +1974,21 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
struct wireless_dev *wdev,
enum nl80211_tx_power_setting type, int mbm)
{
- struct ieee80211_local *local = wiphy_priv(wiphy);
- struct ieee80211_channel *chan = local->_oper_channel;
- u32 changes = 0;
-
- /* FIXME */
- if (local->use_chanctx)
- return -EOPNOTSUPP;
+ struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);

switch (type) {
case NL80211_TX_POWER_AUTOMATIC:
- local->user_power_level = -1;
+ sdata->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
break;
case NL80211_TX_POWER_LIMITED:
- if (mbm < 0 || (mbm % 100))
- return -EOPNOTSUPP;
- local->user_power_level = MBM_TO_DBM(mbm);
- break;
case NL80211_TX_POWER_FIXED:
if (mbm < 0 || (mbm % 100))
return -EOPNOTSUPP;
- /* TODO: move to cfg80211 when it knows the channel */
- if (MBM_TO_DBM(mbm) > chan->max_power)
- return -EINVAL;
- local->user_power_level = MBM_TO_DBM(mbm);
+ sdata->user_power_level = MBM_TO_DBM(mbm);
break;
}

- ieee80211_hw_config(local, changes);
+ ieee80211_recalc_txpower(sdata);

return 0;
}
@@ -2011,8 +1998,12 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy,
int *dbm)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
+ struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);

- *dbm = local->hw.conf.power_level;
+ if (!local->use_chanctx)
+ *dbm = local->hw.conf.power_level;
+ else
+ *dbm = sdata->vif.bss_conf.txpower;

return 0;
}
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index f84b860..a2b06d4 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -173,6 +173,8 @@ static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
rcu_assign_pointer(sdata->vif.chanctx_conf, &ctx->conf);
ctx->refcount++;

+ ieee80211_recalc_txpower(sdata);
+
return 0;
}

diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 466f4b4..eda8929 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -59,8 +59,6 @@ static const struct file_operations name## _ops = { \
debugfs_create_file(#name, mode, phyd, local, &name## _ops);


-DEBUGFS_READONLY_FILE(user_power, "%d",
- local->user_power_level);
DEBUGFS_READONLY_FILE(power, "%d",
local->hw.conf.power_level);
DEBUGFS_READONLY_FILE(total_ps_buffered, "%d",
@@ -251,7 +249,6 @@ void debugfs_hw_add(struct ieee80211_local *local)
DEBUGFS_ADD_MODE(reset, 0200);
#endif
DEBUGFS_ADD(hwflags);
- DEBUGFS_ADD(user_power);
DEBUGFS_ADD(power);

statsd = debugfs_create_dir("statistics", phyd);
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 3393ad5..07c5721 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -168,6 +168,9 @@ IEEE80211_IF_FILE(rc_rateidx_mcs_mask_5ghz,
IEEE80211_IF_FILE(flags, flags, HEX);
IEEE80211_IF_FILE(state, state, LHEX);
IEEE80211_IF_FILE(channel_type, vif.bss_conf.channel_type, DEC);
+IEEE80211_IF_FILE(txpower, vif.bss_conf.txpower, DEC);
+IEEE80211_IF_FILE(ap_power_level, ap_power_level, DEC);
+IEEE80211_IF_FILE(user_power_level, user_power_level, DEC);

/* STA attributes */
IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
@@ -632,6 +635,9 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
DEBUGFS_ADD(flags);
DEBUGFS_ADD(state);
DEBUGFS_ADD(channel_type);
+ DEBUGFS_ADD(txpower);
+ DEBUGFS_ADD(user_power_level);
+ DEBUGFS_ADD(ap_power_level);

if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
add_common_files(sdata);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 3026519..7704458 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -743,6 +743,11 @@ struct ieee80211_sub_if_data {
u8 needed_rx_chains;
enum ieee80211_smps_mode smps_mode;

+#define IEEE80211_UNSET_POWER_LEVEL INT_MIN
+
+ int user_power_level; /* in dBm */
+ int ap_power_level; /* in dBm */
+
/*
* AP this belongs to: self in AP mode and
* corresponding AP in VLAN mode, NULL for
@@ -1117,9 +1122,6 @@ struct ieee80211_local {
int dynamic_ps_user_timeout;
bool disable_dynamic_ps;

- int user_power_level; /* in dBm */
- int ap_power_level; /* in dBm */
-
enum ieee80211_smps_mode smps_mode;

struct work_struct restart_work;
@@ -1365,6 +1367,9 @@ void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up);
void ieee80211_sdata_stop(struct ieee80211_sub_if_data *sdata);

+bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata);
+void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata);
+
static inline bool ieee80211_sdata_running(struct ieee80211_sub_if_data *sdata)
{
return test_bit(SDATA_STATE_RUNNING, &sdata->state);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index c50cf6b..be817d1 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -42,6 +42,41 @@
* by either the RTNL, the iflist_mtx or RCU.
*/

+bool __ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_chanctx_conf *chanctx_conf;
+ int power;
+
+ rcu_read_lock();
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
+ if (!chanctx_conf) {
+ rcu_read_unlock();
+ return false;
+ }
+
+ power = chanctx_conf->channel->max_power;
+ rcu_read_unlock();
+
+ if (sdata->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
+ power = min(power, sdata->user_power_level);
+
+ if (sdata->ap_power_level != IEEE80211_UNSET_POWER_LEVEL)
+ power = min(power, sdata->ap_power_level);
+
+ if (power != sdata->vif.bss_conf.txpower) {
+ sdata->vif.bss_conf.txpower = power;
+ ieee80211_hw_config(sdata->local, 0);
+ return true;
+ }
+
+ return false;
+}
+
+void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
+{
+ if (__ieee80211_recalc_txpower(sdata))
+ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER);
+}

static u32 ieee80211_idle_off(struct ieee80211_local *local,
const char *reason)
@@ -1529,6 +1564,9 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,

ieee80211_set_default_queues(sdata);

+ sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
+ sdata->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
+
/* setup type-dependent data */
ieee80211_setup_sdata(sdata, type);

diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index fd8345c..ad97f17 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -95,11 +95,13 @@ static void ieee80211_reconfig_filter(struct work_struct *work)

static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
{
+ struct ieee80211_sub_if_data *sdata;
struct ieee80211_channel *chan;
u32 changed = 0;
int power;
enum nl80211_channel_type channel_type;
u32 offchannel_flag;
+ bool scanning = false;

offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
if (local->scan_channel) {
@@ -146,16 +148,18 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
changed |= IEEE80211_CONF_CHANGE_SMPS;
}

- if (test_bit(SCAN_SW_SCANNING, &local->scanning) ||
- test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
- test_bit(SCAN_HW_SCANNING, &local->scanning) ||
- !local->ap_power_level)
- power = chan->max_power;
- else
- power = min(chan->max_power, local->ap_power_level);
+ scanning = test_bit(SCAN_SW_SCANNING, &local->scanning) ||
+ test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) ||
+ test_bit(SCAN_HW_SCANNING, &local->scanning);
+ power = chan->max_power;

- if (local->user_power_level >= 0)
- power = min(power, local->user_power_level);
+ rcu_read_lock();
+ list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+ if (!rcu_access_pointer(sdata->vif.chanctx_conf))
+ continue;
+ power = min(power, sdata->vif.bss_conf.txpower);
+ }
+ rcu_read_unlock();

if (local->hw.conf.power_level != power) {
changed |= IEEE80211_CONF_CHANGE_POWER;
@@ -633,7 +637,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
local->hw.radiotap_mcs_details = IEEE80211_RADIOTAP_MCS_HAVE_MCS |
IEEE80211_RADIOTAP_MCS_HAVE_GI |
IEEE80211_RADIOTAP_MCS_HAVE_BW;
- local->user_power_level = -1;
wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask;

INIT_LIST_HEAD(&local->interfaces);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 469d864..712baf9 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -820,10 +820,10 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
cbss->beacon_interval));
}

-static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
- struct ieee80211_channel *channel,
- const u8 *country_ie, u8 country_ie_len,
- const u8 *pwr_constr_elem)
+static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_channel *channel,
+ const u8 *country_ie, u8 country_ie_len,
+ const u8 *pwr_constr_elem)
{
struct ieee80211_country_ie_triplet *triplet;
int chan = ieee80211_frequency_to_channel(channel->center_freq);
@@ -832,7 +832,7 @@ static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,

/* Invalid IE */
if (country_ie_len % 2 || country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN)
- return;
+ return 0;

triplet = (void *)(country_ie + 3);
country_ie_len -= 3;
@@ -873,19 +873,21 @@ static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
}

if (!have_chan_pwr)
- return;
+ return 0;

new_ap_level = max_t(int, 0, chan_pwr - *pwr_constr_elem);

- if (sdata->local->ap_power_level == new_ap_level)
- return;
+ if (sdata->ap_power_level == new_ap_level)
+ return 0;

sdata_info(sdata,
"Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n",
new_ap_level, chan_pwr, *pwr_constr_elem,
sdata->u.mgd.bssid);
- sdata->local->ap_power_level = new_ap_level;
- ieee80211_hw_config(sdata->local, 0);
+ sdata->ap_power_level = new_ap_level;
+ if (__ieee80211_recalc_txpower(sdata))
+ return BSS_CHANGED_TXPOWER;
+ return 0;
}

void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif)
@@ -1489,7 +1491,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa));
memset(&ifmgd->ht_capa_mask, 0, sizeof(ifmgd->ht_capa_mask));

- local->ap_power_level = 0;
+ sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL;

del_timer_sync(&local->dynamic_ps_timer);
cancel_work_sync(&local->dynamic_ps_enable_work);
@@ -2624,10 +2626,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
if (elems.country_elem && elems.pwr_constr_elem &&
mgmt->u.probe_resp.capab_info &
cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT))
- ieee80211_handle_pwr_constr(sdata, chan,
- elems.country_elem,
- elems.country_elem_len,
- elems.pwr_constr_elem);
+ changed |= ieee80211_handle_pwr_constr(sdata, chan,
+ elems.country_elem,
+ elems.country_elem_len,
+ elems.pwr_constr_elem);

ieee80211_bss_info_change_notify(sdata, changed);
}
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index 0638541..cba4b12 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -342,6 +342,7 @@ TRACE_EVENT(drv_bss_info_changed,
__field(bool, ps);
__dynamic_array(u8, ssid, info->ssid_len);
__field(bool, hidden_ssid);
+ __field(int, txpower)
),

TP_fast_assign(
@@ -376,6 +377,7 @@ TRACE_EVENT(drv_bss_info_changed,
__entry->ps = info->ps;
memcpy(__get_dynamic_array(ssid), info->ssid, info->ssid_len);
__entry->hidden_ssid = info->hidden_ssid;
+ __entry->txpower = info->txpower;
),

TP_printk(
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 51a4a25..e18694b 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1450,7 +1450,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
BSS_CHANGED_BSSID |
BSS_CHANGED_CQM |
BSS_CHANGED_QOS |
- BSS_CHANGED_IDLE;
+ BSS_CHANGED_IDLE |
+ BSS_CHANGED_TXPOWER;

switch (sdata->vif.type) {
case NL80211_IFTYPE_STATION:
--
1.7.10.4


2012-10-24 17:40:06

by Ben Greear

[permalink] [raw]
Subject: Re: [PATCH 0/4] multi-channel/interface TX power handling

On 10/24/2012 10:30 AM, Johannes Berg wrote:
> On Wed, 2012-10-24 at 09:31 -0700, Ben Greear wrote:
>
>>> Yeah that'd be the only way, most scripts I've seen always just use the
>>> interface anyway though? I'm not totally happy about this, maybe we
>>> should iterate all interfaces? Not really sure ...
>>
>> Well, I think we should make setting the wiphy work...just iterate
>> all interfaces. Breaking backwards compatibility just causes too
>> much problems for user-space, and many users may either not notice,
>> or not be able to change whatever software is screwing up.
>
> Yeah I guess.
>
>> But, I think we also need some way to know if we can set individual
>> vifs to different tx-power successfully.
>>
>> Maybe a /sys/class/netdev/wlan0/tx-power file to read current power could
>> be added in this patch series? Then user-space could key off of it's
>> existence, and it would give a simple way to read the current tx-power
>> settings (and possibly set it as well)...
>
> sysfs file sounds like about the worst possible way (except maybe for
> procfs), an nl80211 feature flag could be worthwhile though :)

Ok, a feature flag sounds fine to me.

Thanks,
Ben

>
> johannes
>


--
Ben Greear <[email protected]>
Candela Technologies Inc http://www.candelatech.com


2012-10-27 18:19:25

by Arend van Spriel

[permalink] [raw]
Subject: Re: Is Multi-Vif (vaps) Different Channel Operation Supported?

On 10/27/2012 10:19 AM, Adrian Chadd wrote:
> Yeah, how's hostap mode supposed to work in that case? The hostap
> interface doesn't go into and out of power save like stations can. It
> has to be ready to receive anything from any STA, at any point in
> time.

In my Intersil/Conexant days there was a marketing dude coming up with
'time-slicing AP' and there was a way to signal STAs the AP was not able
to receive. Just needed to be back in time to send its beacon. I chose
to forget all about the bad idea.

Gr. AvS


2012-10-24 10:12:52

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 4/4] mac80211_hwsim: print per interface TX power

From: Johannes Berg <[email protected]>

Just for debugging, print the interface TX
power whenever it changes.

Signed-off-by: Johannes Berg <[email protected]>
---
drivers/net/wireless/mac80211_hwsim.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 429ca32..da57fa2 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -972,6 +972,9 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
wiphy_debug(hw->wiphy, " BASIC_RATES: 0x%llx\n",
(unsigned long long) info->basic_rates);
}
+
+ if (changed & BSS_CHANGED_TXPOWER)
+ wiphy_debug(hw->wiphy, " TX Power: %d dBm\n", info->txpower);
}

static int mac80211_hwsim_sta_add(struct ieee80211_hw *hw,
--
1.7.10.4


2012-10-24 17:38:47

by Ben Greear

[permalink] [raw]
Subject: Re: [PATCH 2/4] cfg80211: make TX power setting per interface

On 10/24/2012 10:31 AM, Johannes Berg wrote:
> On Wed, 2012-10-24 at 09:27 -0700, Ben Greear wrote:
>
>>> -static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)
>>> +static int ieee80211_get_tx_power(struct wiphy *wiphy,
>>> + struct wireless_dev *wdev,
>>> + int *dbm)
>>> {
>>> struct ieee80211_local *local = wiphy_priv(wiphy);
>>
>> Do we really set mbm and read back dbm?
>
> Yeah, we did nl80211 APIs in mBm and reading back is only for wext
> compatibility so was dBm ... hindsight being 20/20 we should probably
> never have used mBm, nothing supports it anyway.

ath9k *could* support 1/2 dBm settings from what I remember, but
I am not sure there is any way to currently configure it for that.

>>> @@ -1588,6 +1588,11 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
>>> enum nl80211_tx_power_setting type;
>>> int idx, mbm = 0;
>>>
>>> + if (!wdev) {
>>> + result = -EOPNOTSUPP;
>>> + goto bad_res;
>>> + }
>>
>> I guess this is the part that breaks backwards compat when trying to set wiphy?
>> If it does stay like this, maybe add a WARN_ON_ONCE that tells users to fix their
>> user-space?
>
> Right. Add a user triggerable warning in code like that seems like a
> really bad idea to me though. Maybe a message, that seems to have some
> precedent, but I suppose nobody will really see it anyway?

WARN_ON_ONCE would be once per boot, and it shows stack (and calling user-space application).
It will show up in distribution bug reports automatically in some cases so calling
code might actually get fixed fairly quickly.

Thanks,
Ben

--
Ben Greear <[email protected]>
Candela Technologies Inc http://www.candelatech.com


2012-10-24 10:12:51

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 1/4] nl80211: move "can set channel" check

From: Johannes Berg <[email protected]>

Setting the wdev to NULL when the channel can't be
set for that interface type (to treat the channel
setting for the wiphy/monitor) currently works, but
is confusing in the code if netdev/wdev aren't both
set/unset in the same way. Move the check whether
the channel can be set to where it's needed so that
wdev and netdev are always both assigned or NULL.

Signed-off-by: Johannes Berg <[email protected]>
---
net/wireless/nl80211.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 8c08578..879ca62 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1516,10 +1516,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
result = 0;

mutex_lock(&rdev->mtx);
- } else if (nl80211_can_set_dev_channel(netdev->ieee80211_ptr))
+ } else
wdev = netdev->ieee80211_ptr;
- else
- wdev = NULL;

/*
* end workaround code, by now the rdev is available
@@ -1579,7 +1577,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
}

if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
- result = __nl80211_set_channel(rdev, wdev, info);
+ result = __nl80211_set_channel(rdev,
+ nl80211_can_set_dev_channel(wdev) ? wdev : NULL,
+ info);
if (result)
goto bad_res;
}
--
1.7.10.4


2012-10-24 16:27:58

by Ben Greear

[permalink] [raw]
Subject: Re: [PATCH 2/4] cfg80211: make TX power setting per interface

On 10/24/2012 03:13 AM, Johannes Berg wrote:
> From: Johannes Berg <[email protected]>
>
> The TX power setting is currently per wiphy (hardware
> device) but with multi-channel capabilities that doesn't
> make much sense any more.
>
> Unfortunately, by making it per interface, we loose some
> backward compatibility with userspace, but that isn't a
> big issue since userspace must already accept that not
> all drivers support TX power setting, and mostly uses a
> netdev to identify the hardware anyway.
>

> @@ -1971,6 +1971,7 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
> }
>
> static int ieee80211_set_tx_power(struct wiphy *wiphy,
> + struct wireless_dev *wdev,
> enum nl80211_tx_power_setting type, int mbm)
> {
> struct ieee80211_local *local = wiphy_priv(wiphy);
> @@ -2005,7 +2006,9 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
> return 0;
> }
>
> -static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)
> +static int ieee80211_get_tx_power(struct wiphy *wiphy,
> + struct wireless_dev *wdev,
> + int *dbm)
> {
> struct ieee80211_local *local = wiphy_priv(wiphy);

Do we really set mbm and read back dbm?


>
> diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
> index 879ca62..24175e2 100644
> --- a/net/wireless/nl80211.c
> +++ b/net/wireless/nl80211.c
> @@ -1588,6 +1588,11 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
> enum nl80211_tx_power_setting type;
> int idx, mbm = 0;
>
> + if (!wdev) {
> + result = -EOPNOTSUPP;
> + goto bad_res;
> + }

I guess this is the part that breaks backwards compat when trying to set wiphy?
If it does stay like this, maybe add a WARN_ON_ONCE that tells users to fix their
user-space?

Too bad there is not an -EUSEVIFINSTEAD :P

Thanks,
Ben

--
Ben Greear <[email protected]>
Candela Technologies Inc http://www.candelatech.com


2012-10-24 10:12:52

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 2/4] cfg80211: make TX power setting per interface

From: Johannes Berg <[email protected]>

The TX power setting is currently per wiphy (hardware
device) but with multi-channel capabilities that doesn't
make much sense any more.

Unfortunately, by making it per interface, we loose some
backward compatibility with userspace, but that isn't a
big issue since userspace must already accept that not
all drivers support TX power setting, and mostly uses a
netdev to identify the hardware anyway.

Signed-off-by: Johannes Berg <[email protected]>
---
drivers/net/wireless/ath/ath6kl/cfg80211.c | 9 ++++----
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 6 ++++--
drivers/net/wireless/mwifiex/cfg80211.c | 1 +
drivers/net/wireless/rndis_wlan.c | 10 +++++++--
include/net/cfg80211.h | 5 +++--
net/mac80211/cfg.c | 5 ++++-
net/wireless/nl80211.c | 7 ++++++-
net/wireless/rdev-ops.h | 11 +++++-----
net/wireless/trace.h | 22 +++++++++++---------
net/wireless/wext-compat.c | 4 ++--
10 files changed, 50 insertions(+), 30 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 2770899..d615f9f 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -1384,11 +1384,8 @@ static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
return 0;
}

-/*
- * The type nl80211_tx_power_setting replaces the following
- * data type from 2.6.36 onwards
-*/
static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
enum nl80211_tx_power_setting type,
int mbm)
{
@@ -1423,7 +1420,9 @@ static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
return 0;
}

-static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
+static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ int *dbm)
{
struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
struct ath6kl_vif *vif;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 0e95209..ce88d96 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -1876,7 +1876,7 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
}

static s32
-brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
+brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
enum nl80211_tx_power_setting type, s32 mbm)
{

@@ -1924,7 +1924,9 @@ done:
return err;
}

-static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
+static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ s32 *dbm)
{
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct net_device *ndev = cfg_to_ndev(cfg);
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 38a5871..d3d7a71 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -324,6 +324,7 @@ mwifiex_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
*/
static int
mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
enum nl80211_tx_power_setting type,
int mbm)
{
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index bd1f0cb..5390af3 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -490,9 +490,12 @@ static int rndis_scan(struct wiphy *wiphy,
static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed);

static int rndis_set_tx_power(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
enum nl80211_tx_power_setting type,
int mbm);
-static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm);
+static int rndis_get_tx_power(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ int *dbm);

static int rndis_connect(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_connect_params *sme);
@@ -1903,6 +1906,7 @@ static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed)
}

static int rndis_set_tx_power(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
enum nl80211_tx_power_setting type,
int mbm)
{
@@ -1930,7 +1934,9 @@ static int rndis_set_tx_power(struct wiphy *wiphy,
return -ENOTSUPP;
}

-static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm)
+static int rndis_get_tx_power(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ int *dbm)
{
struct rndis_wlan_private *priv = wiphy_priv(wiphy);
struct usbnet *usbdev = priv->usbdev;
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index aa0e4a1..d44f29b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1747,9 +1747,10 @@ struct cfg80211_ops {

int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed);

- int (*set_tx_power)(struct wiphy *wiphy,
+ int (*set_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
enum nl80211_tx_power_setting type, int mbm);
- int (*get_tx_power)(struct wiphy *wiphy, int *dbm);
+ int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
+ int *dbm);

int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev,
const u8 *addr);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 5eab132..081169a 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1971,6 +1971,7 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
}

static int ieee80211_set_tx_power(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
enum nl80211_tx_power_setting type, int mbm)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
@@ -2005,7 +2006,9 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
return 0;
}

-static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)
+static int ieee80211_get_tx_power(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ int *dbm)
{
struct ieee80211_local *local = wiphy_priv(wiphy);

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 879ca62..24175e2 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1588,6 +1588,11 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
enum nl80211_tx_power_setting type;
int idx, mbm = 0;

+ if (!wdev) {
+ result = -EOPNOTSUPP;
+ goto bad_res;
+ }
+
if (!rdev->ops->set_tx_power) {
result = -EOPNOTSUPP;
goto bad_res;
@@ -1607,7 +1612,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
mbm = nla_get_u32(info->attrs[idx]);
}

- result = rdev_set_tx_power(rdev, type, mbm);
+ result = rdev_set_tx_power(rdev, wdev, type, mbm);
if (result)
goto bad_res;
}
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
index eb5f897..6e5fa65 100644
--- a/net/wireless/rdev-ops.h
+++ b/net/wireless/rdev-ops.h
@@ -476,21 +476,22 @@ rdev_set_wiphy_params(struct cfg80211_registered_device *rdev, u32 changed)
}

static inline int rdev_set_tx_power(struct cfg80211_registered_device *rdev,
+ struct wireless_dev *wdev,
enum nl80211_tx_power_setting type, int mbm)
{
int ret;
- trace_rdev_set_tx_power(&rdev->wiphy, type, mbm);
- ret = rdev->ops->set_tx_power(&rdev->wiphy, type, mbm);
+ trace_rdev_set_tx_power(&rdev->wiphy, wdev, type, mbm);
+ ret = rdev->ops->set_tx_power(&rdev->wiphy, wdev, type, mbm);
trace_rdev_return_int(&rdev->wiphy, ret);
return ret;
}

static inline int rdev_get_tx_power(struct cfg80211_registered_device *rdev,
- int *dbm)
+ struct wireless_dev *wdev, int *dbm)
{
int ret;
- trace_rdev_get_tx_power(&rdev->wiphy);
- ret = rdev->ops->get_tx_power(&rdev->wiphy, dbm);
+ trace_rdev_get_tx_power(&rdev->wiphy, wdev);
+ ret = rdev->ops->get_tx_power(&rdev->wiphy, wdev, dbm);
trace_rdev_return_int_int(&rdev->wiphy, ret, *dbm);
return ret;
}
diff --git a/net/wireless/trace.h b/net/wireless/trace.h
index 0ca71ca..bbb86ad 100644
--- a/net/wireless/trace.h
+++ b/net/wireless/trace.h
@@ -260,11 +260,6 @@ DEFINE_EVENT(wiphy_only_evt, rdev_get_antenna,
TP_ARGS(wiphy)
);

-DEFINE_EVENT(wiphy_only_evt, rdev_get_tx_power,
- TP_PROTO(struct wiphy *wiphy),
- TP_ARGS(wiphy)
-);
-
DEFINE_EVENT(wiphy_only_evt, rdev_rfkill_poll,
TP_PROTO(struct wiphy *wiphy),
TP_ARGS(wiphy)
@@ -1230,22 +1225,29 @@ TRACE_EVENT(rdev_set_wiphy_params,
WIPHY_PR_ARG, __entry->changed)
);

+DEFINE_EVENT(wiphy_wdev_evt, rdev_get_tx_power,
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
+ TP_ARGS(wiphy, wdev)
+);
+
TRACE_EVENT(rdev_set_tx_power,
- TP_PROTO(struct wiphy *wiphy, enum nl80211_tx_power_setting type,
- int mbm),
- TP_ARGS(wiphy, type, mbm),
+ TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev,
+ enum nl80211_tx_power_setting type, int mbm),
+ TP_ARGS(wiphy, wdev, type, mbm),
TP_STRUCT__entry(
WIPHY_ENTRY
+ WDEV_ENTRY
__field(enum nl80211_tx_power_setting, type)
__field(int, mbm)
),
TP_fast_assign(
WIPHY_ASSIGN;
+ WDEV_ASSIGN;
__entry->type = type;
__entry->mbm = mbm;
),
- TP_printk(WIPHY_PR_FMT ", type: %d, mbm: %d",
- WIPHY_PR_ARG, __entry->type, __entry->mbm)
+ TP_printk(WIPHY_PR_FMT WDEV_PR_FMT ", type: %d, mbm: %d",
+ WIPHY_PR_ARG, WDEV_PR_ARG,__entry->type, __entry->mbm)
);

TRACE_EVENT(rdev_return_int_int,
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 6488d2d..742ab6e 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -895,7 +895,7 @@ static int cfg80211_wext_siwtxpower(struct net_device *dev,
return 0;
}

- return rdev_set_tx_power(rdev, type, DBM_TO_MBM(dbm));
+ return rdev_set_tx_power(rdev, wdev, type, DBM_TO_MBM(dbm));
}

static int cfg80211_wext_giwtxpower(struct net_device *dev,
@@ -914,7 +914,7 @@ static int cfg80211_wext_giwtxpower(struct net_device *dev,
if (!rdev->ops->get_tx_power)
return -EOPNOTSUPP;

- err = rdev_get_tx_power(rdev, &val);
+ err = rdev_get_tx_power(rdev, wdev, &val);
if (err)
return err;

--
1.7.10.4


2012-10-28 22:06:26

by Adrian Chadd

[permalink] [raw]
Subject: Re: Is Multi-Vif (vaps) Different Channel Operation Supported?

On 27 October 2012 11:19, Arend van Spriel <[email protected]> wrote:

> In my Intersil/Conexant days there was a marketing dude coming up with
> 'time-slicing AP' and there was a way to signal STAs the AP was not able to
> receive. Just needed to be back in time to send its beacon. I chose to
> forget all about the bad idea.

Yup that's what you'd have to do.. with all the timing / settling
issues inherent in that.



adrian

2012-10-24 15:40:09

by Ben Greear

[permalink] [raw]
Subject: Re: [PATCH 0/4] multi-channel/interface TX power handling

On 10/24/2012 03:13 AM, Johannes Berg wrote:
> This was the remaining work I had to do in mac80211, but it
> got a little larger because cfg80211 wasn't doing per-vif
> TX power ...
>
> I disallowed setting TX power per hardware now, we could in
> theory do something like set all interfaces in that case, but
> it seemed like a lot of work for very little gain. If someone
> needs it, we can do it later :-)

Is there any good way for user-space to know if kernel supports
old or new version? Maybe just try to set per wiphy and if that fails,
try to set per vif?

Thanks,
Ben

>
> johannes
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>


--
Ben Greear <[email protected]>
Candela Technologies Inc http://www.candelatech.com



2012-10-24 17:31:11

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 2/4] cfg80211: make TX power setting per interface

On Wed, 2012-10-24 at 09:27 -0700, Ben Greear wrote:

> > -static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)
> > +static int ieee80211_get_tx_power(struct wiphy *wiphy,
> > + struct wireless_dev *wdev,
> > + int *dbm)
> > {
> > struct ieee80211_local *local = wiphy_priv(wiphy);
>
> Do we really set mbm and read back dbm?

Yeah, we did nl80211 APIs in mBm and reading back is only for wext
compatibility so was dBm ... hindsight being 20/20 we should probably
never have used mBm, nothing supports it anyway.

> > @@ -1588,6 +1588,11 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
> > enum nl80211_tx_power_setting type;
> > int idx, mbm = 0;
> >
> > + if (!wdev) {
> > + result = -EOPNOTSUPP;
> > + goto bad_res;
> > + }
>
> I guess this is the part that breaks backwards compat when trying to set wiphy?
> If it does stay like this, maybe add a WARN_ON_ONCE that tells users to fix their
> user-space?

Right. Add a user triggerable warning in code like that seems like a
really bad idea to me though. Maybe a message, that seems to have some
precedent, but I suppose nobody will really see it anyway?

johannes


2012-10-24 17:29:46

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 0/4] multi-channel/interface TX power handling

On Wed, 2012-10-24 at 09:31 -0700, Ben Greear wrote:

> > Yeah that'd be the only way, most scripts I've seen always just use the
> > interface anyway though? I'm not totally happy about this, maybe we
> > should iterate all interfaces? Not really sure ...
>
> Well, I think we should make setting the wiphy work...just iterate
> all interfaces. Breaking backwards compatibility just causes too
> much problems for user-space, and many users may either not notice,
> or not be able to change whatever software is screwing up.

Yeah I guess.

> But, I think we also need some way to know if we can set individual
> vifs to different tx-power successfully.
>
> Maybe a /sys/class/netdev/wlan0/tx-power file to read current power could
> be added in this patch series? Then user-space could key off of it's
> existence, and it would give a simple way to read the current tx-power
> settings (and possibly set it as well)...

sysfs file sounds like about the worst possible way (except maybe for
procfs), an nl80211 feature flag could be worthwhile though :)

johannes


2012-10-24 15:41:39

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 0/4] multi-channel/interface TX power handling

On Wed, 2012-10-24 at 08:40 -0700, Ben Greear wrote:
> On 10/24/2012 03:13 AM, Johannes Berg wrote:
> > This was the remaining work I had to do in mac80211, but it
> > got a little larger because cfg80211 wasn't doing per-vif
> > TX power ...
> >
> > I disallowed setting TX power per hardware now, we could in
> > theory do something like set all interfaces in that case, but
> > it seemed like a lot of work for very little gain. If someone
> > needs it, we can do it later :-)
>
> Is there any good way for user-space to know if kernel supports
> old or new version? Maybe just try to set per wiphy and if that fails,
> try to set per vif?

Yeah that'd be the only way, most scripts I've seen always just use the
interface anyway though? I'm not totally happy about this, maybe we
should iterate all interfaces? Not really sure ...

johannes


2012-10-24 23:56:20

by Ben Greear

[permalink] [raw]
Subject: Re: Is Multi-Vif (vaps) Different Channel Operation Supported?

On 10/24/2012 04:05 PM, Kelly Hogan wrote:
> Hi All,
>
> We are utilizing current ath9k and mac80211 and are trying to discern if multi-channel support is possible on different Vifs, on the same phy.
>
> Example:
>
> Two Vifs running as masters, controlled via hostapd
> One Vif running as a Station, controlled by wpa_supplicant
> One Vif running as a mesh vap
>
> We can run all the Vifs fine, but it appears that with shared hostapd/wpa_supplicant control files, that the master Vifs always have to follow the channel that the station is connected to. The mesh vap also seems to require being on the same channel of the station.
>
> Any info on if this is supported, or what order to process creation, channel setting, etc to get them to simultaneously allow different channel support would be helpful, or save us the time of assuming that it can be done if it in fact can't.

It cannot work as far as I know.

Thanks,
Ben

--
Ben Greear <[email protected]>
Candela Technologies Inc http://www.candelatech.com


2012-10-24 16:31:32

by Ben Greear

[permalink] [raw]
Subject: Re: [PATCH 0/4] multi-channel/interface TX power handling

On 10/24/2012 08:42 AM, Johannes Berg wrote:
> On Wed, 2012-10-24 at 08:40 -0700, Ben Greear wrote:
>> On 10/24/2012 03:13 AM, Johannes Berg wrote:
>>> This was the remaining work I had to do in mac80211, but it
>>> got a little larger because cfg80211 wasn't doing per-vif
>>> TX power ...
>>>
>>> I disallowed setting TX power per hardware now, we could in
>>> theory do something like set all interfaces in that case, but
>>> it seemed like a lot of work for very little gain. If someone
>>> needs it, we can do it later :-)
>>
>> Is there any good way for user-space to know if kernel supports
>> old or new version? Maybe just try to set per wiphy and if that fails,
>> try to set per vif?
>
> Yeah that'd be the only way, most scripts I've seen always just use the
> interface anyway though? I'm not totally happy about this, maybe we
> should iterate all interfaces? Not really sure ...

Well, I think we should make setting the wiphy work...just iterate
all interfaces. Breaking backwards compatibility just causes too
much problems for user-space, and many users may either not notice,
or not be able to change whatever software is screwing up.

But, I think we also need some way to know if we can set individual
vifs to different tx-power successfully.

Maybe a /sys/class/netdev/wlan0/tx-power file to read current power could
be added in this patch series? Then user-space could key off of it's
existence, and it would give a simple way to read the current tx-power
settings (and possibly set it as well)...

Thanks,
Ben

--
Ben Greear <[email protected]>
Candela Technologies Inc http://www.candelatech.com


2012-10-27 08:19:01

by Adrian Chadd

[permalink] [raw]
Subject: Re: Is Multi-Vif (vaps) Different Channel Operation Supported?

Yeah, how's hostap mode supposed to work in that case? The hostap
interface doesn't go into and out of power save like stations can. It
has to be ready to receive anything from any STA, at any point in
time.




Adrian

On 24 October 2012 16:56, Ben Greear <[email protected]> wrote:
> On 10/24/2012 04:05 PM, Kelly Hogan wrote:
>>
>> Hi All,
>>
>> We are utilizing current ath9k and mac80211 and are trying to discern if
>> multi-channel support is possible on different Vifs, on the same phy.
>>
>> Example:
>>
>> Two Vifs running as masters, controlled via hostapd
>> One Vif running as a Station, controlled by wpa_supplicant
>> One Vif running as a mesh vap
>>
>> We can run all the Vifs fine, but it appears that with shared
>> hostapd/wpa_supplicant control files, that the master Vifs always have to
>> follow the channel that the station is connected to. The mesh vap also
>> seems to require being on the same channel of the station.
>>
>> Any info on if this is supported, or what order to process creation,
>> channel setting, etc to get them to simultaneously allow different channel
>> support would be helpful, or save us the time of assuming that it can be
>> done if it in fact can't.
>
>
> It cannot work as far as I know.
>
> Thanks,
> Ben
>
> --
> Ben Greear <[email protected]>
> Candela Technologies Inc http://www.candelatech.com
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html