Linux wireless drivers development
 help / color / mirror / Atom feed
* Re: [RFT/RFC 0/4] iwlegacy: workaround for firmware frame tx rejection
From: Stanislaw Gruszka @ 2013-06-11 16:09 UTC (permalink / raw)
  To: Jake Edge; +Cc: linux-wireless, Johannes Berg
In-Reply-To: <20130610214134.36085c4b@chukar.edge2.net>

On Mon, Jun 10, 2013 at 09:41:34PM -0600, Jake Edge wrote:
> On Mon, 10 Jun 2013 14:38:48 -0600 Jake Edge wrote:
> 
> > > Please apply it together with this mac80211 patch:
> > > http://marc.info/?l=linux-wireless&m=136879090123023&w=2 
> > > which I already posted and is queued to upstream. Not having
> > > it may cause troubles and influence negatively this set test.
> > 
> > I tried it on both 3.9 (without 4/4 since it doesn't have that
> > workaround in it) and on 3.10-rc4 and in both cases, i get the same
> > behavior: it tries to connect many times and fails, then eventually
> > connects (after like 20 tries from KDE network manager) ...
> 
> actually, i spoke too soon, the 3.10-rc4 has not been able to connect
> at all, after many hours of trying.  I manually went in and selected
> the other 2.4GHz SSID (rather than the 5GHz it had been trying) and it
> connected right away, fwiw ...

I found a bug in one patch, perhaps it is a reason of failure.
Please apply patch 5/4 from here:
http://marc.info/?l=linux-wireless&m=136947199729148&q=raw 
and patch from the end of this email, which fix the bug.

Could you also recheck that "mac80211: fix direct probe auth" patch
is applied, note that it is included in 3.10-rc5 as commit
6211dd12da609bc6893b9c3182630b494737ec4b

If it still will not help, please provide dmesg with debug messages
gathered by following instructions:

dmesg -c
modprobe -r iwl4965
modprobe iwl4965 debug=0x00800001
# wait about 30 seconds until first connection try fail
modprobe -r iwl4965
dmesg > dmesg.txt

Kernel has to be compiled with CONFIG_IWLEGACY_DEBUG=y to print debug
messages.

Thanks
Stanislaw

diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index 2c77431..d287fd2 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -2818,7 +2818,7 @@ il4965_hdl_tx(struct il_priv *il, struct il_rx_buf *rxb)
 	 * note received beacon or other frame. We unblock queues in
 	 * il4965_pass_packet_to_mac80211 or in il_mac_bss_info_changed.
 	 */
-	if (unlikely(status == TX_STATUS_FAIL_PASSIVE_NO_RX) &&
+	if (unlikely((status & TX_STATUS_MSK) == TX_STATUS_FAIL_PASSIVE_NO_RX) &&
 	    il->iw_mode == NL80211_IFTYPE_STATION) {
 		il_stop_queues_by_reason(il, IL_STOP_REASON_PASSIVE);
 		D_INFO("Stopped queues - RX waiting on passive channel\n");


^ permalink raw reply related

* [PATCH] carl9170: make use of the new rate control API
From: Thomas Huehn @ 2013-06-11 15:57 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, nbd, johannes, chunkeey

This patch enabels carl9170 to use the new rate table to lookup each
mrr rate and retry information per packet.

Signed-off-by: Benjamin Vahl <bvahl@net.t-labs.tu-berlin.de>
Signed-off-by: Thomas Huehn <thomas@net.t-labs.tu-berlin.de>
---
 drivers/net/wireless/ath/carl9170/carl9170.h |    1 +
 drivers/net/wireless/ath/carl9170/tx.c       |    8 +++++++-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index 9dce106..ddaa149 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -322,6 +322,7 @@ struct ar9170 {
 
 	/* MAC */
 	enum carl9170_erp_modes erp_mode;
+	struct ieee80211_tx_rate rates[4];
 
 	/* PHY */
 	struct ieee80211_channel *channel;
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index c61cafa..d21c81d 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -266,6 +266,7 @@ static void carl9170_tx_release(struct kref *ref)
 	struct carl9170_tx_info *arinfo;
 	struct ieee80211_tx_info *txinfo;
 	struct sk_buff *skb;
+	int size;
 
 	arinfo = container_of(ref, struct carl9170_tx_info, ref);
 	txinfo = container_of((void *) arinfo, struct ieee80211_tx_info,
@@ -324,6 +325,9 @@ static void carl9170_tx_release(struct kref *ref)
 		}
 	}
 
+	size = min_t(int, sizeof(txinfo->status.rates), sizeof(ar->rates));
+	memcpy(txinfo->status.rates, ar->rates, size);
+
 	skb_pull(skb, sizeof(struct _carl9170_tx_superframe));
 	ieee80211_tx_status_irqsafe(ar->hw, skb);
 }
@@ -982,6 +986,8 @@ static int carl9170_tx_prepare(struct ar9170 *ar,
 			txc->s.ampdu_settings, factor);
 	}
 
+	ieee80211_get_tx_rates(info->control.vif, sta, skb, ar->rates, ARRAY_SIZE(ar->rates));
+
 	/*
 	 * NOTE: For the first rate, the ERP & AMPDU flags are directly
 	 * taken from mac_control. For all fallback rate, the firmware
@@ -989,7 +995,7 @@ static int carl9170_tx_prepare(struct ar9170 *ar,
 	 */
 	for (i = 0; i < CARL9170_TX_MAX_RATES; i++) {
 		__le32 phy_set;
-		txrate = &info->control.rates[i];
+		txrate = &ar->rates[i];
 		if (txrate->idx < 0)
 			break;
 
-- 
1.7.9.5


^ permalink raw reply related

* Re: [RFC 4/5] mac80211: enforce address verification on monitors
From: Johannes Berg @ 2013-06-11 15:14 UTC (permalink / raw)
  To: Jakub Kiciński
  Cc: Felix Fietkau, linux-wireless, Helmut Schaa,
	nietrywialneprzejscie
In-Reply-To: <20130611150129.0413f67d@north>


> > I think we should "just" move ieee80211_verify_mac() into do_open().
> > Semantically anyway, I'm clearly handwaving a bit. But I would argue
> > that you can set any MAC address that you like, as long as you don't
> > bring the interface up, hence the verification really shouldn't be done
> > when you assign the address but when you bring it up.
> 
> I've considered this initially. Two reasons that made me
> think the current approach is cleaner are:
>  - it's nice when user gets the error during the action that
>    puts system in inconsistent state not some time later. I
>    personally hate to get vague EBUSY and have to figure out
>    what's wrong.
>  - suppose there are two interfaces, both down with
>    incompatible addresses. User adds third ifc, what address
>    should we assign to it?

Right now you can assign the same addresses to multiple interfaces and
then you can't bring them up. This happens for example if there are no
more addresses to assign.

> Besides who would care what address does passive monitor
> have? ;)

Well those obviously don't matter, which is really the problem here, no?

> > address mask: 00:00:00:00:00:03
> > wlan0: 02:00:00:00:00:00
> > wlan1: 02:00:00:00:00:01
> >
> > Now you want to change to
> > wlan0: 03:00:00:00:00:00
> > wlan1: 03:00:00:00:00:01
> >
> > It seems that right now you can't do this at all, which also seems
> > wrong.
> 
> Right but I believe user would understand what is the problem
> here and just remove and recreate one of the interfaces. They
> have to be down to change MAC addr anyway.

Dunno, you could also argue the other way around, that since they're
down the MAC address really shouldn't matter at all...

johannes


^ permalink raw reply

* [PATCH] cfg80211: fix rtnl leak in wiphy dump error cases
From: Johannes Berg @ 2013-06-11 14:53 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg

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

In two wiphy dump error cases, most often when the dump allocation
must be increased, the RTNL is leaked. This quickly results in a
complete system lockup. Release the RTNL correctly.

Reported-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/wireless/nl80211.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 398ce2c..e402819 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1541,8 +1541,10 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
 			int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
 
 			netdev = dev_get_by_index(sock_net(skb->sk), ifidx);
-			if (!netdev)
+			if (!netdev) {
+				rtnl_unlock();
 				return -ENODEV;
+			}
 			if (netdev->ieee80211_ptr) {
 				dev = wiphy_to_dev(
 					netdev->ieee80211_ptr->wiphy);
@@ -1586,6 +1588,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
 				    !skb->len &&
 				    cb->min_dump_alloc < 4096) {
 					cb->min_dump_alloc = 4096;
+					rtnl_unlock();
 					return 1;
 				}
 				idx--;
-- 
1.8.0


^ permalink raw reply related

* Re: [RFC 0/4] add master channel switch announcement support
From: Simon Wunderlich @ 2013-06-11 14:18 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Simon Wunderlich, linux-wireless, Mathias Kretschmer,
	Simon Wunderlich
In-Reply-To: <1370953885.8356.38.camel@jlt4.sipsolutions.net>

[-- Attachment #1: Type: text/plain, Size: 2045 bytes --]

> > > >  * could other drivers (next to ath9k) work with this API?
> > > 
> > > Probably not easily. Any TI folks reading this?
> > 
> > I was thinking about adding another callback function or option for that for drivers
> > who do the channel switch internally. Then we would only need mac80211 to adapt.
> > 
> > Would that help, or what would be problematic?
> 
> I don't really know. If you look at what we do in managed mode now, some
> drivers will do the switching and report back when done.
> 

OK, maybe we should leave that open to people who implement that feature for
their respective drivers.

> > Yeah, that would be an alternative. I've been inspired by IEEE 802.11-2012/6.3.17
> > (MLME-CHANNELSWITCH) originally. :)
> > I think your suggestion is good for AP where we control the beacon. For IBSS it
> > would be a little different: when a channel switch is triggered, userspace does
> > not know the beacon (and will not set it). Therefore, we could only accept the
> > change IEs and skip the "after-switch-beacon" IEs (these would be re-generated
> > internally) in IBSS mode. I guess it would be similar for mesh.
> 
> Yeah, agree, IBSS/mesh modes are somewhat different here, userspace
> doesn't really know the channel is switching at all, does it?

IBSS/Mesh does not process CSA so far. When we do, we should switch the channel
and inform userspace by using an event (the same way it is done for station, I think).

What I'm concered about is to initiate a channel switch from userspace. This will be
required for IBSS-DFS: when a radar is detected and this event is sent to userspace, it
must react by initiating a channel switch.

My plan was to use the same "channel switch" command, just without the CSA-IE and
after-change IEs (see the new PATCH series). The rest would be pretty similar to the
AP-operation: add CSA IEs, switch channel, create a new beacon for the new channel and
set it. Only that this would be done in kernel space instead of userspace.

Cheers,
	Simon

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply

* [PATCH -next 3/3] cw1200:  Fix an assorted pile of checkpatch warnings.
From: Solomon Peachy @ 2013-06-11 13:49 UTC (permalink / raw)
  To: linux-wireless; +Cc: Solomon Peachy
In-Reply-To: <1370958580-6463-1-git-send-email-pizza@shaftnet.org>

Signed-off-by: Solomon Peachy <pizza@shaftnet.org>
---
 drivers/net/wireless/cw1200/bh.c          |  9 +++--
 drivers/net/wireless/cw1200/cw1200.h      |  3 +-
 drivers/net/wireless/cw1200/cw1200_sdio.c |  3 +-
 drivers/net/wireless/cw1200/cw1200_spi.c  |  4 +--
 drivers/net/wireless/cw1200/hwio.h        |  5 ++-
 drivers/net/wireless/cw1200/sta.c         | 30 ++++++++---------
 drivers/net/wireless/cw1200/txrx.c        | 43 ++++++++++++++----------
 drivers/net/wireless/cw1200/wsm.c         |  3 +-
 drivers/net/wireless/cw1200/wsm.h         | 55 +++++++++++++++----------------
 9 files changed, 80 insertions(+), 75 deletions(-)

diff --git a/drivers/net/wireless/cw1200/bh.c b/drivers/net/wireless/cw1200/bh.c
index 324b570..c1ec2a4 100644
--- a/drivers/net/wireless/cw1200/bh.c
+++ b/drivers/net/wireless/cw1200/bh.c
@@ -31,7 +31,8 @@ static int cw1200_bh(void *arg);
 
 #define DOWNLOAD_BLOCK_SIZE_WR	(0x1000 - 4)
 /* an SPI message cannot be bigger than (2"12-1)*2 bytes
- * "*2" to cvt to bytes */
+ * "*2" to cvt to bytes
+ */
 #define MAX_SZ_RD_WR_BUFFERS	(DOWNLOAD_BLOCK_SIZE_WR*2)
 #define PIGGYBACK_CTRL_REG	(2)
 #define EFFECTIVE_BUF_SIZE	(MAX_SZ_RD_WR_BUFFERS - PIGGYBACK_CTRL_REG)
@@ -217,7 +218,8 @@ static int cw1200_device_wakeup(struct cw1200_common *priv)
 		return ret;
 
 	/* If the device returns WLAN_RDY as 1, the device is active and will
-	 * remain active. */
+	 * remain active.
+	 */
 	if (ctrl_reg & ST90TDS_CONT_RDY_BIT) {
 		pr_debug("[BH] Device awake.\n");
 		return 1;
@@ -262,7 +264,8 @@ static int cw1200_bh_rx_helper(struct cw1200_common *priv,
 	}
 
 	/* Add SIZE of PIGGYBACK reg (CONTROL Reg)
-	 * to the NEXT Message length + 2 Bytes for SKB */
+	 * to the NEXT Message length + 2 Bytes for SKB
+	 */
 	read_len = read_len + 2;
 
 	alloc_len = priv->hwbus_ops->align_size(
diff --git a/drivers/net/wireless/cw1200/cw1200.h b/drivers/net/wireless/cw1200/cw1200.h
index 91ff7f1..243e963 100644
--- a/drivers/net/wireless/cw1200/cw1200.h
+++ b/drivers/net/wireless/cw1200/cw1200.h
@@ -207,7 +207,8 @@ struct cw1200_common {
 	/* Scan status */
 	struct cw1200_scan scan;
 	/* Keep cw1200 awake (WUP = 1) 1 second after each scan to avoid
-	 * FW issue with sleeping/waking up. */
+	 * FW issue with sleeping/waking up.
+	 */
 	atomic_t			recent_scan;
 	struct delayed_work		clear_recent_scan_work;
 
diff --git a/drivers/net/wireless/cw1200/cw1200_sdio.c b/drivers/net/wireless/cw1200/cw1200_sdio.c
index bb1f405..ebdcdf4 100644
--- a/drivers/net/wireless/cw1200/cw1200_sdio.c
+++ b/drivers/net/wireless/cw1200/cw1200_sdio.c
@@ -323,7 +323,8 @@ static int cw1200_sdio_probe(struct sdio_func *func,
 }
 
 /* Disconnect Function to be called by SDIO stack when
- * device is disconnected */
+ * device is disconnected
+ */
 static void cw1200_sdio_disconnect(struct sdio_func *func)
 {
 	struct hwbus_priv *self = sdio_get_drvdata(func);
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
index e58f0a5..953bd19 100644
--- a/drivers/net/wireless/cw1200/cw1200_spi.c
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -47,15 +47,13 @@ struct hwbus_priv {
 #define SET_WRITE 0x7FFF /* usage: and operation */
 #define SET_READ 0x8000  /* usage: or operation */
 
-/*
-   Notes on byte ordering:
+/* Notes on byte ordering:
    LE:  B0 B1 B2 B3
    BE:  B3 B2 B1 B0
 
    Hardware expects 32-bit data to be written as 16-bit BE words:
 
    B1 B0 B3 B2
-
 */
 
 static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self,
diff --git a/drivers/net/wireless/cw1200/hwio.h b/drivers/net/wireless/cw1200/hwio.h
index 7ee73fe..563329c 100644
--- a/drivers/net/wireless/cw1200/hwio.h
+++ b/drivers/net/wireless/cw1200/hwio.h
@@ -97,9 +97,8 @@ struct download_cntl_t {
 
 #define CW1200_APB(addr)		(PAC_SHARED_MEMORY_SILICON + (addr))
 
-/* ***************************************************************
-*Device register definitions
-*************************************************************** */
+/* Device register definitions */
+
 /* WBF - SPI Register Addresses */
 #define ST90TDS_ADDR_ID_BASE		(0x0000)
 /* 16/32 bits */
diff --git a/drivers/net/wireless/cw1200/sta.c b/drivers/net/wireless/cw1200/sta.c
index 679c55f..4cd0352 100644
--- a/drivers/net/wireless/cw1200/sta.c
+++ b/drivers/net/wireless/cw1200/sta.c
@@ -483,15 +483,14 @@ void cw1200_update_filtering(struct cw1200_common *priv)
 		bf_tbl.num = __cpu_to_le32(3);
 	}
 
-	/*
-	* When acting as p2p client being connected to p2p GO, in order to
-	* receive frames from a different p2p device, turn off bssid filter.
-	*
-	* WARNING: FW dependency!
-	* This can only be used with FW WSM371 and its successors.
-	* In that FW version even with bssid filter turned off,
-	* device will block most of the unwanted frames.
-	*/
+	/* When acting as p2p client being connected to p2p GO, in order to
+	 * receive frames from a different p2p device, turn off bssid filter.
+	 *
+	 * WARNING: FW dependency!
+	 * This can only be used with FW WSM371 and its successors.
+	 * In that FW version even with bssid filter turned off,
+	 * device will block most of the unwanted frames.
+	 */
 	if (is_p2p)
 		bssid_filtering = false;
 
@@ -1015,17 +1014,17 @@ void cw1200_event_handler(struct work_struct *work)
 			/* RSSI: signed Q8.0, RCPI: unsigned Q7.1
 			 * RSSI = RCPI / 2 - 110
 			 */
-			int rcpiRssi = (int)(event->evt.data & 0xFF);
+			int rcpi_rssi = (int)(event->evt.data & 0xFF);
 			int cqm_evt;
 			if (priv->cqm_use_rssi)
-				rcpiRssi = (s8)rcpiRssi;
+				rcpi_rssi = (s8)rcpi_rssi;
 			else
-				rcpiRssi =  rcpiRssi / 2 - 110;
+				rcpi_rssi =  rcpi_rssi / 2 - 110;
 
-			cqm_evt = (rcpiRssi <= priv->cqm_rssi_thold) ?
+			cqm_evt = (rcpi_rssi <= priv->cqm_rssi_thold) ?
 				NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW :
 				NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH;
-			pr_debug("[CQM] RSSI event: %d.\n", rcpiRssi);
+			pr_debug("[CQM] RSSI event: %d.\n", rcpi_rssi);
 			ieee80211_cqm_rssi_notify(priv->vif, cqm_evt,
 						  GFP_KERNEL);
 			break;
@@ -1068,8 +1067,7 @@ void cw1200_bss_params_work(struct work_struct *work)
 /* ******************************************************************** */
 /* Internal API								*/
 
-/*
- * This function is called to Parse the SDD file
+/* This function is called to Parse the SDD file
  * to extract listen_interval and PTA related information
  * sdd is a TLV: u8 id, u8 len, u8 data[]
  */
diff --git a/drivers/net/wireless/cw1200/txrx.c b/drivers/net/wireless/cw1200/txrx.c
index 451d746..44ca10c 100644
--- a/drivers/net/wireless/cw1200/txrx.c
+++ b/drivers/net/wireless/cw1200/txrx.c
@@ -75,9 +75,6 @@ static void tx_policy_build(const struct cw1200_common *priv,
 	BUG_ON(rates[0].idx < 0);
 	memset(policy, 0, sizeof(*policy));
 
-	/* minstrel is buggy a little bit, so distille
-	 * incoming rates first. */
-
 	/* Sort rates in descending order. */
 	for (i = 1; i < count; ++i) {
 		if (rates[i].idx < 0) {
@@ -108,7 +105,8 @@ static void tx_policy_build(const struct cw1200_common *priv,
 	count = i + 1;
 
 	/* Re-fill policy trying to keep every requested rate and with
-	 * respect to the global max tx retransmission count. */
+	 * respect to the global max tx retransmission count.
+	 */
 	if (limit < count)
 		limit = count;
 	if (total > limit) {
@@ -129,7 +127,6 @@ static void tx_policy_build(const struct cw1200_common *priv,
 	if (count == 2 && !(rates[0].flags & IEEE80211_TX_RC_MCS) &&
 	    rates[0].idx > 4 && rates[0].count > 2 &&
 	    rates[1].idx < 2) {
-		/* ">> 1" is an equivalent of "/ 2", but faster */
 		int mid_rate = (rates[0].idx + 4) >> 1;
 
 		/* Decrease number of retries for the initial rate */
@@ -151,7 +148,8 @@ static void tx_policy_build(const struct cw1200_common *priv,
 			/* Fallback to 1 Mbps is a really bad thing,
 			 * so let's try to increase probability of
 			 * successful transmission on the lowest g rate
-			 * even more */
+			 * even more
+			 */
 			if (rates[0].count >= 3) {
 				--rates[0].count;
 				++rates[2].count;
@@ -220,7 +218,8 @@ static int tx_policy_find(struct tx_policy_cache *cache,
 {
 	/* O(n) complexity. Not so good, but there's only 8 entries in
 	 * the cache.
-	 * Also lru helps to reduce search time. */
+	 * Also lru helps to reduce search time.
+	 */
 	struct tx_policy_cache_entry *it;
 	/* First search for policy in "used" list */
 	list_for_each_entry(it, &cache->used, link) {
@@ -264,7 +263,8 @@ void tx_policy_clean(struct cw1200_common *priv)
 	for (idx = 0; idx < TX_POLICY_CACHE_SIZE; idx++) {
 		entry = &cache->cache[idx];
 		/* Policy usage count should be 0 at this time as all queues
-		   should be empty */
+		   should be empty
+		 */
 		if (WARN_ON(entry->policy.usage_count)) {
 			entry->policy.usage_count = 0;
 			list_move(&entry->link, &cache->free);
@@ -319,7 +319,8 @@ static int tx_policy_get(struct cw1200_common *priv,
 		struct tx_policy_cache_entry *entry;
 		*renew = true;
 		/* If policy is not found create a new one
-		 * using the oldest entry in "free" list */
+		 * using the oldest entry in "free" list
+		 */
 		entry = list_entry(cache->free.prev,
 			struct tx_policy_cache_entry, link);
 		entry->policy = wanted;
@@ -612,7 +613,8 @@ cw1200_tx_h_bt(struct cw1200_common *priv,
 				 priv->listen_interval,
 				 mgt_frame->u.assoc_req.listen_interval);
 			/* Replace listen interval derieved from
-			 * the one read from SDD */
+			 * the one read from SDD
+			 */
 			mgt_frame->u.assoc_req.listen_interval =
 				priv->listen_interval;
 		}
@@ -667,7 +669,8 @@ cw1200_tx_h_rate_policy(struct cw1200_common *priv,
 		pr_debug("[TX] TX policy renew.\n");
 		/* It's not so optimal to stop TX queues every now and then.
 		 * Better to reimplement task scheduling with
-		 * a counter. TODO. */
+		 * a counter. TODO.
+		 */
 		wsm_lock_tx_async(priv);
 		cw1200_tx_queues_lock(priv);
 		if (queue_work(priv->workqueue,
@@ -832,8 +835,7 @@ static int cw1200_handle_pspoll(struct cw1200_common *priv,
 	priv->pspoll_mask |= pspoll_mask;
 	drop = 0;
 
-	/* Do not report pspols if data for given link id is
-	 * queued already. */
+	/* Do not report pspols if data for given link id is queued already. */
 	for (i = 0; i < 4; ++i) {
 		if (cw1200_queue_get_num_queued(&priv->tx_queue[i],
 						pspoll_mask)) {
@@ -924,7 +926,8 @@ void cw1200_tx_confirm_cb(struct cw1200_common *priv,
 			cw1200_debug_txed(priv);
 			if (arg->flags & WSM_TX_STATUS_AGGREGATION) {
 				/* Do not report aggregation to mac80211:
-				 * it confuses minstrel a lot. */
+				 * it confuses minstrel a lot.
+				 */
 				/* tx->flags |= IEEE80211_TX_STAT_AMPDU; */
 				cw1200_debug_txed_agg(priv);
 			}
@@ -1044,7 +1047,8 @@ void cw1200_rx_cb(struct cw1200_common *priv,
 	    ieee80211_is_action(frame->frame_control) &&
 	    (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)) {
 		/* Link ID already exists for the ACTION frame.
-		 * Reset and Remap */
+		 * Reset and Remap
+		 */
 		WARN_ON(work_pending(&priv->linkid_reset_work));
 		memcpy(&priv->action_frame_sa[0],
 		       ieee80211_get_SA(frame), ETH_ALEN);
@@ -1074,7 +1078,6 @@ void cw1200_rx_cb(struct cw1200_common *priv,
 		if (cw1200_handle_pspoll(priv, skb))
 			goto drop;
 
-	hdr->mactime = 0; /* Not supported by WSM */
 	hdr->band = ((arg->channel_number & 0xff00) ||
 		     (arg->channel_number > 14)) ?
 			IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ;
@@ -1102,7 +1105,8 @@ void cw1200_rx_cb(struct cw1200_common *priv,
 		hdr->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED;
 
 		/* Oops... There is no fast way to ask mac80211 about
-		 * IV/ICV lengths. Even defineas are not exposed.*/
+		 * IV/ICV lengths. Even defineas are not exposed.
+		 */
 		switch (WSM_RX_STATUS_ENCRYPTION(arg->flags)) {
 		case WSM_RX_STATUS_WEP:
 			iv_len = 4 /* WEP_IV_LEN */;
@@ -1149,6 +1153,8 @@ void cw1200_rx_cb(struct cw1200_common *priv,
 		hdr->mactime = le64_to_cpu(hdr->mactime);
 		if (skb->len >= 8)
 			skb_trim(skb, skb->len - 8);
+	} else {
+		hdr->mactime = 0;
 	}
 
 	cw1200_debug_rxed(priv);
@@ -1192,7 +1198,8 @@ void cw1200_rx_cb(struct cw1200_common *priv,
 
 	/* Stay awake after frame is received to give
 	 * userspace chance to react and acquire appropriate
-	 * wakelock. */
+	 * wakelock.
+	 */
 	if (ieee80211_is_auth(frame->frame_control))
 		grace_period = 5 * HZ;
 	else if (ieee80211_is_deauth(frame->frame_control))
diff --git a/drivers/net/wireless/cw1200/wsm.c b/drivers/net/wireless/cw1200/wsm.c
index d185f29..d95094f 100644
--- a/drivers/net/wireless/cw1200/wsm.c
+++ b/drivers/net/wireless/cw1200/wsm.c
@@ -1106,8 +1106,7 @@ static int wsm_cmd_send(struct cw1200_common *priv,
 	else
 		pr_debug("[WSM] >>> 0x%.4X (%zu)\n", cmd, buf_len);
 
-	/*
-	 * Due to buggy SPI on CW1200, we need to
+	/* Due to buggy SPI on CW1200, we need to
 	 * pad the message by a few bytes to ensure
 	 * that it's completely received.
 	 */
diff --git a/drivers/net/wireless/cw1200/wsm.h b/drivers/net/wireless/cw1200/wsm.h
index 4689dff..2816171 100644
--- a/drivers/net/wireless/cw1200/wsm.h
+++ b/drivers/net/wireless/cw1200/wsm.h
@@ -314,13 +314,16 @@ struct cw1200_common;
 #define WSM_JOIN_FLAGS_P2P_GO		BIT(1)
 /* Force to join BSS with the BSSID and the
  * SSID specified without waiting for beacons. The
- * ProbeForJoin parameter is ignored. */
+ * ProbeForJoin parameter is ignored.
+ */
 #define WSM_JOIN_FLAGS_FORCE		BIT(2)
 /* Give probe request/response higher
- * priority over the BT traffic */
+ * priority over the BT traffic
+ */
 #define WSM_JOIN_FLAGS_PRIO		BIT(3)
 /* Issue immediate join confirmation and use
- * join complete to notify about completion */
+ * join complete to notify about completion
+ */
 #define WSM_JOIN_FLAGS_FORCE_WITH_COMPLETE_IND BIT(5)
 
 /* Key types */
@@ -1015,22 +1018,19 @@ struct wsm_add_key {
 	u16 reserved;
 	union {
 		struct {
-			u8 peer[6];	/* MAC address of the
-						 * peer station */
+			u8 peer[6];	/* MAC address of the peer station */
 			u8 reserved;
 			u8 keylen;		/* Key length in bytes */
 			u8 keydata[16];		/* Key data */
 		} __packed wep_pairwise;
 		struct {
-			u8 keyid;		/* Unique per key identifier
-						 * (0..3) */
+			u8 keyid;	/* Unique per key identifier (0..3) */
 			u8 keylen;		/* Key length in bytes */
 			u16 reserved;
 			u8 keydata[16];		/* Key data */
 		} __packed wep_group;
 		struct {
-			u8 peer[6];	/* MAC address of the
-						 * peer station */
+			u8 peer[6];	/* MAC address of the peer station */
 			u16 reserved;
 			u8 keydata[16];	/* TKIP key data */
 			u8 rx_mic_key[8];		/* Rx MIC key */
@@ -1044,8 +1044,7 @@ struct wsm_add_key {
 			u8 rx_seqnum[8];	/* Receive Sequence Counter */
 		} __packed tkip_group;
 		struct {
-			u8 peer[6];	/* MAC address of the
-						 * peer station */
+			u8 peer[6];	/* MAC address of the peer station */
 			u16 reserved;
 			u8 keydata[16];	/* AES key data */
 		} __packed aes_pairwise;
@@ -1056,8 +1055,7 @@ struct wsm_add_key {
 			u8 rx_seqnum[8];	/* Receive Sequence Counter */
 		} __packed aes_group;
 		struct {
-			u8 peer[6];	/* MAC address of the
-						 * peer station */
+			u8 peer[6];	/* MAC address of the peer station */
 			u8 keyid;		/* Key ID */
 			u8 reserved;
 			u8 keydata[16];	/* WAPI key data */
@@ -1550,7 +1548,8 @@ struct wsm_tx_rate_retry_policy {
 	 *          finishes.
 	 * BIT(3) - Count initial frame transmission as part of
 	 *          rate retry counting but not as a retry
-	 *          attempt */
+	 *          attempt
+	 */
 	u8 flags;
 	u8 rate_recoveries;
 	u8 reserved[3];
@@ -1618,24 +1617,24 @@ static inline int wsm_set_udp_port_filter(struct cw1200_common *priv,
 #define D11_MAX_SSID_LEN		(32)
 
 struct wsm_p2p_device_type {
-	__le16 categoryId;
+	__le16 category_id;
 	u8 oui[4];
-	__le16 subCategoryId;
+	__le16 subcategory_id;
 } __packed;
 
 struct wsm_p2p_device_info {
 	struct wsm_p2p_device_type primaryDevice;
 	u8 reserved1[3];
-	u8 devNameSize;
-	u8 localDevName[D11_MAX_SSID_LEN];
+	u8 devname_size;
+	u8 local_devname[D11_MAX_SSID_LEN];
 	u8 reserved2[3];
-	u8 numSecDevSupported;
-	struct wsm_p2p_device_type secondaryDevices[0];
+	u8 num_secdev_supported;
+	struct wsm_p2p_device_type secdevs[0];
 } __packed;
 
 /* 4.36 SetWCDMABand - WO */
 struct wsm_cdma_band {
-	u8 WCDMA_Band;
+	u8 wcdma_band;
 	u8 reserved[3];
 } __packed;
 
@@ -1668,19 +1667,19 @@ struct wsm_ht_protection {
 #define WSM_GPIO_ALL_PINS	0xFF
 
 struct wsm_gpio_command {
-	u8 GPIO_Command;
+	u8 command;
 	u8 pin;
 	__le16 config;
 } __packed;
 
 /* 4.41 TSFCounter - RO */
 struct wsm_tsf_counter {
-	__le64 TSF_Counter;
+	__le64 tsf_counter;
 } __packed;
 
 /* 4.43 Keep alive period */
 struct wsm_keep_alive_period {
-	__le16 keepAlivePeriod;
+	__le16 period;
 	u8 reserved[2];
 } __packed;
 
@@ -1688,7 +1687,7 @@ static inline int wsm_keep_alive_period(struct cw1200_common *priv,
 					int period)
 {
 	struct wsm_keep_alive_period arg = {
-		.keepAlivePeriod = __cpu_to_le16(period),
+		.period = __cpu_to_le16(period),
 	};
 	return wsm_write_mib(priv, WSM_MIB_ID_KEEP_ALIVE_PERIOD,
 			&arg, sizeof(arg));
@@ -1739,13 +1738,13 @@ static inline int wsm_set_arp_ipv4_filter(struct cw1200_common *priv,
 
 /* P2P Power Save Mode Info - 4.31 */
 struct wsm_p2p_ps_modeinfo {
-	u8	oppPsCTWindow;
+	u8	opp_ps_ct_window;
 	u8	count;
 	u8	reserved;
-	u8	dtimCount;
+	u8	dtim_count;
 	__le32	duration;
 	__le32	interval;
-	__le32	startTime;
+	__le32	start_time;
 } __packed;
 
 static inline int wsm_set_p2p_ps_modeinfo(struct cw1200_common *priv,
-- 
1.8.2.1


^ permalink raw reply related

* [PATCH -next 2/3] cw1200:  Eliminate the ETF debug/engineering code.
From: Solomon Peachy @ 2013-06-11 13:49 UTC (permalink / raw)
  To: linux-wireless; +Cc: Solomon Peachy
In-Reply-To: <1370958580-6463-1-git-send-email-pizza@shaftnet.org>

This is only really useful for people who are bringing up new hardware
designs and have access to the proprietary vendor tools that interface
with this mode.

It'll live out of tree until it's rewritten to use a less kludgy interface.

Signed-off-by: Solomon Peachy <pizza@shaftnet.org>
---
 drivers/net/wireless/cw1200/Kconfig  |  10 --
 drivers/net/wireless/cw1200/cw1200.h |   9 --
 drivers/net/wireless/cw1200/debug.c  | 236 -----------------------------------
 drivers/net/wireless/cw1200/fwio.c   |   5 -
 drivers/net/wireless/cw1200/main.c   |  30 +----
 drivers/net/wireless/cw1200/wsm.c    |  56 +--------
 drivers/net/wireless/cw1200/wsm.h    |   5 -
 7 files changed, 2 insertions(+), 349 deletions(-)

diff --git a/drivers/net/wireless/cw1200/Kconfig b/drivers/net/wireless/cw1200/Kconfig
index fc1b472..0880742 100644
--- a/drivers/net/wireless/cw1200/Kconfig
+++ b/drivers/net/wireless/cw1200/Kconfig
@@ -27,14 +27,4 @@ config CW1200_WLAN_SPI
 	  need to add appropriate platform data glue in your board setup
 	  file.
 
-menu "Driver debug features"
-	depends on CW1200 && DEBUG_FS
-
-config CW1200_ETF
-	bool "Enable CW1200 Engineering Test Framework hooks"
-	help
-	  If you don't know what this is, just say N.
-
-endmenu
-
 endif
diff --git a/drivers/net/wireless/cw1200/cw1200.h b/drivers/net/wireless/cw1200/cw1200.h
index 95320f2..91ff7f1 100644
--- a/drivers/net/wireless/cw1200/cw1200.h
+++ b/drivers/net/wireless/cw1200/cw1200.h
@@ -35,11 +35,6 @@ struct task_struct;
 struct cw1200_debug_priv;
 struct firmware;
 
-#ifdef CONFIG_CW1200_ETF
-extern int etf_mode;
-extern char *etf_firmware;
-#endif
-
 #define CW1200_MAX_CTRL_FRAME_LEN	(0x1000)
 
 #define CW1200_MAX_STA_IN_AP_MODE	(5)
@@ -287,10 +282,6 @@ struct cw1200_common {
 	struct work_struct	linkid_reset_work;
 	u8			action_frame_sa[ETH_ALEN];
 	u8			action_linkid;
-
-#ifdef CONFIG_CW1200_ETF
-	struct sk_buff_head etf_q;
-#endif
 };
 
 struct cw1200_sta_priv {
diff --git a/drivers/net/wireless/cw1200/debug.c b/drivers/net/wireless/cw1200/debug.c
index ac9c219..e323b4d 100644
--- a/drivers/net/wireless/cw1200/debug.c
+++ b/drivers/net/wireless/cw1200/debug.c
@@ -357,144 +357,6 @@ static const struct file_operations fops_counters = {
 	.owner = THIS_MODULE,
 };
 
-#ifdef CONFIG_CW1200_ETF
-static int cw1200_etf_out_show(struct seq_file *seq, void *v)
-{
-	struct cw1200_common *priv = seq->private;
-	struct sk_buff *skb;
-	u32 len = 0;
-
-	skb = skb_dequeue(&priv->etf_q);
-
-	if (skb)
-		len = skb->len;
-
-	seq_write(seq, &len, sizeof(len));
-
-	if (skb) {
-		seq_write(seq, skb->data, len);
-		kfree_skb(skb);
-	}
-
-	return 0;
-}
-
-static int cw1200_etf_out_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, &cw1200_etf_out_show,
-			   inode->i_private);
-}
-
-static const struct file_operations fops_etf_out = {
-	.open = cw1200_etf_out_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-	.owner = THIS_MODULE,
-};
-
-struct etf_req_msg;
-static int etf_request(struct cw1200_common *priv,
-		       struct etf_req_msg *msg, u32 len);
-
-#define MAX_RX_SIZE 2600
-
-struct etf_in_state {
-	struct cw1200_common *priv;
-	u16 total_len;
-	u16 written;
-	u8 buf[MAX_RX_SIZE];
-};
-
-static int cw1200_etf_in_open(struct inode *inode, struct file *file)
-{
-	struct etf_in_state *etf = kmalloc(sizeof(struct etf_in_state),
-					   GFP_KERNEL);
-
-	if (!etf)
-		return -ENOMEM;
-
-	etf->written = 0;
-	etf->total_len = 0;
-	etf->priv = inode->i_private;
-
-	file->private_data = etf;
-
-	return 0;
-}
-
-static int cw1200_etf_in_release(struct inode *inode, struct file *file)
-{
-	kfree(file->private_data);
-	return 0;
-}
-
-static ssize_t cw1200_etf_in_write(struct file *file,
-	const char __user *user_buf, size_t count, loff_t *ppos)
-{
-	struct etf_in_state *etf = file->private_data;
-
-	ssize_t written = 0;
-
-	if (!etf->total_len) {
-		if (count < sizeof(etf->total_len)) {
-			pr_err("count < sizeof(total_len)\n");
-			return -EINVAL;
-		}
-
-		if (copy_from_user(&etf->total_len, user_buf,
-				   sizeof(etf->total_len))) {
-			pr_err("copy_from_user (len) failed\n");
-			return -EFAULT;
-		}
-
-		if (etf->total_len > MAX_RX_SIZE) {
-			pr_err("requested length > MAX_RX_SIZE\n");
-			return -EINVAL;
-		}
-
-		written += sizeof(etf->total_len);
-		count -= sizeof(etf->total_len);
-	}
-
-	if (!count)
-		goto done;
-
-	if (count > (etf->total_len - written)) {
-		pr_err("Tried to write > MAX_RX_SIZE\n");
-		return -EINVAL;
-	}
-
-	if (copy_from_user(etf->buf + etf->written, user_buf + written,
-			   count)) {
-		pr_err("copy_from_user (payload %zu) failed\n", count);
-		return -EFAULT;
-	}
-
-	written += count;
-	etf->written += count;
-
-	if (etf->written >= etf->total_len) {
-		if (etf_request(etf->priv, (struct etf_req_msg *)etf->buf,
-				etf->total_len)) {
-			pr_err("etf_request failed\n");
-			return -EIO;
-		}
-	}
-
-done:
-	return written;
-}
-
-static const struct file_operations fops_etf_in = {
-	.open = cw1200_etf_in_open,
-	.release = cw1200_etf_in_release,
-	.write = cw1200_etf_in_write,
-	.llseek = default_llseek,
-	.owner = THIS_MODULE,
-};
-#endif /* CONFIG_CW1200_ETF */
-
 static ssize_t cw1200_wsm_dumps(struct file *file,
 	const char __user *user_buf, size_t count, loff_t *ppos)
 {
@@ -542,19 +404,6 @@ int cw1200_debug_init(struct cw1200_common *priv)
 				 priv, &fops_counters))
 		goto err;
 
-#ifdef CONFIG_CW1200_ETF
-	if (etf_mode) {
-		skb_queue_head_init(&priv->etf_q);
-
-		if (!debugfs_create_file("etf_out", S_IRUSR, d->debugfs_phy,
-					 priv, &fops_etf_out))
-			goto err;
-		if (!debugfs_create_file("etf_in", S_IWUSR, d->debugfs_phy,
-					 priv, &fops_etf_in))
-			goto err;
-	}
-#endif /* CONFIG_CW1200_ETF */
-
 	if (!debugfs_create_file("wsm_dumps", S_IWUSR, d->debugfs_phy,
 				 priv, &fops_wsm_dumps))
 		goto err;
@@ -577,88 +426,3 @@ void cw1200_debug_release(struct cw1200_common *priv)
 		kfree(d);
 	}
 }
-
-#ifdef CONFIG_CW1200_ETF
-struct cw1200_sdd {
-	u8 id;
-	u8 len;
-	u8 data[];
-};
-
-struct etf_req_msg {
-	u32 id;
-	u32 len;
-	u8 data[];
-};
-
-static int parse_sdd_file(struct cw1200_common *priv, u8 *data, u32 length)
-{
-	struct cw1200_sdd *ie;
-
-	while (length > 0) {
-		ie = (struct cw1200_sdd *)data;
-		if (ie->id == SDD_REFERENCE_FREQUENCY_ELT_ID) {
-			priv->hw_refclk = cpu_to_le16(*((u16 *)ie->data));
-			pr_info("Using Reference clock frequency %d KHz\n",
-				priv->hw_refclk);
-			break;
-		}
-
-		length -= ie->len + sizeof(*ie);
-		data += ie->len + sizeof(*ie);
-	}
-	return 0;
-}
-
-char *etf_firmware;
-
-#define ST90TDS_START_ADAPTER           0x09 /* Loads firmware too */
-#define ST90TDS_STOP_ADAPTER            0x0A
-#define ST90TDS_CONFIG_ADAPTER          0x0E /* Send configuration params */
-#define ST90TDS_SBUS_READ               0x13
-#define ST90TDS_SBUS_WRITE              0x14
-#define ST90TDS_GET_DEVICE_OPTION       0x19
-#define ST90TDS_SET_DEVICE_OPTION       0x1A
-#define ST90TDS_SEND_SDD                0x1D /* SDD File used to find DPLL */
-
-#include "fwio.h"
-
-static int etf_request(struct cw1200_common *priv,
-		       struct etf_req_msg *msg,
-		       u32 len)
-{
-	int rval = -1;
-	switch (msg->id) {
-	case ST90TDS_START_ADAPTER:
-		etf_firmware = "cw1200_etf.bin";
-		pr_info("ETF_START (len %d, '%s')\n", len, etf_firmware);
-		rval = cw1200_load_firmware(priv);
-		break;
-	case ST90TDS_STOP_ADAPTER:
-		pr_info("ETF_STOP (unhandled)\n");
-		break;
-	case ST90TDS_SEND_SDD:
-		pr_info("ETF_SDD\n");
-		rval = parse_sdd_file(priv, msg->data, msg->len);
-		break;
-	case ST90TDS_CONFIG_ADAPTER:
-		pr_info("ETF_CONFIG_ADAP (unhandled)\n");
-		break;
-	case ST90TDS_SBUS_READ:
-		pr_info("ETF_SBUS_READ (unhandled)\n");
-		break;
-	case ST90TDS_SBUS_WRITE:
-		pr_info("ETF_SBUS_WRITE (unhandled)\n");
-		break;
-	case ST90TDS_SET_DEVICE_OPTION:
-		pr_info("ETF_SET_DEV_OPT (unhandled)\n");
-		break;
-	default:
-		pr_info("ETF_PASSTHRU (0x%08x)\n", msg->id);
-		rval = wsm_raw_cmd(priv, (u8 *)msg, len);
-		break;
-	}
-
-	return rval;
-}
-#endif /* CONFIG_CW1200_ETF */
diff --git a/drivers/net/wireless/cw1200/fwio.c b/drivers/net/wireless/cw1200/fwio.c
index 427c9f2..acdff0f 100644
--- a/drivers/net/wireless/cw1200/fwio.c
+++ b/drivers/net/wireless/cw1200/fwio.c
@@ -139,11 +139,6 @@ static int cw1200_load_firmware_cw1200(struct cw1200_common *priv)
 	val32 &= ~ST90TDS_CONFIG_CPU_CLK_DIS_BIT;
 	REG_WRITE(ST90TDS_CONFIG_REG_ID, val32);
 
-#ifdef CONFIG_CW1200_ETF
-	if (etf_mode)
-		fw_path = etf_firmware;
-#endif
-
 	/* Load a firmware file */
 	ret = request_firmware(&firmware, fw_path, priv->pdev);
 	if (ret) {
diff --git a/drivers/net/wireless/cw1200/main.c b/drivers/net/wireless/cw1200/main.c
index 2ea1bad..9f9adb4 100644
--- a/drivers/net/wireless/cw1200/main.c
+++ b/drivers/net/wireless/cw1200/main.c
@@ -61,12 +61,6 @@ int cw1200_power_mode = wsm_power_mode_quiescent;
 module_param(cw1200_power_mode, int, 0644);
 MODULE_PARM_DESC(cw1200_power_mode, "WSM power mode.  0 == active, 1 == doze, 2 == quiescent (default)");
 
-#ifdef CONFIG_CW1200_ETF
-int etf_mode;
-module_param(etf_mode, int, 0644);
-MODULE_PARM_DESC(etf_mode, "Enable EngineeringTestingFramework operation");
-#endif
-
 #define RATETAB_ENT(_rate, _rateid, _flags)		\
 	{						\
 		.bitrate	= (_rate),		\
@@ -418,11 +412,6 @@ static int cw1200_register_common(struct ieee80211_hw *dev)
 	struct cw1200_common *priv = dev->priv;
 	int err;
 
-#ifdef CONFIG_CW1200_ETF
-	if (etf_mode)
-		goto done;
-#endif
-
 #ifdef CONFIG_PM
 	err = cw1200_pm_init(&priv->pm_state, priv);
 	if (err) {
@@ -442,9 +431,6 @@ static int cw1200_register_common(struct ieee80211_hw *dev)
 		return err;
 	}
 
-#ifdef CONFIG_CW1200_ETF
-done:
-#endif
 	cw1200_debug_init(priv);
 
 	pr_info("Registered as '%s'\n", wiphy_name(dev->wiphy));
@@ -461,13 +447,7 @@ static void cw1200_unregister_common(struct ieee80211_hw *dev)
 	struct cw1200_common *priv = dev->priv;
 	int i;
 
-#ifdef CONFIG_CW1200_ETF
-	if (!etf_mode) {
-#endif
-		ieee80211_unregister_hw(dev);
-#ifdef CONFIG_CW1200_ETF
-	}
-#endif
+	ieee80211_unregister_hw(dev);
 
 	del_timer_sync(&priv->mcast_timeout);
 	cw1200_unregister_bh(priv);
@@ -568,11 +548,6 @@ int cw1200_core_probe(const struct hwbus_ops *hwbus_ops,
 	if (err)
 		goto err1;
 
-#ifdef CONFIG_CW1200_ETF
-	if (etf_mode)
-		goto skip_fw;
-#endif
-
 	err = cw1200_load_firmware(priv);
 	if (err)
 		goto err2;
@@ -594,9 +569,6 @@ int cw1200_core_probe(const struct hwbus_ops *hwbus_ops,
 	/* Enable multi-TX confirmation */
 	wsm_use_multi_tx_conf(priv, true);
 
-#ifdef CONFIG_CW1200_ETF
-skip_fw:
-#endif
 	err = cw1200_register_common(dev);
 	if (err)
 		goto err2;
diff --git a/drivers/net/wireless/cw1200/wsm.c b/drivers/net/wireless/cw1200/wsm.c
index e99f34e..d185f29 100644
--- a/drivers/net/wireless/cw1200/wsm.c
+++ b/drivers/net/wireless/cw1200/wsm.c
@@ -1111,10 +1111,7 @@ static int wsm_cmd_send(struct cw1200_common *priv,
 	 * pad the message by a few bytes to ensure
 	 * that it's completely received.
 	 */
-#ifdef CONFIG_CW1200_ETF
-	if (!etf_mode)
-#endif
-		buf_len += 4;
+	buf_len += 4;
 
 	/* Fill HI message header */
 	/* BH will add sequence number */
@@ -1165,29 +1162,6 @@ done:
 	return ret;
 }
 
-#ifdef CONFIG_CW1200_ETF
-int wsm_raw_cmd(struct cw1200_common *priv, u8 *data, size_t len)
-{
-	struct wsm_buf *buf = &priv->wsm_cmd_buf;
-	int ret;
-
-	u16 *cmd = (u16 *)(data + 2);
-
-	wsm_cmd_lock(priv);
-
-	WSM_PUT(buf, data + 4, len - 4);  /* Skip over header (u16+u16) */
-
-	ret = wsm_cmd_send(priv, buf, NULL, __le16_to_cpu(*cmd), WSM_CMD_TIMEOUT);
-
-	wsm_cmd_unlock(priv);
-	return ret;
-
-nomem:
-	wsm_cmd_unlock(priv);
-	return -ENOMEM;
-}
-#endif /* CONFIG_CW1200_ETF */
-
 /* ******************************************************************** */
 /* WSM TX port control							*/
 
@@ -1343,34 +1317,6 @@ int wsm_handle_rx(struct cw1200_common *priv, u16 id,
 	pr_debug("[WSM] <<< 0x%.4X (%td)\n", id,
 		 wsm_buf.end - wsm_buf.begin);
 
-#ifdef CONFIG_CW1200_ETF
-	if (etf_mode) {
-		struct sk_buff *skb = alloc_skb(wsm_buf.end - wsm_buf.begin, GFP_KERNEL);
-
-		/* Strip out Sequence num before passing up */
-		wsm->id = __le16_to_cpu(wsm->id);
-		wsm->id &= 0x0FFF;
-		wsm->id = __cpu_to_le16(wsm->id);
-
-		memcpy(skb_put(skb, wsm_buf.end - wsm_buf.begin),
-		       wsm_buf.begin,
-		       wsm_buf.end - wsm_buf.begin);
-		skb_queue_tail(&priv->etf_q, skb);
-
-		/* Special case for startup */
-		if (id == WSM_STARTUP_IND_ID) {
-			wsm_startup_indication(priv, &wsm_buf);
-		} else if (id & 0x0400) {
-			spin_lock(&priv->wsm_cmd.lock);
-			priv->wsm_cmd.done = 1;
-			spin_unlock(&priv->wsm_cmd.lock);
-			wake_up(&priv->wsm_cmd_wq);
-		}
-
-		goto out;
-	}
-#endif
-
 	if (id == WSM_TX_CONFIRM_IND_ID) {
 		ret = wsm_tx_confirm(priv, &wsm_buf, link_id);
 	} else if (id == WSM_MULTI_TX_CONFIRM_ID) {
diff --git a/drivers/net/wireless/cw1200/wsm.h b/drivers/net/wireless/cw1200/wsm.h
index 8d902d6..4689dff 100644
--- a/drivers/net/wireless/cw1200/wsm.h
+++ b/drivers/net/wireless/cw1200/wsm.h
@@ -1871,9 +1871,4 @@ static inline u8 wsm_queue_id_to_wsm(u8 queue_id)
 	return queue_mapping[queue_id];
 }
 
-
-#ifdef CONFIG_CW1200_ETF
-int wsm_raw_cmd(struct cw1200_common *priv, u8 *data, size_t len);
-#endif
-
 #endif /* CW1200_HWIO_H_INCLUDED */
-- 
1.8.2.1


^ permalink raw reply related

* [PATCH -next 1/3] cw1200:  Remove "ITP" debug subsystem.
From: Solomon Peachy @ 2013-06-11 13:49 UTC (permalink / raw)
  To: linux-wireless; +Cc: Solomon Peachy

This can live on as an out-of-tree patch for those that care.

Signed-off-by: Solomon Peachy <pizza@shaftnet.org>
---
 drivers/net/wireless/cw1200/Kconfig  |   5 -
 drivers/net/wireless/cw1200/Makefile |   1 -
 drivers/net/wireless/cw1200/debug.c  |   6 +-
 drivers/net/wireless/cw1200/debug.h  |   5 -
 drivers/net/wireless/cw1200/itp.c    | 730 -----------------------------------
 drivers/net/wireless/cw1200/itp.h    | 144 -------
 drivers/net/wireless/cw1200/txrx.c   |  10 +-
 drivers/net/wireless/cw1200/wsm.c    |   7 -
 8 files changed, 3 insertions(+), 905 deletions(-)
 delete mode 100644 drivers/net/wireless/cw1200/itp.c
 delete mode 100644 drivers/net/wireless/cw1200/itp.h

diff --git a/drivers/net/wireless/cw1200/Kconfig b/drivers/net/wireless/cw1200/Kconfig
index 7a585d4..fc1b472 100644
--- a/drivers/net/wireless/cw1200/Kconfig
+++ b/drivers/net/wireless/cw1200/Kconfig
@@ -35,11 +35,6 @@ config CW1200_ETF
 	help
 	  If you don't know what this is, just say N.
 
-config CW1200_ITP
-	bool "Enable ITP access"
-	help
-	  If you don't know what this is, just say N.
-
 endmenu
 
 endif
diff --git a/drivers/net/wireless/cw1200/Makefile b/drivers/net/wireless/cw1200/Makefile
index bc6cbf9..b086aac 100644
--- a/drivers/net/wireless/cw1200/Makefile
+++ b/drivers/net/wireless/cw1200/Makefile
@@ -9,7 +9,6 @@ cw1200_core-y := \
 		sta.o \
 		scan.o \
 		debug.o
-cw1200_core-$(CONFIG_CW1200_ITP)	+= itp.o
 cw1200_core-$(CONFIG_PM)	+= pm.o
 
 # CFLAGS_sta.o += -DDEBUG
diff --git a/drivers/net/wireless/cw1200/debug.c b/drivers/net/wireless/cw1200/debug.c
index 1596b70..ac9c219 100644
--- a/drivers/net/wireless/cw1200/debug.c
+++ b/drivers/net/wireless/cw1200/debug.c
@@ -559,10 +559,6 @@ int cw1200_debug_init(struct cw1200_common *priv)
 				 priv, &fops_wsm_dumps))
 		goto err;
 
-	ret = cw1200_itp_init(priv);
-	if (ret)
-		goto err;
-
 	return 0;
 
 err:
@@ -576,7 +572,7 @@ void cw1200_debug_release(struct cw1200_common *priv)
 {
 	struct cw1200_debug_priv *d = priv->debug;
 	if (d) {
-		cw1200_itp_release(priv);
+		debugfs_remove_recursive(d->debugfs_phy);
 		priv->debug = NULL;
 		kfree(d);
 	}
diff --git a/drivers/net/wireless/cw1200/debug.h b/drivers/net/wireless/cw1200/debug.h
index 1fea5b2..b525aba 100644
--- a/drivers/net/wireless/cw1200/debug.h
+++ b/drivers/net/wireless/cw1200/debug.h
@@ -12,8 +12,6 @@
 #ifndef CW1200_DEBUG_H_INCLUDED
 #define CW1200_DEBUG_H_INCLUDED
 
-#include "itp.h"
-
 struct cw1200_debug_priv {
 	struct dentry *debugfs_phy;
 	int tx;
@@ -30,9 +28,6 @@ struct cw1200_debug_priv {
 	int ba_acc;
 	int ba_cnt_rx;
 	int ba_acc_rx;
-#ifdef CONFIG_CW1200_ITP
-	struct cw1200_itp itp;
-#endif /* CONFIG_CW1200_ITP */
 };
 
 int cw1200_debug_init(struct cw1200_common *priv);
diff --git a/drivers/net/wireless/cw1200/itp.c b/drivers/net/wireless/cw1200/itp.c
deleted file mode 100644
index c0730bb..0000000
--- a/drivers/net/wireless/cw1200/itp.c
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- * mac80211 glue code for mac80211 ST-Ericsson CW1200 drivers
- * ITP code
- *
- * Copyright (c) 2010, ST-Ericsson
- * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/debugfs.h>
-#include <linux/poll.h>
-#include <linux/time.h>
-#include <linux/random.h>
-#include <linux/kallsyms.h>
-#include <net/mac80211.h>
-#include "cw1200.h"
-#include "debug.h"
-#include "itp.h"
-#include "sta.h"
-
-static int __cw1200_itp_open(struct cw1200_common *priv);
-static int __cw1200_itp_close(struct cw1200_common *priv);
-static void cw1200_itp_rx_start(struct cw1200_common *priv);
-static void cw1200_itp_rx_stop(struct cw1200_common *priv);
-static void cw1200_itp_rx_stats(struct cw1200_common *priv);
-static void cw1200_itp_rx_reset(struct cw1200_common *priv);
-static void cw1200_itp_tx_stop(struct cw1200_common *priv);
-static void cw1200_itp_handle(struct cw1200_common *priv,
-			      struct sk_buff *skb);
-static void cw1200_itp_err(struct cw1200_common *priv,
-			   int err,
-			   int arg);
-static void __cw1200_itp_tx_stop(struct cw1200_common *priv);
-
-static ssize_t cw1200_itp_read(struct file *file,
-	char __user *user_buf, size_t count, loff_t *ppos)
-{
-	struct cw1200_common *priv = file->private_data;
-	struct cw1200_itp *itp = &priv->debug->itp;
-	struct sk_buff *skb;
-	int ret;
-
-	if (skb_queue_empty(&itp->log_queue))
-		return 0;
-
-	skb = skb_dequeue(&itp->log_queue);
-	ret = copy_to_user(user_buf, skb->data, skb->len);
-	*ppos += skb->len;
-	skb->data[skb->len] = 0;
-	pr_debug("[ITP] >>> %s", skb->data);
-	consume_skb(skb);
-
-	return skb->len - ret;
-}
-
-static ssize_t cw1200_itp_write(struct file *file,
-	const char __user *user_buf, size_t count, loff_t *ppos)
-{
-	struct cw1200_common *priv = file->private_data;
-	struct sk_buff *skb;
-
-	if (!count || count > 1024)
-		return -EINVAL;
-	skb = dev_alloc_skb(count + 1);
-	if (!skb)
-		return -ENOMEM;
-	skb_trim(skb, 0);
-	skb_put(skb, count + 1);
-	if (copy_from_user(skb->data, user_buf, count)) {
-		kfree_skb(skb);
-		return -EFAULT;
-	}
-	skb->data[count] = 0;
-
-	cw1200_itp_handle(priv, skb);
-	consume_skb(skb);
-	return count;
-}
-
-static unsigned int cw1200_itp_poll(struct file *file, poll_table *wait)
-{
-	struct cw1200_common *priv = file->private_data;
-	struct cw1200_itp *itp = &priv->debug->itp;
-	unsigned int mask = 0;
-
-	poll_wait(file, &itp->read_wait, wait);
-
-	if (!skb_queue_empty(&itp->log_queue))
-		mask |= POLLIN | POLLRDNORM;
-
-	mask |= POLLOUT | POLLWRNORM;
-
-	return mask;
-}
-
-static int cw1200_itp_open(struct inode *inode, struct file *file)
-{
-	struct cw1200_common *priv = inode->i_private;
-	struct cw1200_itp *itp = &priv->debug->itp;
-	int ret = 0;
-
-	file->private_data = priv;
-	if (atomic_inc_return(&itp->open_count) == 1) {
-		ret = __cw1200_itp_open(priv);
-		if (ret && !atomic_dec_return(&itp->open_count))
-			__cw1200_itp_close(priv);
-	} else {
-		atomic_dec(&itp->open_count);
-		ret = -EBUSY;
-	}
-
-	return ret;
-}
-
-static int cw1200_itp_close(struct inode *inode, struct file *file)
-{
-	struct cw1200_common *priv = file->private_data;
-	struct cw1200_itp *itp = &priv->debug->itp;
-	if (!atomic_dec_return(&itp->open_count)) {
-		__cw1200_itp_close(priv);
-		wake_up(&itp->close_wait);
-	}
-	return 0;
-}
-
-static const struct file_operations fops_itp = {
-	.open = cw1200_itp_open,
-	.read = cw1200_itp_read,
-	.write = cw1200_itp_write,
-	.poll = cw1200_itp_poll,
-	.release = cw1200_itp_close,
-	.llseek = default_llseek,
-	.owner = THIS_MODULE,
-};
-
-static void cw1200_itp_fill_pattern(u8 *data, int size,
-		enum cw1200_itp_data_modes mode)
-{
-	if (size <= 0)
-		return;
-
-	switch (mode) {
-	default:
-	case ITP_DATA_ZEROS:
-		memset(data, 0x0, size);
-		break;
-	case ITP_DATA_ONES:
-		memset(data, 0xff, size);
-		break;
-	case ITP_DATA_ZERONES:
-		memset(data, 0x55, size);
-		break;
-	case ITP_DATA_RANDOM:
-		get_random_bytes(data, size);
-		break;
-	}
-	return;
-}
-
-static void cw1200_itp_tx_work(struct work_struct *work)
-{
-	struct cw1200_itp *itp = container_of(work, struct cw1200_itp,
-		    tx_work.work);
-	struct cw1200_common *priv = itp->priv;
-	atomic_set(&priv->bh_tx, 1);
-	wake_up(&priv->bh_wq);
-}
-
-static void cw1200_itp_tx_finish(struct work_struct *work)
-{
-	struct cw1200_itp *itp = container_of(work, struct cw1200_itp,
-		    tx_finish.work);
-	__cw1200_itp_tx_stop(itp->priv);
-}
-
-int cw1200_itp_init(struct cw1200_common *priv)
-{
-	struct cw1200_itp *itp = &priv->debug->itp;
-
-	itp->priv = priv;
-	atomic_set(&itp->open_count, 0);
-	atomic_set(&itp->stop_tx, 0);
-	atomic_set(&itp->awaiting_confirm, 0);
-	skb_queue_head_init(&itp->log_queue);
-	spin_lock_init(&itp->tx_lock);
-	init_waitqueue_head(&itp->read_wait);
-	init_waitqueue_head(&itp->write_wait);
-	init_waitqueue_head(&itp->close_wait);
-	INIT_DELAYED_WORK(&itp->tx_work, cw1200_itp_tx_work);
-	INIT_DELAYED_WORK(&itp->tx_finish, cw1200_itp_tx_finish);
-	itp->data = NULL;
-	itp->hdr_len = WSM_TX_EXTRA_HEADROOM +
-			sizeof(struct ieee80211_hdr_3addr);
-
-	if (!debugfs_create_file("itp", S_IRUSR | S_IWUSR,
-				 priv->debug->debugfs_phy, priv, &fops_itp))
-		return -ENOMEM;
-
-	return 0;
-}
-
-void cw1200_itp_release(struct cw1200_common *priv)
-{
-	struct cw1200_itp *itp = &priv->debug->itp;
-
-	wait_event_interruptible(itp->close_wait,
-				 !atomic_read(&itp->open_count));
-
-	WARN_ON(atomic_read(&itp->open_count));
-
-	skb_queue_purge(&itp->log_queue);
-	cw1200_itp_tx_stop(priv);
-}
-
-static int __cw1200_itp_open(struct cw1200_common *priv)
-{
-	struct cw1200_itp *itp = &priv->debug->itp;
-
-	if (!priv->vif)
-		return -EINVAL;
-	if (priv->join_status)
-		return -EINVAL;
-	itp->saved_channel = priv->channel;
-	if (!priv->channel)
-		priv->channel = &priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ]->channels[0];
-	wsm_set_bssid_filtering(priv, false);
-	cw1200_itp_rx_reset(priv);
-	return 0;
-}
-
-static int __cw1200_itp_close(struct cw1200_common *priv)
-{
-	struct cw1200_itp *itp = &priv->debug->itp;
-	if (atomic_read(&itp->test_mode) == TEST_MODE_RX_TEST)
-		cw1200_itp_rx_stop(priv);
-	cw1200_itp_tx_stop(priv);
-	cw1200_disable_listening(priv);
-	cw1200_update_filtering(priv);
-	priv->channel = itp->saved_channel;
-	return 0;
-}
-
-bool cw1200_is_itp(struct cw1200_common *priv)
-{
-	struct cw1200_itp *itp = &priv->debug->itp;
-	return atomic_read(&itp->open_count) != 0;
-}
-
-static void cw1200_itp_rx_reset(struct cw1200_common *priv)
-{
-	struct cw1200_itp *itp = &priv->debug->itp;
-	itp->rx_cnt = 0;
-	itp->rx_rssi = 0;
-	itp->rx_rssi_max = -1000;
-	itp->rx_rssi_min = 1000;
-}
-
-static void cw1200_itp_rx_start(struct cw1200_common *priv)
-{
-	struct cw1200_itp *itp = &priv->debug->itp;
-
-	pr_debug("[ITP] RX start, band = %d, ch = %d\n",
-		 itp->band, itp->ch);
-	atomic_set(&itp->test_mode, TEST_MODE_RX_TEST);
-	cw1200_update_listening(priv, false);
-	priv->channel = &priv->hw->
-		wiphy->bands[itp->band]->channels[itp->ch];
-	cw1200_update_listening(priv, true);
-	wsm_set_bssid_filtering(priv, false);
-}
-
-static void cw1200_itp_rx_stop(struct cw1200_common *priv)
-{
-	struct cw1200_itp *itp = &priv->debug->itp;
-	pr_debug("[ITP] RX stop\n");
-	atomic_set(&itp->test_mode, TEST_MODE_NO_TEST);
-	cw1200_itp_rx_reset(priv);
-}
-
-static void cw1200_itp_rx_stats(struct cw1200_common *priv)
-{
-	struct cw1200_itp *itp = &priv->debug->itp;
-	struct sk_buff *skb;
-	char buf[128];
-	int len, ret;
-	struct wsm_mib_counters_table counters;
-
-	ret = wsm_get_counters_table(priv, &counters);
-
-	if (ret)
-		cw1200_itp_err(priv, -EBUSY, 20);
-
-	if (!itp->rx_cnt)
-		len = snprintf(buf, sizeof(buf), "1,0,0,0,0,%d\n",
-			       counters.rx_packet_errors);
-	else
-		len = snprintf(buf, sizeof(buf), "1,%d,%ld,%d,%d,%d\n",
-			       itp->rx_cnt,
-			       itp->rx_cnt ? itp->rx_rssi / itp->rx_cnt : 0,
-			       itp->rx_rssi_min, itp->rx_rssi_max,
-			       counters.rx_packet_errors);
-
-	if (len <= 0) {
-		cw1200_itp_err(priv, -EBUSY, 21);
-		return;
-	}
-
-	skb = dev_alloc_skb(len);
-	if (!skb) {
-		cw1200_itp_err(priv, -ENOMEM, 22);
-		return;
-	}
-
-	itp->rx_cnt = 0;
-	itp->rx_rssi = 0;
-	itp->rx_rssi_max = -1000;
-	itp->rx_rssi_min = 1000;
-
-	skb_trim(skb, 0);
-	skb_put(skb, len);
-
-	memcpy(skb->data, buf, len);
-	skb_queue_tail(&itp->log_queue, skb);
-	wake_up(&itp->read_wait);
-}
-
-static void cw1200_itp_tx_start(struct cw1200_common *priv)
-{
-	struct wsm_tx *tx;
-	struct ieee80211_hdr_3addr *hdr;
-	struct cw1200_itp *itp = &priv->debug->itp;
-	struct wsm_mib_association_mode assoc_mode = {
-		.flags = WSM_ASSOCIATION_MODE_USE_PREAMBLE_TYPE,
-		.preamble = itp->preamble,
-	};
-	int len;
-	u8 da_addr[6] = ITP_DEFAULT_DA_ADDR;
-
-	/* Rates index 4 and 5 are not supported */
-	if (itp->rate > 3)
-		itp->rate += 2;
-
-	pr_debug("[ITP] TX start: band = %d, ch = %d, rate = %d, preamble = %d, number = %d, data_mode = %d, interval = %d, power = %d, data_len = %d\n",
-		 itp->band, itp->ch, itp->rate, itp->preamble,
-		 itp->number, itp->data_mode, itp->interval_us,
-		 itp->power, itp->data_len);
-
-	len = itp->hdr_len + itp->data_len;
-
-	itp->data = kmalloc(len, GFP_KERNEL);
-	tx = (struct wsm_tx *)itp->data;
-	tx->hdr.len = itp->data_len + itp->hdr_len;
-	tx->hdr.id = __cpu_to_le16(0x0004 | 1 << 6);
-	tx->max_tx_rate = itp->rate;
-	tx->queue_id = 3;
-	tx->more = 0;
-	tx->flags = 0xc;
-	tx->packet_id = 0x55ff55;
-	tx->reserved = 0;
-	tx->expire_time = 1;
-
-	if (itp->preamble == ITP_PREAMBLE_GREENFIELD)
-		tx->ht_tx_parameters = WSM_HT_TX_GREENFIELD;
-	else if (itp->preamble == ITP_PREAMBLE_MIXED)
-		tx->ht_tx_parameters = WSM_HT_TX_MIXED;
-
-	hdr = (struct ieee80211_hdr_3addr *)&itp->data[sizeof(struct wsm_tx)];
-	memset(hdr, 0, sizeof(*hdr));
-	hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |	IEEE80211_FCTL_TODS);
-	memcpy(hdr->addr1, da_addr, ETH_ALEN);
-	memcpy(hdr->addr2, priv->vif->addr, ETH_ALEN);
-	memcpy(hdr->addr3, da_addr, ETH_ALEN);
-
-	cw1200_itp_fill_pattern(&itp->data[itp->hdr_len],
-				itp->data_len, itp->data_mode);
-
-	cw1200_update_listening(priv, false);
-	priv->channel = &priv->hw->wiphy->bands[itp->band]->channels[itp->ch];
-	WARN_ON(wsm_set_output_power(priv, itp->power));
-	if (itp->preamble == ITP_PREAMBLE_SHORT ||
-	    itp->preamble == ITP_PREAMBLE_LONG)
-		WARN_ON(wsm_set_association_mode(priv,
-						 &assoc_mode));
-	wsm_set_bssid_filtering(priv, false);
-	cw1200_update_listening(priv, true);
-
-	spin_lock_bh(&itp->tx_lock);
-	atomic_set(&itp->test_mode, TEST_MODE_TX_TEST);
-	atomic_set(&itp->awaiting_confirm, 0);
-	atomic_set(&itp->stop_tx, 0);
-	atomic_set(&priv->bh_tx, 1);
-	ktime_get_ts(&itp->last_sent);
-	wake_up(&priv->bh_wq);
-	spin_unlock_bh(&itp->tx_lock);
-}
-
-void __cw1200_itp_tx_stop(struct cw1200_common *priv)
-{
-	struct cw1200_itp *itp = &priv->debug->itp;
-	spin_lock_bh(&itp->tx_lock);
-	kfree(itp->data);
-	itp->data = NULL;
-	atomic_set(&itp->test_mode, TEST_MODE_NO_TEST);
-	spin_unlock_bh(&itp->tx_lock);
-}
-
-static void cw1200_itp_tx_stop(struct cw1200_common *priv)
-{
-	struct cw1200_itp *itp = &priv->debug->itp;
-	pr_debug("[ITP] TX stop\n");
-	atomic_set(&itp->stop_tx, 1);
-	flush_workqueue(priv->workqueue);
-
-	/* time for FW to confirm all tx requests */
-	msleep(500);
-
-	__cw1200_itp_tx_stop(priv);
-}
-
-static int cw1200_print_fw_version(struct cw1200_common *priv,
-				   u8 *buf, size_t len)
-{
-	return snprintf(buf, len, "%s %d.%d",
-			cw1200_fw_types[priv->wsm_caps.fw_type],
-			priv->wsm_caps.fw_ver,
-			priv->wsm_caps.fw_build);
-}
-
-static void cw1200_itp_get_version(struct cw1200_common *priv,
-		enum cw1200_itp_version_type type)
-{
-	struct cw1200_itp *itp = &priv->debug->itp;
-	struct sk_buff *skb;
-	char buf[ITP_BUF_SIZE];
-	size_t size = 0;
-	int len;
-	pr_debug("[ITP] print %s version\n",
-		 type == ITP_CHIP_ID ? "chip" : "firmware");
-
-	len = snprintf(buf, ITP_BUF_SIZE, "2,");
-	if (len <= 0) {
-		cw1200_itp_err(priv, -EINVAL, 40);
-		return;
-	}
-	size += len;
-
-	switch (type) {
-	case ITP_CHIP_ID:
-		len = cw1200_print_fw_version(priv, buf+size,
-				ITP_BUF_SIZE - size);
-
-		if (len <= 0) {
-			cw1200_itp_err(priv, -EINVAL, 41);
-			return;
-		}
-		size += len;
-		break;
-	case ITP_FW_VER:
-		len = snprintf(buf+size, ITP_BUF_SIZE - size,
-				"%d.%d", priv->wsm_caps.hw_id,
-				priv->wsm_caps.hw_subid);
-		if (len <= 0) {
-			cw1200_itp_err(priv, -EINVAL, 42);
-			return;
-		}
-		size += len;
-		break;
-	default:
-		cw1200_itp_err(priv, -EINVAL, 43);
-		break;
-	}
-
-	len = snprintf(buf+size, ITP_BUF_SIZE-size, "\n");
-	if (len <= 0) {
-		cw1200_itp_err(priv, -EINVAL, 44);
-		return;
-	}
-	size += len;
-
-	skb = dev_alloc_skb(size);
-	if (!skb) {
-		cw1200_itp_err(priv, -ENOMEM, 45);
-		return;
-	}
-
-	skb_trim(skb, 0);
-	skb_put(skb, size);
-
-	memcpy(skb->data, buf, size);
-	skb_queue_tail(&itp->log_queue, skb);
-	wake_up(&itp->read_wait);
-}
-
-int cw1200_itp_get_tx(struct cw1200_common *priv, u8 **data,
-		size_t *tx_len, int *burst)
-{
-	struct cw1200_itp *itp;
-	struct timespec now;
-	int time_left_us;
-
-	if (!priv->debug)
-		return 0;
-
-	itp	= &priv->debug->itp;
-
-	if (!itp)
-		return 0;
-
-	spin_lock_bh(&itp->tx_lock);
-	if (atomic_read(&itp->test_mode) != TEST_MODE_TX_TEST)
-		goto out;
-
-	if (atomic_read(&itp->stop_tx))
-		goto out;
-
-	if (itp->number == 0) {
-		atomic_set(&itp->stop_tx, 1);
-		queue_delayed_work(priv->workqueue, &itp->tx_finish, HZ/10);
-		goto out;
-	}
-
-	if (!itp->data)
-		goto out;
-
-	if (priv->hw_bufs_used >= 2) {
-		if (!atomic_read(&priv->bh_rx))
-			atomic_set(&priv->bh_rx, 1);
-		atomic_set(&priv->bh_tx, 1);
-		goto out;
-	}
-
-	ktime_get_ts(&now);
-	time_left_us = (itp->last_sent.tv_sec -	now.tv_sec)*1000000 +
-		(itp->last_sent.tv_nsec - now.tv_nsec)/1000 +
-		itp->interval_us;
-
-	if (time_left_us > ITP_TIME_THRES_US) {
-		queue_delayed_work(priv->workqueue, &itp->tx_work,
-				   ITP_US_TO_MS(time_left_us)*HZ/1000);
-		goto out;
-	}
-
-	if (time_left_us > 50)
-		udelay(time_left_us);
-
-	if (itp->number > 0)
-		itp->number--;
-
-	*data = itp->data;
-	*tx_len = itp->data_len + itp->hdr_len;
-
-	if (itp->data_mode == ITP_DATA_RANDOM)
-		cw1200_itp_fill_pattern(&itp->data[itp->hdr_len],
-					itp->data_len, itp->data_mode);
-	*burst = 2;
-	atomic_set(&priv->bh_tx, 1);
-	ktime_get_ts(&itp->last_sent);
-	atomic_add(1, &itp->awaiting_confirm);
-	spin_unlock_bh(&itp->tx_lock);
-	return 1;
-
-out:
-	spin_unlock_bh(&itp->tx_lock);
-	return 0;
-}
-
-bool cw1200_itp_rxed(struct cw1200_common *priv, struct sk_buff *skb)
-{
-	struct cw1200_itp *itp = &priv->debug->itp;
-	struct ieee80211_rx_status *rx = IEEE80211_SKB_RXCB(skb);
-	int signal;
-
-	if (atomic_read(&itp->test_mode) != TEST_MODE_RX_TEST)
-		return cw1200_is_itp(priv);
-	if (rx->freq != priv->channel->center_freq)
-		return true;
-
-	signal = rx->signal;
-	itp->rx_cnt++;
-	itp->rx_rssi += signal;
-	if (itp->rx_rssi_min > rx->signal)
-		itp->rx_rssi_min = rx->signal;
-	if (itp->rx_rssi_max < rx->signal)
-		itp->rx_rssi_max = rx->signal;
-
-	return true;
-}
-
-void cw1200_itp_wake_up_tx(struct cw1200_common *priv)
-{
-	wake_up(&priv->debug->itp.write_wait);
-}
-
-bool cw1200_itp_tx_running(struct cw1200_common *priv)
-{
-	if (atomic_read(&priv->debug->itp.awaiting_confirm) ||
-	    atomic_read(&priv->debug->itp.test_mode) ==
-	    TEST_MODE_TX_TEST) {
-		atomic_sub(1, &priv->debug->itp.awaiting_confirm);
-		return true;
-	}
-	return false;
-}
-
-static void cw1200_itp_handle(struct cw1200_common *priv,
-			      struct sk_buff *skb)
-{
-	struct cw1200_itp *itp = &priv->debug->itp;
-	const struct wiphy *wiphy = priv->hw->wiphy;
-	int cmd;
-	int ret;
-
-	pr_debug("[ITP] <<< %s", skb->data);
-	if (sscanf(skb->data, "%d", &cmd) != 1) {
-		cw1200_itp_err(priv, -EINVAL, 1);
-		return;
-	}
-
-	switch (cmd) {
-	case 1: /* RX test */
-		if (atomic_read(&itp->test_mode)) {
-			cw1200_itp_err(priv, -EBUSY, 0);
-			return;
-		}
-		ret = sscanf(skb->data, "%d,%d,%d",
-				&cmd, &itp->band, &itp->ch);
-		if (ret != 3) {
-			cw1200_itp_err(priv, -EINVAL, ret + 1);
-			return;
-		}
-		if (itp->band >= 2) {
-			cw1200_itp_err(priv, -EINVAL, 2);
-		} else if (!wiphy->bands[itp->band]) {
-			cw1200_itp_err(priv, -EINVAL, 2);
-		} else if (itp->ch >= wiphy->bands[itp->band]->n_channels) {
-			cw1200_itp_err(priv, -EINVAL, 3);
-		} else {
-			cw1200_itp_rx_stats(priv);
-			cw1200_itp_rx_start(priv);
-		}
-		break;
-	case 2: /* RX stat */
-		cw1200_itp_rx_stats(priv);
-		break;
-	case 3: /* RX/TX stop */
-		if (atomic_read(&itp->test_mode) == TEST_MODE_RX_TEST) {
-			cw1200_itp_rx_stats(priv);
-			cw1200_itp_rx_stop(priv);
-		} else if (atomic_read(&itp->test_mode) == TEST_MODE_TX_TEST) {
-			cw1200_itp_tx_stop(priv);
-		} else {
-			cw1200_itp_err(priv, -EBUSY, 0);
-		}
-		break;
-	case 4: /* TX start */
-		if (atomic_read(&itp->test_mode) != TEST_MODE_NO_TEST) {
-			cw1200_itp_err(priv, -EBUSY, 0);
-			return;
-		}
-		ret = sscanf(skb->data, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
-				&cmd, &itp->band, &itp->ch, &itp->rate,
-				&itp->preamble, &itp->number, &itp->data_mode,
-				&itp->interval_us, &itp->power, &itp->data_len);
-		if (ret != 10) {
-			cw1200_itp_err(priv, -EINVAL, ret + 1);
-			return;
-		}
-		if (itp->band >= 2) {
-			cw1200_itp_err(priv, -EINVAL, 2);
-		} else if (!wiphy->bands[itp->band]) {
-			cw1200_itp_err(priv, -EINVAL, 2);
-		} else if (itp->ch >= wiphy->bands[itp->band]->n_channels) {
-			cw1200_itp_err(priv, -EINVAL, 3);
-		} else if (itp->rate >= 20) {
-			cw1200_itp_err(priv, -EINVAL, 4);
-		} else if (itp->preamble >= ITP_PREAMBLE_MAX) {
-			cw1200_itp_err(priv, -EINVAL, 5);
-		} else if (itp->data_mode >= ITP_DATA_MAX_MODE) {
-			cw1200_itp_err(priv, -EINVAL, 7);
-		} else if (itp->data_len < ITP_MIN_DATA_SIZE ||
-			   itp->data_len > (priv->wsm_caps.input_buffer_size - itp->hdr_len)) {
-			cw1200_itp_err(priv, -EINVAL, 8);
-		} else {
-		    cw1200_itp_tx_start(priv);
-		}
-		break;
-	case 5:
-		cw1200_itp_get_version(priv, ITP_CHIP_ID);
-		break;
-	case 6:
-		cw1200_itp_get_version(priv, ITP_FW_VER);
-		break;
-	}
-}
-
-static void cw1200_itp_err(struct cw1200_common *priv,
-			   int err, int arg)
-{
-	struct cw1200_itp *itp = &priv->debug->itp;
-	struct sk_buff *skb;
-	static char buf[255];
-	int len;
-
-	len = snprintf(buf, sizeof(buf), "%d,%d\n",
-		err, arg);
-	if (len <= 0)
-		return;
-
-	skb = dev_alloc_skb(len);
-	if (!skb)
-		return;
-
-	skb_trim(skb, 0);
-	skb_put(skb, len);
-
-	memcpy(skb->data, buf, len);
-	skb_queue_tail(&itp->log_queue, skb);
-	wake_up(&itp->read_wait);
-
-	len = sprint_symbol(buf,
-			(unsigned long)__builtin_return_address(0));
-	if (len <= 0)
-		return;
-	pr_debug("[ITP] error %d,%d from %s\n",
-		 err, arg, buf);
-}
diff --git a/drivers/net/wireless/cw1200/itp.h b/drivers/net/wireless/cw1200/itp.h
deleted file mode 100644
index 1e9dfb7..0000000
--- a/drivers/net/wireless/cw1200/itp.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * ITP code for ST-Ericsson CW1200 mac80211 driver
- *
- * Copyright (c) 2011, ST-Ericsson
- * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef CW1200_ITP_H_INCLUDED
-#define CW1200_ITP_H_INCLUDED
-
-struct cw200_common;
-struct wsm_tx_confirm;
-struct dentry;
-
-#ifdef CONFIG_CW1200_ITP
-
-/*extern*/ struct ieee80211_channel;
-
-#define TEST_MODE_NO_TEST	(0)
-#define TEST_MODE_RX_TEST	(1)
-#define TEST_MODE_TX_TEST	(2)
-#define ITP_DEFAULT_DA_ADDR {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
-#define ITP_MIN_DATA_SIZE 6
-#define ITP_MAX_DATA_SIZE 1600
-#define ITP_TIME_THRES_US 10000
-#define ITP_US_TO_MS(x) ((x)/1000)
-#define ITP_MS_TO_US(x) ((x)*1000)
-#define ITP_BUF_SIZE 255
-
-
-enum cw1200_itp_data_modes {
-	ITP_DATA_ZEROS,
-	ITP_DATA_ONES,
-	ITP_DATA_ZERONES,
-	ITP_DATA_RANDOM,
-	ITP_DATA_MAX_MODE,
-};
-
-enum cw1200_itp_version_type {
-	ITP_CHIP_ID,
-	ITP_FW_VER,
-};
-
-enum cw1200_itp_preamble_type {
-	ITP_PREAMBLE_LONG,
-	ITP_PREAMBLE_SHORT,
-	ITP_PREAMBLE_OFDM,
-	ITP_PREAMBLE_MIXED,
-	ITP_PREAMBLE_GREENFIELD,
-	ITP_PREAMBLE_MAX,
-};
-
-
-struct cw1200_itp {
-	struct cw1200_common	*priv;
-	atomic_t		open_count;
-	atomic_t		awaiting_confirm;
-	struct sk_buff_head	log_queue;
-	wait_queue_head_t	read_wait;
-	wait_queue_head_t	write_wait;
-	wait_queue_head_t	close_wait;
-	struct ieee80211_channel *saved_channel;
-	atomic_t		stop_tx;
-	struct delayed_work	tx_work;
-	struct delayed_work	tx_finish;
-	spinlock_t		tx_lock;
-	struct timespec		last_sent;
-	atomic_t		test_mode;
-	int			rx_cnt;
-	long			rx_rssi;
-	int			rx_rssi_max;
-	int			rx_rssi_min;
-	unsigned		band;
-	unsigned		ch;
-	unsigned		rate;
-	unsigned		preamble;
-	unsigned int		number;
-	unsigned		data_mode;
-	int			interval_us;
-	int			power;
-	u8			*data;
-	int			hdr_len;
-	int			data_len;
-};
-
-int cw1200_itp_init(struct cw1200_common *priv);
-void cw1200_itp_release(struct cw1200_common *priv);
-
-bool cw1200_is_itp(struct cw1200_common *priv);
-bool cw1200_itp_rxed(struct cw1200_common *priv, struct sk_buff *skb);
-void cw1200_itp_wake_up_tx(struct cw1200_common *priv);
-int cw1200_itp_get_tx(struct cw1200_common *priv, u8 **data,
-		size_t *tx_len, int *burst);
-bool cw1200_itp_tx_running(struct cw1200_common *priv);
-
-#else /* CONFIG_CW1200_ITP */
-
-static inline int cw1200_itp_init(struct cw1200_common *priv)
-{
-	return 0;
-}
-
-static inline void cw1200_itp_release(struct cw1200_common *priv)
-{
-}
-
-static inline bool cw1200_is_itp(struct cw1200_common *priv)
-{
-	return false;
-}
-
-static inline bool cw1200_itp_rxed(struct cw1200_common *priv,
-				   struct sk_buff *skb)
-{
-	return false;
-}
-
-
-static inline void cw1200_itp_consume_txed(struct cw1200_common *priv)
-{
-}
-
-static inline void cw1200_itp_wake_up_tx(struct cw1200_common *priv)
-{
-}
-
-static inline int cw1200_itp_get_tx(struct cw1200_common *priv, u8 **data,
-				    size_t *tx_len, int *burst)
-{
-	return 0;
-}
-
-static inline bool cw1200_itp_tx_running(struct cw1200_common *priv)
-{
-	return false;
-}
-
-#endif /* CONFIG_CW1200_ITP */
-
-#endif /* CW1200_ITP_H_INCLUDED */
diff --git a/drivers/net/wireless/cw1200/txrx.c b/drivers/net/wireless/cw1200/txrx.c
index a254747..451d746 100644
--- a/drivers/net/wireless/cw1200/txrx.c
+++ b/drivers/net/wireless/cw1200/txrx.c
@@ -861,9 +861,6 @@ void cw1200_tx_confirm_cb(struct cw1200_common *priv,
 	pr_debug("[TX] TX confirm: %d, %d.\n",
 		 arg->status, arg->ack_failures);
 
-	if (cw1200_itp_tx_running(priv))
-		return;
-
 	if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
 		/* STA is stopped. */
 		return;
@@ -1001,8 +998,7 @@ void cw1200_skb_dtor(struct cw1200_common *priv,
 					  txpriv->raw_link_id, txpriv->tid);
 		tx_policy_put(priv, txpriv->rate_id);
 	}
-	if (!cw1200_is_itp(priv))
-		ieee80211_tx_status(priv->hw, skb);
+	ieee80211_tx_status(priv->hw, skb);
 }
 
 void cw1200_rx_cb(struct cw1200_common *priv,
@@ -1205,9 +1201,7 @@ void cw1200_rx_cb(struct cw1200_common *priv,
 		grace_period = 1 * HZ;
 	cw1200_pm_stay_awake(&priv->pm_state, grace_period);
 
-	if (cw1200_itp_rxed(priv, skb)) {
-		consume_skb(skb);
-	} else if (early_data) {
+	if (early_data) {
 		spin_lock_bh(&priv->ps_state_lock);
 		/* Double-check status with lock held */
 		if (entry->status == CW1200_LINK_SOFT)
diff --git a/drivers/net/wireless/cw1200/wsm.c b/drivers/net/wireless/cw1200/wsm.c
index 3ab25f6..e99f34e 100644
--- a/drivers/net/wireless/cw1200/wsm.c
+++ b/drivers/net/wireless/cw1200/wsm.c
@@ -21,7 +21,6 @@
 #include "bh.h"
 #include "sta.h"
 #include "debug.h"
-#include "itp.h"
 
 #define WSM_CMD_TIMEOUT		(2 * HZ) /* With respect to interrupt loss */
 #define WSM_CMD_START_TIMEOUT	(7 * HZ)
@@ -1733,12 +1732,6 @@ int wsm_get_tx(struct cw1200_common *priv, u8 **data,
 	/* More is used only for broadcasts. */
 	bool more = false;
 
-#ifdef CONFIG_CW1200_ITP
-	count = cw1200_itp_get_tx(priv, data, tx_len, burst);
-	if (count)
-		return count;
-#endif
-
 	if (priv->wsm_cmd.ptr) { /* CMD request */
 		++count;
 		spin_lock(&priv->wsm_cmd.lock);
-- 
1.8.2.1


^ permalink raw reply related

* Re: rtl8192cu: slow path warning and connection problem v3.10-rc5
From: Richard Genoud @ 2013-06-11 13:42 UTC (permalink / raw)
  To: Larry Finger; +Cc: Chaoming Li, John W. Linville, linux-wireless, linux-kernel
In-Reply-To: <20130611123814.GA9854@lnx-rg>

2013/6/11 Richard GENOUD <richard.genoud@gmail.com>:
> Hi,
>
> I've got an usb wireless adapter TP-Link TL-WN725N
> http://www.tp-link.com/ca/products/details/?categoryid=241&model=TL-WN725N
> It is based on the rtl8192cu chip.
> I'm running a recent kernel (3.10-rc5) on a arm-based board (at91sam9g35-ek).
> and last linux-firmwares (2892af0)
> # iw wlan0 connect test
> # [   70.718750] wlan0: authenticate with 00:1c:10:69:90:fe
> [   70.718750] wlan0: Allocated STA 00:1c:10:69:90:fe
> [   70.742187] wlan0: Inserted STA 00:1c:10:69:90:fe
> [   70.742187] wlan0: send auth to 00:1c:10:69:90:fe (try 1/3)
> [   70.757812] wlan0: authenticated
> [   70.757812] wlan0: moving STA 00:1c:10:69:90:fe to state 2
> [   70.765625] rtl8192cu 1-2.3:1.0 wlan0: disabling HT as WMM/QoS is not supported by the AP
> [   70.773437] rtl8192cu 1-2.3:1.0 wlan0: disabling VHT as WMM/QoS is not supported by the AP
> [   70.789062] wlan0: associate with 00:1c:10:69:90:fe (try 1/3)
> [   70.804687] wlan0: RX AssocResp from 00:1c:10:69:90:fe (capab=0x401 status=0 aid=1)
> [   70.812500] wlan0: moving STA 00:1c:10:69:90:fe to state 3
> [   70.820312] wlan0: moving STA 00:1c:10:69:90:fe to state 4
> [   70.828125] wlan0: associated
> [   71.187500] ------------[ cut here ]------------
> [   71.187500] WARNING: at kernel/workqueue.c:1365 __queue_work+0x180/0x1f8()
> [   71.187500] CPU: 0 PID: 593 Comm: kworker/0:2 Not tainted 3.10.0-rc5-00133-g691a986 #6
> [   71.187500] Workqueue: rtl92c_usb rtl_watchdog_wq_callback
> [   71.187500] [<c000d2a0>] (unwind_backtrace+0x0/0xf0) from [<c000ba34>] (show_stack+0x10/0x14)
> [   71.187500] [<c000ba34>] (show_stack+0x10/0x14) from [<c00150fc>] (warn_slowpath_common+0x48/0x64)
> [   71.187500] [<c00150fc>] (warn_slowpath_common+0x48/0x64) from [<c00151e0>] (warn_slowpath_null+0x1c/0x24)
> [   71.187500] [<c00151e0>] (warn_slowpath_null+0x1c/0x24) from [<c0029878>] (__queue_work+0x180/0x1f8)
> [   71.187500] [<c0029878>] (__queue_work+0x180/0x1f8) from [<c0029ee8>] (queue_work_on+0x44/0x50)
> [   71.187500] [<c0029ee8>] (queue_work_on+0x44/0x50) from [<c01fd850>] (rtl_watchdog_wq_callback+0x290/0x4e0)
> [   71.187500] [<c01fd850>] (rtl_watchdog_wq_callback+0x290/0x4e0) from [<c002a138>] (process_one_work+0x110/0x358)
> [   71.187500] [<c002a138>] (process_one_work+0x110/0x358) from [<c002a728>] (worker_thread+0xf4/0x308)
> [   71.187500] [<c002a728>] (worker_thread+0xf4/0x308) from [<c002f8b4>] (kthread+0xa4/0xb0)
> [   71.187500] [<c002f8b4>] (kthread+0xa4/0xb0) from [<c00091b0>] (ret_from_fork+0x14/0x24)
> [   71.187500] ---[ end trace 5f274d456b3a4c7f ]---

I've should have check this before, but the connection problem is
corrected with the patch "rtlwifi: rtl8192cu: Fix problem in
connecting to WEP or WPA(1) networks"
Sorry for that...

Anyway, running 3.10-rc5 with the for-davem wireless branch, I still
have the slow path warning


# iw wlan0 connect test
# [   42.226562] wlan0: authenticate with 00:1c:10:69:90:fe
[   42.226562] wlan0: Allocated STA 00:1c:10:69:90:fe
[   42.250000] wlan0: Inserted STA 00:1c:10:69:90:fe
[   42.250000] wlan0: send auth to 00:1c:10:69:90:fe (try 1/3)
[   42.281250] wlan0: authenticated
[   42.289062] wlan0: moving STA 00:1c:10:69:90:fe to state 2
[   42.296875] rtl8192cu 1-2.3:1.0 wlan0: disabling HT as WMM/QoS is
not supported by the AP
[   42.304687] rtl8192cu 1-2.3:1.0 wlan0: disabling VHT as WMM/QoS is
not supported by the AP
[   42.312500] wlan0: associate with 00:1c:10:69:90:fe (try 1/3)
[   42.335937] wlan0: RX AssocResp from 00:1c:10:69:90:fe (capab=0x401
status=0 aid=1)
[   42.343750] wlan0: moving STA 00:1c:10:69:90:fe to state 3
[   42.343750] wlan0: moving STA 00:1c:10:69:90:fe to state 4
[   42.351562] wlan0: associated

[   44.179687] ------------[ cut here ]------------
[   44.179687] WARNING: at kernel/workqueue.c:1365 __queue_work+0x180/0x1f8()
[   44.179687] CPU: 0 PID: 580 Comm: kworker/0:2 Not tainted
3.10.0-rc5-00150-g4b16b55 #10
[   44.179687] Workqueue: rtl92c_usb rtl_watchdog_wq_callback
[   44.179687] [<c000d2a0>] (unwind_backtrace+0x0/0xf0) from
[<c000ba34>] (show_stack+0x10/0x14)
[   44.179687] [<c000ba34>] (show_stack+0x10/0x14) from [<c00150fc>]
(warn_slowpath_common+0x48/0x64)
[   44.179687] [<c00150fc>] (warn_slowpath_common+0x48/0x64) from
[<c00151e0>] (warn_slowpath_null+0x1c/0x24)
[   44.179687] [<c00151e0>] (warn_slowpath_null+0x1c/0x24) from
[<c0029878>] (__queue_work+0x180/0x1f8)
[   44.179687] [<c0029878>] (__queue_work+0x180/0x1f8) from
[<c0029ee8>] (queue_work_on+0x44/0x50)
[   44.179687] [<c0029ee8>] (queue_work_on+0x44/0x50) from
[<c01fd850>] (rtl_watchdog_wq_callback+0x290/0x4e0)
[   44.179687] [<c01fd850>] (rtl_watchdog_wq_callback+0x290/0x4e0)
from [<c002a138>] (process_one_work+0x110/0x358)
[   44.179687] [<c002a138>] (process_one_work+0x110/0x358) from
[<c002a728>] (worker_thread+0xf4/0x308)
[   44.179687] [<c002a728>] (worker_thread+0xf4/0x308) from
[<c002f8b4>] (kthread+0xa4/0xb0)
[   44.179687] [<c002f8b4>] (kthread+0xa4/0xb0) from [<c00091b0>]
(ret_from_fork+0x14/0x24)
[   44.179687] ---[ end trace d23aec3c204a06ee ]---

regards,
Richard.

^ permalink raw reply

* Re: [PATCHv5 1/4] mac80211: make mgmt_tx accept a NULL channel
From: Antonio Quartulli @ 2013-06-11 13:35 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Antonio Quartulli
In-Reply-To: <1370955736.8356.47.camel@jlt4.sipsolutions.net>

[-- Attachment #1: Type: text/plain, Size: 230 bytes --]

On Tue, Jun 11, 2013 at 03:02:16PM +0200, Johannes Berg wrote:
> Applied all, but I fixed your locking.

Thank you Johannes.

Cheers,

-- 
Antonio Quartulli

..each of us alone is worth nothing..
Ernesto "Che" Guevara

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply

* [PATCH v4] ath5k: make use of the new rate control API
From: Thomas Huehn @ 2013-06-11 13:10 UTC (permalink / raw)
  To: linville
  Cc: linux-wireless, nbd, johannes, mickflemm, mcgrof, rmanohar,
	adrian, ath5k-devel, bvahl

This patch enabels ath5k to use the new rate table to lookup each
mrr rate and retry information per packet.

Signed-off-by: Benjamin Vahl <bvahl@net.t-labs.tu-berlin.de>
Signed-off-by: Thomas Huehn <thomas@net.t-labs.tu-berlin.de>
---
check for size mismatch between info->status.rates & bf-rates. thx to Felix Fietkau
---
 drivers/net/wireless/ath/ath5k/base.c         |   79 ++++++++++++++++++++-----
 drivers/net/wireless/ath/ath5k/base.h         |   14 +++--
 drivers/net/wireless/ath/ath5k/mac80211-ops.c |    2 +-
 3 files changed, 74 insertions(+), 21 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 7f702fe..ce67ab7 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -60,6 +60,7 @@
 
 #include <asm/unaligned.h>
 
+#include <net/mac80211.h>
 #include "base.h"
 #include "reg.h"
 #include "debug.h"
@@ -666,9 +667,46 @@ static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb)
 	return htype;
 }
 
+static struct ieee80211_rate *
+ath5k_get_rate(const struct ieee80211_hw *hw,
+	       const struct ieee80211_tx_info *info,
+	       struct ath5k_buf *bf, int idx)
+{
+	/*
+	* convert a ieee80211_tx_rate RC-table entry to
+	* the respective ieee80211_rate struct
+	*/
+	if (bf->rates[idx].idx < 0) {
+		return NULL;
+	}
+
+	return &hw->wiphy->bands[info->band]->bitrates[ bf->rates[idx].idx ];
+}
+
+static u16
+ath5k_get_rate_hw_value(const struct ieee80211_hw *hw,
+			const struct ieee80211_tx_info *info,
+			struct ath5k_buf *bf, int idx)
+{
+	struct ieee80211_rate *rate;
+	u16 hw_rate;
+	u8 rc_flags;
+
+	rate = ath5k_get_rate(hw, info, bf, idx);
+	if (!rate)
+		return 0;
+
+	rc_flags = bf->rates[idx].flags;
+	hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
+		   rate->hw_value_short : rate->hw_value;
+
+	return hw_rate;
+}
+
 static int
 ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
-		  struct ath5k_txq *txq, int padsize)
+		  struct ath5k_txq *txq, int padsize,
+		  struct ieee80211_tx_control *control)
 {
 	struct ath5k_desc *ds = bf->desc;
 	struct sk_buff *skb = bf->skb;
@@ -688,7 +726,11 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
 	bf->skbaddr = dma_map_single(ah->dev, skb->data, skb->len,
 			DMA_TO_DEVICE);
 
-	rate = ieee80211_get_tx_rate(ah->hw, info);
+	ieee80211_get_tx_rates(info->control.vif, (control) ? control->sta : NULL, skb, bf->rates,
+			       ARRAY_SIZE(bf->rates));
+
+	rate = ath5k_get_rate(ah->hw, info, bf, 0);
+
 	if (!rate) {
 		ret = -EINVAL;
 		goto err_unmap;
@@ -698,8 +740,8 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
 		flags |= AR5K_TXDESC_NOACK;
 
 	rc_flags = info->control.rates[0].flags;
-	hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
-		rate->hw_value_short : rate->hw_value;
+
+	hw_rate = ath5k_get_rate_hw_value(ah->hw, info, bf, 0);
 
 	pktlen = skb->len;
 
@@ -722,12 +764,13 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
 		duration = le16_to_cpu(ieee80211_ctstoself_duration(ah->hw,
 			info->control.vif, pktlen, info));
 	}
+
 	ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
 		ieee80211_get_hdrlen_from_skb(skb), padsize,
 		get_hw_packet_type(skb),
 		(ah->ah_txpower.txp_requested * 2),
 		hw_rate,
-		info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
+		bf->rates[0].count, keyidx, ah->ah_tx_ant, flags,
 		cts_rate, duration);
 	if (ret)
 		goto err_unmap;
@@ -736,13 +779,15 @@ ath5k_txbuf_setup(struct ath5k_hw *ah, struct ath5k_buf *bf,
 	if (ah->ah_capabilities.cap_has_mrr_support) {
 		memset(mrr_rate, 0, sizeof(mrr_rate));
 		memset(mrr_tries, 0, sizeof(mrr_tries));
+
 		for (i = 0; i < 3; i++) {
-			rate = ieee80211_get_alt_retry_rate(ah->hw, info, i);
+
+			rate = ath5k_get_rate(ah->hw, info, bf, i);
 			if (!rate)
 				break;
 
-			mrr_rate[i] = rate->hw_value;
-			mrr_tries[i] = info->control.rates[i + 1].count;
+			mrr_rate[i] = ath5k_get_rate_hw_value(ah->hw, info, bf, i);
+			mrr_tries[i] = bf->rates[i].count;
 		}
 
 		ath5k_hw_setup_mrr_tx_desc(ah, ds,
@@ -1515,7 +1560,7 @@ unlock:
 
 void
 ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
-	       struct ath5k_txq *txq)
+	       struct ath5k_txq *txq, struct ieee80211_tx_control *control)
 {
 	struct ath5k_hw *ah = hw->priv;
 	struct ath5k_buf *bf;
@@ -1555,7 +1600,7 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
 
 	bf->skb = skb;
 
-	if (ath5k_txbuf_setup(ah, bf, txq, padsize)) {
+	if (ath5k_txbuf_setup(ah, bf, txq, padsize, control)) {
 		bf->skb = NULL;
 		spin_lock_irqsave(&ah->txbuflock, flags);
 		list_add_tail(&bf->list, &ah->txbuf);
@@ -1571,11 +1616,13 @@ drop_packet:
 
 static void
 ath5k_tx_frame_completed(struct ath5k_hw *ah, struct sk_buff *skb,
-			 struct ath5k_txq *txq, struct ath5k_tx_status *ts)
+			 struct ath5k_txq *txq, struct ath5k_tx_status *ts,
+			 struct ath5k_buf *bf)
 {
 	struct ieee80211_tx_info *info;
 	u8 tries[3];
 	int i;
+	int size = 0;
 
 	ah->stats.tx_all_count++;
 	ah->stats.tx_bytes_count += skb->len;
@@ -1587,6 +1634,9 @@ ath5k_tx_frame_completed(struct ath5k_hw *ah, struct sk_buff *skb,
 
 	ieee80211_tx_info_clear_status(info);
 
+	size = min_t(int, sizeof(info->status.rates), sizeof(bf->rates));
+	memcpy(info->status.rates, bf->rates, size);
+
 	for (i = 0; i < ts->ts_final_idx; i++) {
 		struct ieee80211_tx_rate *r =
 			&info->status.rates[i];
@@ -1663,7 +1713,7 @@ ath5k_tx_processq(struct ath5k_hw *ah, struct ath5k_txq *txq)
 
 			dma_unmap_single(ah->dev, bf->skbaddr, skb->len,
 					DMA_TO_DEVICE);
-			ath5k_tx_frame_completed(ah, skb, txq, &ts);
+			ath5k_tx_frame_completed(ah, skb, txq, &ts, bf);
 		}
 
 		/*
@@ -1917,7 +1967,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
 
 	skb = ieee80211_get_buffered_bc(ah->hw, vif);
 	while (skb) {
-		ath5k_tx_queue(ah->hw, skb, ah->cabq);
+		ath5k_tx_queue(ah->hw, skb, ah->cabq, NULL);
 
 		if (ah->cabq->txq_len >= ah->cabq->txq_max)
 			break;
@@ -2442,7 +2492,8 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
 			IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
 			IEEE80211_HW_SIGNAL_DBM |
 			IEEE80211_HW_MFP_CAPABLE |
-			IEEE80211_HW_REPORTS_TX_ACK_STATUS;
+			IEEE80211_HW_REPORTS_TX_ACK_STATUS |
+			IEEE80211_HW_SUPPORTS_RC_TABLE;
 
 	hw->wiphy->interface_modes =
 		BIT(NL80211_IFTYPE_AP) |
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 6c94c7f..ca9a83c 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -47,6 +47,7 @@ struct ath5k_hw;
 struct ath5k_txq;
 struct ieee80211_channel;
 struct ath_bus_ops;
+struct ieee80211_tx_control;
 enum nl80211_iftype;
 
 enum ath5k_srev_type {
@@ -61,11 +62,12 @@ struct ath5k_srev_name {
 };
 
 struct ath5k_buf {
-	struct list_head	list;
-	struct ath5k_desc	*desc;	/* virtual addr of desc */
-	dma_addr_t		daddr;	/* physical addr of desc */
-	struct sk_buff		*skb;	/* skbuff for buf */
-	dma_addr_t		skbaddr;/* physical addr of skb data */
+	struct list_head		list;
+	struct ath5k_desc		*desc;		/* virtual addr of desc */
+	dma_addr_t			daddr;		/* physical addr of desc */
+	struct sk_buff			*skb;		/* skbuff for buf */
+	dma_addr_t			skbaddr;	/* physical addr of skb data */
+	struct ieee80211_tx_rate	rates[4];	/* number of multi-rate stages */
 };
 
 struct ath5k_vif {
@@ -103,7 +105,7 @@ int ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan);
 void ath5k_txbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
 void ath5k_rxbuf_free_skb(struct ath5k_hw *ah, struct ath5k_buf *bf);
 void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
-		    struct ath5k_txq *txq);
+		    struct ath5k_txq *txq, struct ieee80211_tx_control *control);
 
 const char *ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val);
 
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index 06f86f4..81b686c 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -66,7 +66,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
 		return;
 	}
 
-	ath5k_tx_queue(hw, skb, &ah->txqs[qnum]);
+	ath5k_tx_queue(hw, skb, &ah->txqs[qnum], control);
 }
 
 
-- 
1.7.9.5


^ permalink raw reply related

* Re: [PATCHv5 1/4] mac80211: make mgmt_tx accept a NULL channel
From: Johannes Berg @ 2013-06-11 13:02 UTC (permalink / raw)
  To: Antonio Quartulli; +Cc: linux-wireless, Antonio Quartulli
In-Reply-To: <1370953203-4086-1-git-send-email-ordex@autistici.org>

Applied all, but I fixed your locking.

johannes


^ permalink raw reply

* Re: [RFC 4/5] mac80211: enforce address verification on monitors
From: Jakub Kiciński @ 2013-06-11 13:01 UTC (permalink / raw)
  To: Johannes Berg
  Cc: Felix Fietkau, linux-wireless, Helmut Schaa,
	nietrywialneprzejscie
In-Reply-To: <1370951175.8356.17.camel@jlt4.sipsolutions.net>

On Tue, 11 Jun 2013 13:46:15 +0200, Johannes Berg wrote:
>On Fri, 2013-06-07 at 18:42 +0200, Jakub Kiciński wrote:
>
>> Now I can start two hostapd on those interfaces and
>> everything works just fine. 
>> 
>> # iw dev wlan0-1 set type monitor
>> # ip link set dev wlan0-1 address 00:00:fa:22:7c:00
>> # iw dev wlan0-1 set type managed
>> # ip link
>> 75: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
>>     link/ether 00:4f:6a:06:57:90 brd ff:ff:ff:ff:ff:ff
>> 76: wlan0-1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
>>     link/ether 00:00:fa:22:7c:00 brd ff:ff:ff:ff:ff:ff
>> 
>> If I start hostapd on both interfaces now the one on wlan0-1
>> will not work correctly (hw won't ack frames).
>> 
>> Also I think it's possible to change active flag on a monitor
>> while it's down (check in net/mac80211/cfg.c:75 only applies
>> to interfaces that are up):
>
> I think we should "just" move ieee80211_verify_mac() into do_open().
> Semantically anyway, I'm clearly handwaving a bit. But I would argue
> that you can set any MAC address that you like, as long as you don't
> bring the interface up, hence the verification really shouldn't be done
> when you assign the address but when you bring it up.

I've considered this initially. Two reasons that made me
think the current approach is cleaner are:
 - it's nice when user gets the error during the action that
   puts system in inconsistent state not some time later. I
   personally hate to get vague EBUSY and have to figure out
   what's wrong.
 - suppose there are two interfaces, both down with
   incompatible addresses. User adds third ifc, what address
   should we assign to it?

Besides who would care what address does passive monitor
have? ;)

> Consider also this. Say you have this scenario:
>
> address mask: 00:00:00:00:00:03
> wlan0: 02:00:00:00:00:00
> wlan1: 02:00:00:00:00:01
>
> Now you want to change to
> wlan0: 03:00:00:00:00:00
> wlan1: 03:00:00:00:00:01
>
> It seems that right now you can't do this at all, which also seems
> wrong.

Right but I believe user would understand what is the problem
here and just remove and recreate one of the interfaces. They
have to be down to change MAC addr anyway.

Obviously this change is no matter for a big discussion. I
already feel like stealing your time a bit, because only
rt2x00 cares about this stuff anyway (I think). So please
let me know if my reasoning convinces you and if not I will
be happy to rewrite this the way you suggest.

  -- kuba

^ permalink raw reply

* rtl8192cu: slow path warning and connection problem v3.10-rc5
From: Richard GENOUD @ 2013-06-11 12:38 UTC (permalink / raw)
  To: Larry Finger; +Cc: Chaoming Li, John W. Linville, linux-wireless, linux-kernel

Hi,

I've got an usb wireless adapter TP-Link TL-WN725N
http://www.tp-link.com/ca/products/details/?categoryid=241&model=TL-WN725N
It is based on the rtl8192cu chip.
I'm running a recent kernel (3.10-rc5) on a arm-based board (at91sam9g35-ek).
and last linux-firmwares (2892af0)

The problem I've got it that the device authenticates to the AP
(with a slow path warning), but there's no traffic (I can't get an IP
address from DHCP for example).

Here is the log:
***Insert the TP-Link key
[   22.710937] usb 1-2.3: new high-speed USB device number 3 using atmel-ehci
[   22.828125] rtl8192cu: Chip version 0x10
[   22.921875] rtl8192cu: MAC address: a0:f3:c1:1a:28:5f
[   22.929687] rtl8192cu: Board Type 0
[   22.929687] rtlwifi: rx_max_size 15360, rx_urb_num 8, in_ep 1
[   22.937500] rtl8192cu: Loading firmware rtlwifi/rtl8192cufw.bin
[   22.953125] ieee80211 phy0: Selected rate control algorithm 'rtl_rc'
[   22.968750] rtlwifi: wireless switch is on

# ip link set wlan0 up
[   34.656250] rtl8192cu: MAC auto ON okay!
[   34.695312] rtl8192cu: Tx queue select: 0x05
# iw dev wlan0 scan
BSS 00:1c:10:69:90:fe (on wlan0)
	TSF: 1046528539 usec (0d, 00:17:26)
	freq: 2412
	beacon interval: 100
	capability: ESS ShortSlotTime (0x0401)
	signal: -58.00 dBm
	last seen: 500 ms ago
	Information elements from Probe Response frame:
	SSID: test
	Supported rates: 1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 
	DS Parameter set: channel 1
	TIM: DTIM Count 1 DTIM Period 2 Bitmap Control 0x0 Bitmap[0] 0x0
	ERP: Barker_Preamble_Mode
	Extended supported rates: 24.0 36.0 48.0 54.0 
# iw wlan0 connect test
[   51.851562] wlan0: authenticate with 00:1c:10:69:90:fe
[   51.859375] wlan0: Allocated STA 00:1c:10:69:90:fe
[   51.867187] wlan0: Inserted STA 00:1c:10:69:90:fe
[   51.875000] wlan0: direct probe to 00:1c:10:69:90:fe (try 1/3)
# [   52.078125] wlan0: direct probe to 00:1c:10:69:90:fe (try 2/3)
[   52.281250] wlan0: direct probe to 00:1c:10:69:90:fe (try 3/3)
[   52.484375] wlan0: authentication with 00:1c:10:69:90:fe timed out
[   52.484375] wlan0: Removed STA 00:1c:10:69:90:fe
[   52.492187] wlan0: Destroyed STA 00:1c:10:69:90:fe

# iw wlan0 connect test
# [   70.718750] wlan0: authenticate with 00:1c:10:69:90:fe
[   70.718750] wlan0: Allocated STA 00:1c:10:69:90:fe
[   70.742187] wlan0: Inserted STA 00:1c:10:69:90:fe
[   70.742187] wlan0: send auth to 00:1c:10:69:90:fe (try 1/3)
[   70.757812] wlan0: authenticated
[   70.757812] wlan0: moving STA 00:1c:10:69:90:fe to state 2
[   70.765625] rtl8192cu 1-2.3:1.0 wlan0: disabling HT as WMM/QoS is not supported by the AP
[   70.773437] rtl8192cu 1-2.3:1.0 wlan0: disabling VHT as WMM/QoS is not supported by the AP
[   70.789062] wlan0: associate with 00:1c:10:69:90:fe (try 1/3)
[   70.804687] wlan0: RX AssocResp from 00:1c:10:69:90:fe (capab=0x401 status=0 aid=1)
[   70.812500] wlan0: moving STA 00:1c:10:69:90:fe to state 3
[   70.820312] wlan0: moving STA 00:1c:10:69:90:fe to state 4
[   70.828125] wlan0: associated
[   71.187500] ------------[ cut here ]------------
[   71.187500] WARNING: at kernel/workqueue.c:1365 __queue_work+0x180/0x1f8()
[   71.187500] CPU: 0 PID: 593 Comm: kworker/0:2 Not tainted 3.10.0-rc5-00133-g691a986 #6
[   71.187500] Workqueue: rtl92c_usb rtl_watchdog_wq_callback
[   71.187500] [<c000d2a0>] (unwind_backtrace+0x0/0xf0) from [<c000ba34>] (show_stack+0x10/0x14)
[   71.187500] [<c000ba34>] (show_stack+0x10/0x14) from [<c00150fc>] (warn_slowpath_common+0x48/0x64)
[   71.187500] [<c00150fc>] (warn_slowpath_common+0x48/0x64) from [<c00151e0>] (warn_slowpath_null+0x1c/0x24)
[   71.187500] [<c00151e0>] (warn_slowpath_null+0x1c/0x24) from [<c0029878>] (__queue_work+0x180/0x1f8)
[   71.187500] [<c0029878>] (__queue_work+0x180/0x1f8) from [<c0029ee8>] (queue_work_on+0x44/0x50)
[   71.187500] [<c0029ee8>] (queue_work_on+0x44/0x50) from [<c01fd850>] (rtl_watchdog_wq_callback+0x290/0x4e0)
[   71.187500] [<c01fd850>] (rtl_watchdog_wq_callback+0x290/0x4e0) from [<c002a138>] (process_one_work+0x110/0x358)
[   71.187500] [<c002a138>] (process_one_work+0x110/0x358) from [<c002a728>] (worker_thread+0xf4/0x308)
[   71.187500] [<c002a728>] (worker_thread+0xf4/0x308) from [<c002f8b4>] (kthread+0xa4/0xb0)
[   71.187500] [<c002f8b4>] (kthread+0xa4/0xb0) from [<c00091b0>] (ret_from_fork+0x14/0x24)
[   71.187500] ---[ end trace 5f274d456b3a4c7f ]---
iw dev wlan0 link
Connected to 00:1c:10:69:90:fe (on wlan0)
	SSID: test
	freq: 2412
	RX: 8896 bytes (256 packets)
	TX: 80 bytes (2 packets)
	signal: -48 dBm
	tx bitrate: 1.0 MBit/s

	bss flags:	short-slot-time
	dtim period:	0
	beacon int:	100
# udhcpc -i wlan0 -f -n -q
udhcpc (v1.21.0) started
Sending discover...
Sending discover...
Sending discover...
No lease, failing
**** inserting another key (an older cisco/linksys WUSG54GC)
# [  108.875000] usb 1-2.2: new high-speed USB device number 4 using atmel-ehci
[  109.109375] usb 1-2.2: reset high-speed USB device number 4 using atmel-ehci
[  109.242187] ieee80211 phy1: rt2x00_set_rt: Info - RT chipset 3070, rev 0201 detected
[  109.265625] ieee80211 phy1: rt2x00_set_rf: Info - RF chipset 0006 detected
[  109.273437] ieee80211 phy1: Selected rate control algorithm 'minstrel_ht'

# ip link set wlan1 up
[  116.234375] ieee80211 phy1: rt2x00lib_request_firmware: Info - Loading firmware file 'rt2870.bin'
[  116.250000] ieee80211 phy1: rt2x00lib_request_firmware: Info - Firmware detected - version: 0.29
# iw dev wlan1 scan
BSS 00:1c:10:69:90:fe (on wlan1)
	TSF: 1144496990 usec (0d, 00:19:04)
	freq: 2412
	beacon interval: 100
	capability: ESS ShortSlotTime (0x0401)
	signal: -27.00 dBm
	last seen: 1429 ms ago
	SSID: test
	Supported rates: 1.0* 2.0* 5.5* 11.0* 6.0 9.0 12.0 18.0 
	DS Parameter set: channel 1
	ERP: Barker_Preamble_Mode
	Extended supported rates: 24.0 36.0 48.0 54.0 
BSS 00:17:9a:84:fb:94 (on wlan1)
	TSF: 5965523554325 usec (69d, 01:05:23)
	freq: 2437
	beacon interval: 100
	capability: ESS Privacy ShortPreamble ShortSlotTime (0x0431)
	signal: -55.00 dBm
	last seen: 960 ms ago
	Information elements from Probe Response frame:
	SSID: paratronic
	Supported rates: 1.0* 2.0* 5.5* 11.0* 6.0 12.0 24.0 36.0 
	DS Parameter set: channel 6
	Country: GB	Environment: Indoor/Outdoor
		Channels [1 - 13] @ 14 dBm
	ERP: <no flags>
	Extended supported rates: 9.0 18.0 48.0 54.0 
	WMM:	 * Parameter version 1
		 * BE: CW 15-1023, AIFSN 3
		 * BK: CW 15-1023, AIFSN 7
		 * VI: CW 7-15, AIFSN 2, TXOP 3008 usec
		 * VO: CW 3-7, AIFSN 2, TXOP 1504 usec
# iw wlan1 connect test
[  135.710937] wlan1: authenticate with 00:1c:10:69:90:fe
[  135.718750] wlan1: Allocated STA 00:1c:10:69:90:fe
[  135.726562] wlan1: Inserted STA 00:1c:10:69:90:fe
[  135.734375] wlan1: send auth to 00:1c:10:69:90:fe (try 1/3)
[  135.742187] wlan1: authenticated
[  135.742187] wlan1: moving STA 00:1c:10:69:90:fe to state 2
# [  135.750000] rt2800usb 1-2.2:1.0 wlan1: disabling HT as WMM/QoS is not supported by the AP
[  135.757812] rt2800usb 1-2.2:1.0 wlan1: disabling VHT as WMM/QoS is not supported by the AP
[  135.773437] wlan1: associate with 00:1c:10:69:90:fe (try 1/3)
[  135.773437] wlan1: RX AssocResp from 00:1c:10:69:90:fe (capab=0x401 status=0 aid=2)
[  135.789062] wlan1: moving STA 00:1c:10:69:90:fe to state 3
[  135.796875] wlan1: moving STA 00:1c:10:69:90:fe to state 4
[  135.812500] wlan1: associated

# udhcpc -i wlan1 -f -n -q
udhcpc (v1.21.0) started
Sending discover...
Sending select for 10.125.0.205...
Lease of 10.125.0.205 obtained, lease time 60
deleting routers
route: SIOCDELRT: No such process
# ping 10.125.0.201
PING 10.125.0.201 (10.125.0.201): 56 data bytes
\x03
--- 10.125.0.201 ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss
# ping 10.125.0.1
PING 10.125.0.1 (10.125.0.1): 56 data bytes
64 bytes from 10.125.0.1: seq=0 ttl=64 time=6.966 ms
64 bytes from 10.125.0.1: seq=1 ttl=64 time=2.677 ms
64 bytes from 10.125.0.1: seq=2 ttl=64 time=2.895 ms
\x03
--- 10.125.0.1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 2.677/4.179/6.966 ms
# 

So it works allright with the other key, but not with the tp-link one.

Did I do something wrong ?

Regards,
Richard.

^ permalink raw reply

* Re: [PATCH v2] cfg80211: Allow TDLS peer AID to be configured for VHT
From: Johannes Berg @ 2013-06-11 12:37 UTC (permalink / raw)
  To: Jouni Malinen; +Cc: linux-wireless
In-Reply-To: <20130527152402.GC12369@jouni.qca.qualcomm.com>

On Mon, 2013-05-27 at 18:24 +0300, Jouni Malinen wrote:
> VHT uses peer AID in the PARTIAL_AID field in TDLS frames. The current
> design for TDLS is to first add a dummy STA entry before completing TDLS
> Setup and then update information on this STA entry based on what was
> received from the peer during the setup exchange.
> 
> In theory, this could use NL80211_ATTR_STA_AID to set the peer AID just
> like this is used in AP mode to set the AID of an association station.
> However, existing cfg80211 validation rules prevent this attribute from
> being used with set_station operation. To avoid interoperability issues
> between different kernel and user space version combinations, introduce
> a new nl80211 attribute for the purpose of setting TDLS peer AID. This
> attribute can be used in both the new_station and set_station
> operations. It is not supposed to be allowed to change the AID value
> during the lifetime of the STA entry, but that validation is left for
> drivers to do in the change_station callback.

Hmm. I guess I accidentally applied the first version, I've now applied
the differences.

johannes


^ permalink raw reply

* Re: [RFC 0/4] add master channel switch announcement support
From: Johannes Berg @ 2013-06-11 12:31 UTC (permalink / raw)
  To: Simon Wunderlich; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <20130514092734.GA16426@pandem0nium>


> > >  * channels are announced by adding IEs (CSA and Extended CSA) in beacons
> > >  * after some (configurable) time, the channel is switched
> > >  * with the channel switch, CSA/ECSA IEs are removed and channel information
> > >    is updated.
> > >  * Userspace calls a new command NL80211_CMD_CHANNEL_SWITCH along with channel info
> > >    (freq + width), whether traffic should be blocked and timing information
> > >  * it currently works for me [TM] on my ath9k based machine
> > 
> > I don't really like your approach of building all the IEs in the kernel.
> > There are some things, like the country-after-switch in the CSA wrapper
> > (introduced in 11ac), that would be really awkward this way.
> 
> Hmm ... OK. I have not checked 802.11ac yet (actually I don't have access to the
> drafts anyway). So what we have to expect is changing the country after the switch,
> or also other new things?

There are a few things in the channel switch wrapper: new country, wide
bandwidth channel switch, new VHT transmit power envelope. I guess the
intention is to allow for extensions in the future.

> > >  * could other drivers (next to ath9k) work with this API?
> > 
> > Probably not easily. Any TI folks reading this?
> 
> I was thinking about adding another callback function or option for that for drivers
> who do the channel switch internally. Then we would only need mac80211 to adapt.
> 
> Would that help, or what would be problematic?

I don't really know. If you look at what we do in managed mode now, some
drivers will do the switching and report back when done.

> Yeah, that would be an alternative. I've been inspired by IEEE 802.11-2012/6.3.17
> (MLME-CHANNELSWITCH) originally. :)
> I think your suggestion is good for AP where we control the beacon. For IBSS it
> would be a little different: when a channel switch is triggered, userspace does
> not know the beacon (and will not set it). Therefore, we could only accept the
> change IEs and skip the "after-switch-beacon" IEs (these would be re-generated
> internally) in IBSS mode. I guess it would be similar for mesh.

Yeah, agree, IBSS/mesh modes are somewhat different here, userspace
doesn't really know the channel is switching at all, does it?

johannes


^ permalink raw reply

* Re: [PATCH 1/2] iw: Allow user to provide freq during mesh join
From: Johannes Berg @ 2013-06-11 12:26 UTC (permalink / raw)
  To: Ashok Nagarajan; +Cc: linux-wireless, linville, devel, javier
In-Reply-To: <1370280859-9860-1-git-send-email-ashok@cozybit.com>

On Mon, 2013-06-03 at 10:34 -0700, Ashok Nagarajan wrote:
> Allow user to configure frequency and channel type during mesh join command.
> 
> Signed-off-by: Ashok Nagarajan <ashok@cozybit.com>
> ---
>  mesh.c |   49 ++++++++++++++++++++++++++++++++++++++++++++++---
>  1 files changed, 46 insertions(+), 3 deletions(-)
> 
> diff --git a/mesh.c b/mesh.c
> index 5a09b62..ec202c9 100644
> --- a/mesh.c
> +++ b/mesh.c
> @@ -431,8 +431,18 @@ static int join_mesh(struct nl80211_state *state, struct nl_cb *cb,
>  {
>  	struct nlattr *container;
>  	float rate;
> -	int bintval, dtim_period;
> +	int bintval, dtim_period, i;
>  	char *end;
> +	static const struct {
> +		const char *name;
> +		unsigned int val;
> +	} htmap[] = {
> +		{ .name = "HT20", .val = NL80211_CHAN_HT20, },
> +		{ .name = "HT40+", .val = NL80211_CHAN_HT40PLUS, },
> +		{ .name = "HT40-", .val = NL80211_CHAN_HT40MINUS, },
> +		{ .name = "NOHT", .val = NL80211_CHAN_NO_HT, },
> +	};

I think you should use chandefs already, to allow for VHT. Also, it'd be
good to refactor the channel parsing for this, monitor and IBSS (though
I wonder why I haven't done that already?)

johannes


^ permalink raw reply

* Re: [PATCH v2] {nl,mac,cfg}80211: Allow user to configure basic rates for mesh
From: Johannes Berg @ 2013-06-11 12:25 UTC (permalink / raw)
  To: Ashok Nagarajan; +Cc: linux-wireless, linville, devel, javier
In-Reply-To: <1370280816-9799-1-git-send-email-ashok@cozybit.com>

On Mon, 2013-06-03 at 10:33 -0700, Ashok Nagarajan wrote:
> Currently mesh uses mandatory rates as the default basic rates. Allow basic
> rates to be configured during mesh join. Basic rates are applied only if
> channel is also provided with mesh join command.

Applied, I fixed some whitespace and made it remove rates specification
w/o channel specification. Please check.

johannes


^ permalink raw reply

* [PATCHv5 4/4] nl80211: allow sending CMD_FRAME without specifying any frequency
From: Antonio Quartulli @ 2013-06-11 12:20 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Antonio Quartulli
In-Reply-To: <1370953203-4086-1-git-send-email-ordex@autistici.org>

From: Antonio Quartulli <antonio@open-mesh.com>

Users may want to send a frame on the current channel
without specifying it.

This is particularly useful for the correct implementation
of the IBSS/RSN support in wpa_supplicant which requires to
receive and send AUTH frames.

Make mgmt_tx pass a NULL channel to the driver if none has
been specified by the user.

Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---

v5:
- return -EINVAL if NL80211_ATTR_WIPHY_FREQ is set while
  NL80211_ATTR_OFFCHANNEL_TX_OK is not


 net/wireless/nl80211.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 88e820b..d8f43df 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -7139,6 +7139,9 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
 		return -EOPNOTSUPP;
 
 	switch (wdev->iftype) {
+	case NL80211_IFTYPE_P2P_DEVICE:
+		if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
+			return -EINVAL;
 	case NL80211_IFTYPE_STATION:
 	case NL80211_IFTYPE_ADHOC:
 	case NL80211_IFTYPE_P2P_CLIENT:
@@ -7146,7 +7149,6 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
 	case NL80211_IFTYPE_AP_VLAN:
 	case NL80211_IFTYPE_MESH_POINT:
 	case NL80211_IFTYPE_P2P_GO:
-	case NL80211_IFTYPE_P2P_DEVICE:
 		break;
 	default:
 		return -EOPNOTSUPP;
@@ -7174,9 +7176,18 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
 
 	no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
 
-	err = nl80211_parse_chandef(rdev, info, &chandef);
-	if (err)
-		return err;
+	/* get the channel if any has been specified, otherwise pass NULL to
+	 * the driver. The latter will use the current one
+	 */
+	chandef.chan = NULL;
+	if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
+		err = nl80211_parse_chandef(rdev, info, &chandef);
+		if (err)
+			return err;
+	}
+
+	if (!chandef.chan && offchan)
+		return -EINVAL;
 
 	if (!dont_wait_for_ack) {
 		msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
-- 
1.8.1.5


^ permalink raw reply related

* [PATCHv5 2/4] brcm80211: make mgmt_tx in brcmfmac accept a NULL channel
From: Antonio Quartulli @ 2013-06-11 12:20 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Antonio Quartulli, brcm80211-dev-list
In-Reply-To: <1370953203-4086-1-git-send-email-ordex@autistici.org>

From: Antonio Quartulli <antonio@open-mesh.com>

cfg80211 passes a NULL channel to mgmt_tx if the frame has
to be sent on the one currently in use by the device.
Make the implementation of mgmt_tx correctly handle this
case

Cc: brcm80211-dev-list@broadcom.com
Acked-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
 drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 15 ++++++++++++---
 1 file changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 6d758f2..8bd256b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -3917,6 +3917,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 	struct brcmf_fil_af_params_le *af_params;
 	bool ack;
 	s32 chan_nr;
+	u32 freq;
 
 	brcmf_dbg(TRACE, "Enter\n");
 
@@ -3929,6 +3930,8 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 		return -EPERM;
 	}
 
+	vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
+
 	if (ieee80211_is_probe_resp(mgmt->frame_control)) {
 		/* Right now the only reason to get a probe response */
 		/* is for p2p listen response or for p2p GO from     */
@@ -3944,7 +3947,6 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 		ie_offset =  DOT11_MGMT_HDR_LEN +
 			     DOT11_BCN_PRB_FIXED_LEN;
 		ie_len = len - ie_offset;
-		vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
 		if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
 			vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
 		err = brcmf_vif_set_mgmt_ie(vif,
@@ -3968,8 +3970,15 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 		memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
 		/* Add the length exepted for 802.11 header  */
 		action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
-		/* Add the channel */
-		chan_nr = ieee80211_frequency_to_channel(chan->center_freq);
+		/* Add the channel. Use the one specified as parameter if any or
+		 * the current one (got from the firmware) otherwise
+		 */
+		if (chan)
+			freq = chan->center_freq;
+		else
+			brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
+					      &freq);
+		chan_nr = ieee80211_frequency_to_channel(freq);
 		af_params->channel = cpu_to_le32(chan_nr);
 
 		memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
-- 
1.8.1.5


^ permalink raw reply related

* [PATCHv5 3/4] ath6kl: make mgmt_tx accept a NULL channel
From: Antonio Quartulli @ 2013-06-11 12:20 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Antonio Quartulli, Nicolas Cavallari
In-Reply-To: <1370953203-4086-1-git-send-email-ordex@autistici.org>

From: Antonio Quartulli <antonio@open-mesh.com>

cfg80211 passes a NULL channel to mgmt_tx if the frame has
to be sent on the one currently in use by the device.
Make the implementation of mgmt_tx correctly handle this
case

Cc: Nicolas Cavallari <Nicolas.Cavallari@lri.fr>
Acked-by: Kalle Valo <kvalo@qca.qualcomm.com>
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
 drivers/net/wireless/ath/ath6kl/cfg80211.c | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index f7995b2..2437ad2 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -3175,10 +3175,21 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 {
 	struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
 	struct ath6kl *ar = ath6kl_priv(vif->ndev);
-	u32 id;
+	u32 id, freq;
 	const struct ieee80211_mgmt *mgmt;
 	bool more_data, queued;
 
+	/* default to the current channel, but use the one specified as argument
+	 * if any
+	 */
+	freq = vif->ch_hint;
+	if (chan)
+		freq = chan->center_freq;
+
+	/* never send freq zero to the firmware */
+	if (WARN_ON(freq == 0))
+		return -EINVAL;
+
 	mgmt = (const struct ieee80211_mgmt *) buf;
 	if (vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
 	    ieee80211_is_probe_resp(mgmt->frame_control) &&
@@ -3188,8 +3199,7 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 		 * command to allow the target to fill in the generic IEs.
 		 */
 		*cookie = 0; /* TX status not supported */
-		return ath6kl_send_go_probe_resp(vif, buf, len,
-						 chan->center_freq);
+		return ath6kl_send_go_probe_resp(vif, buf, len, freq);
 	}
 
 	id = vif->send_action_id++;
@@ -3205,17 +3215,14 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 
 	/* AP mode Power saving processing */
 	if (vif->nw_type == AP_NETWORK) {
-		queued = ath6kl_mgmt_powersave_ap(vif,
-					id, chan->center_freq,
-					wait, buf,
-					len, &more_data, no_cck);
+		queued = ath6kl_mgmt_powersave_ap(vif, id, freq, wait, buf, len,
+						  &more_data, no_cck);
 		if (queued)
 			return 0;
 	}
 
-	return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id,
-					chan->center_freq, wait,
-					buf, len, no_cck);
+	return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id, freq,
+					wait, buf, len, no_cck);
 }
 
 static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
-- 
1.8.1.5


^ permalink raw reply related

* [PATCHv5 1/4] mac80211: make mgmt_tx accept a NULL channel
From: Antonio Quartulli @ 2013-06-11 12:20 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Antonio Quartulli

From: Antonio Quartulli <antonio@open-mesh.com>

cfg80211 passes a NULL channel to mgmt_tx if the frame has
to be sent on the one currently in use by the device.
Make the implementation of mgmt_tx correctly handle this
case. Fail if offchan is required.

Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
 net/mac80211/cfg.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 3062210..617c5c8 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2838,6 +2838,12 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 		return -EOPNOTSUPP;
 	}
 
+	/* configurations requiring offchan cannot work if no channel has been
+	 * specified
+	 */
+	if (need_offchan && !chan)
+		return -EINVAL;
+
 	mutex_lock(&local->mtx);
 
 	/* Check if the operating channel is the requested channel */
@@ -2847,10 +2853,14 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
 		rcu_read_lock();
 		chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
 
-		if (chanctx_conf)
-			need_offchan = chan != chanctx_conf->def.chan;
-		else
+		if (chanctx_conf) {
+			need_offchan = chan && (chan != chanctx_conf->def.chan);
+		} else if (!chan) {
+			ret = -EINVAL;
+			goto out_unlock;
+		} else {
 			need_offchan = true;
+		}
 		rcu_read_unlock();
 	}
 
-- 
1.8.1.5


^ permalink raw reply related

* Re: [PATCH 1/2] {nl,cfg}80211: make peer link expiration time configurable
From: Johannes Berg @ 2013-06-11 12:17 UTC (permalink / raw)
  To: Colleen Twitty; +Cc: linux-wirelss, open80211s
In-Reply-To: <1370278420-10135-1-git-send-email-colleen@cozybit.com>

On Mon, 2013-06-03 at 09:53 -0700, Colleen Twitty wrote:
> If a STA has a peer that it hasn't seen any tx activity
> from for a certain length of time, the peer link is
> expired. This means the inactive STA is removed from the
> list of peers and that STA is not considered a peer again
> unless it re-peers.  Previously, this inactivity time was
> always 30 minutes.  Now, add it to the mesh configuration
> and allow it to be configured.  Retain 30 minutes as a
> default value.

Applied both.

johannes


^ permalink raw reply

* Re: [PATCH] nl80211: add kernel-doc for NL80211_FEATURE_ACTIVE_MONITOR
From: Johannes Berg @ 2013-06-11 12:14 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: linux-wireless
In-Reply-To: <1370275845-97370-1-git-send-email-nbd@openwrt.org>

Applied.

johannes


^ permalink raw reply

* Re: [PATCH v8] cfg80211: P2P find phase offload
From: Johannes Berg @ 2013-06-11 12:12 UTC (permalink / raw)
  To: Vladimir Kondratiev
  Cc: Jouni Malinen, Peer, Ilan, linux-wireless@vger.kernel.org,
	Rodriguez, Luis, John W . Linville
In-Reply-To: <1894431.CPHELQbCIP@lx-vladimir>


> > ---
> > When probe response offload it supported, the device should not report
> > probe requests to the host that it already responded to. It must report
> > (and therefore not respond to) probe requests that indicate the sending
> > device is in active PBC mode (specifically, <...add more details...>).
> > It may also drop invalid or malformed probe requests or ones that would
> > not be replied to for other reasons.
> > ---
> 
> > 
> > I think this would be a reasonable tradeoff. It means that if a probe
> > request is actually reported, wpa_supplicant must reply to it, and we
> > don't have to get into the business of having to decide whether or not
> > it needs to respond.
> > 
> > Alternatively, we could specify that the device _must_ respond if
> > offload is supported, and then report it.
> 
> I like this alternative. Except, reporting is accordingly to the rx filter.
> wpa_s may be not interesting in probes at all, or want only ones with PBC.
> If device answer probes in firmware, this would reduce CPU wake-ups.

Well, wpa_s is always going to be interested, and it can't really
specify in the subscription filter that it only wants PBC ones. The
filters aren't expressive enough for that.

This isn't really my favourite alternative because it means the device
can't just "chicken out" and treat this as a best effort thing, it means
that it always has to reply. I fear that for some devices this might
mean having to reply in software in certain circumstances, which seems
like a bad idea.

> > However, we need to clearly specify this so that we don't get two
> > responses, one from the device and one from wpa_s. If there's no way to
> > specify this, we need to introduce a "reply already sent" flag into the
> > frame reporting.
> 
> Said above translates to all-or-nothing approach w.r.t. responses:
> 
> - If device indicate probe-resp offload, it must reply all probes, supplicant
> must not send probe-resp.
> - If device does not indicate probe-resp offload, it should never send
> probe-resp by itself; it should report all matching probes
> and supplicant will generate probe-resp.

Right. I guess I can live with this, though see above.

> Regarding what probes to report, I'd specify relaxed requirements
> for the driver:
> 
> - in non-offload case, driver must report all matching probes
> (but may just report all, and wpa_s will filter)
> - in offload case, must report matching probes if rx filter says so. It is not
> neccessary to report all probes that device replied to.

see above -- the filters aren't expressive enough to allow specifying "I
want PBC". For probe requests, the filter is going to be all or nothing,
so this won't really do anything useful.

> I don't want to force firmware or driver to parse probes to detect PBC; if we
> got frame to the host, from power perspective there is no much difference who
> will filter it - driver or wpa_s; and wpa_s already do this parsing.

Firmware should parse it, obviously.

> For PBC - can one specify "probes with PBC" using existing rx filter mechanism?

No.

> Also, I feel this explanation get large, it deserves separate comment block,
> it is overkill for start_p2p_find comment. Maybe do it in another patch?

I think we need to nail this down before we merge the API. I have a
feeling we may end up having to implement the third alternative (report
whether a response was sent or not)

johannes


^ 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