Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH v2 2/6] nl80211: Pass probe response data to drivers
From: Arik Nemtsov @ 2011-01-23 21:02 UTC (permalink / raw)
  To: linux-wireless
  Cc: Luciano Coelho, Johannes Berg, John W. Linville, Arik Nemtsov
In-Reply-To: <1295816579-28925-1-git-send-email-arik@wizery.com>

Allow usermode to pass probe-response data. This data can be used as a
template probe-response offloading.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
---
 include/linux/nl80211.h |    9 +++++++++
 include/net/cfg80211.h  |    3 +++
 net/wireless/nl80211.c  |   32 ++++++++++++++++++++++++++++++++
 3 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 821ffb9..ba19c4b 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -410,6 +410,9 @@
  *	notification. This event is used to indicate that an unprotected
  *	disassociation frame was dropped when MFP is in use.
  *
+ * @NL80211_CMD_SET_PROBE_RESP: Set a Probe Response template to an access
+ *	point interface
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -522,6 +525,8 @@ enum nl80211_commands {
 	NL80211_CMD_UNPROT_DEAUTHENTICATE,
 	NL80211_CMD_UNPROT_DISASSOCIATE,
 
+	NL80211_CMD_SET_PROBE_RESP,
+
 	/* add new commands above here */
 
 	/* used to define NL80211_CMD_MAX below */
@@ -887,6 +892,8 @@ enum nl80211_commands {
  * @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute
  *	containing attributes from &enum nl80211_meshconf_params.
  *
+ * @NL80211_ATTR_PROBE_RESP: Probe Response template data
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1074,6 +1081,8 @@ enum nl80211_attrs {
 	NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
 	NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
 
+	NL80211_ATTR_PROBE_RESP,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 03b1b0c..8b3f427 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1366,6 +1366,9 @@ struct cfg80211_ops {
 
 	int	(*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant);
 	int	(*get_antenna)(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant);
+
+	int	(*set_probe_resp)(struct wiphy *wiphy, struct net_device *dev,
+				  u8 *resp, size_t resp_len);
 };
 
 /*
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index ce5453d..50151a2 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -172,6 +172,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
 	[NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
 	[NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
 	[NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
+	[NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY,
+				      .len = IEEE80211_MAX_DATA_LEN },
 };
 
 /* policy for the key attributes */
@@ -1917,6 +1919,28 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
 	return rdev->ops->del_beacon(&rdev->wiphy, dev);
 }
 
+static int nl80211_set_probe_resp(struct sk_buff *skb, struct genl_info *info)
+{
+	struct cfg80211_registered_device *rdev = info->user_ptr[0];
+	struct net_device *dev = info->user_ptr[1];
+	u8 *resp;
+	size_t resp_len;
+
+	if (!rdev->ops->set_probe_resp)
+		return -EOPNOTSUPP;
+
+	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP)
+		return -EOPNOTSUPP;
+
+	if (!info->attrs[NL80211_ATTR_PROBE_RESP])
+		return -EINVAL;
+
+	resp = nla_data(info->attrs[NL80211_ATTR_PROBE_RESP]);
+	resp_len = nla_len(info->attrs[NL80211_ATTR_PROBE_RESP]);
+
+	return rdev->ops->set_probe_resp(&rdev->wiphy, dev, resp, resp_len);
+}
+
 static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
 	[NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
 	[NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
@@ -5266,6 +5290,14 @@ static struct genl_ops nl80211_ops[] = {
 		.internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
 				  NL80211_FLAG_NEED_RTNL,
 	},
+	{
+		.cmd = NL80211_CMD_SET_PROBE_RESP,
+		.policy = nl80211_policy,
+		.flags = GENL_ADMIN_PERM,
+		.doit = nl80211_set_probe_resp,
+		.internal_flags = NL80211_FLAG_NEED_NETDEV |
+				  NL80211_FLAG_NEED_RTNL,
+	},
 };
 
 static struct genl_multicast_group nl80211_mlme_mcgrp = {
-- 
1.7.1


^ permalink raw reply related

* [PATCH v2 1/6] nl80211: allow passing SSID in nl80211_set_bss
From: Arik Nemtsov @ 2011-01-23 21:02 UTC (permalink / raw)
  To: linux-wireless
  Cc: Luciano Coelho, Johannes Berg, John W. Linville, Arik Nemtsov
In-Reply-To: <1295816579-28925-1-git-send-email-arik@wizery.com>

wl12xx require knowledge of the real SSID when operating as AP
with SSID hidden in beacon data. Allow passing the real SSID from
usermode apart from beacon data.

Signed-off-by: Arik Nemtsov <arik@wizery.com>
---
 include/net/cfg80211.h |    5 +++++
 net/wireless/nl80211.c |    8 ++++++++
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 1322695..03b1b0c 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -607,6 +607,9 @@ struct mpath_info {
  * @ap_isolate: do not forward packets between connected stations
  * @ht_opmode: HT Operation mode
  * 	(u16 = opmode, -1 = do not change)
+ * @ssid_len: length of ssid string
+ *	(>0 = ssid_len, -1 = do not change)
+ * @ssid: SSID string (for AP mode). NULL termination not required.
  */
 struct bss_parameters {
 	int use_cts_prot;
@@ -616,6 +619,8 @@ struct bss_parameters {
 	u8 basic_rates_len;
 	int ap_isolate;
 	int ht_opmode;
+	int ssid_len;
+	u8 *ssid;
 };
 
 /*
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 9b62710..ce5453d 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2576,6 +2576,7 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
 	params.use_short_slot_time = -1;
 	params.ap_isolate = -1;
 	params.ht_opmode = -1;
+	params.ssid_len = -1;
 
 	if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
 		params.use_cts_prot =
@@ -2597,6 +2598,13 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
 	if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE])
 		params.ht_opmode =
 			nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]);
+	if (info->attrs[NL80211_ATTR_SSID]) {
+		params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
+		params.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
+		if (params.ssid_len == 0 ||
+		    params.ssid_len > IEEE80211_MAX_SSID_LEN)
+			return -EINVAL;
+	}
 
 	if (!rdev->ops->change_bss)
 		return -EOPNOTSUPP;
-- 
1.7.1


^ permalink raw reply related

* [PATCH v2 0/6] Probe-resp offloading support
From: Arik Nemtsov @ 2011-01-23 21:02 UTC (permalink / raw)
  To: linux-wireless
  Cc: Luciano Coelho, Johannes Berg, John W. Linville, Arik Nemtsov

Support passing SSID and probe-response template to drivers.
This data can be used to offload the beacon -> probe-req -> probe-resp
process to HW.

v1->v2: Add probe response template configuration

Arik Nemtsov (6):
  nl80211: allow passing SSID in nl80211_set_bss
  nl80211: Pass probe response data to drivers
  mac80211: add SSID for AP mode with change notification
  mac80211: Save probe response data for BSS
  wl12xx: AP mode - support hidden SSID
  wl12xx: configure probe-resp template according to notification

 drivers/net/wireless/wl12xx/cmd.c  |   23 +++++++++-----------
 drivers/net/wireless/wl12xx/main.c |   32 +++++++++++++++++++++++++++-
 include/linux/nl80211.h            |    9 ++++++++
 include/net/cfg80211.h             |    8 +++++++
 include/net/mac80211.h             |   21 ++++++++++++++++++
 net/mac80211/cfg.c                 |   40 ++++++++++++++++++++++++++++++++++++
 net/mac80211/ieee80211_i.h         |    1 +
 net/mac80211/iface.c               |    5 +++-
 net/mac80211/tx.c                  |   31 +++++++++++++++++++++++++++
 net/mac80211/util.c                |    8 ++++++-
 net/wireless/nl80211.c             |   40 ++++++++++++++++++++++++++++++++++++
 11 files changed, 202 insertions(+), 16 deletions(-)


^ permalink raw reply

* Compat-wireless release for 2011-01-23 is baked
From: Compat-wireless cronjob account @ 2011-01-23 20:02 UTC (permalink / raw)
  To: linux-wireless


compat-wireless code metrics

    782984 - Total upstream lines of code being pulled
      2103 - backport code changes
      1843 - backport code additions
       260 - backport code deletions
      7279 - backport from compat module
      9382 - total backport code
    1.1982 - % of code consists of backport work
      1531 - Crap changes not yet posted
      1488 - Crap additions not yet posted
        43 - Crap deletions not yet posted
    0.1955 - % of crap code

Base tree: linux-next.git
Base tree version: next-20110121
compat-wireless release: compat-wireless-2011-01-06-3-g8db1608-pc

^ permalink raw reply

* Re: [PATCH 04/14]  iwlagn: 2000 series devices support
From: Guy, Wey-Yi @ 2011-01-23 18:12 UTC (permalink / raw)
  To: Bernhard Schmidt
  Cc: linville@tuxdriver.com, linux-wireless@vger.kernel.org,
	ipw3945-devel@lists.sourceforge.net
In-Reply-To: <201101231225.03056.bschmidt@techwires.net>

On Sun, 2011-01-23 at 03:25 -0800, Bernhard Schmidt wrote:
> On Saturday 22 January 2011 01:06:39 Wey-Yi Guy wrote:
> > From: Wey-Yi Guy <wey-yi.w.guy@intel.com>
> > 
> > Adding 2000 series devices supports, the 2000 series devices has
> > many different SKUs which includes 1x1 and 2x2 devices,also with
> > and without BT combo.
> > 
> > Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
> > [..]
> > +
> > +#define IWL_DEVICE_2030						\
> > +	.fw_name_pre = IWL2030_FW_PRE,				\
> > +	.ucode_api_max = IWL2030_UCODE_API_MAX,			\
> > +	.ucode_api_min = IWL2030_UCODE_API_MIN,			\
> > +	.eeprom_ver = EEPROM_2000_EEPROM_VERSION,		\
> > +	.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,	\
> > +	.ops = &iwl2030_ops,					\
> > +	.mod_params = &iwlagn_mod_params,			\
> > +	.base_params = &iwl2030_base_params,			\
> > +	.bt_params = &iwl2030_bt_params,			\
> > +	.need_dc_calib = true,					\
> > +	.need_temp_offset_calib = true,				\
> > +	.led_mode = IWL_LED_RF_STATE,				\
> > +	.adv_pm = true						\
> > +
> > +struct iwl_cfg iwl2030_2bgn_cfg = {
> > +	.name = "2000 Series 2x2 BGN/BT",
> > +	IWL_DEVICE_2000,
> > +	.ht_params = &iwl2000_ht_params,
> > +};
> > +
> > +struct iwl_cfg iwl2030_2bg_cfg = {
> > +	.name = "2000 Series 2x2 BG/BT",
> > +	IWL_DEVICE_2000,
> > +};
> 
> Shouldn't these use the IWL_DEVICE_2030 macro?
> 
good catch, thank you very much, will submit separated patch to address
it

Wey




^ permalink raw reply

* Re: [PATCH 01/14] iwlwifi: use mac80211 throughput trigger
From: Guy, Wey-Yi @ 2011-01-23 18:05 UTC (permalink / raw)
  To: Johannes Berg
  Cc: linville@tuxdriver.com, linux-wireless@vger.kernel.org,
	ipw3945-devel@lists.sourceforge.net
In-Reply-To: <1295773526.3639.3.camel@jlt3.sipsolutions.net>

On Sun, 2011-01-23 at 01:05 -0800, Johannes Berg wrote:
> That should have
> 
> From: Johannes Berg <johannes.berg@intel.com>
> 
> :-)
> 
Very sorry, never mean to take the credit from you :-)
my mistake and need to be really careful and read twice before push.

Wey



^ permalink raw reply

* Re: [PATCH 1/3] nl80211: allow passing SSID in nl80211_set_bss
From: Jouni Malinen @ 2011-01-23 16:26 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Arik Nemtsov, linux-wireless, Luciano Coelho, John W. Linville
In-Reply-To: <1295774590.3639.20.camel@jlt3.sipsolutions.net>

On Sun, Jan 23, 2011 at 10:23:10AM +0100, Johannes Berg wrote:
> Not really, except that I think that by itself it's insufficient. I
> might add that depending on how the probe response thing works out in
> the supplicant, it might make sense to add a capability flag that makes
> the driver request this behaviour, since it would also disable
> multi-SSID operation on a single BSSID (if that gets ever implemented)
> for example since only a single probe request can be transmitted.

Yes, it would be useful to allow user space to figure out whether the
driver is generating Probe Response frames on it own (without having to
guess this based on never seeing Probe Request frames or something
similar).

> Also, P2P GO might be quite tricky with this, but I'm not exactly sure.

For the most basic functionality, it need a mechanism that allows the
Probe Response template to be updated during the lifetime of the BSS.
However, to fully comply with the P2P spec, whatever code is taking care
of processing Probe Request frames would need to be able to
conditionally include the P2P IE(s) from the template based on whether
the Probe Request frame included a P2P IE. In addition, it would need to
be able to check the Requested Device Type against the list of device
types (both local and remote) in the group to determine whether to reply
to the request.

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply

* Re: [PATCH v2] mac80211:  Optimize scans on current operating channel.
From: Ben Greear @ 2011-01-23 15:49 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless
In-Reply-To: <1295774293.3639.15.camel@jlt3.sipsolutions.net>

On 01/23/2011 01:18 AM, Johannes Berg wrote:
> On Fri, 2011-01-21 at 10:05 -0800, greearb@candelatech.com wrote:
>
>> + * @SCAN_LEFT_OPER_CHANNEL:  Set this flag if the scan process leaves the
>> + *      operating channel at any time.  If scanning ONLY the current operating
>> + *      channel this flag should not be set, and this will allow fewer
>> + *      offchannel changes.
>
> Why does this make sense? In the code below, you do
>
>
>> -	ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
>> +	if ((local->oper_channel != local->hw.conf.channel) || was_hw_scan)
>> +		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
>> +
>>   	if (!was_hw_scan) {
>>   		ieee80211_configure_filter(local);
>>   		drv_sw_scan_complete(local);
>> -		ieee80211_offchannel_return(local, true);
>> +		if (test_bit(SCAN_LEFT_OPER_CHANNEL,&local->scanning))
>> +			ieee80211_offchannel_return(local, true);
>
> so you could just as well use a local variable (the first if you add is
> exactly this test).

I'm sorry, but I don't understand your comments.  I need some way to track
whether we ever called the offchannel-stop-beaconing code so that it can
be selectively re-enabled in the code above.  I was using a flag
instead of adding another boolean to the local struct.

The flag could be called 'SCAN_STOPPED_BEACONING' instead if that makes more
sense?

>>   static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local,
>>   						    unsigned long *next_delay)
>>   {
>> +	ieee80211_offchannel_stop_beaconing(local);
>> +
>
> Won't that confuse drivers that expect not to be beaconing between
> sw_scan_start and sw_scan_end?

I didn't know that any would care.  Maybe we need a phy_features set of
flags and let each driver enable this optimization as it is tested/verified?
Seems to work fine for ath9k with multiple VIFs, for what that's worth.

> Also, are you sure the filter configuration works correctly this way? If
> you can, I'd like to look at a binary trace of the commands going to the
> device with this change: "trace-cmd record -e mac80211".

I'll try to run this soon and post the results.

Thanks,
Ben


-- 
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc  http://www.candelatech.com

^ permalink raw reply

* Re: [PATCH 04/14]  iwlagn: 2000 series devices support
From: Bernhard Schmidt @ 2011-01-23 11:25 UTC (permalink / raw)
  To: Wey-Yi Guy; +Cc: linville, linux-wireless, ipw3945-devel
In-Reply-To: <1295654809-5790-5-git-send-email-wey-yi.w.guy@intel.com>

On Saturday 22 January 2011 01:06:39 Wey-Yi Guy wrote:
> From: Wey-Yi Guy <wey-yi.w.guy@intel.com>
> 
> Adding 2000 series devices supports, the 2000 series devices has
> many different SKUs which includes 1x1 and 2x2 devices,also with
> and without BT combo.
> 
> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
> [..]
> +
> +#define IWL_DEVICE_2030						\
> +	.fw_name_pre = IWL2030_FW_PRE,				\
> +	.ucode_api_max = IWL2030_UCODE_API_MAX,			\
> +	.ucode_api_min = IWL2030_UCODE_API_MIN,			\
> +	.eeprom_ver = EEPROM_2000_EEPROM_VERSION,		\
> +	.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,	\
> +	.ops = &iwl2030_ops,					\
> +	.mod_params = &iwlagn_mod_params,			\
> +	.base_params = &iwl2030_base_params,			\
> +	.bt_params = &iwl2030_bt_params,			\
> +	.need_dc_calib = true,					\
> +	.need_temp_offset_calib = true,				\
> +	.led_mode = IWL_LED_RF_STATE,				\
> +	.adv_pm = true						\
> +
> +struct iwl_cfg iwl2030_2bgn_cfg = {
> +	.name = "2000 Series 2x2 BGN/BT",
> +	IWL_DEVICE_2000,
> +	.ht_params = &iwl2000_ht_params,
> +};
> +
> +struct iwl_cfg iwl2030_2bg_cfg = {
> +	.name = "2000 Series 2x2 BG/BT",
> +	IWL_DEVICE_2000,
> +};

Shouldn't these use the IWL_DEVICE_2030 macro?

-- 
Bernhard

^ permalink raw reply

* [PATCH] wl12xx: wrong values are returned in gpio_power_write()
From: Eliad Peller @ 2011-01-23 10:25 UTC (permalink / raw)
  To: Luciano Coelho; +Cc: linux-wireless

Return values were assigned to incorrect var / weren't assigned.
fix it, and defer mutex_lock after the sanity checks.

Signed-off-by: Eliad Peller <eliad@wizery.com>
---
 drivers/net/wireless/wl12xx/debugfs.c |   10 ++++------
 1 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index 36e7ec1..1f85dc2 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -261,27 +261,25 @@ static ssize_t gpio_power_write(struct file *file,
 	unsigned long value;
 	int ret;
 
-	mutex_lock(&wl->mutex);
-
 	len = min(count, sizeof(buf) - 1);
 	if (copy_from_user(buf, user_buf, len)) {
-		ret = -EFAULT;
-		goto out;
+		return -EFAULT;
 	}
 	buf[len] = '\0';
 
 	ret = strict_strtoul(buf, 0, &value);
 	if (ret < 0) {
 		wl1271_warning("illegal value in gpio_power");
-		goto out;
+		return -EINVAL;
 	}
 
+	mutex_lock(&wl->mutex);
+
 	if (value)
 		wl1271_power_on(wl);
 	else
 		wl1271_power_off(wl);
 
-out:
 	mutex_unlock(&wl->mutex);
 	return count;
 }
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2] mac80211: use DECLARE_EVENT_CLASS
From: Johannes Berg @ 2011-01-23 10:12 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <20110121212447.GB7092@tuxdriver.com>

From: Johannes Berg <johannes.berg@intel.com>

For events that include only the local struct as
their parameter, we can use DECLARE_EVENT_CLASS
and save quite some binary size across segments
as well lines of code.

   text	   data	    bss	    dec	    hex	filename
 375745	  19296	    916	 395957	  60ab5	mac80211.ko.before
 367473	  17888	    916	 386277	  5e4e5	mac80211.ko.after
  -8272   -1408       0   -9680   -25d0 delta

Some more tracepoints with identical arguments
could be combined like this but for now this is
the one that benefits most.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/driver-trace.h |  197 ++++++--------------------------------------
 1 file changed, 28 insertions(+), 169 deletions(-)

--- wireless-testing.orig/net/mac80211/driver-trace.h	2011-01-23 10:57:48.000000000 +0100
+++ wireless-testing/net/mac80211/driver-trace.h	2011-01-23 10:57:56.000000000 +0100
@@ -38,7 +38,7 @@ static inline void trace_ ## name(proto)
  * Tracing for driver callbacks.
  */
 
-TRACE_EVENT(drv_return_void,
+DECLARE_EVENT_CLASS(local_only_evt,
 	TP_PROTO(struct ieee80211_local *local),
 	TP_ARGS(local),
 	TP_STRUCT__entry(
@@ -50,6 +50,11 @@ TRACE_EVENT(drv_return_void,
 	TP_printk(LOCAL_PR_FMT, LOCAL_PR_ARG)
 );
 
+DEFINE_EVENT(local_only_evt, drv_return_void,
+	TP_PROTO(struct ieee80211_local *local),
+	TP_ARGS(local)
+);
+
 TRACE_EVENT(drv_return_int,
 	TP_PROTO(struct ieee80211_local *local, int ret),
 	TP_ARGS(local, ret),
@@ -78,40 +83,14 @@ TRACE_EVENT(drv_return_u64,
 	TP_printk(LOCAL_PR_FMT " - %llu", LOCAL_PR_ARG, __entry->ret)
 );
 
-TRACE_EVENT(drv_start,
+DEFINE_EVENT(local_only_evt, drv_start,
 	TP_PROTO(struct ieee80211_local *local),
-
-	TP_ARGS(local),
-
-	TP_STRUCT__entry(
-		LOCAL_ENTRY
-	),
-
-	TP_fast_assign(
-		LOCAL_ASSIGN;
-	),
-
-	TP_printk(
-		LOCAL_PR_FMT, LOCAL_PR_ARG
-	)
+	TP_ARGS(local)
 );
 
-TRACE_EVENT(drv_stop,
+DEFINE_EVENT(local_only_evt, drv_stop,
 	TP_PROTO(struct ieee80211_local *local),
-
-	TP_ARGS(local),
-
-	TP_STRUCT__entry(
-		LOCAL_ENTRY
-	),
-
-	TP_fast_assign(
-		LOCAL_ASSIGN;
-	),
-
-	TP_printk(
-		LOCAL_PR_FMT, LOCAL_PR_ARG
-	)
+	TP_ARGS(local)
 );
 
 TRACE_EVENT(drv_add_interface,
@@ -439,40 +418,14 @@ TRACE_EVENT(drv_hw_scan,
 	)
 );
 
-TRACE_EVENT(drv_sw_scan_start,
+DEFINE_EVENT(local_only_evt, drv_sw_scan_start,
 	TP_PROTO(struct ieee80211_local *local),
-
-	TP_ARGS(local),
-
-	TP_STRUCT__entry(
-		LOCAL_ENTRY
-	),
-
-	TP_fast_assign(
-		LOCAL_ASSIGN;
-	),
-
-	TP_printk(
-		LOCAL_PR_FMT, LOCAL_PR_ARG
-	)
+	TP_ARGS(local)
 );
 
-TRACE_EVENT(drv_sw_scan_complete,
+DEFINE_EVENT(local_only_evt, drv_sw_scan_complete,
 	TP_PROTO(struct ieee80211_local *local),
-
-	TP_ARGS(local),
-
-	TP_STRUCT__entry(
-		LOCAL_ENTRY
-	),
-
-	TP_fast_assign(
-		LOCAL_ASSIGN;
-	),
-
-	TP_printk(
-		LOCAL_PR_FMT, LOCAL_PR_ARG
-	)
+	TP_ARGS(local)
 );
 
 TRACE_EVENT(drv_get_stats,
@@ -702,23 +655,9 @@ TRACE_EVENT(drv_conf_tx,
 	)
 );
 
-TRACE_EVENT(drv_get_tsf,
+DEFINE_EVENT(local_only_evt, drv_get_tsf,
 	TP_PROTO(struct ieee80211_local *local),
-
-	TP_ARGS(local),
-
-	TP_STRUCT__entry(
-		LOCAL_ENTRY
-	),
-
-	TP_fast_assign(
-		LOCAL_ASSIGN;
-	),
-
-	TP_printk(
-		LOCAL_PR_FMT,
-		LOCAL_PR_ARG
-	)
+	TP_ARGS(local)
 );
 
 TRACE_EVENT(drv_set_tsf,
@@ -742,41 +681,14 @@ TRACE_EVENT(drv_set_tsf,
 	)
 );
 
-TRACE_EVENT(drv_reset_tsf,
+DEFINE_EVENT(local_only_evt, drv_reset_tsf,
 	TP_PROTO(struct ieee80211_local *local),
-
-	TP_ARGS(local),
-
-	TP_STRUCT__entry(
-		LOCAL_ENTRY
-	),
-
-	TP_fast_assign(
-		LOCAL_ASSIGN;
-	),
-
-	TP_printk(
-		LOCAL_PR_FMT, LOCAL_PR_ARG
-	)
+	TP_ARGS(local)
 );
 
-TRACE_EVENT(drv_tx_last_beacon,
+DEFINE_EVENT(local_only_evt, drv_tx_last_beacon,
 	TP_PROTO(struct ieee80211_local *local),
-
-	TP_ARGS(local),
-
-	TP_STRUCT__entry(
-		LOCAL_ENTRY
-	),
-
-	TP_fast_assign(
-		LOCAL_ASSIGN;
-	),
-
-	TP_printk(
-		LOCAL_PR_FMT,
-		LOCAL_PR_ARG
-	)
+	TP_ARGS(local)
 );
 
 TRACE_EVENT(drv_ampdu_action,
@@ -962,22 +874,9 @@ TRACE_EVENT(drv_remain_on_channel,
 	)
 );
 
-TRACE_EVENT(drv_cancel_remain_on_channel,
+DEFINE_EVENT(local_only_evt, drv_cancel_remain_on_channel,
 	TP_PROTO(struct ieee80211_local *local),
-
-	TP_ARGS(local),
-
-	TP_STRUCT__entry(
-		LOCAL_ENTRY
-	),
-
-	TP_fast_assign(
-		LOCAL_ASSIGN;
-	),
-
-	TP_printk(
-		LOCAL_PR_FMT, LOCAL_PR_ARG
-	)
+	TP_ARGS(local)
 );
 
 /*
@@ -1072,23 +971,9 @@ TRACE_EVENT(api_stop_tx_ba_cb,
 	)
 );
 
-TRACE_EVENT(api_restart_hw,
+DEFINE_EVENT(local_only_evt, api_restart_hw,
 	TP_PROTO(struct ieee80211_local *local),
-
-	TP_ARGS(local),
-
-	TP_STRUCT__entry(
-		LOCAL_ENTRY
-	),
-
-	TP_fast_assign(
-		LOCAL_ASSIGN;
-	),
-
-	TP_printk(
-		LOCAL_PR_FMT,
-		LOCAL_PR_ARG
-	)
+	TP_ARGS(local)
 );
 
 TRACE_EVENT(api_beacon_loss,
@@ -1217,40 +1102,14 @@ TRACE_EVENT(api_chswitch_done,
 	)
 );
 
-TRACE_EVENT(api_ready_on_channel,
+DEFINE_EVENT(local_only_evt, api_ready_on_channel,
 	TP_PROTO(struct ieee80211_local *local),
-
-	TP_ARGS(local),
-
-	TP_STRUCT__entry(
-		LOCAL_ENTRY
-	),
-
-	TP_fast_assign(
-		LOCAL_ASSIGN;
-	),
-
-	TP_printk(
-		LOCAL_PR_FMT, LOCAL_PR_ARG
-	)
+	TP_ARGS(local)
 );
 
-TRACE_EVENT(api_remain_on_channel_expired,
+DEFINE_EVENT(local_only_evt, api_remain_on_channel_expired,
 	TP_PROTO(struct ieee80211_local *local),
-
-	TP_ARGS(local),
-
-	TP_STRUCT__entry(
-		LOCAL_ENTRY
-	),
-
-	TP_fast_assign(
-		LOCAL_ASSIGN;
-	),
-
-	TP_printk(
-		LOCAL_PR_FMT, LOCAL_PR_ARG
-	)
+	TP_ARGS(local)
 );
 
 /*



^ permalink raw reply

* Re: [PATCH] mac80211: use DECLARE_EVENT_CLASS
From: Johannes Berg @ 2011-01-23 10:12 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <20110121212447.GB7092@tuxdriver.com>

On Fri, 2011-01-21 at 16:24 -0500, John W. Linville wrote:
> On Wed, Jan 19, 2011 at 12:50:59PM +0100, Johannes Berg wrote:
> > From: Johannes Berg <johannes.berg@intel.com>
> > 
> > For events that include only the local struct as
> > their parameter, we can use DECLARE_EVENT_CLASS
> > and save quite some binary size across segments
> > as well lines of code.
> > 
> >    text	   data	    bss	    dec	    hex	filename
> >  375745	  19296	    916	 395957	  60ab5	mac80211.ko.before
> >  367473	  17888	    916	 386277	  5e4e5	mac80211.ko.after
> >   -8272   -1408       0   -9680   -25d0 delta
> > 
> > Some more tracepoints with identical arguments
> > could be combined like this but for now this is
> > the one that benefits most.
> > 
> > Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> 
> Is this patch complete?  It seems to break the build with undefined symbols...

Yes, I believe it is, I'll resend the version I just compile tested
against wireless-testing.

johannes


^ permalink raw reply

* Re: [RFC/WIP 00/33] ath9k_htc AP mode
From: Johannes Berg @ 2011-01-23 10:05 UTC (permalink / raw)
  To: Sujith; +Cc: Christian Lamparter, linux-wireless, ath9k-devel, Jouni Malinen
In-Reply-To: <19771.64642.436528.605150@gargle.gargle.HOWL>

On Sun, 2011-01-23 at 15:31 +0530, Sujith wrote:

> * The host driver has no way of knowing if the FW failed to send out a frame,
>   so keeping track of pending frames is impossible. Am not sure if ATH9K_TXERR_FILT
>   is similar to TX_STATUS_FAIL_DEST_PS in iwlagn (I think not), so that can't be used
>   either.

I don't know, but I thought it was supposed to be? At least mac80211
calls this "filtered" as well, which surely comes from Atheros
terminology.

johannes


^ permalink raw reply

* Re: [RFC/WIP 00/33] ath9k_htc AP mode
From: Sujith @ 2011-01-23 10:01 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Christian Lamparter, linux-wireless, ath9k-devel, Jouni Malinen
In-Reply-To: <1295773884.3639.9.camel@jlt3.sipsolutions.net>

Johannes Berg wrote:
> On Sat, 2011-01-22 at 09:02 +0530, Sujith wrote:
> 
> > It does make it a bit neat to have such a mechanism. And for AP mode, I would think
> > that it's kinda essential unless someone comes with an ingenious way of solving
> > the PS race for drivers that don't set IEEE80211_HW_REPORTS_TX_ACK_STATUS. :-)
> 
> Well, you can handle the PS stuff in the device completely -- or do it
> like iwlwifi does, where it doesn't rely on the ACK to detect the race,
> but the firmware will reject TX frames to sleeping stations until the
> driver tells it the station woke up.
> 
> How it works is like this:
> 
> STA AWAKE -> ASLEEP transition:
>   - firmware marks station as asleep
>   - firmware rejects TX frames for this station that are in queue
>   - driver keeps track of # of such frames, and uses
>     ieee80211_sta_block_awake() to block this station while it has
>     frames in the queue
>   - rejected frames are rejected to mac80211 and queued up
> 
> ASLEEP -> AWAKE:
>   - due to ieee80211_sta_block_awake() wakeup is blocked until the
>     queue has drained as well (if station very quick wakes up), then
>     when both conditions are met,
>   - driver tells device that this station woke up
>   - mac80211 re-transmits all those frames
>   - driver queues up all those frames

Thanks for the explanation, but ath9k_htc has deeper problems in AP mode. :)

* The FW doesn't mark stations or add them to a filter list on receiving a
  PS-enable frame from a station.

* The host driver has no way of knowing if the FW failed to send out a frame,
  so keeping track of pending frames is impossible. Am not sure if ATH9K_TXERR_FILT
  is similar to TX_STATUS_FAIL_DEST_PS in iwlagn (I think not), so that can't be used
  either.
  
Sujith

^ permalink raw reply

* Re: [RFC][PATCH] cfg80211: report monitor interface channel via wext when possible
From: Paul Fertser @ 2011-01-23  9:41 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Thomas d'Otreppe, Richard Farina
In-Reply-To: <1295773599.3639.4.camel@jlt3.sipsolutions.net>

On Sun, Jan 23, 2011 at 10:06:39AM +0100, Johannes Berg wrote:
> On Sat, 2011-01-22 at 03:11 +0300, Paul Fertser wrote:
> > This makes it possible to retrieve the channel for the monitor interface
> > in cases when it can be determined unambigously. Tested with ath5k.
> 
> NAK.
> 
> http://article.gmane.org/gmane.linux.kernel.wireless.general/61860

If i understood your correctly, "somehow query oper_channel" means one
needs to extend cfg80211 API a little and add necessary code to
mac80211. And the result would be higher-level API depending on
mac80211 implementation details (which are going to be soon changed
anyway after introduction of the real multi-channel feature).

What i propose should work with any cfg80211 driver where
set_channel() is properly implemented for monitor interfaces, and
mac80211 is certainly one of them. When in the first place one
requests set_channel() for a monitor that's not compatible with the
current configuration, it'll return an error, and so wdev->channel
would not be set at all. If it succeeded and then someone later wants
to verify the monitor channel, set_channel() is still the best
opportunity because it is this function that has all the checks to
verify the channel is still valid.

To sum up, i see no drawbacks in using set_channel() for that, it
doesn't add any implicit requirements, doesn't change semantics,
non-intrusive, doesn't break anything and works correctly every time.

-- 
Be free, use free (http://www.gnu.org/philosophy/free-sw.html) software!
mailto:fercerpav@gmail.com

^ permalink raw reply

* Re: [PATCH 00/83] staging: ath6kl: Style cleanup
From: Greg KH @ 2011-01-23  9:32 UTC (permalink / raw)
  To: Joe Perches
  Cc: Vipin Mehta, Vipin Mehta, linux-wireless@vger.kernel.org,
	devel@driverdev.osuosl.org
In-Reply-To: <1295742255.21754.3.camel@Joe-Laptop>

On Sat, Jan 22, 2011 at 04:24:15PM -0800, Joe Perches wrote:
> On Fri, 2011-01-21 at 13:16 -0800, Greg KH wrote:
> > I need this series against the proper branch, if I am going to be able
> > to apply them.
> 
> I am working on this major style rewrite of ath6kl right now.
> 
> Please do not apply new patches to ath6kl this upcoming week
> as it takes quite a bit of work to resync and validate 100+
> patches.

Sorry, but that's not how you do things.  Nor is it how I do things, if
people send me patches, I take them in the order in which they arrive.

NEVER send 100+ patches, send out what you have, when you have them,
which makes stuff like this, much easier to handle.

And wasn't this driver just a "placeholder" while a "real" driver was
being written?

good luck,

greg k-h

^ permalink raw reply

* Re: [PATCH 1/3] nl80211: allow passing SSID in nl80211_set_bss
From: Johannes Berg @ 2011-01-23  9:23 UTC (permalink / raw)
  To: Arik Nemtsov; +Cc: linux-wireless, Luciano Coelho, John W. Linville
In-Reply-To: <AANLkTinZwZbnzbT2UvOg7PgUsCRAR-+Hx+Je0zgoRYHd@mail.gmail.com>

On Fri, 2011-01-21 at 20:01 +0200, Arik Nemtsov wrote:
> On Thu, Jan 20, 2011 at 22:52, Johannes Berg <johannes@sipsolutions.net> wrote:
> >
> > As I also just commented on the corresponding hostapd patch, I'm not
> > sure this is sufficient. If this is necessary for probe response
> > offloading, I'm tempted to say that we should be honest about it and let
> > userspace determine the entire probe response (which will contain the
> > correct SSID) since it can be different from the beacon which presumably
> > you're now using to generate probe responses.
> >
> 
> Well the SSID is still needed in its pure form (i.e. not bundled up
> inside some skb).

Technically you can easily parse it out but I agree.

> You're talking about adding another set_probe_resp() callback from
> hostapd. That makes sense. I'll look into it.
> 
> In the meanwhile are there any comments for this portion?

Not really, except that I think that by itself it's insufficient. I
might add that depending on how the probe response thing works out in
the supplicant, it might make sense to add a capability flag that makes
the driver request this behaviour, since it would also disable
multi-SSID operation on a single BSSID (if that gets ever implemented)
for example since only a single probe request can be transmitted.

Also, P2P GO might be quite tricky with this, but I'm not exactly sure.

johannes


^ permalink raw reply

* Re: [PATCH v2] mac80211:  Optimize scans on current operating channel.
From: Johannes Berg @ 2011-01-23  9:18 UTC (permalink / raw)
  To: greearb; +Cc: linux-wireless
In-Reply-To: <1295633142-7437-1-git-send-email-greearb@candelatech.com>

On Fri, 2011-01-21 at 10:05 -0800, greearb@candelatech.com wrote:

> + * @SCAN_LEFT_OPER_CHANNEL:  Set this flag if the scan process leaves the
> + *      operating channel at any time.  If scanning ONLY the current operating
> + *      channel this flag should not be set, and this will allow fewer
> + *      offchannel changes.

Why does this make sense? In the code below, you do


> -	ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
> +	if ((local->oper_channel != local->hw.conf.channel) || was_hw_scan)
> +		ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
> +
>  	if (!was_hw_scan) {
>  		ieee80211_configure_filter(local);
>  		drv_sw_scan_complete(local);
> -		ieee80211_offchannel_return(local, true);
> +		if (test_bit(SCAN_LEFT_OPER_CHANNEL, &local->scanning))
> +			ieee80211_offchannel_return(local, true);

so you could just as well use a local variable (the first if you add is
exactly this test).

>  static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local,
>  						    unsigned long *next_delay)
>  {
> +	ieee80211_offchannel_stop_beaconing(local);
> +

Won't that confuse drivers that expect not to be beaconing between
sw_scan_start and sw_scan_end?


Also, are you sure the filter configuration works correctly this way? If
you can, I'd like to look at a binary trace of the commands going to the
device with this change: "trace-cmd record -e mac80211".


johannes


^ permalink raw reply

* Re: [RFC/WIP 00/33] ath9k_htc AP mode
From: Johannes Berg @ 2011-01-23  9:11 UTC (permalink / raw)
  To: Sujith; +Cc: Christian Lamparter, linux-wireless, ath9k-devel, Jouni Malinen
In-Reply-To: <19770.20402.711305.279934@gargle.gargle.HOWL>

On Sat, 2011-01-22 at 09:02 +0530, Sujith wrote:

> It does make it a bit neat to have such a mechanism. And for AP mode, I would think
> that it's kinda essential unless someone comes with an ingenious way of solving
> the PS race for drivers that don't set IEEE80211_HW_REPORTS_TX_ACK_STATUS. :-)

Well, you can handle the PS stuff in the device completely -- or do it
like iwlwifi does, where it doesn't rely on the ACK to detect the race,
but the firmware will reject TX frames to sleeping stations until the
driver tells it the station woke up.

How it works is like this:

STA AWAKE -> ASLEEP transition:
  - firmware marks station as asleep
  - firmware rejects TX frames for this station that are in queue
  - driver keeps track of # of such frames, and uses
    ieee80211_sta_block_awake() to block this station while it has
    frames in the queue
  - rejected frames are rejected to mac80211 and queued up

ASLEEP -> AWAKE:
  - due to ieee80211_sta_block_awake() wakeup is blocked until the
    queue has drained as well (if station very quick wakes up), then
    when both conditions are met,
  - driver tells device that this station woke up
  - mac80211 re-transmits all those frames
  - driver queues up all those frames

johannes


^ permalink raw reply

* Re: [RFC][PATCH] cfg80211: report monitor interface channel via wext when possible
From: Johannes Berg @ 2011-01-23  9:06 UTC (permalink / raw)
  To: Paul Fertser; +Cc: linux-wireless, Thomas d'Otreppe, Richard Farina
In-Reply-To: <1295655098-17534-1-git-send-email-fercerpav@gmail.com>

On Sat, 2011-01-22 at 03:11 +0300, Paul Fertser wrote:
> This makes it possible to retrieve the channel for the monitor interface
> in cases when it can be determined unambigously. Tested with ath5k.

NAK.

http://article.gmane.org/gmane.linux.kernel.wireless.general/61860

johannes


^ permalink raw reply

* Re: [PATCH 01/14] iwlwifi: use mac80211 throughput trigger
From: Johannes Berg @ 2011-01-23  9:05 UTC (permalink / raw)
  To: Wey-Yi Guy; +Cc: linville, linux-wireless, ipw3945-devel
In-Reply-To: <1295654809-5790-2-git-send-email-wey-yi.w.guy@intel.com>

That should have

From: Johannes Berg <johannes.berg@intel.com>

:-)

> Instead of keeping track of LED blink speed
> in the driver, use the new mac80211 trigger
> and link it up with an LED classdev that we
> now register. This also allows users more
> flexibility in how they want to have the LED
> blink or not.
> 
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>

...



^ permalink raw reply

* Re: [PATCH 2/2] ath9k: Fix power save usage count imbalance on deinit
From: Rajkumar Manoharan @ 2011-01-23  7:21 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Rajkumar Manoharan, Paul Stewart, linux-wireless@vger.kernel.org
In-Reply-To: <AANLkTim4d5xBBRnzWDoyZhJKriX3MByA-XbHsnTOW5+B@mail.gmail.com>

On Fri, Jan 21, 2011 at 04:32:20AM +0530, Luis R. Rodriguez wrote:
> On Wed, Jan 19, 2011 at 11:51 PM, Rajkumar Manoharan
> <rmanoharan@atheros.com> wrote:
> > On Thu, Jan 20, 2011 at 12:54:56AM +0530, Luis R. Rodriguez wrote:
> >> On Wed, Jan 19, 2011 at 7:47 AM, Rajkumar Manoharan
> >> <rmanoharan@atheros.com> wrote:
> >> > Upon unloading the driver, the ps_usecount is incremented
> >> > before configuring gpio registers in deinit_device.
> >> > But it is failed to restore the ps_usecount after that.
> >> > The problem is that the chip is moved to FULL SLEEP
> >> > by radio_disable when mac80211 is reporting as idle
> >> > though ps_usecount is not zero.
> >> >
> >> > This patch retores ps_usecount properly and ensures that
> >> > the chip is always moved to full sleep only if ps usage
> >> > counte is zero which helps in debugging. And also fixes
> >> > the following warning.
> >> >
> >> > ath: DMA failed to stop in 10 ms AR_CR=0xdeadbeef AR_DIAG_SW=0xdeadbeef
> >> > ath: Could not stop RX, we could be confusing the DMA engine when we
> >> > start RX up
> >> > ------------[ cut here ]------------
> >> > WARNING: at drivers/net/wireless/ath/ath9k/recv.c:536
> >> > ath_stoprecv+0xf4/0x100 [ath9k]()
> >> >
> >>
> >> Are you sure this hunk does not regress the suspend/resume case when
> >> using the new dbus API?
> >>
> > I verfied the suspend/resume case with AR9280 card. But I don't
> > understand how the new dbus API is related with this patch?
> 
> Paul, if you get a chance to give this a spin before it gets merged
> it'd be appreciated.
Paul,
Did you get a chance to evaluate this patch? Shall we proceed further?

--
Rajkumar

^ permalink raw reply

* [PATCH v5  2/2] wl12xx: BA receiver support
From: Shahar Levi @ 2011-01-23  6:27 UTC (permalink / raw)
  To: linux-wireless; +Cc: Luciano Coelho
In-Reply-To: <1295764043-29918-1-git-send-email-shahar_levi@ti.com>

Add new ampdu_action ops to support receiver BA.
The BA initiator session management in FW independently.

Signed-off-by: Shahar Levi <shahar_levi@ti.com>
---
Dependencies:
- BA Initiator patches have a runtime dependency on commit
  "[RFC v6] wl1271: BA Initiator support"

Limitation:
- For now only one BA per direction is supported

Changes from v1:
- Add mutex and (wl->state == WL1271_STATE_OFF) protection
- "BIT(tid)" instead of "BIT(0) << tid"
- Move all event code move to the next patch

Changes from v2:
- Add supported FW version auto detection mechanism

Changes from v3:
- Stylish

Changes from v4:
- More stylish

 drivers/net/wireless/wl12xx/acx.c    |   34 +++++++++++++++++++
 drivers/net/wireless/wl12xx/acx.h    |   21 ++++++++++++
 drivers/net/wireless/wl12xx/init.c   |    1 -
 drivers/net/wireless/wl12xx/main.c   |   60 ++++++++++++++++++++++++++++++++++
 drivers/net/wireless/wl12xx/wl12xx.h |    1 -
 5 files changed, 115 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index 588056a..bff586a 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -1393,6 +1393,40 @@ out:
 	return ret;
 }
 
+/* setup BA session receiver setting in the FW. */
+int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn,
+					bool enable)
+{
+	struct wl1271_acx_ba_receiver_setup *acx;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx ba receiver session setting");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* Single link for now */
+	acx->link_id = 1;
+	acx->tid = tid_index;
+	acx->enable = enable;
+	acx->win_size = 0;
+	acx->ssn = ssn;
+
+	ret = wl1271_cmd_configure(wl, ACX_BA_SESSION_RX_SETUP, acx,
+				   sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("acx ba receiver session failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
 int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
 {
 	struct wl1271_acx_fw_tsf_information *tsf_info;
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index c0abaf4..c683801 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -1095,6 +1095,25 @@ struct wl1271_acx_ba_session_policy {
 	u8 padding[3];
 } __packed;
 
+struct wl1271_acx_ba_receiver_setup {
+	struct acx_header header;
+
+	/* Specifies Link Id, Range 0-31, 0xFF means ANY  Link Id */
+	u8 link_id;
+
+	u8 tid;
+
+	u8 enable;
+
+	u8 padding[1];
+
+	/* Windows size in number of packets */
+	u16 win_size;
+
+	/* BA session starting sequence number.  RANGE 0-FFF */
+	u16 ssn;
+} __packed;
+
 struct wl1271_acx_fw_tsf_information {
 	struct acx_header header;
 
@@ -1246,6 +1265,8 @@ int wl1271_acx_set_ht_information(struct wl1271 *wl,
 int wl1271_acx_set_ba_session(struct wl1271 *wl,
 			      enum ieee80211_back_parties direction,
 			      u8 tid_index, u8 policy);
+int wl1271_acx_set_ba_receiver_session(struct wl1271 *wl, u8 tid_index, u16 ssn,
+				       bool enable);
 int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
 int wl1271_acx_max_tx_retry(struct wl1271 *wl);
 
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
index 0d939a2..fe6ea71 100644
--- a/drivers/net/wireless/wl12xx/init.c
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -473,7 +473,6 @@ static int wl1271_set_ba_policies(struct wl1271 *wl)
 	u8 ret = 0;
 
 	/* Reset the BA RX indicators */
-	wl->ba_allowed = true;
 	wl->ba_rx_bitmap = 0;
 
 	/* validate that FW support BA */
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 542b1de..fc7da94 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -2717,6 +2717,65 @@ out:
 	return ret;
 }
 
+int wl1271_op_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+			    enum ieee80211_ampdu_mlme_action action,
+			    struct ieee80211_sta *sta, u16 tid, u16 *ssn)
+{
+	struct wl1271 *wl = hw->priv;
+	int ret;
+
+	mutex_lock(&wl->mutex);
+
+	if (unlikely(wl->state == WL1271_STATE_OFF)) {
+		ret = -EAGAIN;
+		goto out;
+	}
+
+	ret = wl1271_ps_elp_wakeup(wl, false);
+	if (ret < 0)
+		goto out;
+
+	switch (action) {
+	case IEEE80211_AMPDU_RX_START:
+		if (wl->ba_support) {
+			ret = wl1271_acx_set_ba_receiver_session(wl, tid, *ssn,
+								 true);
+			if (!ret)
+				wl->ba_rx_bitmap |= BIT(tid);
+		} else {
+			ret = -ENOTSUPP;
+		}
+		break;
+
+	case IEEE80211_AMPDU_RX_STOP:
+		ret = wl1271_acx_set_ba_receiver_session(wl, tid, 0, false);
+		if (!ret)
+			wl->ba_rx_bitmap &= ~BIT(tid);
+		break;
+
+	/*
+	 * The BA initiator session management in FW independently.
+	 * Falling break here on purpose for all TX APDU commands.
+	 */
+	case IEEE80211_AMPDU_TX_START:
+	case IEEE80211_AMPDU_TX_STOP:
+	case IEEE80211_AMPDU_TX_OPERATIONAL:
+		ret = -EINVAL;
+		break;
+
+	default:
+		wl1271_error("Incorrect ampdu action id=%x\n", action);
+		ret = -EINVAL;
+	}
+
+	wl1271_ps_elp_sleep(wl);
+
+out:
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+
 /* can't be const, mac80211 writes to this */
 static struct ieee80211_rate wl1271_rates[] = {
 	{ .bitrate = 10,
@@ -2965,6 +3024,7 @@ static const struct ieee80211_ops wl1271_ops = {
 	.get_survey = wl1271_op_get_survey,
 	.sta_add = wl1271_op_sta_add,
 	.sta_remove = wl1271_op_sta_remove,
+	.ampdu_action = wl1271_op_ampdu_action,
 	CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
 };
 
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 443befc..a3d1179 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -473,7 +473,6 @@ struct wl1271 {
 
 	/* RX BA constraint value */
 	bool ba_support;
-	u8 ba_allowed;
 	u8 ba_rx_bitmap;
 };
 
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v7  1/2] wl12xx: BA initiator support
From: Shahar Levi @ 2011-01-23  6:27 UTC (permalink / raw)
  To: linux-wireless; +Cc: Luciano Coelho
In-Reply-To: <1295764043-29918-1-git-send-email-shahar_levi@ti.com>

Add 80211n BA initiator session support wl1271 driver.
Include BA supported FW version auto detection mechanism.
BA initiator session management included in FW independently.

Signed-off-by: Shahar Levi <shahar_levi@ti.com>
---
Limitation:
- For now only one BA per direction is supported

Changes from v1:
- Remove wl1271_op_ampdu_action()
- set CONF_BA_INACTIVITY_TIMEOUT as configurable value
- Clean to Linux code style.

Changes from v2:
- Two new ACX commands ACX_BA_SESSION_POLICY_CFG & ACX_BA_SESSION_RX_SETUP
- New struct wl1271_acx_ba_session_policy
- Calling wl1271_set_ba_policies() once in init
- Use ieee80211_back_parties
- Rebase to latest

Changes from v3:
- New FW file name due to new FW API

Changes from v4:
- Reverse change of "New FW file name due to new FW API"
- Add supported FW version auto detection mechanism (Parsing fw version once and
 use it to validate BA support)

Changes from v5:
- Improve implantation of FW parsing
- Stylish

Changes from v6:
- (ret != 5) instead of (ret <= 0) in wl1271_parse_fw_ver()

 drivers/net/wireless/wl12xx/acx.c    |   51 ++++++++++++++++++++++++++++++++++
 drivers/net/wireless/wl12xx/acx.h    |   41 ++++++++++++++++++++++++++-
 drivers/net/wireless/wl12xx/boot.c   |   24 ++++++++++++++--
 drivers/net/wireless/wl12xx/conf.h   |    6 ++++
 drivers/net/wireless/wl12xx/init.c   |   42 ++++++++++++++++++++++++++++
 drivers/net/wireless/wl12xx/main.c   |   12 +++++--
 drivers/net/wireless/wl12xx/wl12xx.h |   17 ++++++++++-
 7 files changed, 183 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index 646d278..588056a 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -1342,6 +1342,57 @@ out:
 	return ret;
 }
 
+/* Configure BA session initiator/receiver parameters setting in the FW. */
+int wl1271_acx_set_ba_session(struct wl1271 *wl,
+			       enum ieee80211_back_parties direction,
+			       u8 tid_index, u8 policy)
+{
+	struct wl1271_acx_ba_session_policy *acx;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx ba session setting");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* ANY role */
+	acx->role_id = 0xff;
+	acx->tid = tid_index;
+	acx->enable = policy;
+	acx->ba_direction = direction;
+
+	switch (direction) {
+	case WLAN_BACK_INITIATOR:
+		acx->win_size = wl->conf.ht.tx_ba_win_size;
+		acx->inactivity_timeout = wl->conf.ht.inactivity_timeout;
+		break;
+	case WLAN_BACK_RECIPIENT:
+		acx->win_size = RX_BA_WIN_SIZE;
+		acx->inactivity_timeout = 0;
+		break;
+	default:
+		wl1271_error("Incorrect acx command id=%x\n", direction);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	ret = wl1271_cmd_configure(wl,
+				   ACX_BA_SESSION_POLICY_CFG,
+				   acx,
+				   sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("acx ba session setting failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
 int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime)
 {
 	struct wl1271_acx_fw_tsf_information *tsf_info;
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index 89d3748..c0abaf4 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -1061,6 +1061,40 @@ struct wl1271_acx_ht_information {
 	u8 padding[3];
 } __packed;
 
+#define RX_BA_WIN_SIZE 8
+
+struct wl1271_acx_ba_session_policy {
+	struct acx_header header;
+	/*
+	 * Specifies role Id, Range 0-7, 0xFF means ANY role.
+	 * Future use. For now this field is irrelevant
+	 */
+	u8 role_id;
+	/*
+	 * Specifies Link Id, Range 0-31, 0xFF means ANY  Link Id.
+	 * Not applicable if Role Id is set to ANY.
+	 */
+	u8 link_id;
+
+	u8 tid;
+
+	u8 enable;
+
+	/* Windows size in number of packets */
+	u16 win_size;
+
+	/*
+	 * As initiator inactivity timeout in time units(TU) of 1024us.
+	 * As receiver reserved
+	 */
+	u16 inactivity_timeout;
+
+	/* Initiator = 1/Receiver = 0 */
+	u8 ba_direction;
+
+	u8 padding[3];
+} __packed;
+
 struct wl1271_acx_fw_tsf_information {
 	struct acx_header header;
 
@@ -1134,8 +1168,8 @@ enum {
 	ACX_RSSI_SNR_WEIGHTS        = 0x0052,
 	ACX_KEEP_ALIVE_MODE         = 0x0053,
 	ACX_SET_KEEP_ALIVE_CONFIG   = 0x0054,
-	ACX_BA_SESSION_RESPONDER_POLICY = 0x0055,
-	ACX_BA_SESSION_INITIATOR_POLICY = 0x0056,
+	ACX_BA_SESSION_POLICY_CFG   = 0x0055,
+	ACX_BA_SESSION_RX_SETUP     = 0x0056,
 	ACX_PEER_HT_CAP             = 0x0057,
 	ACX_HT_BSS_OPERATION        = 0x0058,
 	ACX_COEX_ACTIVITY           = 0x0059,
@@ -1209,6 +1243,9 @@ int wl1271_acx_set_ht_capabilities(struct wl1271 *wl,
 				    bool allow_ht_operation);
 int wl1271_acx_set_ht_information(struct wl1271 *wl,
 				   u16 ht_operation_mode);
+int wl1271_acx_set_ba_session(struct wl1271 *wl,
+			       enum ieee80211_back_parties direction,
+			       u8 tid_index, u8 policy);
 int wl1271_acx_tsf_info(struct wl1271 *wl, u64 *mactime);
 int wl1271_acx_max_tx_retry(struct wl1271 *wl);
 
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
index d7e036f..1ffbad6 100644
--- a/drivers/net/wireless/wl12xx/boot.c
+++ b/drivers/net/wireless/wl12xx/boot.c
@@ -101,6 +101,22 @@ static void wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
 	wl1271_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
 }
 
+static void wl1271_parse_fw_ver(struct wl1271 *wl)
+{
+	int ret;
+
+	ret = sscanf(wl->chip.fw_ver_str + 4, "%u.%u.%u.%u.%u",
+		     &wl->chip.fw_ver[0], &wl->chip.fw_ver[1],
+		     &wl->chip.fw_ver[2], &wl->chip.fw_ver[3],
+		     &wl->chip.fw_ver[4]);
+
+	if (ret != 5) {
+		wl1271_warning("fw version incorrect value");
+		memset(wl->chip.fw_ver, 0, sizeof(wl->chip.fw_ver));
+		return;
+	}
+}
+
 static void wl1271_boot_fw_version(struct wl1271 *wl)
 {
 	struct wl1271_static_data static_data;
@@ -108,11 +124,13 @@ static void wl1271_boot_fw_version(struct wl1271 *wl)
 	wl1271_read(wl, wl->cmd_box_addr, &static_data, sizeof(static_data),
 		    false);
 
-	strncpy(wl->chip.fw_ver, static_data.fw_version,
-		sizeof(wl->chip.fw_ver));
+	strncpy(wl->chip.fw_ver_str, static_data.fw_version,
+		sizeof(wl->chip.fw_ver_str));
 
 	/* make sure the string is NULL-terminated */
-	wl->chip.fw_ver[sizeof(wl->chip.fw_ver) - 1] = '\0';
+	wl->chip.fw_ver_str[sizeof(wl->chip.fw_ver_str) - 1] = '\0';
+
+	wl1271_parse_fw_ver(wl);
 }
 
 static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
diff --git a/drivers/net/wireless/wl12xx/conf.h b/drivers/net/wireless/wl12xx/conf.h
index f5c048c..135d837 100644
--- a/drivers/net/wireless/wl12xx/conf.h
+++ b/drivers/net/wireless/wl12xx/conf.h
@@ -1138,6 +1138,11 @@ struct conf_rf_settings {
 	u8 tx_per_channel_power_compensation_5[CONF_TX_PWR_COMPENSATION_LEN_5];
 };
 
+struct conf_ht_setting {
+	u16 tx_ba_win_size;
+	u16 inactivity_timeout;
+};
+
 struct conf_drv_settings {
 	struct conf_sg_settings sg;
 	struct conf_rx_settings rx;
@@ -1148,6 +1153,7 @@ struct conf_drv_settings {
 	struct conf_roam_trigger_settings roam_trigger;
 	struct conf_scan_settings scan;
 	struct conf_rf_settings rf;
+	struct conf_ht_setting ht;
 };
 
 #endif
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
index bdb6123..0d939a2 100644
--- a/drivers/net/wireless/wl12xx/init.c
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -455,6 +455,43 @@ static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
 	return 0;
 }
 
+static void wl1271_check_ba_support(struct wl1271 *wl)
+{
+	/* validate FW cose ver x.x.x.50-60.x */
+	if ((wl->chip.fw_ver[3] >= WL12XX_BA_SUPPORT_FW_COST_VER2_START) &&
+	    (wl->chip.fw_ver[3] < WL12XX_BA_SUPPORT_FW_COST_VER2_END)) {
+		wl->ba_support = true;
+		return;
+	}
+
+	wl->ba_support = false;
+}
+
+static int wl1271_set_ba_policies(struct wl1271 *wl)
+{
+	u8 tid_index;
+	u8 ret = 0;
+
+	/* Reset the BA RX indicators */
+	wl->ba_allowed = true;
+	wl->ba_rx_bitmap = 0;
+
+	/* validate that FW support BA */
+	wl1271_check_ba_support(wl);
+
+	if (wl->ba_support)
+		/* 802.11n initiator BA session setting */
+		for (tid_index = 0; tid_index < CONF_TX_MAX_TID_COUNT;
+		     ++tid_index) {
+			ret = wl1271_acx_set_ba_session(wl, WLAN_BACK_INITIATOR,
+							tid_index, true);
+			if (ret < 0)
+				break;
+		}
+
+	return ret;
+}
+
 int wl1271_hw_init(struct wl1271 *wl)
 {
 	struct conf_tx_ac_category *conf_ac;
@@ -568,6 +605,11 @@ int wl1271_hw_init(struct wl1271 *wl)
 	if (ret < 0)
 		goto out_free_memmap;
 
+	/* Configure initiator BA sessions policies */
+	ret = wl1271_set_ba_policies(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
 	return 0;
 
  out_free_memmap:
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 9076555..542b1de 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -274,7 +274,7 @@ static struct conf_drv_settings default_conf = {
 		.avg_weight_rssi_beacon       = 20,
 		.avg_weight_rssi_data         = 10,
 		.avg_weight_snr_beacon        = 20,
-		.avg_weight_snr_data          = 10
+		.avg_weight_snr_data          = 10,
 	},
 	.scan = {
 		.min_dwell_time_active        = 7500,
@@ -293,6 +293,10 @@ static struct conf_drv_settings default_conf = {
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		},
 	},
+	.ht = {
+		.tx_ba_win_size = 64,
+		.inactivity_timeout = 10000,
+	},
 };
 
 static void __wl1271_op_remove_interface(struct wl1271 *wl);
@@ -890,7 +894,7 @@ int wl1271_plt_start(struct wl1271 *wl)
 
 		wl->state = WL1271_STATE_PLT;
 		wl1271_notice("firmware booted in PLT mode (%s)",
-			      wl->chip.fw_ver);
+			      wl->chip.fw_ver_str);
 		goto out;
 
 irq_disable:
@@ -1131,11 +1135,11 @@ power_off:
 
 	wl->vif = vif;
 	wl->state = WL1271_STATE_ON;
-	wl1271_info("firmware booted (%s)", wl->chip.fw_ver);
+	wl1271_info("firmware booted (%s)", wl->chip.fw_ver_str);
 
 	/* update hw/fw version info in wiphy struct */
 	wiphy->hw_version = wl->chip.id;
-	strncpy(wiphy->fw_version, wl->chip.fw_ver,
+	strncpy(wiphy->fw_version, wl->chip.fw_ver_str,
 		sizeof(wiphy->fw_version));
 
 	/*
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index cf5c1a5..443befc 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -38,6 +38,13 @@
 #define DRIVER_NAME "wl1271"
 #define DRIVER_PREFIX DRIVER_NAME ": "
 
+/*
+ * FW versions support BA 11n
+ * versions marks x.x.x.50-60.x
+ */
+#define WL12XX_BA_SUPPORT_FW_COST_VER2_START    50
+#define WL12XX_BA_SUPPORT_FW_COST_VER2_END      60
+
 enum {
 	DEBUG_NONE	= 0,
 	DEBUG_IRQ	= BIT(0),
@@ -182,10 +189,13 @@ struct wl1271_partition_set {
 
 struct wl1271;
 
+#define WL12XX_NUM_FW_VER 5
+
 /* FIXME: I'm not sure about this structure name */
 struct wl1271_chip {
 	u32 id;
-	char fw_ver[21];
+	char fw_ver_str[ETHTOOL_BUSINFO_LEN];
+	unsigned int fw_ver[WL12XX_NUM_FW_VER];
 };
 
 struct wl1271_stats {
@@ -460,6 +470,11 @@ struct wl1271 {
 
 	/* bands supported by this instance of wl12xx */
 	struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
+
+	/* RX BA constraint value */
+	bool ba_support;
+	u8 ba_allowed;
+	u8 ba_rx_bitmap;
 };
 
 struct wl1271_station {
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v3  0/2] wl12xx: BA Initiator & receiver support
From: Shahar Levi @ 2011-01-23  6:27 UTC (permalink / raw)
  To: linux-wireless; +Cc: Luciano Coelho

That series gather two patches:
[PATCH v7] wl12xx: BA initiator support
[PATCH v5] wl12xx: BA receiver support

Add 80211n BA initiator & receiver session support wl1271 driver.
BA initiator session management included in FW independently.
Include supported FW version auto detection mechanism.

Limitation:
- For now only one BA per direction is supported

Shahar Levi (2):
  wl12xx: BA initiator support
  wl12xx: BA receiver support

 drivers/net/wireless/wl12xx/acx.c    |   85 ++++++++++++++++++++++++++++++++++
 drivers/net/wireless/wl12xx/acx.h    |   62 ++++++++++++++++++++++++-
 drivers/net/wireless/wl12xx/boot.c   |   24 ++++++++-
 drivers/net/wireless/wl12xx/conf.h   |    6 ++
 drivers/net/wireless/wl12xx/init.c   |   41 ++++++++++++++++
 drivers/net/wireless/wl12xx/main.c   |   72 +++++++++++++++++++++++++++--
 drivers/net/wireless/wl12xx/wl12xx.h |   16 ++++++-
 7 files changed, 296 insertions(+), 10 deletions(-)


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox