linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/6] carl9170: import hw/fw header updates
  2010-10-29 23:10 [PATCH 0/6] carl9170: 2.6.38 patches Christian Lamparter
@ 2010-10-29 20:44 ` Christian Lamparter
  2010-10-29 21:11 ` [PATCH 2/6] carl9170: use generic sign_extend32 Christian Lamparter
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Christian Lamparter @ 2010-10-29 20:44 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville

This patch imports all shared header changes
from carl9170fw.git.

 * add some strategic __aligned(4).
   This allows the compiler generate optimized code for
   architectures which can't access (unaligned/packed)
   data efficiently.
   ("ath9k_hw: optimize all descriptor access functions")

 * add a forgotten __CARL9170FW__ ifdef around
   a private firmware-internal struct.

 * GET_VAL macro helper
   Very useful for extracting data out of the
   bit-packed PHY registers.

 * cosmetic changes
   e.g.: _CCA_MINCCA_ to just _CCA_MIN_.

 * version bump 1.8.8.3 -> 1.9.0.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
 drivers/net/wireless/ath/carl9170/fwcmd.h   |   13 +++++++++----
 drivers/net/wireless/ath/carl9170/hw.h      |    7 ++++++-
 drivers/net/wireless/ath/carl9170/phy.h     |   24 ++++++++++++------------
 drivers/net/wireless/ath/carl9170/version.h |    6 +++---
 4 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ath/carl9170/fwcmd.h b/drivers/net/wireless/ath/carl9170/fwcmd.h
index d552166..3680dfc7 100644
--- a/drivers/net/wireless/ath/carl9170/fwcmd.h
+++ b/drivers/net/wireless/ath/carl9170/fwcmd.h
@@ -97,13 +97,13 @@ struct carl9170_set_key_cmd {
 	__le16		type;
 	u8		macAddr[6];
 	u32		key[4];
-} __packed;
+} __packed __aligned(4);
 #define CARL9170_SET_KEY_CMD_SIZE		28
 
 struct carl9170_disable_key_cmd {
 	__le16		user;
 	__le16		padding;
-} __packed;
+} __packed __aligned(4);
 #define CARL9170_DISABLE_KEY_CMD_SIZE		4
 
 struct carl9170_u32_list {
@@ -206,7 +206,7 @@ struct carl9170_cmd {
 		struct carl9170_rx_filter_cmd	rx_filter;
 		u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
 	} __packed;
-} __packed;
+} __packed __aligned(4);
 
 #define	CARL9170_TX_STATUS_QUEUE	3
 #define	CARL9170_TX_STATUS_QUEUE_S	0
@@ -216,6 +216,7 @@ struct carl9170_cmd {
 #define	CARL9170_TX_STATUS_TRIES	(7 << CARL9170_TX_STATUS_TRIES_S)
 #define	CARL9170_TX_STATUS_SUCCESS	0x80
 
+#ifdef __CARL9170FW__
 /*
  * NOTE:
  * Both structs [carl9170_tx_status and _carl9170_tx_status]
@@ -232,6 +233,8 @@ struct carl9170_tx_status {
 	u8 tries:3;
 	u8 success:1;
 } __packed;
+#endif /* __CARL9170FW__ */
+
 struct _carl9170_tx_status {
 	/*
 	 * This version should be immune to all alignment bugs.
@@ -272,13 +275,15 @@ struct carl9170_rsp {
 		struct carl9170_rf_init_result	rf_init_res;
 		struct carl9170_u32_list	rreg_res;
 		struct carl9170_u32_list	echo;
+#ifdef __CARL9170FW__
 		struct carl9170_tx_status	tx_status[0];
+#endif /* __CARL9170FW__ */
 		struct _carl9170_tx_status	_tx_status[0];
 		struct carl9170_gpio		gpio;
 		struct carl9170_tsf_rsp		tsf;
 		struct carl9170_psm		psm;
 		u8 data[CARL9170_MAX_CMD_PAYLOAD_LEN];
 	} __packed;
-} __packed;
+} __packed __aligned(4);
 
 #endif /* __CARL9170_SHARED_FWCMD_H */
diff --git a/drivers/net/wireless/ath/carl9170/hw.h b/drivers/net/wireless/ath/carl9170/hw.h
index 2f471b3..e85df6e 100644
--- a/drivers/net/wireless/ath/carl9170/hw.h
+++ b/drivers/net/wireless/ath/carl9170/hw.h
@@ -712,7 +712,8 @@ struct ar9170_stream {
 	__le16 tag;
 
 	u8 payload[0];
-};
+} __packed __aligned(4);
+#define AR9170_STREAM_LEN				4
 
 #define AR9170_MAX_ACKTABLE_ENTRIES			8
 #define AR9170_MAX_VIRTUAL_MAC				7
@@ -736,4 +737,8 @@ struct ar9170_stream {
 
 #define MOD_VAL(reg, value, newvalue)					\
 	(((value) & ~reg) | (((newvalue) << reg##_S) & reg))
+
+#define GET_VAL(reg, value)						\
+	(((value) & reg) >> reg##_S)
+
 #endif	/* __CARL9170_SHARED_HW_H */
diff --git a/drivers/net/wireless/ath/carl9170/phy.h b/drivers/net/wireless/ath/carl9170/phy.h
index 02c34eb..024fb42 100644
--- a/drivers/net/wireless/ath/carl9170/phy.h
+++ b/drivers/net/wireless/ath/carl9170/phy.h
@@ -139,8 +139,8 @@
 #define		AR9170_PHY_AGC_CONTROL_NO_UPDATE_NF	0x00020000
 
 #define	AR9170_PHY_REG_CCA			(AR9170_PHY_REG_BASE + 0x0064)
-#define		AR9170_PHY_CCA_MINCCA_PWR		0x0ff80000
-#define		AR9170_PHY_CCA_MINCCA_PWR_S		19
+#define		AR9170_PHY_CCA_MIN_PWR			0x0ff80000
+#define		AR9170_PHY_CCA_MIN_PWR_S		19
 #define		AR9170_PHY_CCA_THRESH62			0x0007f000
 #define		AR9170_PHY_CCA_THRESH62_S		12
 
@@ -338,8 +338,8 @@
 #define		AR9170_PHY_EXT_CCA_CYCPWR_THR1_S	9
 #define		AR9170_PHY_EXT_CCA_THRESH62		0x007f0000
 #define		AR9170_PHY_EXT_CCA_THRESH62_S		16
-#define		AR9170_PHY_EXT_MINCCA_PWR		0xff800000
-#define		AR9170_PHY_EXT_MINCCA_PWR_S		23
+#define		AR9170_PHY_EXT_CCA_MIN_PWR		0xff800000
+#define		AR9170_PHY_EXT_CCA_MIN_PWR_S		23
 
 #define	AR9170_PHY_REG_SFCORR_EXT		(AR9170_PHY_REG_BASE + 0x01c0)
 #define		AR9170_PHY_SFCORR_EXT_M1_THRESH		0x0000007f
@@ -546,19 +546,19 @@
 #define		AR9170_PHY_FORCE_XPA_CFG_S		0
 
 #define	AR9170_PHY_REG_CH1_CCA			(AR9170_PHY_REG_BASE + 0x1064)
-#define		AR9170_PHY_CH1_MINCCA_PWR		0x0ff80000
-#define		AR9170_PHY_CH1_MINCCA_PWR_S		19
+#define		AR9170_PHY_CH1_CCA_MIN_PWR		0x0ff80000
+#define		AR9170_PHY_CH1_CCA_MIN_PWR_S		19
 
 #define	AR9170_PHY_REG_CH2_CCA			(AR9170_PHY_REG_BASE + 0x2064)
-#define		AR9170_PHY_CH2_MINCCA_PWR		0x0ff80000
-#define		AR9170_PHY_CH2_MINCCA_PWR_S		19
+#define		AR9170_PHY_CH2_CCA_MIN_PWR		0x0ff80000
+#define		AR9170_PHY_CH2_CCA_MIN_PWR_S		19
 
 #define	AR9170_PHY_REG_CH1_EXT_CCA		(AR9170_PHY_REG_BASE + 0x11bc)
-#define		AR9170_PHY_CH1_EXT_MINCCA_PWR		0xff800000
-#define		AR9170_PHY_CH1_EXT_MINCCA_PWR_S		23
+#define		AR9170_PHY_CH1_EXT_CCA_MIN_PWR		0xff800000
+#define		AR9170_PHY_CH1_EXT_CCA_MIN_PWR_S	23
 
 #define	AR9170_PHY_REG_CH2_EXT_CCA		(AR9170_PHY_REG_BASE + 0x21bc)
-#define		AR9170_PHY_CH2_EXT_MINCCA_PWR		0xff800000
-#define		AR9170_PHY_CH2_EXT_MINCCA_PWR_S		23
+#define		AR9170_PHY_CH2_EXT_CCA_MIN_PWR		0xff800000
+#define		AR9170_PHY_CH2_EXT_CCA_MIN_PWR_S	23
 
 #endif	/* __CARL9170_SHARED_PHY_H */
diff --git a/drivers/net/wireless/ath/carl9170/version.h b/drivers/net/wireless/ath/carl9170/version.h
index ff53f07..ee0f84f 100644
--- a/drivers/net/wireless/ath/carl9170/version.h
+++ b/drivers/net/wireless/ath/carl9170/version.h
@@ -1,7 +1,7 @@
 #ifndef __CARL9170_SHARED_VERSION_H
 #define __CARL9170_SHARED_VERSION_H
 #define CARL9170FW_VERSION_YEAR 10
-#define CARL9170FW_VERSION_MONTH 9
-#define CARL9170FW_VERSION_DAY 28
-#define CARL9170FW_VERSION_GIT "1.8.8.3"
+#define CARL9170FW_VERSION_MONTH 10
+#define CARL9170FW_VERSION_DAY 29
+#define CARL9170FW_VERSION_GIT "1.9.0"
 #endif /* __CARL9170_SHARED_VERSION_H */
-- 
1.7.2.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/6] carl9170: use generic sign_extend32
  2010-10-29 23:10 [PATCH 0/6] carl9170: 2.6.38 patches Christian Lamparter
  2010-10-29 20:44 ` [PATCH 1/6] carl9170: import hw/fw header updates Christian Lamparter
@ 2010-10-29 21:11 ` Christian Lamparter
  2010-11-10 20:06   ` John W. Linville
  2010-10-29 21:17 ` [PATCH 3/6] carl9170: initialize HW aMPDU parameters properly Christian Lamparter
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Christian Lamparter @ 2010-10-29 21:11 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville

This patch replaces the handcrafted
sign extension cruft with a generic
bitop function.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
 drivers/net/wireless/ath/carl9170/phy.c |   17 ++++-------------
 1 files changed, 4 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
index 89deca3..82bc81c 100644
--- a/drivers/net/wireless/ath/carl9170/phy.c
+++ b/drivers/net/wireless/ath/carl9170/phy.c
@@ -1554,15 +1554,6 @@ static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq,
 	return carl9170_regwrite_result();
 }
 
-/* TODO: replace this with sign_extend32(noise, 8) */
-static int carl9170_calc_noise_dbm(u32 raw_noise)
-{
-	if (raw_noise & 0x100)
-		return ~0x1ff | raw_noise;
-	else
-		return raw_noise;
-}
-
 int carl9170_get_noisefloor(struct ar9170 *ar)
 {
 	static const u32 phy_regs[] = {
@@ -1578,11 +1569,11 @@ int carl9170_get_noisefloor(struct ar9170 *ar)
 		return err;
 
 	for (i = 0; i < 2; i++) {
-		ar->noise[i] = carl9170_calc_noise_dbm(
-			(phy_res[i] >> 19) & 0x1ff);
+		ar->noise[i] = sign_extend32(GET_VAL(
+			AR9170_PHY_CCA_MIN_PWR, phy_res[i]), 8);
 
-		ar->noise[i + 2] = carl9170_calc_noise_dbm(
-			(phy_res[i + 2] >> 23) & 0x1ff);
+		ar->noise[i + 2] = sign_extend32(GET_VAL(
+			AR9170_PHY_EXT_CCA_MIN_PWR, phy_res[i + 2]), 8);
 	}
 
 	return 0;
-- 
1.7.2.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/6] carl9170: initialize HW aMPDU parameters properly
  2010-10-29 23:10 [PATCH 0/6] carl9170: 2.6.38 patches Christian Lamparter
  2010-10-29 20:44 ` [PATCH 1/6] carl9170: import hw/fw header updates Christian Lamparter
  2010-10-29 21:11 ` [PATCH 2/6] carl9170: use generic sign_extend32 Christian Lamparter
@ 2010-10-29 21:17 ` Christian Lamparter
  2010-10-29 21:26 ` [PATCH 4/6] carl9170: fix spurious restart due to high latency Christian Lamparter
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Christian Lamparter @ 2010-10-29 21:17 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville

This patch changes the initial aMPDU density and
factor settings to match those of Otus.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
 drivers/net/wireless/ath/carl9170/mac.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c
index 2305bc2..c34eeee 100644
--- a/drivers/net/wireless/ath/carl9170/mac.c
+++ b/drivers/net/wireless/ath/carl9170/mac.c
@@ -205,8 +205,8 @@ int carl9170_init_mac(struct ar9170 *ar)
 	carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
 
 	/* Aggregation MAX number and timeout */
-	carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0xa);
-	carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a00);
+	carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0x8000a);
+	carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a07);
 
 	carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
 			  AR9170_MAC_FTF_DEFAULTS);
-- 
1.7.2.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/6] carl9170: fix spurious restart due to high latency
  2010-10-29 23:10 [PATCH 0/6] carl9170: 2.6.38 patches Christian Lamparter
                   ` (2 preceding siblings ...)
  2010-10-29 21:17 ` [PATCH 3/6] carl9170: initialize HW aMPDU parameters properly Christian Lamparter
@ 2010-10-29 21:26 ` Christian Lamparter
  2010-10-29 21:41 ` [PATCH 5/6] carl9170: stop stale uplink BA sessions Christian Lamparter
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Christian Lamparter @ 2010-10-29 21:26 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville

RX Stress tests of unidirectional bulk traffic with
bitrates of up to 220Mbit/s have revealed that the
fatal-event recovery logic [which was solely triggered
by an out-of-rx-buffer situation] is too aggressive.

The new method now "pings" the device and then
decides - based on the response - whenever
a restart is needed or not.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
 drivers/net/wireless/ath/carl9170/carl9170.h |    3 ++-
 drivers/net/wireless/ath/carl9170/main.c     |   17 +++++++++++++++++
 drivers/net/wireless/ath/carl9170/usb.c      |    2 +-
 3 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index 6cf0c9e..f1212ba 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -215,7 +215,7 @@ enum carl9170_restart_reasons {
 	CARL9170_RR_TOO_MANY_FIRMWARE_ERRORS,
 	CARL9170_RR_WATCHDOG,
 	CARL9170_RR_STUCK_TX,
-	CARL9170_RR_SLOW_SYSTEM,
+	CARL9170_RR_UNRESPONSIVE_DEVICE,
 	CARL9170_RR_COMMAND_TIMEOUT,
 	CARL9170_RR_TOO_MANY_PHY_ERRORS,
 	CARL9170_RR_LOST_RSP,
@@ -287,6 +287,7 @@ struct ar9170 {
 
 	/* reset / stuck frames/queue detection */
 	struct work_struct restart_work;
+	struct work_struct ping_work;
 	unsigned int restart_counter;
 	unsigned long queue_stop_timeout[__AR9170_NUM_TXQ];
 	unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ];
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index d56f440..b997844 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -428,6 +428,7 @@ static void carl9170_cancel_worker(struct ar9170 *ar)
 	cancel_delayed_work_sync(&ar->led_work);
 #endif /* CONFIG_CARL9170_LEDS */
 	cancel_work_sync(&ar->ps_work);
+	cancel_work_sync(&ar->ping_work);
 	cancel_work_sync(&ar->ampdu_work);
 }
 
@@ -533,6 +534,21 @@ void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r)
 	 */
 }
 
+static void carl9170_ping_work(struct work_struct *work)
+{
+	struct ar9170 *ar = container_of(work, struct ar9170, ping_work);
+	int err;
+
+	if (!IS_STARTED(ar))
+		return;
+
+	mutex_lock(&ar->mutex);
+	err = carl9170_echo_test(ar, 0xdeadbeef);
+	if (err)
+		carl9170_restart(ar, CARL9170_RR_UNRESPONSIVE_DEVICE);
+	mutex_unlock(&ar->mutex);
+}
+
 static int carl9170_init_interface(struct ar9170 *ar,
 				   struct ieee80211_vif *vif)
 {
@@ -1614,6 +1630,7 @@ void *carl9170_alloc(size_t priv_size)
 		skb_queue_head_init(&ar->tx_pending[i]);
 	}
 	INIT_WORK(&ar->ps_work, carl9170_ps_work);
+	INIT_WORK(&ar->ping_work, carl9170_ping_work);
 	INIT_WORK(&ar->restart_work, carl9170_restart_work);
 	INIT_WORK(&ar->ampdu_work, carl9170_ampdu_work);
 	INIT_DELAYED_WORK(&ar->tx_janitor, carl9170_tx_janitor);
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c
index d8607f4..ddf5373 100644
--- a/drivers/net/wireless/ath/carl9170/usb.c
+++ b/drivers/net/wireless/ath/carl9170/usb.c
@@ -431,7 +431,7 @@ static void carl9170_usb_rx_complete(struct urb *urb)
 			 * device.
 			 */
 
-			carl9170_restart(ar, CARL9170_RR_SLOW_SYSTEM);
+			ieee80211_queue_work(ar->hw, &ar->ping_work);
 		}
 	} else {
 		/*
-- 
1.7.2.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/6] carl9170: stop stale uplink BA sessions
  2010-10-29 23:10 [PATCH 0/6] carl9170: 2.6.38 patches Christian Lamparter
                   ` (3 preceding siblings ...)
  2010-10-29 21:26 ` [PATCH 4/6] carl9170: fix spurious restart due to high latency Christian Lamparter
@ 2010-10-29 21:41 ` Christian Lamparter
  2010-10-29 22:36 ` [PATCH 6/6] carl9170: configurable beacon rates Christian Lamparter
  2010-10-29 22:49 ` [RFT] carl9170: improve rx ampdu software deaggregation Christian Lamparter
  6 siblings, 0 replies; 11+ messages in thread
From: Christian Lamparter @ 2010-10-29 21:41 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville

This patch fixes a possible lengthy stall if the device
is operating as an experimental 11n AP and an STA
[during heavy txrx action] suddenly signalized to go
off-channel (old NetworkManager), or (sleep - which is
unlikely, because then it wouldn't be *active* at all!?).

Because the driver has to manage the BA Window, the
sudden PSM transition can leave active uplink BA
sessions to the STA in a bad state and a proper
cleanup is needed.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
 drivers/net/wireless/ath/carl9170/tx.c |   54 ++++++++++++++++++++++++++++++++
 1 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index b575c86..b27969c 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -524,6 +524,59 @@ next:
 	}
 }
 
+static void carl9170_tx_ampdu_timeout(struct ar9170 *ar)
+{
+	struct carl9170_sta_tid *iter;
+	struct sk_buff *skb;
+	struct ieee80211_tx_info *txinfo;
+	struct carl9170_tx_info *arinfo;
+	struct _carl9170_tx_superframe *super;
+	struct ieee80211_sta *sta;
+	struct ieee80211_vif *vif;
+	struct ieee80211_hdr *hdr;
+	unsigned int vif_id;
+
+	rcu_read_lock();
+	list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) {
+		if (iter->state < CARL9170_TID_STATE_IDLE)
+			continue;
+
+		spin_lock_bh(&iter->lock);
+		skb = skb_peek(&iter->queue);
+		if (!skb)
+			goto unlock;
+
+		txinfo = IEEE80211_SKB_CB(skb);
+		arinfo = (void *)txinfo->rate_driver_data;
+		if (time_is_after_jiffies(arinfo->timeout +
+		    msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT)))
+			goto unlock;
+
+		super = (void *) skb->data;
+		hdr = (void *) super->frame_data;
+
+		vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
+			 CARL9170_TX_SUPER_MISC_VIF_ID_S;
+
+		if (WARN_ON(vif_id >= AR9170_MAX_VIRTUAL_MAC))
+			goto unlock;
+
+		vif = rcu_dereference(ar->vif_priv[vif_id].vif);
+		if (WARN_ON(!vif))
+			goto unlock;
+
+		sta = ieee80211_find_sta(vif, hdr->addr1);
+		if (WARN_ON(!sta))
+			goto unlock;
+
+		ieee80211_stop_tx_ba_session(sta, iter->tid);
+unlock:
+		spin_unlock_bh(&iter->lock);
+
+	}
+	rcu_read_unlock();
+}
+
 void carl9170_tx_janitor(struct work_struct *work)
 {
 	struct ar9170 *ar = container_of(work, struct ar9170,
@@ -534,6 +587,7 @@ void carl9170_tx_janitor(struct work_struct *work)
 	ar->tx_janitor_last_run = jiffies;
 
 	carl9170_check_queue_stop_timeout(ar);
+	carl9170_tx_ampdu_timeout(ar);
 
 	if (!atomic_read(&ar->tx_total_queued))
 		return;
-- 
1.7.2.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 6/6] carl9170: configurable beacon rates
  2010-10-29 23:10 [PATCH 0/6] carl9170: 2.6.38 patches Christian Lamparter
                   ` (4 preceding siblings ...)
  2010-10-29 21:41 ` [PATCH 5/6] carl9170: stop stale uplink BA sessions Christian Lamparter
@ 2010-10-29 22:36 ` Christian Lamparter
  2010-10-29 22:49 ` [RFT] carl9170: improve rx ampdu software deaggregation Christian Lamparter
  6 siblings, 0 replies; 11+ messages in thread
From: Christian Lamparter @ 2010-10-29 22:36 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville

Previously, the beacon rate was fixed to either:
 * 1Mb/s [2.4GHz band]
 * 6Mb/s [5GHz band]

This limitation has been addressed and now the
beacon rate is selected by ieee80211_tx_info's
rate control info, almost like any ordinary
data frame.

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
 drivers/net/wireless/ath/carl9170/mac.c |   52 +++++++++++++++++++------------
 1 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c
index c34eeee..385cf50 100644
--- a/drivers/net/wireless/ath/carl9170/mac.c
+++ b/drivers/net/wireless/ath/carl9170/mac.c
@@ -457,8 +457,9 @@ int carl9170_set_beacon_timers(struct ar9170 *ar)
 
 int carl9170_update_beacon(struct ar9170 *ar, const bool submit)
 {
-	struct sk_buff *skb;
+	struct sk_buff *skb = NULL;
 	struct carl9170_vif_info *cvif;
+	struct ieee80211_tx_info *txinfo;
 	__le32 *data, *old = NULL;
 	u32 word, off, addr, len;
 	int i = 0, err = 0;
@@ -487,7 +488,13 @@ found:
 
 	if (!skb) {
 		err = -ENOMEM;
-		goto out_unlock;
+		goto err_free;
+	}
+
+	txinfo = IEEE80211_SKB_CB(skb);
+	if (txinfo->control.rates[0].flags & IEEE80211_TX_RC_MCS) {
+		err = -EINVAL;
+		goto err_free;
 	}
 
 	spin_lock_bh(&ar->beacon_lock);
@@ -504,11 +511,8 @@ found:
 			wiphy_err(ar->hw->wiphy, "beacon does not "
 				  "fit into device memory!\n");
 		}
-
-		spin_unlock_bh(&ar->beacon_lock);
-		dev_kfree_skb_any(skb);
 		err = -EINVAL;
-		goto out_unlock;
+		goto err_unlock;
 	}
 
 	if (len > AR9170_MAC_BCN_LENGTH_MAX) {
@@ -518,22 +522,22 @@ found:
 				 AR9170_MAC_BCN_LENGTH_MAX, len);
 		}
 
-		spin_unlock_bh(&ar->beacon_lock);
-		dev_kfree_skb_any(skb);
 		err = -EMSGSIZE;
-		goto out_unlock;
+		goto err_unlock;
 	}
 
-	carl9170_async_regwrite_begin(ar);
+	i = txinfo->control.rates[0].idx;
+	if (txinfo->band != IEEE80211_BAND_2GHZ)
+		i += 4;
 
-	/* XXX: use skb->cb info */
-	if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
-		carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP,
-				((skb->len + FCS_LEN) << (3 + 16)) + 0x0400);
-	} else {
-		carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP,
-				((skb->len + FCS_LEN) << 16) + 0x001b);
-	}
+	word = __carl9170_ratetable[i].hw_value & 0xf;
+	if (i < 4)
+		word |= ((skb->len + FCS_LEN) << (3 + 16)) + 0x0400;
+	else
+		word |= ((skb->len + FCS_LEN) << 16) + 0x0010;
+
+	carl9170_async_regwrite_begin(ar);
+	carl9170_async_regwrite(AR9170_MAC_REG_BCN_PLCP, word);
 
 	for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
 		/*
@@ -557,7 +561,7 @@ found:
 		cvif->beacon = skb;
 	spin_unlock_bh(&ar->beacon_lock);
 	if (err)
-		goto out_unlock;
+		goto err_free;
 
 	if (submit) {
 		err = carl9170_bcn_ctrl(ar, cvif->id,
@@ -565,10 +569,18 @@ found:
 					addr, skb->len + FCS_LEN);
 
 		if (err)
-			goto out_unlock;
+			goto err_free;
 	}
 out_unlock:
 	rcu_read_unlock();
+	return 0;
+
+err_unlock:
+	spin_unlock_bh(&ar->beacon_lock);
+
+err_free:
+	rcu_read_unlock();
+	dev_kfree_skb_any(skb);
 	return err;
 }
 
-- 
1.7.2.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RFT] carl9170: improve rx ampdu software deaggregation
  2010-10-29 23:10 [PATCH 0/6] carl9170: 2.6.38 patches Christian Lamparter
                   ` (5 preceding siblings ...)
  2010-10-29 22:36 ` [PATCH 6/6] carl9170: configurable beacon rates Christian Lamparter
@ 2010-10-29 22:49 ` Christian Lamparter
  6 siblings, 0 replies; 11+ messages in thread
From: Christian Lamparter @ 2010-10-29 22:49 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville

This patch improves the stateless ampdu rx filter to
scan and salvage intact MPDUs from otherwise "bad data".

Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
---
Note: The search is expensive [compared to the other approach],
but it helps in my setup and if the stats are true it saves
around 10% of the otherwise lost data [but mostly small frames]. 
---
 drivers/net/wireless/ath/carl9170/carl9170.h |    3 +
 drivers/net/wireless/ath/carl9170/main.c     |    1 +
 drivers/net/wireless/ath/carl9170/rx.c       |  117 +++++++++++++++++++++-----
 3 files changed, 101 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index f1212ba..17109cc 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -402,6 +402,9 @@ struct ar9170 {
 	/* rxstream mpdu merge */
 	struct ar9170_rx_head rx_plcp;
 	bool rx_has_plcp;
+	bool has_ampdu_id;
+	__le16 ampdu_id;
+	u8 ampdu_ra[ETH_ALEN];
 	struct sk_buff *rx_failover;
 	int rx_failover_missing;
 
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index b997844..1b1645a 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -561,6 +561,7 @@ static int carl9170_init_interface(struct ar9170 *ar,
 	}
 
 	memcpy(common->macaddr, vif->addr, ETH_ALEN);
+	memcpy(ar->ampdu_ra, vif->addr, ETH_ALEN);
 
 	if (modparam_nohwcrypt ||
 	    ((vif->type != NL80211_IFTYPE_STATION) &&
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c
index 939a0e9..0ef658b 100644
--- a/drivers/net/wireless/ath/carl9170/rx.c
+++ b/drivers/net/wireless/ath/carl9170/rx.c
@@ -576,18 +576,13 @@ static void carl9170_ps_beacon(struct ar9170 *ar, void *data, unsigned int len)
 	}
 }
 
-static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms)
-{
-	__le16 fc;
+/* FC + DU + RA + FCS */
+#define MIN_LEN	(2 + 2 + ETH_ALEN + FCS_LEN)
 
-	if ((ms & AR9170_RX_STATUS_MPDU) == AR9170_RX_STATUS_MPDU_SINGLE) {
-		/*
-		 * This frame is not part of an aMPDU.
-		 * Therefore it is not subjected to any
-		 * of the following content restrictions.
-		 */
-		return true;
-	}
+static bool carl9170_ampdu_check(struct ar9170 *ar, struct ieee80211_hdr *hdr,
+				 int len)
+{
+	__le16 fc = hdr->frame_control;
 
 	/*
 	 * "802.11n - 7.4a.3 A-MPDU contents" describes in which contexts
@@ -597,20 +592,103 @@ static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms)
 	 * stateless filter solely based on the frame control field.
 	 */
 
-	fc = ((struct ieee80211_hdr *)buf)->frame_control;
-	if (ieee80211_is_data_qos(fc) && ieee80211_is_data_present(fc))
+	if (ieee80211_has_tods(fc) &&
+	    memcmp(hdr->addr1, ar->ampdu_ra, ETH_ALEN) != 0)
+		return false;
+
+	if (ieee80211_is_data_qos(fc) && ieee80211_is_data_present(fc) &&
+	    !ieee80211_has_morefrags(fc) && !(hdr->seq_ctrl & cpu_to_le16(0xf))
+	    && !ieee80211_has_pm(fc) && len >= sizeof(*hdr) + FCS_LEN)
 		return true;
 
-	if (ieee80211_is_ack(fc) || ieee80211_is_back(fc) ||
-	    ieee80211_is_back_req(fc))
+	if ((ieee80211_is_ack(fc) && len == MIN_LEN) ||
+	   ((ieee80211_is_back(fc) || ieee80211_is_back_req(fc)) &&
+	     len >= sizeof(struct ieee80211_bar)))
 		return true;
 
-	if (ieee80211_is_action(fc))
+	if (ieee80211_is_action(fc) && len > MIN_LEN)
 		return true;
 
 	return false;
 }
 
+static bool carl9170_ampdu_checker(struct ar9170 *ar, u8 **buf, int *len)
+{
+	struct ieee80211_hdr *hdr;
+
+	do {
+		hdr = (struct ieee80211_hdr *) *(buf);
+
+		/*
+		 * 802.11n - 7.4a.3: "All the MPDUs within an A-MPDU are
+		 * addressed to the same RA."
+		 */
+		if ((memcmp(ar->ampdu_ra, hdr->addr1, ETH_ALEN) == 0)) {
+			/*
+			 * 802.11n - 7.4a.3: "The Duration/ID fields in the
+			 * MAC headers of all MPDUs in an A-MPDU carry the
+			 * same value."
+			 */
+			if (!(ar->has_ampdu_id &&
+			    (ar->ampdu_id != hdr->duration_id))) {
+				if (carl9170_ampdu_check(ar, hdr, *len))
+					return true;
+			}
+		}
+
+		(*buf)++;
+		(*len)--;
+	} while (*len >= MIN_LEN);
+
+	return false;
+}
+
+static bool carl9170_ampdu_state_check(struct ar9170 *ar, u8 **buf,
+				       u8 ms, int *len)
+{
+	int i;
+
+	if ((ms & AR9170_RX_STATUS_MPDU) == AR9170_RX_STATUS_MPDU_SINGLE ||
+	    unlikely(ar->sniffer_enabled)) {
+		/*
+		 * This frame is not part of an aMPDU.
+		 * Therefore it is not subjected to any
+		 * of the following content restrictions.
+		 *
+		 * Also, in sniffer mode we don't want
+		 * anything to touch the raw frames.
+		 */
+		return true;
+	}
+
+	if (carl9170_ampdu_checker(ar, buf, len))
+		return true;
+
+	if ((ms & AR9170_RX_STATUS_MPDU) != AR9170_RX_STATUS_MPDU_FIRST)
+		return false;
+
+	rcu_read_lock();
+	for_each_set_bit(i, &ar->vif_bitmap, ar->fw.vif_num) {
+		struct ieee80211_vif *vif;
+
+		vif = rcu_dereference(ar->vif_priv[i].vif);
+		if (vif) {
+			memcpy(ar->ampdu_ra, vif->addr, ETH_ALEN);
+
+			if (carl9170_ampdu_checker(ar, buf, len)) {
+				struct ieee80211_hdr *hdr = (void *)(*buf);
+
+				ar->has_ampdu_id = true;
+				ar->ampdu_id = hdr->duration_id;
+				break;
+			}
+		}
+	}
+	rcu_read_unlock();
+
+	return i == ar->fw.vif_num;
+}
+
 /*
  * If the frame alignment is right (or the kernel has
  * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
@@ -660,7 +738,7 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
 
 			mpdu_len -= sizeof(struct ar9170_rx_head);
 			buf += sizeof(struct ar9170_rx_head);
-
+			ar->has_ampdu_id = false;
 			ar->rx_has_plcp = true;
 		} else {
 			if (net_ratelimit()) {
@@ -722,15 +800,14 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
 		break;
 	}
 
-	/* FC + DU + RA + FCS */
-	if (unlikely(mpdu_len < (2 + 2 + ETH_ALEN + FCS_LEN)))
+	if (unlikely(mpdu_len < MIN_LEN))
 		goto drop;
 
 	memset(&status, 0, sizeof(status));
 	if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status)))
 		goto drop;
 
-	if (!carl9170_ampdu_check(ar, buf, mac_status))
+	if (!carl9170_ampdu_state_check(ar, &buf, mac_status, &mpdu_len))
 		goto drop;
 
 	if (phy)
-- 
1.7.2.3


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 0/6] carl9170: 2.6.38 patches
@ 2010-10-29 23:10 Christian Lamparter
  2010-10-29 20:44 ` [PATCH 1/6] carl9170: import hw/fw header updates Christian Lamparter
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: Christian Lamparter @ 2010-10-29 23:10 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville

I haven't heard of any serious complains yet?
So I'm moving on with the next batch for the
next -next cycle.

Christian Lamparter (7):
  carl9170: import hw/fw header updates
  carl9170: use generic sign_extend32
  carl9170: initialize HW aMPDU parameters properly
  carl9170: fix spurious restart due to high latency
  carl9170: stop stale uplink BA sessions
  carl9170: configurable beacon rates
  carl9170: improve rx ampdu software deaggregation

 drivers/net/wireless/ath/carl9170/carl9170.h |    6 +-
 drivers/net/wireless/ath/carl9170/fwcmd.h    |   13 ++-
 drivers/net/wireless/ath/carl9170/hw.h       |    7 ++-
 drivers/net/wireless/ath/carl9170/mac.c      |   56 ++++++++-----
 drivers/net/wireless/ath/carl9170/main.c     |   18 ++++
 drivers/net/wireless/ath/carl9170/phy.c      |   17 +---
 drivers/net/wireless/ath/carl9170/phy.h      |   24 +++---
 drivers/net/wireless/ath/carl9170/rx.c       |  117 +++++++++++++++++++++-----
 drivers/net/wireless/ath/carl9170/tx.c       |   54 ++++++++++++
 drivers/net/wireless/ath/carl9170/usb.c      |    2 +-
 drivers/net/wireless/ath/carl9170/version.h  |    6 +-
 11 files changed, 243 insertions(+), 77 deletions(-)

-- 
1.7.2.3


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/6] carl9170: use generic sign_extend32
  2010-10-29 21:11 ` [PATCH 2/6] carl9170: use generic sign_extend32 Christian Lamparter
@ 2010-11-10 20:06   ` John W. Linville
  2010-11-10 20:21     ` Christian Lamparter
  0 siblings, 1 reply; 11+ messages in thread
From: John W. Linville @ 2010-11-10 20:06 UTC (permalink / raw)
  To: Christian Lamparter; +Cc: linux-wireless

On Fri, Oct 29, 2010 at 11:11:23PM +0200, Christian Lamparter wrote:
> This patch replaces the handcrafted
> sign extension cruft with a generic
> bitop function.
> 
> Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>

  CC [M]  drivers/net/wireless/ath/carl9170/phy.o
drivers/net/wireless/ath/carl9170/phy.c: In function ‘carl9170_get_noisefloor’:
drivers/net/wireless/ath/carl9170/phy.c:1572: error: implicit declaration of function ‘sign_extend32’
make[3]: *** [drivers/net/wireless/ath/carl9170/phy.o] Error 1
make[2]: *** [drivers/net/wireless/ath/carl9170] Error 2
make[1]: *** [drivers/net/wireless/ath] Error 2
make: *** [drivers/net/wireless/] Error 2

Maybe we should wait until this function exists before we use it? :-)

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/6] carl9170: use generic sign_extend32
  2010-11-10 20:06   ` John W. Linville
@ 2010-11-10 20:21     ` Christian Lamparter
  2010-11-10 20:43       ` John W. Linville
  0 siblings, 1 reply; 11+ messages in thread
From: Christian Lamparter @ 2010-11-10 20:21 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, Andreas Herrmann

On Wednesday 10 November 2010 21:06:36 John W. Linville wrote:
> On Fri, Oct 29, 2010 at 11:11:23PM +0200, Christian Lamparter wrote:
> > This patch replaces the handcrafted
> > sign extension cruft with a generic
> > bitop function.
> > 
> > Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
> 
>   CC [M]  drivers/net/wireless/ath/carl9170/phy.o
> drivers/net/wireless/ath/carl9170/phy.c: In function ‘carl9170_get_noisefloor’:
> drivers/net/wireless/ath/carl9170/phy.c:1572: error: implicit declaration of function ‘sign_extend32’
> make[3]: *** [drivers/net/wireless/ath/carl9170/phy.o] Error 1
> make[2]: *** [drivers/net/wireless/ath/carl9170] Error 2
> make[1]: *** [drivers/net/wireless/ath] Error 2
> make: *** [drivers/net/wireless/] Error 2
> 
> Maybe we should wait until this function exists before we use it? :-)
interesting,

https://patchwork.kernel.org/patch/143241/

so why exactly wasn't this patch merged?

Regards,
	Chr

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [PATCH 2/6] carl9170: use generic sign_extend32
  2010-11-10 20:21     ` Christian Lamparter
@ 2010-11-10 20:43       ` John W. Linville
  0 siblings, 0 replies; 11+ messages in thread
From: John W. Linville @ 2010-11-10 20:43 UTC (permalink / raw)
  To: Christian Lamparter; +Cc: linux-wireless, Andreas Herrmann

On Wed, Nov 10, 2010 at 09:21:49PM +0100, Christian Lamparter wrote:
> On Wednesday 10 November 2010 21:06:36 John W. Linville wrote:
> > On Fri, Oct 29, 2010 at 11:11:23PM +0200, Christian Lamparter wrote:
> > > This patch replaces the handcrafted
> > > sign extension cruft with a generic
> > > bitop function.
> > > 
> > > Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
> > 
> >   CC [M]  drivers/net/wireless/ath/carl9170/phy.o
> > drivers/net/wireless/ath/carl9170/phy.c: In function ‘carl9170_get_noisefloor’:
> > drivers/net/wireless/ath/carl9170/phy.c:1572: error: implicit declaration of function ‘sign_extend32’
> > make[3]: *** [drivers/net/wireless/ath/carl9170/phy.o] Error 1
> > make[2]: *** [drivers/net/wireless/ath/carl9170] Error 2
> > make[1]: *** [drivers/net/wireless/ath] Error 2
> > make: *** [drivers/net/wireless/] Error 2
> > 
> > Maybe we should wait until this function exists before we use it? :-)
> interesting,
> 
> https://patchwork.kernel.org/patch/143241/
> 
> so why exactly wasn't this patch merged?

Probably because the combination of To: and Cc: he used made everyone
think it was someone else's patch to merge. :-(

I can take it, thanks for the link.

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2010-11-10 20:44 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-29 23:10 [PATCH 0/6] carl9170: 2.6.38 patches Christian Lamparter
2010-10-29 20:44 ` [PATCH 1/6] carl9170: import hw/fw header updates Christian Lamparter
2010-10-29 21:11 ` [PATCH 2/6] carl9170: use generic sign_extend32 Christian Lamparter
2010-11-10 20:06   ` John W. Linville
2010-11-10 20:21     ` Christian Lamparter
2010-11-10 20:43       ` John W. Linville
2010-10-29 21:17 ` [PATCH 3/6] carl9170: initialize HW aMPDU parameters properly Christian Lamparter
2010-10-29 21:26 ` [PATCH 4/6] carl9170: fix spurious restart due to high latency Christian Lamparter
2010-10-29 21:41 ` [PATCH 5/6] carl9170: stop stale uplink BA sessions Christian Lamparter
2010-10-29 22:36 ` [PATCH 6/6] carl9170: configurable beacon rates Christian Lamparter
2010-10-29 22:49 ` [RFT] carl9170: improve rx ampdu software deaggregation Christian Lamparter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).