2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 00/18] wireless: rate cleanups

Few rate cleanup and fixes. Thanks to Jouni and Johannes
for spotting the real issue with nullfunc frames during scan.

Luis R. Rodriguez (18):
mac80211: disable moving between PS modes during scan
mac80211: drop frames for sta with no valid rate
ath9k: downgrade assert in rc.c for invalid rate
iwlwifi: remove rs_get_rate workaround
ath9k: cleanup try count for MRR in rate control
ath9k: remove unused min rate calculation code
ath9k: remove unused stepdown when looking for the next rate
ath9k: remove pointless wrapper ath_rc_rate_getidx()
ath9k: rename ath_rc_get_nextlowervalid_txrate()
ath9k: remove unused ath_rc_isvalid_txmask()
ath9k: remove ATH9K_MODE_11B
ath9k: remap ATH9K_MODE_*
ath9k: rename ath_rc_ratefind_ht() to ath_rc_get_highest_rix()
ath9k: remove unnecessary IEEE80211_TX_CTL_NO_ACK checks
mac80211: make minstrel/pid RC use ieee80211_is_data(fc)
iwlwifi: use ieee80211_is_data(fc)
mac80211: add helper for management / no-ack frame rate decision
ath9k: remove rate control wraper

drivers/net/wireless/ath/ath9k/ath9k.h | 1 -
drivers/net/wireless/ath/ath9k/hw.c | 1 -
drivers/net/wireless/ath/ath9k/hw.h | 17 ++--
drivers/net/wireless/ath/ath9k/main.c | 3 +-
drivers/net/wireless/ath/ath9k/rc.c | 174 +++++++++-------------------
drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 24 +---
drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 16 +---
drivers/net/wireless/iwlwifi/iwl-sta.c | 5 +-
include/net/mac80211.h | 34 ++++++
net/mac80211/rate.c | 29 +++++
net/mac80211/rc80211_minstrel.c | 23 +----
net/mac80211/rc80211_pid_algo.c | 12 +--
net/mac80211/tx.c | 26 ++++-
13 files changed, 160 insertions(+), 205 deletions(-)



2009-06-10 19:01:48

by Reinette Chatre

[permalink] [raw]
Subject: Re: [PATCH 04/18] iwlwifi: remove rs_get_rate workaround

Hi Luis,

On Wed, 2009-06-10 at 01:19 -0700, Luis R. Rodriguez wrote:
> This removes the work around implemented for transmitting on
> an unsupported band on iwlwifi. This was added via the patch:
>
> 8e1856e82cb8f541e925738bebfbc473420cda68:
> iwlwifi: fix rs_get_rate WARN_ON()
>
> Cc: Mohamed Abbas <[email protected]>
> Cc: Reinette Chatre <[email protected]>
> Signed-off-by: Luis R. Rodriguez <[email protected]>
> ---
> drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 12 ++----------
> drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 11 +----------
> 2 files changed, 3 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
> index 5eb538d..b23fd53 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
> @@ -674,28 +674,20 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
> unsigned long flags;
> struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
> u16 fc;
> - u16 rate_mask = 0;
> + u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0;
> s8 max_rate_idx = -1;
> struct iwl_priv *priv = (struct iwl_priv *)priv_r;
> struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
>
> IWL_DEBUG_RATE(priv, "enter\n");
>
> - if (sta)
> - rate_mask = sta->supp_rates[sband->band];
> -
> /* Send management frames and NO_ACK data using lowest rate. */
> fc = le16_to_cpu(hdr->frame_control);
> if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
> info->flags & IEEE80211_TX_CTL_NO_ACK ||
> !sta || !priv_sta) {
> IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n");
> - if (!rate_mask)
> - info->control.rates[0].idx =
> - rate_lowest_index(sband, NULL);
> - else
> - info->control.rates[0].idx =
> - rate_lowest_index(sband, sta);
> + info->control.rates[0].idx = rate_lowest_index(sband, sta);
> if (info->flags & IEEE80211_TX_CTL_NO_ACK)
> info->control.rates[0].count = 1;
> return;
> diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
> index ff20e50..3fea027 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
> @@ -2466,7 +2466,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
> struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
> struct iwl_lq_sta *lq_sta = priv_sta;
> int rate_idx;
> - u64 mask_bit = 0;
>
> IWL_DEBUG_RATE_LIMIT(priv, "rate scale calculate new rate for skb\n");
>
> @@ -2481,18 +2480,10 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
> lq_sta->max_rate_idx = -1;
> }
>
> - if (sta)
> - mask_bit = sta->supp_rates[sband->band];
> -
> /* Send management frames and NO_ACK data using lowest rate. */
> if (!ieee80211_is_data(hdr->frame_control) ||
> info->flags & IEEE80211_TX_CTL_NO_ACK || !sta || !lq_sta) {
> - if (!mask_bit)
> - info->control.rates[0].idx =
> - rate_lowest_index(sband, NULL);
> - else
> - info->control.rates[0].idx =
> - rate_lowest_index(sband, sta);
> + info->control.rates[0].idx = rate_lowest_index(sband, sta);
> if (info->flags & IEEE80211_TX_CTL_NO_ACK)
> info->control.rates[0].count = 1;
> return;


I applied patches 1, 2, and 4 from your series. After this I can again
trigger the rs_get_rate warning.

The steps I use are:
$ ip link set wlan0 up
$ iwlist wlan0 scan
$ iwconfig wlan0 channel <from G band> essid essid
$ #assign IP and ping to test association
$ iwconfig wlan0 channel <from A band> essid essid

The last command triggers the warning below (the warning that tainted
the kernel is this same warning):

[ 6447.873784] WARNING: at /home/wifi/iwlwifi-2.6/include/net/mac80211.h:2104 rs_get_rate+0x1e5/0x430 [iwlagn]()
[ 6447.883695] Hardware name: Santa Rosa platform
[ 6447.888179] Modules linked in: iwlagn iwlcore led_class mac80211 cfg80211 rfkill arc4 ecb i915 drm i2c_algo_bit i2c_core binf
mt_misc ppdev acpi_cpufreq cpufreq_powersave cpufreq_conservative cpufreq_ondemand cpufreq_stats freq_table cpufreq_userspace sb
s sbshc ipv6 iptable_filter ip_tables x_tables parport_pc lp parport psmouse serio_raw pcspkr battery iTCO_wdt iTCO_vendor_support video output container ac processor button intel_agp evdev ext3 jbd mbcache sg sr_mod cdrom sd_mod e100 mii ata_piix ehci_hcd uhci_hcd pata_acpi ata_generic libata usbcore scsi_mod thermal fan thermal_sys fuse [last unloaded: rfkill]
[ 6447.943478] Pid: 9409, comm: iwconfig Tainted: G W 2.6.30-rc8-wl #40
[ 6447.950534] Call Trace:
[ 6447.953005] [<ffffffff8026bee9>] ? is_module_text_address+0x9/0x20
[ 6447.959295] [<ffffffffa055aad5>] ? rs_get_rate+0x1e5/0x430 [iwlagn]
[ 6447.965662] [<ffffffff80239c68>] warn_slowpath_common+0x78/0xd0
[ 6447.971682] [<ffffffff80239ccf>] warn_slowpath_null+0xf/0x20
[ 6447.977451] [<ffffffffa055aad5>] rs_get_rate+0x1e5/0x430 [iwlagn]
[ 6447.983669] [<ffffffffa04ed27e>] rate_control_get_rate+0xbe/0xd0 [mac80211]
[ 6447.990745] [<ffffffffa04f4a61>] invoke_tx_handlers+0x6b1/0xf70 [mac80211]
[ 6447.997734] [<ffffffffa04f3e8e>] ? __ieee80211_tx_prepare+0x1ae/0x3b0 [mac80211]
[ 6448.005244] [<ffffffffa04f5b75>] ieee80211_tx+0xf5/0x2f0 [mac80211]
[ 6448.011628] [<ffffffffa04f5b0d>] ? ieee80211_tx+0x8d/0x2f0 [mac80211]
[ 6448.018224] [<ffffffffa04f6b2a>] ieee80211_master_start_xmit+0x1fa/0x390 [mac80211]
[ 6448.025974] [<ffffffff80467d7d>] dev_hard_start_xmit+0x29d/0x340
[ 6448.032129] [<ffffffff8047aeb6>] __qdisc_run+0x256/0x2a0
[ 6448.037574] [<ffffffff80468268>] dev_queue_xmit+0x308/0x4e0
[ 6448.043243] [<ffffffff80467fb2>] ? dev_queue_xmit+0x52/0x4e0
[ 6448.049059] [<ffffffffa04f8897>] ieee80211_tx_skb+0x67/0x70 [mac80211]
[ 6448.055751] [<ffffffffa04e7803>] ieee80211_send_deauth_disassoc+0x113/0x160 [mac80211]
[ 6448.063813] [<ffffffffa04e7c20>] ieee80211_set_disassoc+0x290/0x370 [mac80211]
[ 6448.071147] [<ffffffffa04e7990>] ? ieee80211_set_disassoc+0x0/0x370 [mac80211]
[ 6448.078518] [<ffffffffa04e8037>] ieee80211_sta_req_auth+0xb7/0xe0 [mac80211]
[ 6448.085726] [<ffffffffa04e030b>] ieee80211_ioctl_siwessid+0xbb/0xd0 [mac80211]
[ 6448.093086] [<ffffffff804eaed4>] ioctl_standard_call+0x1f4/0x460
[ 6448.099206] [<ffffffffa04e0250>] ? ieee80211_ioctl_siwessid+0x0/0xd0 [mac80211]
[ 6448.106643] [<ffffffff804ea92b>] wext_handle_ioctl+0x16b/0x240
[ 6448.112621] [<ffffffff8046a2c2>] dev_ioctl+0x3f2/0x5e0
[ 6448.117893] [<ffffffff802a3432>] ? unlock_page+0x22/0x30
[ 6448.123306] [<ffffffff804553c9>] sock_ioctl+0x89/0x290
[ 6448.128580] [<ffffffff802e5441>] vfs_ioctl+0x31/0xa0
[ 6448.133691] [<ffffffff802e553a>] do_vfs_ioctl+0x8a/0x580
[ 6448.139136] [<ffffffff80256816>] ? up_read+0x26/0x30
[ 6448.144198] [<ffffffff802e5ac9>] sys_ioctl+0x99/0xa0
[ 6448.149269] [<ffffffff8020bdab>] system_call_fastpath+0x16/0x1b
[ 6448.155317] ---[ end trace 487d6d48e50362db ]---

Reinette




2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 05/18] ath9k: cleanup try count for MRR in rate control

This has no functional change and just cleans up the code
to be more legible and removes a useless variable for
Multi Rate Retry.

For regular frames we use 2 retries for MRR segments [0-2].
For the last MRR segment [3] we use 4.

MRR[0] = 2
MRR[1] = 2
MRR[2] = 2
MRR[3] = 4

Cc: Derek Smithies <[email protected]>
Cc: Chittajit Mitra <[email protected]>
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 1 -
drivers/net/wireless/ath/ath9k/main.c | 3 ++-
drivers/net/wireless/ath/ath9k/rc.c | 29 ++++++++++++++++++++---------
3 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 9cd523f..ca14642 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -169,7 +169,6 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
#define WME_NUM_TID 16
#define ATH_TXBUF 512
#define ATH_TXMAXTRY 13
-#define ATH_11N_TXMAXTRY 10
#define ATH_MGT_TXMAXTRY 4
#define WME_BA_BMP_SIZE 64
#define WME_MAX_BA WME_BA_BMP_SIZE
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index f7baa40..2270166 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1573,7 +1573,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
hw->max_rates = 4;
hw->channel_change_time = 5000;
hw->max_listen_interval = 10;
- hw->max_rate_tries = ATH_11N_TXMAXTRY;
+ /* Hardware supports 10 but we use 4 */
+ hw->max_rate_tries = 4;
hw->sta_data_size = sizeof(struct ath_node);
hw->vif_data_size = sizeof(struct ath_vif);

diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index d7f4030..a23b66b 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -853,9 +853,21 @@ static void ath_rc_ratefind(struct ath_softc *sc,
struct ieee80211_tx_rate *rates = tx_info->control.rates;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
__le16 fc = hdr->frame_control;
- u8 try_per_rate = 0, i = 0, rix, nrix;
+ u8 try_per_rate, i = 0, rix, nrix;
int is_probe = 0;

+ /*
+ * For Multi Rate Retry we use a different number of
+ * retry attempt counts. This ends up looking like this:
+ *
+ * MRR[0] = 2
+ * MRR[1] = 2
+ * MRR[2] = 2
+ * MRR[3] = 4
+ *
+ */
+ try_per_rate = sc->hw->max_rate_tries;
+
rate_table = sc->cur_rate_table;
rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, &is_probe);
nrix = rix;
@@ -866,7 +878,6 @@ static void ath_rc_ratefind(struct ath_softc *sc,
ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
1, nrix, 0);

- try_per_rate = (ATH_11N_TXMAXTRY/4);
/* Get the next tried/allowed rate. No RTS for the next series
* after the probe rate
*/
@@ -877,7 +888,6 @@ static void ath_rc_ratefind(struct ath_softc *sc,

tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
} else {
- try_per_rate = (ATH_11N_TXMAXTRY/4);
/* Set the choosen rate. No RTS for first series entry. */
ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
try_per_rate, nrix, 0);
@@ -885,18 +895,19 @@ static void ath_rc_ratefind(struct ath_softc *sc,

/* Fill in the other rates for multirate retry */
for ( ; i < 4; i++) {
- u8 try_num;
u8 min_rate;

- try_num = ((i + 1) == 4) ?
- ATH_11N_TXMAXTRY - (try_per_rate * i) : try_per_rate ;
+ /* Use twice the number of tries for the last MRR segment. */
+ if (i + 1 == 4)
+ try_per_rate = 4;
+
min_rate = (((i + 1) == 4) && 0);

nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
rate_table, nrix, 1, min_rate);
/* All other rates in the series have RTS enabled */
ath_rc_rate_set_series(rate_table, &rates[i], txrc,
- try_num, nrix, 1);
+ try_per_rate, nrix, 1);
}

/*
@@ -1529,7 +1540,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
/*
* If underrun error is seen assume it as an excessive retry only
* if prefetch trigger level have reached the max (0x3f for 5416)
- * Adjust the long retry as if the frame was tried ATH_11N_TXMAXTRY
+ * Adjust the long retry as if the frame was tried hw->max_rate_tries
* times. This affects how ratectrl updates PER for the failed rate.
*/
if (tx_info_priv->tx.ts_flags &
@@ -1544,7 +1555,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
tx_status = 1;

ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status,
- (is_underrun) ? ATH_11N_TXMAXTRY :
+ (is_underrun) ? sc->hw->max_rate_tries :
tx_info_priv->tx.ts_longretry);

/* Check if aggregation has to be enabled for this tid */
--
1.6.0.6


2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 02/18] mac80211: drop frames for sta with no valid rate

When we're associated we should be able to send data to
target sta. If we cannot we may be trying to use the incorrect
band to talk to the sta. Lets catch any such cases, warn, and
drop the frames to not invalidate assumptions being made on
rate control algorithms when they have a valid sta to
communicate with. Any such cases should be handled and fixed.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
include/net/mac80211.h | 11 +++++++++++
net/mac80211/tx.c | 23 +++++++++++++++++++++++
2 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 17d61d1..9559efa 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2103,6 +2103,17 @@ rate_lowest_index(struct ieee80211_supported_band *sband,
return 0;
}

+static inline
+bool rate_usable_index_exists(struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta)
+{
+ unsigned int i;
+
+ for (i = 0; i < sband->n_bitrates; i++)
+ if (rate_supported(sta, sband->band, i))
+ return true;
+ return false;
+}

int ieee80211_rate_control_register(struct rate_control_ops *ops);
void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e43fbb9..915c8a3 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -511,6 +511,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
int i, len;
bool inval = false, rts = false, short_preamble = false;
struct ieee80211_tx_rate_control txrc;
+ u32 sta_flags;

memset(&txrc, 0, sizeof(txrc));

@@ -543,7 +544,29 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
(tx->sta && test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))))
txrc.short_preamble = short_preamble = true;

+ sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0;
+
+ /*
+ * Lets not bother rate control if we're associated and cannot
+ * talk to the sta. This should not happen.
+ */
+ if (unlikely((tx->local->sw_scanning) &&
+ (sta_flags & WLAN_STA_ASSOC) &&
+ !rate_usable_index_exists(sband, &tx->sta->sta))) {
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+ printk(KERN_DEBUG "%s: dropped data frame -- no "
+ "supported rate for station %pM on %c GHz band\n",
+ tx->dev->name, hdr->addr1,
+ tx->channel->band ? '5' : '2');
+#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
+ WARN_ON(1);
+ return TX_DROP;
+ }

+ /*
+ * If we're associated point with the sta we know we can at
+ * least send the frame at the lowest bit rate.
+ */
rate_control_get_rate(tx->sdata, tx->sta, &txrc);

if (unlikely(info->control.rates[0].idx < 0))
--
1.6.0.6


2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 04/18] iwlwifi: remove rs_get_rate workaround

This removes the work around implemented for transmitting on
an unsupported band on iwlwifi. This was added via the patch:

8e1856e82cb8f541e925738bebfbc473420cda68:
iwlwifi: fix rs_get_rate WARN_ON()

Cc: Mohamed Abbas <[email protected]>
Cc: Reinette Chatre <[email protected]>
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 12 ++----------
drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 11 +----------
2 files changed, 3 insertions(+), 20 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 5eb538d..b23fd53 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -674,28 +674,20 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
unsigned long flags;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
u16 fc;
- u16 rate_mask = 0;
+ u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0;
s8 max_rate_idx = -1;
struct iwl_priv *priv = (struct iwl_priv *)priv_r;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);

IWL_DEBUG_RATE(priv, "enter\n");

- if (sta)
- rate_mask = sta->supp_rates[sband->band];
-
/* Send management frames and NO_ACK data using lowest rate. */
fc = le16_to_cpu(hdr->frame_control);
if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
info->flags & IEEE80211_TX_CTL_NO_ACK ||
!sta || !priv_sta) {
IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n");
- if (!rate_mask)
- info->control.rates[0].idx =
- rate_lowest_index(sband, NULL);
- else
- info->control.rates[0].idx =
- rate_lowest_index(sband, sta);
+ info->control.rates[0].idx = rate_lowest_index(sband, sta);
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
info->control.rates[0].count = 1;
return;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index ff20e50..3fea027 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -2466,7 +2466,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct iwl_lq_sta *lq_sta = priv_sta;
int rate_idx;
- u64 mask_bit = 0;

IWL_DEBUG_RATE_LIMIT(priv, "rate scale calculate new rate for skb\n");

@@ -2481,18 +2480,10 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
lq_sta->max_rate_idx = -1;
}

- if (sta)
- mask_bit = sta->supp_rates[sband->band];
-
/* Send management frames and NO_ACK data using lowest rate. */
if (!ieee80211_is_data(hdr->frame_control) ||
info->flags & IEEE80211_TX_CTL_NO_ACK || !sta || !lq_sta) {
- if (!mask_bit)
- info->control.rates[0].idx =
- rate_lowest_index(sband, NULL);
- else
- info->control.rates[0].idx =
- rate_lowest_index(sband, sta);
+ info->control.rates[0].idx = rate_lowest_index(sband, sta);
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
info->control.rates[0].count = 1;
return;
--
1.6.0.6


2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 16/18] iwlwifi: use ieee80211_is_data(fc)

iwl-agn-rs.c already uses this.

Cc: Zhu Yi <[email protected]>
Cc: Reinette Chatre <[email protected]>
Cc: [email protected]
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 7 +++----
drivers/net/wireless/iwlwifi/iwl-sta.c | 5 ++---
2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index b23fd53..2b77692 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -673,7 +673,7 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
s8 scale_action = 0;
unsigned long flags;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- u16 fc;
+ __le16 fc;
u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0;
s8 max_rate_idx = -1;
struct iwl_priv *priv = (struct iwl_priv *)priv_r;
@@ -682,9 +682,8 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
IWL_DEBUG_RATE(priv, "enter\n");

/* Send management frames and NO_ACK data using lowest rate. */
- fc = le16_to_cpu(hdr->frame_control);
- if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
- info->flags & IEEE80211_TX_CTL_NO_ACK ||
+ fc = hdr->frame_control;
+ if (!ieee80211_is_data(fc) || info->flags & IEEE80211_TX_CTL_NO_ACK ||
!sta || !priv_sta) {
IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n");
info->control.rates[0].idx = rate_lowest_index(sband, sta);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 2addf73..afa1633 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1044,11 +1044,10 @@ EXPORT_SYMBOL(iwl_rxon_add_station);
int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
{
int sta_id;
- u16 fc = le16_to_cpu(hdr->frame_control);
+ __le16 fc = hdr->frame_control;

/* If this frame is broadcast or management, use broadcast station id */
- if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
- is_multicast_ether_addr(hdr->addr1))
+ if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1))
return priv->hw_params.bcast_sta_id;

switch (priv->iw_mode) {
--
1.6.0.6


2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 17/18] mac80211: add helper for management / no-ack frame rate decision

All current rate control algorithms agree to send management and no-ack
frames at the lowest rate. They also agree to do this when sta
and the private rate control data is NULL. We add a hlper to mac80211
for this and simplify the rate control algorithm code.

Developers wishing to make enhancements to rate control algorithms
are for broadcast/multicast can opt to not use this in their
gate_rate() mac80211 callback.

Cc: Zhu Yi <[email protected]>
Cc: Reinette Chatre <[email protected]>
Cc: [email protected]
Cc: Gabor Juhos <[email protected]>
Cc: Felix Fietkau <[email protected]>
Cc: Derek Smithies <[email protected]>
Cc: Chittajit Mitra <[email protected]>
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath/ath9k/rc.c | 14 +------------
drivers/net/wireless/iwlwifi/iwl-3945-rs.c | 13 ++---------
drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 7 +-----
include/net/mac80211.h | 23 ++++++++++++++++++++++
net/mac80211/rate.c | 29 ++++++++++++++++++++++++++++
net/mac80211/rc80211_minstrel.c | 22 +--------------------
net/mac80211/rc80211_pid_algo.c | 11 +---------
7 files changed, 59 insertions(+), 60 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 2c72901..630fcf4 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1518,23 +1518,11 @@ exit:
static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
struct ieee80211_tx_rate_control *txrc)
{
- struct ieee80211_supported_band *sband = txrc->sband;
- struct sk_buff *skb = txrc->skb;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
struct ath_softc *sc = priv;
struct ath_rate_priv *ath_rc_priv = priv_sta;
- __le16 fc = hdr->frame_control;

- /* lowest rate for management and NO_ACK frames */
- if (!ieee80211_is_data(fc) ||
- tx_info->flags & IEEE80211_TX_CTL_NO_ACK || !sta) {
- tx_info->control.rates[0].idx = rate_lowest_index(sband, sta);
- tx_info->control.rates[0].count =
- (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) ?
- 1 : ATH_MGT_TXMAXTRY;
+ if (rate_control_send_low(sta, priv_sta, txrc))
return;
- }

/* Find tx rate for unicast frames */
ath_rc_ratefind(sc, ath_rc_priv, txrc);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 2b77692..a16bd41 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -673,7 +673,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
s8 scale_action = 0;
unsigned long flags;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
- __le16 fc;
u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0;
s8 max_rate_idx = -1;
struct iwl_priv *priv = (struct iwl_priv *)priv_r;
@@ -681,16 +680,10 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,

IWL_DEBUG_RATE(priv, "enter\n");

- /* Send management frames and NO_ACK data using lowest rate. */
- fc = hdr->frame_control;
- if (!ieee80211_is_data(fc) || info->flags & IEEE80211_TX_CTL_NO_ACK ||
- !sta || !priv_sta) {
- IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n");
- info->control.rates[0].idx = rate_lowest_index(sband, sta);
- if (info->flags & IEEE80211_TX_CTL_NO_ACK)
- info->control.rates[0].count = 1;
+ if (rate_control_send_low(sta, priv_sta, txrc))
return;
- }
+
+ rate_mask = sta->supp_rates[sband->band];

/* get user max rate if set */
max_rate_idx = txrc->max_rate_idx;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 3fea027..695a841 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -2481,13 +2481,8 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
}

/* Send management frames and NO_ACK data using lowest rate. */
- if (!ieee80211_is_data(hdr->frame_control) ||
- info->flags & IEEE80211_TX_CTL_NO_ACK || !sta || !lq_sta) {
- info->control.rates[0].idx = rate_lowest_index(sband, sta);
- if (info->flags & IEEE80211_TX_CTL_NO_ACK)
- info->control.rates[0].count = 1;
+ if (rate_control_send_low(sta, priv_r, txrc))
return;
- }

rate_idx = lq_sta->last_txrate_idx;

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 9559efa..cf04a74 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2087,6 +2087,29 @@ static inline int rate_supported(struct ieee80211_sta *sta,
return (sta == NULL || sta->supp_rates[band] & BIT(index));
}

+/**
+ * rate_control_send_low - helper for drivers for management/no-ack frames
+ *
+ * Rate control algorithms that agree to use the lowest rate to
+ * send management frames and NO_ACK data with the respective hw
+ * retries should use this in the beginning of their mac80211 get_rate
+ * callback. If true is returned the rate control can simply return.
+ * If false is returned we guarantee that sta and sta and priv_sta is
+ * not null.
+ *
+ * Rate control algorithms wishing to do more intelligent selection of
+ * rate for multicast/broadcast frames may choose to not use this.
+ *
+ * @sta: &struct ieee80211_sta pointer to the target destination. Note
+ * that this may be null.
+ * @priv_sta: private rate control structure. This may be null.
+ * @txrc: rate control information we sholud populate for mac80211.
+ */
+bool rate_control_send_low(struct ieee80211_sta *sta,
+ void *priv_sta,
+ struct ieee80211_tx_rate_control *txrc);
+
+
static inline s8
rate_lowest_index(struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta)
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 4641f00..8ac7a98 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -198,6 +198,35 @@ static void rate_control_release(struct kref *kref)
kfree(ctrl_ref);
}

+static bool rc_no_data_or_no_ack(struct ieee80211_tx_rate_control *txrc)
+{
+ struct sk_buff *skb = txrc->skb;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ __le16 fc;
+
+ fc = hdr->frame_control;
+
+ return ((info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc));
+}
+
+bool rate_control_send_low(struct ieee80211_sta *sta,
+ void *priv_sta,
+ struct ieee80211_tx_rate_control *txrc)
+{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
+
+ if (!sta || !priv_sta || rc_no_data_or_no_ack(txrc)) {
+ info->control.rates[0].idx = rate_lowest_index(txrc->sband, sta);
+ info->control.rates[0].count =
+ (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
+ 1 : txrc->hw->max_rate_tries;
+ return true;
+ }
+ return false;
+}
+EXPORT_SYMBOL(rate_control_send_low);
+
void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
struct sta_info *sta,
struct ieee80211_tx_rate_control *txrc)
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index f5ccb89..eb93c00 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -70,19 +70,6 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix)
return i;
}

-static inline bool
-use_low_rate(struct sk_buff *skb)
-{
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- __le16 fc;
-
- fc = hdr->frame_control;
-
- return ((info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc));
-}
-
-
static void
minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
{
@@ -228,7 +215,6 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
void *priv_sta, struct ieee80211_tx_rate_control *txrc)
{
struct sk_buff *skb = txrc->skb;
- struct ieee80211_supported_band *sband = txrc->sband;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct minstrel_sta_info *mi = priv_sta;
struct minstrel_priv *mp = priv;
@@ -241,14 +227,8 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
int mrr_ndx[3];
int sample_rate;

- if (!sta || !mi || use_low_rate(skb)) {
- ar[0].idx = rate_lowest_index(sband, sta);
- if (info->flags & IEEE80211_TX_CTL_NO_ACK)
- ar[0].count = 1;
- else
- ar[0].count = mp->max_retry;
+ if (rate_control_send_low(sta, priv_sta, txrc))
return;
- }

mrr = mp->has_mrr && !txrc->rts && !txrc->bss_conf->use_cts_prot;

diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index 5496077..8c053be 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -276,11 +276,9 @@ rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta,
{
struct sk_buff *skb = txrc->skb;
struct ieee80211_supported_band *sband = txrc->sband;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct rc_pid_sta_info *spinfo = priv_sta;
int rateidx;
- __le16 fc;

if (txrc->rts)
info->control.rates[0].count =
@@ -290,15 +288,8 @@ rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta,
txrc->hw->conf.short_frame_max_tx_count;

/* Send management frames and NO_ACK data using lowest rate. */
- fc = hdr->frame_control;
- if (!sta || !spinfo || !ieee80211_is_data(fc) ||
- info->flags & IEEE80211_TX_CTL_NO_ACK) {
- info->control.rates[0].idx = rate_lowest_index(sband, sta);
- if (info->flags & IEEE80211_TX_CTL_NO_ACK)
- info->control.rates[0].count = 1;
-
+ if (rate_control_send_low(sta, priv_sta, txrc))
return;
- }

rateidx = spinfo->txrate_idx;

--
1.6.0.6


2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 10/18] ath9k: remove unused ath_rc_isvalid_txmask()

Cc: Derek Smithies <[email protected]>
Cc: Chittajit Mitra <[email protected]>
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath/ath9k/rc.c | 7 -------
1 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index c8f800e..b0e3702 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -454,13 +454,6 @@ static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv,
ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0;
}

-static inline int ath_rc_isvalid_txmask(struct ath_rate_priv *ath_rc_priv,
- u8 index)
-{
- ASSERT(index <= ath_rc_priv->rate_table_size);
- return ath_rc_priv->valid_rate_index[index];
-}
-
static inline
int ath_rc_get_nextvalid_txrate(const struct ath_rate_table *rate_table,
struct ath_rate_priv *ath_rc_priv,
--
1.6.0.6


2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 11/18] ath9k: remove ATH9K_MODE_11B

This saves us 2733 bytes.

text data bss dec hex filename
252265 3628 1584 257477 3edc5 ath9k-has-b-rate.ko
249905 3628 1584 255117 3e48d ath9k.ko

Cc: Derek Smithies <[email protected]>
Cc: Chittajit Mitra <[email protected]>
Siged-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath/ath9k/hw.c | 1 -
drivers/net/wireless/ath/ath9k/hw.h | 1 -
drivers/net/wireless/ath/ath9k/rc.c | 23 -----------------------
3 files changed, 0 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 1579c94..de2c000 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -3294,7 +3294,6 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
}

if (eeval & AR5416_OPFLAGS_11G) {
- set_bit(ATH9K_MODE_11B, pCap->wireless_modes);
set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
if (ah->config.ht_enable) {
if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index dd8508e..73d859e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -113,7 +113,6 @@

enum wireless_mode {
ATH9K_MODE_11A = 0,
- ATH9K_MODE_11B = 2,
ATH9K_MODE_11G = 3,
ATH9K_MODE_11NA_HT20 = 6,
ATH9K_MODE_11NG_HT20 = 7,
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index b0e3702..112a0ec 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -380,27 +380,6 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
0, /* Phy rates allowed initially */
};

-static const struct ath_rate_table ar5416_11b_ratetable = {
- 4,
- {
- { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
- 900, 0x1b, 0x00, (0x80|2),
- 0, 0, 1, 0, 0 },
- { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
- 1800, 0x1a, 0x04, (0x80|4),
- 1, 1, 1, 1, 0 },
- { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
- 4300, 0x19, 0x04, (0x80|11),
- 1, 2, 2, 2, 0 },
- { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
- 7100, 0x18, 0x04, (0x80|22),
- 1, 4, 100, 3, 0 },
- },
- 100, /* probe interval */
- 100, /* rssi reduce interval */
- 0, /* Phy rates allowed initially */
-};
-
static inline int8_t median(int8_t a, int8_t b, int8_t c)
{
if (a >= b) {
@@ -1702,8 +1681,6 @@ static struct rate_control_ops ath_rate_ops = {

void ath_rate_attach(struct ath_softc *sc)
{
- sc->hw_rate_table[ATH9K_MODE_11B] =
- &ar5416_11b_ratetable;
sc->hw_rate_table[ATH9K_MODE_11A] =
&ar5416_11a_ratetable;
sc->hw_rate_table[ATH9K_MODE_11G] =
--
1.6.0.6


2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 12/18] ath9k: remap ATH9K_MODE_*

There are a lot of gaps here.

Cc: Derek Smithies <[email protected]>
Cc: Chittajit Mitra <[email protected]>
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath/ath9k/hw.h | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 73d859e..08eb5ae 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -113,14 +113,14 @@

enum wireless_mode {
ATH9K_MODE_11A = 0,
- ATH9K_MODE_11G = 3,
- ATH9K_MODE_11NA_HT20 = 6,
- ATH9K_MODE_11NG_HT20 = 7,
- ATH9K_MODE_11NA_HT40PLUS = 8,
- ATH9K_MODE_11NA_HT40MINUS = 9,
- ATH9K_MODE_11NG_HT40PLUS = 10,
- ATH9K_MODE_11NG_HT40MINUS = 11,
- ATH9K_MODE_MAX
+ ATH9K_MODE_11G,
+ ATH9K_MODE_11NA_HT20,
+ ATH9K_MODE_11NG_HT20,
+ ATH9K_MODE_11NA_HT40PLUS,
+ ATH9K_MODE_11NA_HT40MINUS,
+ ATH9K_MODE_11NG_HT40PLUS,
+ ATH9K_MODE_11NG_HT40MINUS,
+ ATH9K_MODE_MAX,
};

enum ath9k_hw_caps {
--
1.6.0.6


2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 18/18] ath9k: remove rate control wraper

After the cleanup we just use get_rate as a wrapper, skip
the wrapper.

Cc: Derek Smithies <[email protected]>
Cc: Chittajit Mitra <[email protected]>
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath/ath9k/rc.c | 23 +++++++----------------
1 files changed, 7 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 630fcf4..e66734c 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -786,10 +786,11 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
tx_info->control.rts_cts_rate_idx = cix;
}

-static void ath_rc_ratefind(struct ath_softc *sc,
- struct ath_rate_priv *ath_rc_priv,
- struct ieee80211_tx_rate_control *txrc)
+static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
+ struct ieee80211_tx_rate_control *txrc)
{
+ struct ath_softc *sc = priv;
+ struct ath_rate_priv *ath_rc_priv = priv_sta;
const struct ath_rate_table *rate_table;
struct sk_buff *skb = txrc->skb;
struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
@@ -799,6 +800,9 @@ static void ath_rc_ratefind(struct ath_softc *sc,
u8 try_per_rate, i = 0, rix, nrix;
int is_probe = 0;

+ if (rate_control_send_low(sta, priv_sta, txrc))
+ return;
+
/*
* For Multi Rate Retry we use a different number of
* retry attempt counts. This ends up looking like this:
@@ -1515,19 +1519,6 @@ exit:
kfree(tx_info_priv);
}

-static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
- struct ieee80211_tx_rate_control *txrc)
-{
- struct ath_softc *sc = priv;
- struct ath_rate_priv *ath_rc_priv = priv_sta;
-
- if (rate_control_send_low(sta, priv_sta, txrc))
- return;
-
- /* Find tx rate for unicast frames */
- ath_rc_ratefind(sc, ath_rc_priv, txrc);
-}
-
static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta)
{
--
1.6.0.6


2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 01/18] mac80211: disable moving between PS modes during scan

We don't want to trigger moving between PS mode during
scan. With this enabled we sometimes end up sending nullfunc
frames during scan. We're supposed to only send one prior to
scan and after scan.

This fixes an oops which occured due to an assert in ath9k:

http://marc.info/?l=linux-wireless&m=124277331319024

The assert was happening because the rate control algorithm
figures it should find at least one valid dual stream or
single stream rate. Since we allow mac80211 to send nullfunc
frames during scan and dynamic PS was enabled at times we ended
up trying to send nullfunc frames for the target sta on the
wrong band for which we have no valid rate to communicate with
it. This brakes the assumptions in rate control. We'll handle
this sanity check next, but this fix does prevent the
spurious nullfunc frames from actually being sent.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
net/mac80211/tx.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 1436f74..e43fbb9 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1415,7 +1415,8 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
}

if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
- local->hw.conf.dynamic_ps_timeout > 0) {
+ local->hw.conf.dynamic_ps_timeout > 0 &&
+ !local->sw_scanning && !local->hw_scanning) {
if (local->hw.conf.flags & IEEE80211_CONF_PS) {
ieee80211_stop_queues_by_reason(&local->hw,
IEEE80211_QUEUE_STOP_REASON_PS);
--
1.6.0.6


2009-06-10 12:53:25

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 01/18] mac80211: disable moving between PS modes during scan

On Wed, Jun 10, 2009 at 1:19 AM, Luis R.
Rodriguez<[email protected]> wrote:
> We don't want to trigger moving between PS mode during
> scan. With this enabled we sometimes end up sending nullfunc
> frames during scan. We're supposed to only send one prior to
> scan and after scan.
>
> This fixes an oops which occured due to an assert in ath9k:
>
> http://marc.info/?l=linux-wireless&m=124277331319024
>
> The assert was happening because the rate control algorithm
> figures it should find at least one valid dual stream or
> single stream rate. Since we allow mac80211 to send nullfunc
> frames during scan and dynamic PS was enabled at times we ended
> up trying to send nullfunc frames for the target sta on the
> wrong band for which we have no valid rate to communicate with
> it. This brakes the assumptions in rate control. We'll handle
> this sanity check next, but this fix does prevent the
> spurious nullfunc frames from actually being sent.
>
> Signed-off-by: Luis R. Rodriguez <[email protected]>

John, please use v2, sorry but we noticed one missing issue with this patch.

Luis

2009-06-10 20:31:57

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 04/18] iwlwifi: remove rs_get_rate workaround

On Wed, Jun 10, 2009 at 12:08 PM, reinette
chatre<[email protected]> wrote:
> Hi Luis,
>
> On Wed, 2009-06-10 at 01:19 -0700, Luis R. Rodriguez wrote:
>> This removes the work around implemented for transmitting on
>> an unsupported band on iwlwifi. This was added via the patch:
>>
>> 8e1856e82cb8f541e925738bebfbc473420cda68:
>> iwlwifi: fix rs_get_rate WARN_ON()
>>
>> Cc: Mohamed Abbas <[email protected]>
>> Cc: Reinette Chatre <[email protected]>
>> Signed-off-by: Luis R. Rodriguez <[email protected]>
>> ---
>>  drivers/net/wireless/iwlwifi/iwl-3945-rs.c |   12 ++----------
>>  drivers/net/wireless/iwlwifi/iwl-agn-rs.c  |   11 +----------
>>  2 files changed, 3 insertions(+), 20 deletions(-)
>>
>> diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
>> index 5eb538d..b23fd53 100644
>> --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
>> +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
>> @@ -674,28 +674,20 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
>>       unsigned long flags;
>>       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
>>       u16 fc;
>> -     u16 rate_mask = 0;
>> +     u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0;
>>       s8 max_rate_idx = -1;
>>       struct iwl_priv *priv = (struct iwl_priv *)priv_r;
>>       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
>>
>>       IWL_DEBUG_RATE(priv, "enter\n");
>>
>> -     if (sta)
>> -             rate_mask = sta->supp_rates[sband->band];
>> -
>>       /* Send management frames and NO_ACK data using lowest rate. */
>>       fc = le16_to_cpu(hdr->frame_control);
>>       if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
>>           info->flags & IEEE80211_TX_CTL_NO_ACK ||
>>           !sta || !priv_sta) {
>>               IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n");
>> -             if (!rate_mask)
>> -                     info->control.rates[0].idx =
>> -                                     rate_lowest_index(sband, NULL);
>> -             else
>> -                     info->control.rates[0].idx =
>> -                                     rate_lowest_index(sband, sta);
>> +             info->control.rates[0].idx = rate_lowest_index(sband, sta);
>>               if (info->flags & IEEE80211_TX_CTL_NO_ACK)
>>                       info->control.rates[0].count = 1;
>>               return;
>> diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
>> index ff20e50..3fea027 100644
>> --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
>> +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
>> @@ -2466,7 +2466,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
>>       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
>>       struct iwl_lq_sta *lq_sta = priv_sta;
>>       int rate_idx;
>> -     u64 mask_bit = 0;
>>
>>       IWL_DEBUG_RATE_LIMIT(priv, "rate scale calculate new rate for skb\n");
>>
>> @@ -2481,18 +2480,10 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
>>                       lq_sta->max_rate_idx = -1;
>>       }
>>
>> -     if (sta)
>> -             mask_bit = sta->supp_rates[sband->band];
>> -
>>       /* Send management frames and NO_ACK data using lowest rate. */
>>       if (!ieee80211_is_data(hdr->frame_control) ||
>>           info->flags & IEEE80211_TX_CTL_NO_ACK || !sta || !lq_sta) {
>> -             if (!mask_bit)
>> -                     info->control.rates[0].idx =
>> -                                     rate_lowest_index(sband, NULL);
>> -             else
>> -                     info->control.rates[0].idx =
>> -                                     rate_lowest_index(sband, sta);
>> +             info->control.rates[0].idx = rate_lowest_index(sband, sta);
>>               if (info->flags & IEEE80211_TX_CTL_NO_ACK)
>>                       info->control.rates[0].count = 1;
>>               return;
>
>
> I applied patches 1, 2, and 4 from your series. After this I can again
> trigger the rs_get_rate warning.
>
> The steps I use are:
> $ ip link set wlan0 up
> $ iwlist wlan0 scan
> $ iwconfig wlan0 channel <from G band> essid essid
> $ #assign IP and ping to test association
> $ iwconfig wlan0 channel <from A band> essid essid
>
> The last command triggers the warning below (the warning that tainted
> the kernel is this same warning):
>
> [ 6447.873784] WARNING: at /home/wifi/iwlwifi-2.6/include/net/mac80211.h:2104 rs_get_rate+0x1e5/0x430 [iwlagn]()
> [ 6447.883695] Hardware name: Santa Rosa platform
> [ 6447.888179] Modules linked in: iwlagn iwlcore led_class mac80211 cfg80211 rfkill arc4 ecb i915 drm i2c_algo_bit i2c_core binf
> mt_misc ppdev acpi_cpufreq cpufreq_powersave cpufreq_conservative cpufreq_ondemand cpufreq_stats freq_table cpufreq_userspace sb
> s sbshc ipv6 iptable_filter ip_tables x_tables parport_pc lp parport psmouse serio_raw pcspkr battery iTCO_wdt iTCO_vendor_support video output container ac processor button intel_agp evdev ext3 jbd mbcache sg sr_mod cdrom sd_mod e100 mii ata_piix ehci_hcd uhci_hcd pata_acpi ata_generic libata usbcore scsi_mod thermal fan thermal_sys fuse [last unloaded: rfkill]
> [ 6447.943478] Pid: 9409, comm: iwconfig Tainted: G        W  2.6.30-rc8-wl #40
> [ 6447.950534] Call Trace:
> [ 6447.953005]  [<ffffffff8026bee9>] ? is_module_text_address+0x9/0x20
> [ 6447.959295]  [<ffffffffa055aad5>] ? rs_get_rate+0x1e5/0x430 [iwlagn]
> [ 6447.965662]  [<ffffffff80239c68>] warn_slowpath_common+0x78/0xd0
> [ 6447.971682]  [<ffffffff80239ccf>] warn_slowpath_null+0xf/0x20
> [ 6447.977451]  [<ffffffffa055aad5>] rs_get_rate+0x1e5/0x430 [iwlagn]
> [ 6447.983669]  [<ffffffffa04ed27e>] rate_control_get_rate+0xbe/0xd0 [mac80211]
> [ 6447.990745]  [<ffffffffa04f4a61>] invoke_tx_handlers+0x6b1/0xf70 [mac80211]
> [ 6447.997734]  [<ffffffffa04f3e8e>] ? __ieee80211_tx_prepare+0x1ae/0x3b0 [mac80211]
> [ 6448.005244]  [<ffffffffa04f5b75>] ieee80211_tx+0xf5/0x2f0 [mac80211]
> [ 6448.011628]  [<ffffffffa04f5b0d>] ? ieee80211_tx+0x8d/0x2f0 [mac80211]
> [ 6448.018224]  [<ffffffffa04f6b2a>] ieee80211_master_start_xmit+0x1fa/0x390 [mac80211]
> [ 6448.025974]  [<ffffffff80467d7d>] dev_hard_start_xmit+0x29d/0x340
> [ 6448.032129]  [<ffffffff8047aeb6>] __qdisc_run+0x256/0x2a0
> [ 6448.037574]  [<ffffffff80468268>] dev_queue_xmit+0x308/0x4e0
> [ 6448.043243]  [<ffffffff80467fb2>] ? dev_queue_xmit+0x52/0x4e0
> [ 6448.049059]  [<ffffffffa04f8897>] ieee80211_tx_skb+0x67/0x70 [mac80211]
> [ 6448.055751]  [<ffffffffa04e7803>] ieee80211_send_deauth_disassoc+0x113/0x160 [mac80211]
> [ 6448.063813]  [<ffffffffa04e7c20>] ieee80211_set_disassoc+0x290/0x370 [mac80211]
> [ 6448.071147]  [<ffffffffa04e7990>] ? ieee80211_set_disassoc+0x0/0x370 [mac80211]
> [ 6448.078518]  [<ffffffffa04e8037>] ieee80211_sta_req_auth+0xb7/0xe0 [mac80211]
> [ 6448.085726]  [<ffffffffa04e030b>] ieee80211_ioctl_siwessid+0xbb/0xd0 [mac80211]
> [ 6448.093086]  [<ffffffff804eaed4>] ioctl_standard_call+0x1f4/0x460
> [ 6448.099206]  [<ffffffffa04e0250>] ? ieee80211_ioctl_siwessid+0x0/0xd0 [mac80211]
> [ 6448.106643]  [<ffffffff804ea92b>] wext_handle_ioctl+0x16b/0x240
> [ 6448.112621]  [<ffffffff8046a2c2>] dev_ioctl+0x3f2/0x5e0
> [ 6448.117893]  [<ffffffff802a3432>] ? unlock_page+0x22/0x30
> [ 6448.123306]  [<ffffffff804553c9>] sock_ioctl+0x89/0x290
> [ 6448.128580]  [<ffffffff802e5441>] vfs_ioctl+0x31/0xa0
> [ 6448.133691]  [<ffffffff802e553a>] do_vfs_ioctl+0x8a/0x580
> [ 6448.139136]  [<ffffffff80256816>] ? up_read+0x26/0x30
> [ 6448.144198]  [<ffffffff802e5ac9>] sys_ioctl+0x99/0xa0
> [ 6448.149269]  [<ffffffff8020bdab>] system_call_fastpath+0x16/0x1b
> [ 6448.155317] ---[ end trace 487d6d48e50362db ]---

Please try the patch I just posted.

Luis

2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 08/18] ath9k: remove pointless wrapper ath_rc_rate_getidx()

This is just calling another helper, so just use the other
helper directly. This should make it clear that when do not
find the next rate we stick to the current one.

Cc: Derek Smithies <[email protected]>
Cc: Chittajit Mitra <[email protected]>
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath/ath9k/rc.c | 21 ++++-----------------
1 files changed, 4 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 64cb697..03e7df4 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -814,19 +814,6 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
tx_info->control.rts_cts_rate_idx = cix;
}

-static u8 ath_rc_rate_getidx(struct ath_softc *sc,
- struct ath_rate_priv *ath_rc_priv,
- const struct ath_rate_table *rate_table,
- u8 rix)
-{
- u8 nextindex = 0;
- if (ath_rc_get_nextlowervalid_txrate(rate_table,
- ath_rc_priv, rix, &nextindex))
- return nextindex;
- else
- return rix;
-}
-
static void ath_rc_ratefind(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
struct ieee80211_tx_rate_control *txrc)
@@ -865,8 +852,8 @@ static void ath_rc_ratefind(struct ath_softc *sc,
/* Get the next tried/allowed rate. No RTS for the next series
* after the probe rate
*/
- nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
- rate_table, nrix);
+ ath_rc_get_nextlowervalid_txrate(rate_table, ath_rc_priv,
+ rix, &nrix);
ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
try_per_rate, nrix, 0);

@@ -883,8 +870,8 @@ static void ath_rc_ratefind(struct ath_softc *sc,
if (i + 1 == 4)
try_per_rate = 4;

- nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
- rate_table, nrix);
+ ath_rc_get_nextlowervalid_txrate(rate_table, ath_rc_priv,
+ rix, &nrix);
/* All other rates in the series have RTS enabled */
ath_rc_rate_set_series(rate_table, &rates[i], txrc,
try_per_rate, nrix, 1);
--
1.6.0.6


2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 13/18] ath9k: rename ath_rc_ratefind_ht() to ath_rc_get_highest_rix()

The purpose is to find the highest rate we can use.

Cc: Derek Smithies <[email protected]>
Cc: Chittajit Mitra <[email protected]>
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath/ath9k/rc.c | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 112a0ec..96d46d6 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -601,10 +601,11 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
return hi;
}

-static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
- struct ath_rate_priv *ath_rc_priv,
- const struct ath_rate_table *rate_table,
- int *is_probing)
+/* Finds the highest rate index we can use */
+static u8 ath_rc_get_highest_rix(struct ath_softc *sc,
+ struct ath_rate_priv *ath_rc_priv,
+ const struct ath_rate_table *rate_table,
+ int *is_probing)
{
u32 dt, best_thruput, this_thruput, now_msec;
u8 rate, next_rate, best_rate, maxindex, minindex;
@@ -812,7 +813,7 @@ static void ath_rc_ratefind(struct ath_softc *sc,
try_per_rate = sc->hw->max_rate_tries;

rate_table = sc->cur_rate_table;
- rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, &is_probe);
+ rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
nrix = rix;

if (is_probe) {
--
1.6.0.6


2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 03/18] ath9k: downgrade assert in rc.c for invalid rate

The case where no vaid rate is found should not happen now
but to help debugging and downgrade this to a warn.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath/ath9k/rc.c | 16 ++++++++++++----
1 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index ba06e78..d7f4030 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -741,10 +741,18 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
if (rate > (ath_rc_priv->rate_table_size - 1))
rate = ath_rc_priv->rate_table_size - 1;

- ASSERT((rate_table->info[rate].valid &&
- (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) ||
- (rate_table->info[rate].valid_single_stream &&
- !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)));
+ if (rate_table->info[rate].valid &&
+ (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG))
+ return rate;
+
+ if (rate_table->info[rate].valid_single_stream &&
+ !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG));
+ return rate;
+
+ /* This should not happen */
+ WARN_ON(1);
+
+ rate = ath_rc_priv->valid_rate_index[0];

return rate;
}
--
1.6.0.6


2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 15/18] mac80211: make minstrel/pid RC use ieee80211_is_data(fc)

Cc: Felix Fietkau <[email protected]>
Cc: Derek Smithies <[email protected]>
Cc: Chittajit Mitra <[email protected]>
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
net/mac80211/rc80211_minstrel.c | 7 +++----
net/mac80211/rc80211_pid_algo.c | 7 +++----
2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index b218b98..f5ccb89 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -75,12 +75,11 @@ use_low_rate(struct sk_buff *skb)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- u16 fc;
+ __le16 fc;

- fc = le16_to_cpu(hdr->frame_control);
+ fc = hdr->frame_control;

- return ((info->flags & IEEE80211_TX_CTL_NO_ACK) ||
- (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA);
+ return ((info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc));
}


diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index a0bef76..5496077 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -280,7 +280,7 @@ rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta,
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct rc_pid_sta_info *spinfo = priv_sta;
int rateidx;
- u16 fc;
+ __le16 fc;

if (txrc->rts)
info->control.rates[0].count =
@@ -290,9 +290,8 @@ rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta,
txrc->hw->conf.short_frame_max_tx_count;

/* Send management frames and NO_ACK data using lowest rate. */
- fc = le16_to_cpu(hdr->frame_control);
- if (!sta || !spinfo ||
- (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
+ fc = hdr->frame_control;
+ if (!sta || !spinfo || !ieee80211_is_data(fc) ||
info->flags & IEEE80211_TX_CTL_NO_ACK) {
info->control.rates[0].idx = rate_lowest_index(sband, sta);
if (info->flags & IEEE80211_TX_CTL_NO_ACK)
--
1.6.0.6


2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 07/18] ath9k: remove unused stepdown when looking for the next rate

This is not used, remove this.

Cc: Derek Smithies <[email protected]>
Cc: Chittajit Mitra <[email protected]>
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath/ath9k/rc.c | 21 ++++++++-------------
1 files changed, 8 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 7b37b27..64cb697 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -817,19 +817,14 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
static u8 ath_rc_rate_getidx(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
const struct ath_rate_table *rate_table,
- u8 rix, u16 stepdown)
+ u8 rix)
{
- u32 j;
u8 nextindex = 0;
-
- for (j = stepdown; j > 0; j--) {
- if (ath_rc_get_nextlowervalid_txrate(rate_table,
- ath_rc_priv, rix, &nextindex))
- rix = nextindex;
- else
- break;
- }
- return rix;
+ if (ath_rc_get_nextlowervalid_txrate(rate_table,
+ ath_rc_priv, rix, &nextindex))
+ return nextindex;
+ else
+ return rix;
}

static void ath_rc_ratefind(struct ath_softc *sc,
@@ -871,7 +866,7 @@ static void ath_rc_ratefind(struct ath_softc *sc,
* after the probe rate
*/
nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
- rate_table, nrix, 1);
+ rate_table, nrix);
ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
try_per_rate, nrix, 0);

@@ -889,7 +884,7 @@ static void ath_rc_ratefind(struct ath_softc *sc,
try_per_rate = 4;

nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
- rate_table, nrix, 1);
+ rate_table, nrix);
/* All other rates in the series have RTS enabled */
ath_rc_rate_set_series(rate_table, &rates[i], txrc,
try_per_rate, nrix, 1);
--
1.6.0.6


2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 06/18] ath9k: remove unused min rate calculation code

This is not used, and when we need to get the lowest rate
we should simply use mac80211's own rate_lowest_index(sband, sta).

Cc: Derek Smithies <[email protected]>
Cc: Chittajit Mitra <[email protected]>
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath/ath9k/rc.c | 33 +++++++++------------------------
1 files changed, 9 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index a23b66b..7b37b27 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -817,28 +817,17 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
static u8 ath_rc_rate_getidx(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
const struct ath_rate_table *rate_table,
- u8 rix, u16 stepdown,
- u16 min_rate)
+ u8 rix, u16 stepdown)
{
u32 j;
u8 nextindex = 0;

- if (min_rate) {
- for (j = RATE_TABLE_SIZE; j > 0; j--) {
- if (ath_rc_get_nextlowervalid_txrate(rate_table,
- ath_rc_priv, rix, &nextindex))
- rix = nextindex;
- else
- break;
- }
- } else {
- for (j = stepdown; j > 0; j--) {
- if (ath_rc_get_nextlowervalid_txrate(rate_table,
- ath_rc_priv, rix, &nextindex))
- rix = nextindex;
- else
- break;
- }
+ for (j = stepdown; j > 0; j--) {
+ if (ath_rc_get_nextlowervalid_txrate(rate_table,
+ ath_rc_priv, rix, &nextindex))
+ rix = nextindex;
+ else
+ break;
}
return rix;
}
@@ -882,7 +871,7 @@ static void ath_rc_ratefind(struct ath_softc *sc,
* after the probe rate
*/
nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
- rate_table, nrix, 1, 0);
+ rate_table, nrix, 1);
ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
try_per_rate, nrix, 0);

@@ -895,16 +884,12 @@ static void ath_rc_ratefind(struct ath_softc *sc,

/* Fill in the other rates for multirate retry */
for ( ; i < 4; i++) {
- u8 min_rate;
-
/* Use twice the number of tries for the last MRR segment. */
if (i + 1 == 4)
try_per_rate = 4;

- min_rate = (((i + 1) == 4) && 0);
-
nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
- rate_table, nrix, 1, min_rate);
+ rate_table, nrix, 1);
/* All other rates in the series have RTS enabled */
ath_rc_rate_set_series(rate_table, &rates[i], txrc,
try_per_rate, nrix, 1);
--
1.6.0.6


2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 14/18] ath9k: remove unnecessary IEEE80211_TX_CTL_NO_ACK checks

We check for this condition early on in our mac80211 get_rate()
callback ath_get_rate(), so remove this check later down the path.

Cc: Derek Smithies <[email protected]>
Cc: Chittajit Mitra <[email protected]>
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath/ath9k/rc.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 96d46d6..2c72901 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -777,7 +777,6 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
* just CTS. Note that this is only done for OFDM/HT unicast frames.
*/
if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) &&
- !(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
(rate_table->info[rix].phy == WLAN_RC_PHY_OFDM ||
WLAN_RC_PHY_HT(rate_table->info[rix].phy))) {
rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
@@ -882,9 +881,8 @@ static void ath_rc_ratefind(struct ath_softc *sc,
*
* FIXME: Fix duration
*/
- if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
- (ieee80211_has_morefrags(fc) ||
- (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG))) {
+ if (ieee80211_has_morefrags(fc) ||
+ (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) {
rates[1].count = rates[2].count = rates[3].count = 0;
rates[1].idx = rates[2].idx = rates[3].idx = 0;
rates[0].count = ATH_TXMAXTRY;
--
1.6.0.6


2009-06-10 08:19:45

by Luis R. Rodriguez

[permalink] [raw]
Subject: [PATCH 09/18] ath9k: rename ath_rc_get_nextlowervalid_txrate()

What this does is get us our next lower rate so call it that,
ath_rc_get_lower_rix().

Cc: Derek Smithies <[email protected]>
Cc: Chittajit Mitra <[email protected]>
Signed-off-by: Luis R. Rodriguez <[email protected]>
---
drivers/net/wireless/ath/ath9k/rc.c | 16 +++++++---------
1 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 03e7df4..c8f800e 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -501,9 +501,9 @@ static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
}

static inline int
-ath_rc_get_nextlowervalid_txrate(const struct ath_rate_table *rate_table,
- struct ath_rate_priv *ath_rc_priv,
- u8 cur_valid_txrate, u8 *next_idx)
+ath_rc_get_lower_rix(const struct ath_rate_table *rate_table,
+ struct ath_rate_priv *ath_rc_priv,
+ u8 cur_valid_txrate, u8 *next_idx)
{
int8_t i;

@@ -852,8 +852,7 @@ static void ath_rc_ratefind(struct ath_softc *sc,
/* Get the next tried/allowed rate. No RTS for the next series
* after the probe rate
*/
- ath_rc_get_nextlowervalid_txrate(rate_table, ath_rc_priv,
- rix, &nrix);
+ ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
try_per_rate, nrix, 0);

@@ -870,8 +869,7 @@ static void ath_rc_ratefind(struct ath_softc *sc,
if (i + 1 == 4)
try_per_rate = 4;

- ath_rc_get_nextlowervalid_txrate(rate_table, ath_rc_priv,
- rix, &nrix);
+ ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
/* All other rates in the series have RTS enabled */
ath_rc_rate_set_series(rate_table, &rates[i], txrc,
try_per_rate, nrix, 1);
@@ -1156,8 +1154,8 @@ static void ath_rc_update_ht(struct ath_softc *sc,
if (ath_rc_priv->state[tx_rate].per >= 55 && tx_rate > 0 &&
rate_table->info[tx_rate].ratekbps <=
rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) {
- ath_rc_get_nextlowervalid_txrate(rate_table, ath_rc_priv,
- (u8)tx_rate, &ath_rc_priv->rate_max_phy);
+ ath_rc_get_lower_rix(rate_table, ath_rc_priv,
+ (u8)tx_rate, &ath_rc_priv->rate_max_phy);

/* Don't probe for a little while. */
ath_rc_priv->probe_time = now_msec;
--
1.6.0.6