* [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.