All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.