* Re: [PATCH 1/3] Libertas: cfg80211 support
From: Holger Schurig @ 2010-06-15 13:48 UTC (permalink / raw)
To: Johannes Berg; +Cc: dkiran, linux-wireless
In-Reply-To: <1276519238.3926.20.camel@jlt3.sipsolutions.net>
I'm o.k. with being mentioned in the commit log message.
After all, I *intended* that someone picks this up and continued to work on
it, while I'm off to other projects due to my job. That makes me only able to
work in an on-and-off style with kernel stuff.
^ permalink raw reply
* Re: [RFC] Changes in mac80211 to make at76c50x-usb working again
From: Sebastian Smolorz @ 2010-06-15 13:49 UTC (permalink / raw)
To: Johannes Berg
Cc: John W. Linville, kalle.valo, linux-wireless, Marcel Holtmann
In-Reply-To: <1276609006.3648.233.camel@jlt3.sipsolutions.net>
Johannes Berg wrote:
> On Tue, 2010-06-15 at 09:26 -0400, John W. Linville wrote:
> > On Tue, Jun 15, 2010 at 02:16:36PM +0200, Sebastian Smolorz wrote:
> > > Hi,
> > >
> > > the at76c50x-usb driver fails to authenticate with an AP.
>
> We need more information on how it fails.
The problem is that the following if-statement is never true:
http://lxr.linux.no/#linux+v2.6.34/drivers/net/wireless/at76c50x-usb.c#L1986
What else information do you need? dmesg output, debugfs trace?
>
> > > The last working
> > > major kernel version was 2.6.30. I investigated the problem and found
> > > out that the driver needs to send a join command (CMD_JOIN) prior to
> > > the actual authentication process. For the join command, the driver
> > > needs to know the bssid of the AP. The problem is now that the
> > > mac80211 layer does not inform the driver about the bssid prior to
> > > the authentication. So we have a chicken-and-egg dilemma.
--
Sebastian
^ permalink raw reply
* Re: [RFC] Changes in mac80211 to make at76c50x-usb working again
From: Johannes Berg @ 2010-06-15 13:36 UTC (permalink / raw)
To: John W. Linville
Cc: Sebastian Smolorz, kalle.valo, linux-wireless, Marcel Holtmann
In-Reply-To: <20100615132619.GB12885@tuxdriver.com>
On Tue, 2010-06-15 at 09:26 -0400, John W. Linville wrote:
> On Tue, Jun 15, 2010 at 02:16:36PM +0200, Sebastian Smolorz wrote:
> > Hi,
> >
> > the at76c50x-usb driver fails to authenticate with an AP.
We need more information on how it fails.
> > The last working
> > major kernel version was 2.6.30. I investigated the problem and found out
> > that the driver needs to send a join command (CMD_JOIN) prior to the actual
> > authentication process. For the join command, the driver needs to know the
> > bssid of the AP. The problem is now that the mac80211 layer does not inform
> > the driver about the bssid prior to the authentication. So we have a
> > chicken-and-egg dilemma.
> [1] http://thread.gmane.org/gmane.linux.kernel.wireless.general/32598
> [2] http://www.intellinuxwireless.org/bugzilla/show_bug.cgi?id=1995
>
> Cc: Marcel Holtmann <marcel@holtmann.org>
> Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
> Signed-off-by: John W. Linville <linville@tuxdriver.com>
>
> It would be best to avoid reintroducing the bug mentioned in that
> commit. Perhaps ensuring that iwlwifi's sta_notify is correct would
> be worthwhile?
mac80211's sta_notify was since fixed.
> What other issues might be introduced from setting a non-zero BSSID
> when not associated? Will that limit scan results for any devices?
> Trigger a premature auth or assoc? Etc?
I still think this is the wrong thing to do though.
What if you want to implement fast roaming? In that case, you still have
to authenticate to one AP while associated with another, etc.
johannes
^ permalink raw reply
* Re: [RFC] Changes in mac80211 to make at76c50x-usb working again
From: John W. Linville @ 2010-06-15 13:26 UTC (permalink / raw)
To: Sebastian Smolorz
Cc: kalle.valo, linux-wireless, Marcel Holtmann, Johannes Berg
In-Reply-To: <201006151416.36686.Sebastian.Smolorz@gmx.de>
On Tue, Jun 15, 2010 at 02:16:36PM +0200, Sebastian Smolorz wrote:
> Hi,
>
> the at76c50x-usb driver fails to authenticate with an AP. The last working
> major kernel version was 2.6.30. I investigated the problem and found out
> that the driver needs to send a join command (CMD_JOIN) prior to the actual
> authentication process. For the join command, the driver needs to know the
> bssid of the AP. The problem is now that the mac80211 layer does not inform
> the driver about the bssid prior to the authentication. So we have a
> chicken-and-egg dilemma.
>
> The following patch solves the described problem. As it modifies generic
> mac80211 code and thus has influence on all drivers I'm open for comments on
> how to make a proper, probably less intrusive patch.
>
> Sebastian
Hey, thanks for giving attention to this! See below...
> ---
> diff --git a/net/mac80211/main.c b/net/mac80211/main.c
> index a1bf46c..6c34b4f 100644
> --- a/net/mac80211/main.c
> +++ b/net/mac80211/main.c
> @@ -180,17 +180,9 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
> if (!changed)
> return;
>
> - if (sdata->vif.type == NL80211_IFTYPE_STATION) {
> - /*
> - * While not associated, claim a BSSID of all-zeroes
> - * so that drivers don't do any weird things with the
> - * BSSID at that time.
> - */
> - if (sdata->vif.bss_conf.assoc)
> - sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
> - else
> - sdata->vif.bss_conf.bssid = zero;
> - } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
> + if (sdata->vif.type == NL80211_IFTYPE_STATION)
> + sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
> + else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
> sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
> else if (sdata->vif.type == NL80211_IFTYPE_AP)
> sdata->vif.bss_conf.bssid = sdata->vif.addr;
> diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
> index 4dad08f..b06b175 100644
> --- a/net/mac80211/mlme.c
> +++ b/net/mac80211/mlme.c
> @@ -2042,6 +2042,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
> wk->sdata = sdata;
> wk->done = ieee80211_probe_auth_done;
>
> + memcpy(sdata->u.mgd.bssid, req->bss->bssid, ETH_ALEN);
> + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
> +
> ieee80211_add_work(wk);
> return 0;
> }
FWIW, the code being removed from ieee80211_bss_info_change_notify
above was introduced by the following commit:
commit 9cef873798dfcdc10ff40b02abf1de935ceeba85
Author: Johannes Berg <johannes@sipsolutions.net>
Date: Thu May 14 13:10:14 2009 +0200
mac80211: fix managed mode BSSID handling
Currently, we will ask the driver to configure right away
when somebody changes the desired BSSID. That's totally
strange because then we will configure the driver without
even knowing whether the BSS exists. Change this to only
configure the BSSID when associated, and configure a zero
BSSID when not associated.
As a side effect, this fixes an issue with the iwlwifi
driver which doesn't implement sta_notify properly and
uses the BSSID instead and gets very confused if the
BSSID is cleared before we disassociate, which results
in the warning Marcel posted [1] and iwlwifi bug 1995 [2].
[1] http://thread.gmane.org/gmane.linux.kernel.wireless.general/32598
[2] http://www.intellinuxwireless.org/bugzilla/show_bug.cgi?id=1995
Cc: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
It would be best to avoid reintroducing the bug mentioned in that
commit. Perhaps ensuring that iwlwifi's sta_notify is correct would
be worthwhile?
What other issues might be introduced from setting a non-zero BSSID
when not associated? Will that limit scan results for any devices?
Trigger a premature auth or assoc? Etc?
John
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* [RFC] Changes in mac80211 to make at76c50x-usb working again
From: Sebastian Smolorz @ 2010-06-15 12:16 UTC (permalink / raw)
To: kalle.valo; +Cc: linux-wireless
Hi,
the at76c50x-usb driver fails to authenticate with an AP. The last working
major kernel version was 2.6.30. I investigated the problem and found out
that the driver needs to send a join command (CMD_JOIN) prior to the actual
authentication process. For the join command, the driver needs to know the
bssid of the AP. The problem is now that the mac80211 layer does not inform
the driver about the bssid prior to the authentication. So we have a
chicken-and-egg dilemma.
The following patch solves the described problem. As it modifies generic
mac80211 code and thus has influence on all drivers I'm open for comments on
how to make a proper, probably less intrusive patch.
Sebastian
---
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index a1bf46c..6c34b4f 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -180,17 +180,9 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
if (!changed)
return;
- if (sdata->vif.type == NL80211_IFTYPE_STATION) {
- /*
- * While not associated, claim a BSSID of all-zeroes
- * so that drivers don't do any weird things with the
- * BSSID at that time.
- */
- if (sdata->vif.bss_conf.assoc)
- sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
- else
- sdata->vif.bss_conf.bssid = zero;
- } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+ if (sdata->vif.type == NL80211_IFTYPE_STATION)
+ sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
+ else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
else if (sdata->vif.type == NL80211_IFTYPE_AP)
sdata->vif.bss_conf.bssid = sdata->vif.addr;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 4dad08f..b06b175 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2042,6 +2042,9 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
wk->sdata = sdata;
wk->done = ieee80211_probe_auth_done;
+ memcpy(sdata->u.mgd.bssid, req->bss->bssid, ETH_ALEN);
+ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
+
ieee80211_add_work(wk);
return 0;
}
^ permalink raw reply related
* Re: [RFC PATCH] iw: Add support for setting transmit power
From: Julian Calaby @ 2010-06-15 11:50 UTC (permalink / raw)
To: Juuso Oikarinen; +Cc: linux-wireless
In-Reply-To: <1276593467-28309-1-git-send-email-juuso.oikarinen@nokia.com>
On Tue, Jun 15, 2010 at 19:17, Juuso Oikarinen
<juuso.oikarinen@nokia.com> wrote:
> This patch adds the "set tx_power" command to allow specifying the transmit
> power level to the WLAN stack. The transmit power configuration consists of
> a mode (automatic, fixed, limited) and the limit mBm value.
>
> Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
> ---
> Makefile | 3 ++-
> nl80211.h | 27 ++++++++++++++++++++++++++-
> 2 files changed, 28 insertions(+), 2 deletions(-)
>
> diff --git a/Makefile b/Makefile
> index d303f45..cbb9504 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -17,7 +17,8 @@ CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing
> OBJS = iw.o genl.o event.o info.o phy.o \
> interface.o ibss.o station.o survey.o util.o \
> mesh.o mpath.o scan.o reg.o version.o \
> - reason.o status.o connect.o link.o offch.o ps.o cqm.o
> + reason.o status.o connect.o link.o offch.o ps.o cqm.o \
> + txpower.o
> OBJS += sections.o
> ALL = iw
>
Call me stupid, but is there a txpower.c?
Thanks,
--
Julian Calaby
Email: julian.calaby@gmail.com
.Plan: http://sites.google.com/site/juliancalaby/
^ permalink raw reply
* Re: [ath5k-devel] [PATCH] ath5k: disable all tasklets while resetting
From: Bob Copeland @ 2010-06-15 11:21 UTC (permalink / raw)
To: Bruno Randolf; +Cc: Johannes Berg, ath5k-devel, linux-wireless, linville
In-Reply-To: <201006151354.43744.br1@einfach.org>
On Tue, Jun 15, 2010 at 01:54:43PM +0900, Bruno Randolf wrote:
> if we disable interrupts in the chip (ath5k_hw_set_imr) , the hardware does
> not generate any interrupts. so no tasklets will get scheduled...
The tasklet might already be scheduled on another CPU:
cpu0 cpu1
ath5k_reset()
ath5k_intr()
ath5k_hw_set_imr(0)
synchronize_irq()
// spins until irq finishes
tasklet_schedule(foo)
tasklet_disable(foo)
// reset here
tasklet_action() // spins
--
Bob Copeland %% www.bobcopeland.com
^ permalink raw reply
* Re: [PATCH v2] iw: Configure basic rates when joining ibss network
From: Johannes Berg @ 2010-06-15 10:05 UTC (permalink / raw)
To: Teemu Paasikivi; +Cc: linux-wireless
In-Reply-To: <1276595169-3669-1-git-send-email-ext-teemu.3.paasikivi@nokia.com>
On Tue, 2010-06-15 at 12:46 +0300, Teemu Paasikivi wrote:
> + /* basic rates */
> + if (argc > 1 && strcmp(argv[0], "basic-rates") == 0) {
> if (argc) {
> +COMMAND(ibss, join,
> + "<SSID> <freq in MHz> [fixed-freq] [<fixed bssid>] "
> + "[basic-rates <rate in Mbps,rate2,...>] [key d:0:abcde]",
that doesn't match?
johannes
^ permalink raw reply
* Re: [RFC PATCH] nl80211/cfg80211/mac80211: Add support for setting transmit power
From: Juuso Oikarinen @ 2010-06-15 9:46 UTC (permalink / raw)
To: ext Johannes Berg; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1276594195.3648.54.camel@jlt3.sipsolutions.net>
On Tue, 2010-06-15 at 11:29 +0200, ext Johannes Berg wrote:
> On Tue, 2010-06-15 at 12:17 +0300, Juuso Oikarinen wrote:
>
> > + * @NL80211_CMD_SET_TX_POWER: Set the used transmit power level (using
> > + * %NL80211_ATTR_TX_POWER_SETTING and %NL80211_ATTR_TX_POWER_LEVEL).
>
> We have a lot of such settings (RTS threshold, coverage class, ...) done
> with SET_WIPHY, shouldn't this also be done there?
Ok, I will look into that.
> > + /*
> > + * Though the nl80211 supports negative mBm values, the interface
> > + * below it does not, for now.
> > + */
> > + if (mbm < 0) {
> > + err = -EOPNOTSUPP;
> > + goto out;
> > + }
> > +
> > + rtnl_lock();
> > +
> > + err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
> > + if (err)
> > + goto unlock_rdev;
> > +
> > + wdev = dev->ieee80211_ptr;
> > +
> > + if (!rdev->ops->set_tx_power) {
> > + return -EOPNOTSUPP;
> > + goto unlock_rdev;
> > + }
> > +
> > + err = rdev->ops->set_tx_power(wdev->wiphy, type, MBM_TO_DBM(mbm));
>
> I think the API mismatch should be handled in mac80211 rather than
> cfg80211, that goes for both the negative values (actually, shouldn't
> that be non-positive for mac80211?) and mBm vs. dBm -- and mac80211
> should probably reject fractional dBm values for now.
Ok. If I adjust the cfg80211 ops function for this, I'll need to see
about full-mac drivers also implementing the function besides the
mac80211. I'll look into it.
-Juuso
> johannes
>
^ permalink raw reply
* [PATCH v2] iw: Configure basic rates when joining ibss network
From: Teemu Paasikivi @ 2010-06-15 9:46 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Teemu Paasikivi
This patch adds option to configure basic rates when joining ibss network.
Signed-off-by: Teemu Paasikivi <ext-teemu.3.paasikivi@nokia.com>
---
ibss.c | 35 ++++++++++++++++++++++++++++++++++-
1 files changed, 34 insertions(+), 1 deletions(-)
diff --git a/ibss.c b/ibss.c
index 4715ac8..9260a9f 100644
--- a/ibss.c
+++ b/ibss.c
@@ -18,6 +18,11 @@ static int join_ibss(struct nl80211_state *state,
{
char *end;
unsigned char abssid[6];
+ unsigned char rates[NL80211_MAX_SUPP_RATES];
+ int n_rates = 0;
+ char *value = NULL, *sptr = NULL;
+ float rate;
+
if (argc < 2)
return 1;
@@ -41,6 +46,32 @@ static int join_ibss(struct nl80211_state *state,
argc--;
}
+ /* basic rates */
+ if (argc > 1 && strcmp(argv[0], "basic-rates") == 0) {
+ argv++;
+ argc--;
+
+ value = strtok_r(argv[0], ",", &sptr);
+
+ while (value && n_rates < NL80211_MAX_SUPP_RATES) {
+ rate = strtod(value, &end);
+ rates[n_rates] = rate * 2;
+
+ /* filter out suspicious values */
+ if (*end != '\0' || !rates[n_rates] ||
+ rate*2 != rates[n_rates])
+ return 1;
+
+ n_rates++;
+ value = strtok_r(NULL, ",", &sptr);
+ }
+
+ NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, n_rates, rates);
+
+ argv++;
+ argc--;
+ }
+
if (argc) {
if (mac_addr_a2n(abssid, argv[0]) == 0) {
NLA_PUT(msg, NL80211_ATTR_MAC, 6, abssid);
@@ -73,7 +104,9 @@ static int leave_ibss(struct nl80211_state *state,
COMMAND(ibss, leave, NULL,
NL80211_CMD_LEAVE_IBSS, 0, CIB_NETDEV, leave_ibss,
"Leave the current IBSS cell.");
-COMMAND(ibss, join, "<SSID> <freq in MHz> [fixed-freq] [<fixed bssid>] [key d:0:abcde]",
+COMMAND(ibss, join,
+ "<SSID> <freq in MHz> [fixed-freq] [<fixed bssid>] "
+ "[basic-rates <rate in Mbps,rate2,...>] [key d:0:abcde]",
NL80211_CMD_JOIN_IBSS, 0, CIB_NETDEV, join_ibss,
"Join the IBSS cell with the given SSID, if it doesn't exist create\n"
"it on the given frequency. When fixed frequency is requested, don't\n"
--
1.5.6.3
^ permalink raw reply related
* Re: [RFC PATCH] nl80211/cfg80211/mac80211: Add support for setting transmit power
From: Johannes Berg @ 2010-06-15 9:29 UTC (permalink / raw)
To: Juuso Oikarinen; +Cc: linux-wireless
In-Reply-To: <1276593453-27818-1-git-send-email-juuso.oikarinen@nokia.com>
On Tue, 2010-06-15 at 12:17 +0300, Juuso Oikarinen wrote:
> + * @NL80211_CMD_SET_TX_POWER: Set the used transmit power level (using
> + * %NL80211_ATTR_TX_POWER_SETTING and %NL80211_ATTR_TX_POWER_LEVEL).
We have a lot of such settings (RTS threshold, coverage class, ...) done
with SET_WIPHY, shouldn't this also be done there?
> + /*
> + * Though the nl80211 supports negative mBm values, the interface
> + * below it does not, for now.
> + */
> + if (mbm < 0) {
> + err = -EOPNOTSUPP;
> + goto out;
> + }
> +
> + rtnl_lock();
> +
> + err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
> + if (err)
> + goto unlock_rdev;
> +
> + wdev = dev->ieee80211_ptr;
> +
> + if (!rdev->ops->set_tx_power) {
> + return -EOPNOTSUPP;
> + goto unlock_rdev;
> + }
> +
> + err = rdev->ops->set_tx_power(wdev->wiphy, type, MBM_TO_DBM(mbm));
I think the API mismatch should be handled in mac80211 rather than
cfg80211, that goes for both the negative values (actually, shouldn't
that be non-positive for mac80211?) and mBm vs. dBm -- and mac80211
should probably reject fractional dBm values for now.
johannes
^ permalink raw reply
* [RFC PATCH] iw: Add support for setting transmit power
From: Juuso Oikarinen @ 2010-06-15 9:17 UTC (permalink / raw)
To: linux-wireless
This patch adds the "set tx_power" command to allow specifying the transmit
power level to the WLAN stack. The transmit power configuration consists of
a mode (automatic, fixed, limited) and the limit mBm value.
Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
---
Makefile | 3 ++-
nl80211.h | 27 ++++++++++++++++++++++++++-
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index d303f45..cbb9504 100644
--- a/Makefile
+++ b/Makefile
@@ -17,7 +17,8 @@ CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing
OBJS = iw.o genl.o event.o info.o phy.o \
interface.o ibss.o station.o survey.o util.o \
mesh.o mpath.o scan.o reg.o version.o \
- reason.o status.o connect.o link.o offch.o ps.o cqm.o
+ reason.o status.o connect.o link.o offch.o ps.o cqm.o \
+ txpower.o
OBJS += sections.o
ALL = iw
diff --git a/nl80211.h b/nl80211.h
index b7c77f9..c98a3a1 100644
--- a/nl80211.h
+++ b/nl80211.h
@@ -132,7 +132,7 @@
* %NL80211_ATTR_REG_RULE_POWER_MAX_ANT_GAIN and
* %NL80211_ATTR_REG_RULE_POWER_MAX_EIRP.
* @NL80211_CMD_REQ_SET_REG: ask the wireless core to set the regulatory domain
- * to the the specified ISO/IEC 3166-1 alpha2 country code. The core will
+ * to the specified ISO/IEC 3166-1 alpha2 country code. The core will
* store this as a valid request and then query userspace for it.
*
* @NL80211_CMD_GET_MESH_PARAMS: Get mesh networking properties for the
@@ -340,6 +340,7 @@
* no other interfaces are operating to avoid disturbing the operation
* of any other interfaces, and other interfaces will again take
* precedence when they are used.
+ * @NL80211_CMD_SET_TX_POWER: Set transmit power level and management type.
*
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
@@ -441,6 +442,8 @@ enum nl80211_commands {
NL80211_CMD_SET_CHANNEL,
+ NL80211_CMD_SET_TX_POWER,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -725,6 +728,13 @@ enum nl80211_commands {
* @NL80211_ATTR_AP_ISOLATE: (AP mode) Do not forward traffic between stations
* connected to this BSS.
*
+ * @NL80211_ATTR_TX_POWER_SETTING: Setting of the transmit power, see
+ * &enum nl80211_tx_power_setting for the possible values. This is
+ * currently used with @NL80211_CMD_SET_TX_POWER to specify the transmit
+ * power.
+ * @NL80211_ATTR_TX_POWER_LEVEL: Trasnmit power level in signed mBm format. This
+ * is currently used with @NL80211_CMD_SET_TX_POWER to specify the transmit
+ * power.
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -882,6 +892,9 @@ enum nl80211_attrs {
NL80211_ATTR_AP_ISOLATE,
+ NL80211_ATTR_TX_POWER_SETTING,
+ NL80211_ATTR_TX_POWER_LEVEL,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -1624,6 +1637,18 @@ enum nl80211_ps_state {
};
/**
+ * enum nl80211_tx_power_setting - TX power adjustment
+ * @TX_POWER_AUTOMATIC: automatic TX power handling
+ * @TX_POWER_LIMITED: limit TX power to the specified level
+ * @TX_POWER_FIXED: fix TX power to the specified level
+ */
+enum nl80211_tx_power_setting {
+ NL80211_TX_POWER_AUTOMATIC,
+ NL80211_TX_POWER_LIMITED,
+ NL80211_TX_POWER_FIXED,
+};
+
+/**
* enum nl80211_attr_cqm - connection quality monitor attributes
* @__NL80211_ATTR_CQM_INVALID: invalid
* @NL80211_ATTR_CQM_RSSI_THOLD: RSSI threshold in dBm. This value specifies
--
1.6.3.3
^ permalink raw reply related
* [RFC PATCH] nl80211/cfg80211/mac80211: Add support for setting transmit power
From: Juuso Oikarinen @ 2010-06-15 9:17 UTC (permalink / raw)
To: linux-wireless
This patch adds an interface to adjust the transmit power level. Using this
interface the transmit power mode (automatic, limited or fixed) can be set
along with the power level to be enforced.
The power level is specified with a signed mBm unit value, which allows for
greater accuracy and smaller power levels.
Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
---
include/linux/nl80211.h | 24 ++++++++++++++++
include/net/cfg80211.h | 15 +---------
net/mac80211/cfg.c | 8 ++--
net/wireless/nl80211.c | 66 ++++++++++++++++++++++++++++++++++++++++++++
net/wireless/wext-compat.c | 8 ++--
5 files changed, 99 insertions(+), 22 deletions(-)
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 64fb32b..047d28c 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -340,6 +340,8 @@
* no other interfaces are operating to avoid disturbing the operation
* of any other interfaces, and other interfaces will again take
* precedence when they are used.
+ * @NL80211_CMD_SET_TX_POWER: Set the used transmit power level (using
+ * %NL80211_ATTR_TX_POWER_SETTING and %NL80211_ATTR_TX_POWER_LEVEL).
*
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
@@ -441,6 +443,8 @@ enum nl80211_commands {
NL80211_CMD_SET_CHANNEL,
+ NL80211_CMD_SET_TX_POWER,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -725,6 +729,11 @@ enum nl80211_commands {
* @NL80211_ATTR_AP_ISOLATE: (AP mode) Do not forward traffic between stations
* connected to this BSS.
*
+ * @NL80211_ATTR_TX_POWER_SETTING: Setting of the transmit power, see
+ * &enum nl80211_tx_power_setting for the possible values. This is
+ * currently used with @NL80211_CMD_SET_TX_POWER.
+ * @NL80211_ATTR_TX_POWER_LEVEL: Trasnmit power level in signed mBm format. This
+ * is currently used with @NL80211_CMD_SET_TX_POWER.
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -882,6 +891,9 @@ enum nl80211_attrs {
NL80211_ATTR_AP_ISOLATE,
+ NL80211_ATTR_TX_POWER_SETTING,
+ NL80211_ATTR_TX_POWER_LEVEL,
+
/* add attributes here, update the policy in nl80211.c */
__NL80211_ATTR_AFTER_LAST,
@@ -1624,6 +1636,18 @@ enum nl80211_ps_state {
};
/**
+ * enum nl80211_tx_power_setting - TX power adjustment
+ * @TX_POWER_AUTOMATIC: automatic TX power handling
+ * @TX_POWER_LIMITED: limit TX power to the specified level
+ * @TX_POWER_FIXED: fix TX power to the specified level
+ */
+enum nl80211_tx_power_setting {
+ NL80211_TX_POWER_AUTOMATIC,
+ NL80211_TX_POWER_LIMITED,
+ NL80211_TX_POWER_FIXED,
+};
+
+/**
* enum nl80211_attr_cqm - connection quality monitor attributes
* @__NL80211_ATTR_CQM_INVALID: invalid
* @NL80211_ATTR_CQM_RSSI_THOLD: RSSI threshold in dBm. This value specifies
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 22ab9d8..4db30f8 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -873,19 +873,6 @@ enum wiphy_params_flags {
WIPHY_PARAM_COVERAGE_CLASS = 1 << 4,
};
-/**
- * enum tx_power_setting - TX power adjustment
- *
- * @TX_POWER_AUTOMATIC: the dbm parameter is ignored
- * @TX_POWER_LIMITED: limit TX power by the dbm parameter
- * @TX_POWER_FIXED: fix TX power to the dbm parameter
- */
-enum tx_power_setting {
- TX_POWER_AUTOMATIC,
- TX_POWER_LIMITED,
- TX_POWER_FIXED,
-};
-
/*
* cfg80211_bitrate_mask - masks for bitrate control
*/
@@ -1147,7 +1134,7 @@ struct cfg80211_ops {
int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed);
int (*set_tx_power)(struct wiphy *wiphy,
- enum tx_power_setting type, int dbm);
+ enum nl80211_tx_power_setting type, int dbm);
int (*get_tx_power)(struct wiphy *wiphy, int *dbm);
int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 952845e..c1c149e 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1329,22 +1329,22 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
}
static int ieee80211_set_tx_power(struct wiphy *wiphy,
- enum tx_power_setting type, int dbm)
+ enum nl80211_tx_power_setting type, int dbm)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
struct ieee80211_channel *chan = local->hw.conf.channel;
u32 changes = 0;
switch (type) {
- case TX_POWER_AUTOMATIC:
+ case NL80211_TX_POWER_AUTOMATIC:
local->user_power_level = -1;
break;
- case TX_POWER_LIMITED:
+ case NL80211_TX_POWER_LIMITED:
if (dbm < 0)
return -EINVAL;
local->user_power_level = dbm;
break;
- case TX_POWER_FIXED:
+ case NL80211_TX_POWER_FIXED:
if (dbm < 0)
return -EINVAL;
/* TODO: move to cfg80211 when it knows the channel */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 90ab3c8..32b3352 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -153,6 +153,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_CQM] = { .type = NLA_NESTED, },
[NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG },
[NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 },
+ [NL80211_ATTR_TX_POWER_SETTING] = { .type = NLA_U32 },
+ [NL80211_ATTR_TX_POWER_LEVEL] = { .type = NLA_U32 },
};
/* policy for the attributes */
@@ -4968,6 +4970,64 @@ out:
return err;
}
+static int nl80211_set_tx_power(struct sk_buff *skb, struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev;
+ struct wireless_dev *wdev;
+ struct net_device *dev;
+ enum nl80211_tx_power_setting type;
+ int mbm = 0;
+ int err;
+
+ if (!info->attrs[NL80211_ATTR_TX_POWER_SETTING]) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ type = nla_get_u32(info->attrs[NL80211_ATTR_TX_POWER_SETTING]);
+
+ if (!info->attrs[NL80211_ATTR_TX_POWER_LEVEL] &&
+ (type != NL80211_TX_POWER_AUTOMATIC)) {
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (type != NL80211_TX_POWER_AUTOMATIC)
+ mbm = nla_get_u32(info->attrs[NL80211_ATTR_TX_POWER_LEVEL]);
+
+ /*
+ * Though the nl80211 supports negative mBm values, the interface
+ * below it does not, for now.
+ */
+ if (mbm < 0) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
+ rtnl_lock();
+
+ err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
+ if (err)
+ goto unlock_rdev;
+
+ wdev = dev->ieee80211_ptr;
+
+ if (!rdev->ops->set_tx_power) {
+ return -EOPNOTSUPP;
+ goto unlock_rdev;
+ }
+
+ err = rdev->ops->set_tx_power(wdev->wiphy, type, MBM_TO_DBM(mbm));
+
+unlock_rdev:
+ cfg80211_unlock_rdev(rdev);
+ dev_put(dev);
+ rtnl_unlock();
+
+out:
+ return err;
+}
+
static struct genl_ops nl80211_ops[] = {
{
.cmd = NL80211_CMD_GET_WIPHY,
@@ -5284,6 +5344,12 @@ static struct genl_ops nl80211_ops[] = {
.policy = nl80211_policy,
.flags = GENL_ADMIN_PERM,
},
+ {
+ .cmd = NL80211_CMD_SET_TX_POWER,
+ .doit = nl80211_set_tx_power,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ },
};
static struct genl_multicast_group nl80211_mlme_mcgrp = {
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 9634299..3dfe8ed 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -829,7 +829,7 @@ int cfg80211_wext_siwtxpower(struct net_device *dev,
{
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
- enum tx_power_setting type;
+ enum nl80211_tx_power_setting type;
int dbm = 0;
if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
@@ -852,7 +852,7 @@ int cfg80211_wext_siwtxpower(struct net_device *dev,
if (data->txpower.value < 0)
return -EINVAL;
dbm = data->txpower.value;
- type = TX_POWER_FIXED;
+ type = NL80211_TX_POWER_FIXED;
/* TODO: do regulatory check! */
} else {
/*
@@ -860,10 +860,10 @@ int cfg80211_wext_siwtxpower(struct net_device *dev,
* passed in from userland.
*/
if (data->txpower.value < 0) {
- type = TX_POWER_AUTOMATIC;
+ type = NL80211_TX_POWER_AUTOMATIC;
} else {
dbm = data->txpower.value;
- type = TX_POWER_LIMITED;
+ type = NL80211_TX_POWER_LIMITED;
}
}
} else {
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH] iw: Configure basic rates when joining ibss network
From: Teemu Paasikivi @ 2010-06-15 8:50 UTC (permalink / raw)
To: ext Johannes Berg; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <1276586335.3648.3.camel@jlt3.sipsolutions.net>
On Tue, 2010-06-15 at 09:18 +0200, ext Johannes Berg wrote:
> On Tue, 2010-06-15 at 09:24 +0300, Teemu Paasikivi wrote:
>
> > @@ -41,6 +46,31 @@ static int join_ibss(struct nl80211_state *state,
> > argc--;
> > }
> >
> > + /* basic rates */
> > + if (argc > 1 && strcmp(argv[0], "basic-rates") == 0) {
> > + argv++;
> > + argc--;
> > +
> > + value = strtok_r(argv[0], ",", &sptr);
> > +
> > + while (value && n_rates < NL80211_MAX_SUPP_RATES) {
> > + rate = atof(value);
>
> should that use strtod() to check you didn't give "1a,2b,6c,11d"?
>
Sure, it can be used. I think I'll change it to use that. I was just
wondering that how much the values given by the user should/could be
checked here.
> johannes
>
Br,
Teemu
^ permalink raw reply
* Re: [PATCH] ath9k: Modify LED blinking pattern during wifi activity.
From: Johannes Berg @ 2010-06-15 7:32 UTC (permalink / raw)
To: Vivek Natarajan; +Cc: linville, linux-wireless
In-Reply-To: <1276579217-6837-1-git-send-email-vnatarajan@atheros.com>
On Tue, 2010-06-15 at 10:50 +0530, Vivek Natarajan wrote:
> case LED_FULL:
I wonder if you can just use different triggers which may be easier?
Look at what I suggested earlier for integrating the LEDs with iwlwifi:
http://thread.gmane.org/gmane.linux.kernel.wireless.general/51218/focus=51520
Up to you, of course. I would love to do the iwlwifi stuff I suggested
but simply don't have time for it right now.
johannes
^ permalink raw reply
* Re: [PATCH] iw: Configure basic rates when joining ibss network
From: Johannes Berg @ 2010-06-15 7:18 UTC (permalink / raw)
To: Teemu Paasikivi; +Cc: linux-wireless
In-Reply-To: <1276583053-30638-1-git-send-email-ext-teemu.3.paasikivi@nokia.com>
On Tue, 2010-06-15 at 09:24 +0300, Teemu Paasikivi wrote:
> @@ -41,6 +46,31 @@ static int join_ibss(struct nl80211_state *state,
> argc--;
> }
>
> + /* basic rates */
> + if (argc > 1 && strcmp(argv[0], "basic-rates") == 0) {
> + argv++;
> + argc--;
> +
> + value = strtok_r(argv[0], ",", &sptr);
> +
> + while (value && n_rates < NL80211_MAX_SUPP_RATES) {
> + rate = atof(value);
should that use strtod() to check you didn't give "1a,2b,6c,11d"?
johannes
^ permalink raw reply
* [PATCH] iw: Configure basic rates when joining ibss network
From: Teemu Paasikivi @ 2010-06-15 6:24 UTC (permalink / raw)
To: johannes; +Cc: linux-wireless, Teemu Paasikivi
This patch adds option to configure basic rates when joining ibss network.
Signed-off-by: Teemu Paasikivi <ext-teemu.3.paasikivi@nokia.com>
---
ibss.c | 34 +++++++++++++++++++++++++++++++++-
1 files changed, 33 insertions(+), 1 deletions(-)
diff --git a/ibss.c b/ibss.c
index 4715ac8..cf57cf0 100644
--- a/ibss.c
+++ b/ibss.c
@@ -18,6 +18,11 @@ static int join_ibss(struct nl80211_state *state,
{
char *end;
unsigned char abssid[6];
+ unsigned char rates[NL80211_MAX_SUPP_RATES];
+ int n_rates = 0;
+ char *value = NULL, *sptr = NULL;
+ float rate;
+
if (argc < 2)
return 1;
@@ -41,6 +46,31 @@ static int join_ibss(struct nl80211_state *state,
argc--;
}
+ /* basic rates */
+ if (argc > 1 && strcmp(argv[0], "basic-rates") == 0) {
+ argv++;
+ argc--;
+
+ value = strtok_r(argv[0], ",", &sptr);
+
+ while (value && n_rates < NL80211_MAX_SUPP_RATES) {
+ rate = atof(value);
+ rates[n_rates] = rate * 2;
+
+ /* filter out suspicious values */
+ if (!rates[n_rates] || rate*2 != rates[n_rates])
+ return 1;
+
+ n_rates++;
+ value = strtok_r(NULL, ",", &sptr);
+ }
+
+ NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, n_rates, rates);
+
+ argv++;
+ argc--;
+ }
+
if (argc) {
if (mac_addr_a2n(abssid, argv[0]) == 0) {
NLA_PUT(msg, NL80211_ATTR_MAC, 6, abssid);
@@ -73,7 +103,9 @@ static int leave_ibss(struct nl80211_state *state,
COMMAND(ibss, leave, NULL,
NL80211_CMD_LEAVE_IBSS, 0, CIB_NETDEV, leave_ibss,
"Leave the current IBSS cell.");
-COMMAND(ibss, join, "<SSID> <freq in MHz> [fixed-freq] [<fixed bssid>] [key d:0:abcde]",
+COMMAND(ibss, join,
+ "<SSID> <freq in MHz> [fixed-freq] [<fixed bssid>] "
+ "[basic-rates <rate in Mbps,rate2,...>] [key d:0:abcde]",
NL80211_CMD_JOIN_IBSS, 0, CIB_NETDEV, join_ibss,
"Join the IBSS cell with the given SSID, if it doesn't exist create\n"
"it on the given frequency. When fixed frequency is requested, don't\n"
--
1.5.6.3
^ permalink raw reply related
* [PATCH] ath9k: Modify LED blinking pattern during wifi activity.
From: Vivek Natarajan @ 2010-06-15 5:20 UTC (permalink / raw)
To: linville; +Cc: linux-wireless
Some vendors require the LED to be ON always irrespective of any
radio activity. Introducing a module parameter to enable this,
so that one can choose between always on or led blink during
activity.
Signed-off-by: Vivek Natarajan <vnatarajan@atheros.com>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 1 +
drivers/net/wireless/ath/ath9k/gpio.c | 9 ++++++---
drivers/net/wireless/ath/ath9k/init.c | 4 ++++
drivers/net/wireless/ath/ath9k/main.c | 4 +++-
4 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 8d163ae..3a14630 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -628,6 +628,7 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
extern struct ieee80211_ops ath9k_ops;
extern int modparam_nohwcrypt;
+extern int led_blink;
irqreturn_t ath_isr(int irq, void *dev);
int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 0ee75e7..3a8ee99 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -76,7 +76,8 @@ static void ath_led_brightness(struct led_classdev *led_cdev,
case LED_FULL:
if (led->led_type == ATH_LED_ASSOC) {
sc->sc_flags |= SC_OP_LED_ASSOCIATED;
- ieee80211_queue_delayed_work(sc->hw,
+ if (led_blink)
+ ieee80211_queue_delayed_work(sc->hw,
&sc->ath_led_blink_work, 0);
} else if (led->led_type == ATH_LED_RADIO) {
ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
@@ -143,7 +144,8 @@ void ath_init_leds(struct ath_softc *sc)
/* LED off, active low */
ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
- INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
+ if (led_blink)
+ INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
trigger = ieee80211_get_radio_led_name(sc->hw);
snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
@@ -180,7 +182,8 @@ void ath_init_leds(struct ath_softc *sc)
return;
fail:
- cancel_delayed_work_sync(&sc->ath_led_blink_work);
+ if (led_blink)
+ cancel_delayed_work_sync(&sc->ath_led_blink_work);
ath_deinit_leds(sc);
}
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 514a401..b2bf0e8 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -33,6 +33,10 @@ int modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
+int led_blink;
+module_param_named(blink, led_blink, int, 0444);
+MODULE_PARM_DESC(blink, "Enable LED blink on activity");
+
/* We use the hw_value as an index into our private channel structure */
#define CHAN2G(_freq, _idx) { \
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index c8de50f..5af2596 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1241,7 +1241,9 @@ static void ath9k_stop(struct ieee80211_hw *hw)
aphy->state = ATH_WIPHY_INACTIVE;
- cancel_delayed_work_sync(&sc->ath_led_blink_work);
+ if (led_blink)
+ cancel_delayed_work_sync(&sc->ath_led_blink_work);
+
cancel_delayed_work_sync(&sc->tx_complete_work);
cancel_work_sync(&sc->paprd_work);
--
1.7.1
^ permalink raw reply related
* Re: [ath5k-devel] [PATCH] ath5k: disable all tasklets while resetting
From: Bruno Randolf @ 2010-06-15 4:54 UTC (permalink / raw)
To: Bob Copeland; +Cc: Johannes Berg, ath5k-devel, linux-wireless, linville
In-Reply-To: <20100615041016.GA13984@hash.localnet>
On Tue June 15 2010 13:10:16 Bob Copeland wrote:
> On Tue, Jun 15, 2010 at 10:07:21AM +0900, Bruno Randolf wrote:
> > On Mon June 14 2010 20:43:02 you wrote:
> > > On Mon, Jun 14, 2010 at 10:50:59AM +0900, Bruno Randolf wrote:
> > > > we disable interrupts right after disabling the tasklets, so they
> > > > should not be scheduled again, right? actually, we should disable
> > > > interrupts first, and then disable tasklets... but then it should be
> > > > safe, no?
> > >
> > > Disable interrupts then tasklet_kill should do it.
> >
> > what's wrong with first disable interrupts and tasklet_disable?
>
> Look at the code for tasklet_disable... it only waits for tasks that
> are in the run state but doesn't do anything for scheduled tasks.
> So you can still get the spinning behavior if the interrupt runs and
> schedules the tasklet on another CPU.
if we disable interrupts in the chip (ath5k_hw_set_imr) , the hardware does
not generate any interrupts. so no tasklets will get scheduled...
bruno
^ permalink raw reply
* [PATCH] ath9k_htc: Fix ampdu_action callback
From: Sujith @ 2010-06-15 4:54 UTC (permalink / raw)
To: linville; +Cc: linux-wireless
Now that ampdu_action() can sleep, remove all
the driver hacks and just issue WMI commands
to the target.
Signed-off-by: Sujith <Sujith.Manoharan@atheros.com>
---
drivers/net/wireless/ath/ath9k/htc.h | 20 +----
drivers/net/wireless/ath/ath9k/htc_drv_init.c | 3 -
drivers/net/wireless/ath/ath9k/htc_drv_main.c | 93 +++++++------------------
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 21 +++++-
4 files changed, 45 insertions(+), 92 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index c584fbd..58f52a1 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -223,15 +223,6 @@ struct ath9k_htc_sta {
enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID];
};
-struct ath9k_htc_aggr_work {
- u16 tid;
- u8 sta_addr[ETH_ALEN];
- struct ieee80211_hw *hw;
- struct ieee80211_vif *vif;
- enum ieee80211_ampdu_mlme_action action;
- struct mutex mutex;
-};
-
#define ATH9K_HTC_RXBUF 256
#define HTC_RX_FRAME_HEADER_SIZE 40
@@ -331,11 +322,10 @@ struct htc_beacon_config {
#define OP_LED_ON BIT(4)
#define OP_PREAMBLE_SHORT BIT(5)
#define OP_PROTECT_ENABLE BIT(6)
-#define OP_TXAGGR BIT(7)
-#define OP_ASSOCIATED BIT(8)
-#define OP_ENABLE_BEACON BIT(9)
-#define OP_LED_DEINIT BIT(10)
-#define OP_UNPLUGGED BIT(11)
+#define OP_ASSOCIATED BIT(7)
+#define OP_ENABLE_BEACON BIT(8)
+#define OP_LED_DEINIT BIT(9)
+#define OP_UNPLUGGED BIT(10)
struct ath9k_htc_priv {
struct device *dev;
@@ -376,8 +366,6 @@ struct ath9k_htc_priv {
struct ath9k_htc_rx rx;
struct tasklet_struct tx_tasklet;
struct sk_buff_head tx_queue;
- struct ath9k_htc_aggr_work aggr_work;
- struct delayed_work ath9k_aggr_work;
struct delayed_work ath9k_ani_work;
struct work_struct ps_work;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index d339e5f..a63ae88 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -606,7 +606,6 @@ static void ath9k_init_misc(struct ath9k_htc_priv *priv)
if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
- priv->op_flags |= OP_TXAGGR;
priv->ah->opmode = NL80211_IFTYPE_STATION;
}
@@ -638,14 +637,12 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid)
spin_lock_init(&priv->beacon_lock);
spin_lock_init(&priv->tx_lock);
mutex_init(&priv->mutex);
- mutex_init(&priv->aggr_work.mutex);
mutex_init(&priv->htc_pm_lock);
tasklet_init(&priv->wmi_tasklet, ath9k_wmi_tasklet,
(unsigned long)priv);
tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet,
(unsigned long)priv);
tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, (unsigned long)priv);
- INIT_DELAYED_WORK(&priv->ath9k_aggr_work, ath9k_htc_aggr_work);
INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work);
INIT_WORK(&priv->ps_work, ath9k_ps_work);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index b9206e4..05445d8 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -438,13 +438,13 @@ static void ath9k_htc_update_rate(struct ath9k_htc_priv *priv,
bss_conf->bssid, be32_to_cpu(trate.capflags));
}
-static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv,
- struct ieee80211_vif *vif,
- u8 *sta_addr, u8 tid, bool oper)
+int ath9k_htc_tx_aggr_oper(struct ath9k_htc_priv *priv,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ enum ieee80211_ampdu_mlme_action action, u16 tid)
{
struct ath_common *common = ath9k_hw_common(priv->ah);
struct ath9k_htc_target_aggr aggr;
- struct ieee80211_sta *sta = NULL;
struct ath9k_htc_sta *ista;
int ret = 0;
u8 cmd_rsp;
@@ -453,72 +453,28 @@ static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv,
return -EINVAL;
memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr));
-
- rcu_read_lock();
-
- /* Check if we are able to retrieve the station */
- sta = ieee80211_find_sta(vif, sta_addr);
- if (!sta) {
- rcu_read_unlock();
- return -EINVAL;
- }
-
ista = (struct ath9k_htc_sta *) sta->drv_priv;
- if (oper)
- ista->tid_state[tid] = AGGR_START;
- else
- ista->tid_state[tid] = AGGR_STOP;
-
aggr.sta_index = ista->index;
-
- rcu_read_unlock();
-
- aggr.tidno = tid;
- aggr.aggr_enable = oper;
+ aggr.tidno = tid & 0xf;
+ aggr.aggr_enable = (action == IEEE80211_AMPDU_TX_START) ? true : false;
WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr);
if (ret)
ath_print(common, ATH_DBG_CONFIG,
"Unable to %s TX aggregation for (%pM, %d)\n",
- (oper) ? "start" : "stop", sta->addr, tid);
+ (aggr.aggr_enable) ? "start" : "stop", sta->addr, tid);
else
ath_print(common, ATH_DBG_CONFIG,
- "%s aggregation for (%pM, %d)\n",
- (oper) ? "Starting" : "Stopping", sta->addr, tid);
-
- return ret;
-}
+ "%s TX aggregation for (%pM, %d)\n",
+ (aggr.aggr_enable) ? "Starting" : "Stopping",
+ sta->addr, tid);
-void ath9k_htc_aggr_work(struct work_struct *work)
-{
- int ret = 0;
- struct ath9k_htc_priv *priv =
- container_of(work, struct ath9k_htc_priv,
- ath9k_aggr_work.work);
- struct ath9k_htc_aggr_work *wk = &priv->aggr_work;
-
- mutex_lock(&wk->mutex);
-
- switch (wk->action) {
- case IEEE80211_AMPDU_TX_START:
- ret = ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr,
- wk->tid, true);
- if (!ret)
- ieee80211_start_tx_ba_cb_irqsafe(wk->vif, wk->sta_addr,
- wk->tid);
- break;
- case IEEE80211_AMPDU_TX_STOP:
- ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr,
- wk->tid, false);
- ieee80211_stop_tx_ba_cb_irqsafe(wk->vif, wk->sta_addr, wk->tid);
- break;
- default:
- ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
- "Unknown AMPDU action\n");
- }
+ spin_lock_bh(&priv->tx_lock);
+ ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP;
+ spin_unlock_bh(&priv->tx_lock);
- mutex_unlock(&wk->mutex);
+ return ret;
}
/*********/
@@ -1266,7 +1222,6 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
/* Cancel all the running timers/work .. */
cancel_work_sync(&priv->ps_work);
cancel_delayed_work_sync(&priv->ath9k_ani_work);
- cancel_delayed_work_sync(&priv->ath9k_aggr_work);
cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
ath9k_led_stop_brightness(priv);
@@ -1767,8 +1722,8 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
u16 tid, u16 *ssn)
{
struct ath9k_htc_priv *priv = hw->priv;
- struct ath9k_htc_aggr_work *work = &priv->aggr_work;
struct ath9k_htc_sta *ista;
+ int ret = 0;
switch (action) {
case IEEE80211_AMPDU_RX_START:
@@ -1776,26 +1731,26 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
case IEEE80211_AMPDU_RX_STOP:
break;
case IEEE80211_AMPDU_TX_START:
+ ret = ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
+ if (!ret)
+ ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+ break;
case IEEE80211_AMPDU_TX_STOP:
- if (!(priv->op_flags & OP_TXAGGR))
- return -ENOTSUPP;
- memcpy(work->sta_addr, sta->addr, ETH_ALEN);
- work->hw = hw;
- work->vif = vif;
- work->action = action;
- work->tid = tid;
- ieee80211_queue_delayed_work(hw, &priv->ath9k_aggr_work, 0);
+ ath9k_htc_tx_aggr_oper(priv, vif, sta, action, tid);
+ ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
break;
case IEEE80211_AMPDU_TX_OPERATIONAL:
ista = (struct ath9k_htc_sta *) sta->drv_priv;
+ spin_lock_bh(&priv->tx_lock);
ista->tid_state[tid] = AGGR_OPERATIONAL;
+ spin_unlock_bh(&priv->tx_lock);
break;
default:
ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL,
"Unknown AMPDU action\n");
}
- return 0;
+ return ret;
}
static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw)
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 89d3848..bd0b4ac 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -187,6 +187,19 @@ int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
return htc_send(priv->htc, skb, epid, &tx_ctl);
}
+static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
+ struct ath9k_htc_sta *ista, u8 tid)
+{
+ bool ret = false;
+
+ spin_lock_bh(&priv->tx_lock);
+ if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP))
+ ret = true;
+ spin_unlock_bh(&priv->tx_lock);
+
+ return ret;
+}
+
void ath9k_tx_tasklet(unsigned long data)
{
struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
@@ -216,8 +229,7 @@ void ath9k_tx_tasklet(unsigned long data)
/* Check if we need to start aggregation */
if (sta && conf_is_ht(&priv->hw->conf) &&
- (priv->op_flags & OP_TXAGGR)
- && !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
+ !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
if (ieee80211_is_data_qos(fc)) {
u8 *qc, tid;
struct ath9k_htc_sta *ista;
@@ -226,10 +238,11 @@ void ath9k_tx_tasklet(unsigned long data)
tid = qc[0] & 0xf;
ista = (struct ath9k_htc_sta *)sta->drv_priv;
- if ((tid < ATH9K_HTC_MAX_TID) &&
- ista->tid_state[tid] == AGGR_STOP) {
+ if (ath9k_htc_check_tx_aggr(priv, ista, tid)) {
ieee80211_start_tx_ba_session(sta, tid);
+ spin_lock_bh(&priv->tx_lock);
ista->tid_state[tid] = AGGR_PROGRESS;
+ spin_unlock_bh(&priv->tx_lock);
}
}
}
--
1.7.1
^ permalink raw reply related
* Re: [ath5k-devel] [PATCH] ath5k: disable all tasklets while resetting
From: Bob Copeland @ 2010-06-15 4:10 UTC (permalink / raw)
To: Bruno Randolf; +Cc: Johannes Berg, ath5k-devel, linux-wireless, linville
In-Reply-To: <201006151007.21708.br1@einfach.org>
On Tue, Jun 15, 2010 at 10:07:21AM +0900, Bruno Randolf wrote:
> On Mon June 14 2010 20:43:02 you wrote:
> > On Mon, Jun 14, 2010 at 10:50:59AM +0900, Bruno Randolf wrote:
> > > we disable interrupts right after disabling the tasklets, so they should
> > > not be scheduled again, right? actually, we should disable interrupts
> > > first, and then disable tasklets... but then it should be safe, no?
> >
> > Disable interrupts then tasklet_kill should do it.
>
> what's wrong with first disable interrupts and tasklet_disable?
Look at the code for tasklet_disable... it only waits for tasks that
are in the run state but doesn't do anything for scheduled tasks.
So you can still get the spinning behavior if the interrupt runs and
schedules the tasklet on another CPU.
--
Bob Copeland %% www.bobcopeland.com
^ permalink raw reply
* Re: [ath5k-devel] [PATCH] ath5k: disable all tasklets while resetting
From: Bruno Randolf @ 2010-06-15 1:07 UTC (permalink / raw)
To: Bob Copeland; +Cc: Johannes Berg, ath5k-devel, linux-wireless, linville
In-Reply-To: <20100614114302.GA15017@hash.localnet>
On Mon June 14 2010 20:43:02 you wrote:
> On Mon, Jun 14, 2010 at 10:50:59AM +0900, Bruno Randolf wrote:
> > we disable interrupts right after disabling the tasklets, so they should
> > not be scheduled again, right? actually, we should disable interrupts
> > first, and then disable tasklets... but then it should be safe, no?
>
> Disable interrupts then tasklet_kill should do it.
what's wrong with first disable interrupts and tasklet_disable?
bruno
^ permalink raw reply
* [PATCH] ath9k_hw: avoid setting cwmin/cwmax to 0 for IBSS for AR9003
From: Luis R. Rodriguez @ 2010-06-15 0:17 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Luis R. Rodriguez
IBSS requires the cwmin and cwmax to be respected when
we reset the txqueues on AR9003 otherwise the distribution
of beacons will be balanced towards the AR9003 card first
preventing equal contention for air time for other peers
on the IBSS.
Without this IBSS will work but only the AR9003 card will be
be issuing beacons on the IBSS.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath9k/mac.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 1550591..e955bb9 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -555,8 +555,13 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
REGWRITE_BUFFER_FLUSH(ah);
DISABLE_REGWRITE_BUFFER(ah);
- /* cwmin and cwmax should be 0 for beacon queue */
- if (AR_SREV_9300_20_OR_LATER(ah)) {
+ /*
+ * cwmin and cwmax should be 0 for beacon queue
+ * but not for IBSS as we would create an imbalance
+ * on beaconing fairness for participating nodes.
+ */
+ if (AR_SREV_9300_20_OR_LATER(ah) &&
+ ah->opmode != NL80211_IFTYPE_ADHOC) {
REG_WRITE(ah, AR_DLCL_IFS(q), SM(0, AR_D_LCL_IFS_CWMIN)
| SM(0, AR_D_LCL_IFS_CWMAX)
| SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
--
1.6.3.3
^ permalink raw reply related
* Re: wireless button problem with atheros on hp machines
From: Luis R. Rodriguez @ 2010-06-14 22:49 UTC (permalink / raw)
To: Leonardo; +Cc: linux-wireless
In-Reply-To: <AANLkTik2kYW-GxWK7ZIPj7crBZKP6JTsWJs2Mfy7xvoe@mail.gmail.com>
On Mon, Jun 14, 2010 at 2:35 PM, Leonardo <sombriks@gmail.com> wrote:
> 2010/6/13 Luis R. Rodriguez <mcgrof@gmail.com>:
>> On Sun, Jun 13, 2010 at 1:49 PM, Leonardo <sombriks@gmail.com> wrote:
>>> hello all, i don't know if this is the correct channel to report, but
>>> from Slackware 13.0 (2.6.29.6) to 13.1 (2.6.33.4) the wireless button
>>> stopped to work properly.
>>
>> Try 2.6.30, 2.6.31, and 2.6.32 and see if you see the issue on one of
>> those. If so then you can use git bisect to find the culprit. I
>> realize this can be quite cumbersome, but without more information I'm
>> afraid this is as good as it gets. Instead of using Linus' tree you'll
>> want to use the linux-2.6-allstable.git tree since that will have the
>> extra version kernel revisions.
>>
>> git://git.kernel.org/pub/scm/linux/kernel/git/hpa/linux-2.6-allstable.git
>>
>> Luis
>>
>
> Hello currently i'm trying those other kernel versions. I'm grabbing
> it from http://www.kernel.org/
>
> for now i have about 3 kernels running ok or almost ok:
>
> 2.6.33.4
> 2.6.29.6
> 2.6.31.13
>
> 29 and 33 are default packages from slackware, and as i related before
> by using 2.6.29.6 i get the perfect functionality of wireless
> button/led (those hp machines have the led, and if i touch the led it
> changes de color.. nvm)
>
> today i got the 31.13 running; i have to say, maybe i have missed
> something, because i lost sound and the 3d stuff. also ath5k.ko wasn't
> created... but the bluetooth worked as expected, just as 2.6.29.6; i
> am almost sure that i missed the kernel configuration, but fortunately
> i've made a package (make targz-pkg) so i can fix it.
>
> next i'll try the 2.6.32.15 and then 2.6.34, and with some hope find
> when the problem began and report there.
Once you narrow it down between kernel revisions then you can git
bisect yourself to narrow down the issue to the specific culprit
commit.
Luis
^ permalink raw reply
* Re: CARL9170
From: Christian Lamparter @ 2010-06-14 22:32 UTC (permalink / raw)
To: David H. Lynch Jr.; +Cc: linux-wireless
In-Reply-To: <4C169610.5020907@dlasys.net>
On Monday 14 June 2010 22:50:24 David H. Lynch Jr. wrote:
> Many routines are coded to look like interrupt handlers, but the
> code seems to be entirely polled ?
Hardware design decision.
(See "AR9170 STA Programming Guide" - Paragraph 3-3.)
> Am I correct there ? If so do you know if the AR9170-fw code or
> something else might show an example of interrupt handling for the
> AR9170. I must have tx complete interrupts.
Well you have to "poll" the MAC's WLAN Status Registers (0x1c3510?) for
BIT(0)=TX COMP (and BIT(2) = TX FAIL) changes...
Or, if you are only sending one frame at a time, you might be able to poll
0x1c36d4 instead. Also you could decrease the maximum pending tx "interrupt"
timeout in 0x1c3d7c etc...
But if that does not satisfy your need for "real-time responsiveness", you
should contact Stephen Chen @ Atheros directly, maybe he knows a undocumented
feature register which enables real-time interrupt processing.
> Next there are remarks throught the driver and firmware regarding
> cookies.
> I think a cookie is a u8 that uniquely identifies a packet - is
> that correct ?
>
> In the firmware there is a remark somewhere that suguests that the
> cookie AND something else are needed - is that correct or is the cookie
> sufficient ?
This is because of historic reasons. In ar9170usb the driver had
use dirty tricks to get the AC_ID into the firmware's tx report.
So it could do some primitive frame lookup.
carl9170 driver still needs the AC_ID (but now) to reduce the frame lookup cost.
This is somewhat necessary because tx feedback is usually processed in a
critical section and when aggregation is enabled, it can be up to 16 frames
at any time...
regards,
Chr
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox