1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2024-07-07 22:02:00 +03:00

mac80211: add rate control rewrite and enhance the performance of the minstrel algorithm for non-mrr configurations

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@12948 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
nbd 2008-10-11 01:33:09 +00:00
parent 042b8de61d
commit 090f16f6fb
22 changed files with 7636 additions and 129 deletions

View File

@ -1,31 +0,0 @@
This fixes tx status processing for drivers that do not support mrr.
If the retry count is bigger than the maximum retry count configured in
the hardware, do not count the rate attempt as successful, the hardware
has probably switched to a lower rate.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -171,6 +171,7 @@ minstrel_tx_status(void *priv, struct ie
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_altrate *ar = info->status.retries;
struct minstrel_priv *mp = priv;
+ struct ieee80211_local *local = hw_to_local(mp->hw);
int i, ndx, tries;
int success = 0;
@@ -180,6 +181,13 @@ minstrel_tx_status(void *priv, struct ie
if (!mp->has_mrr || (ar[0].rate_idx < 0)) {
ndx = rix_to_ndx(mi, info->tx_rate_idx);
tries = info->status.retry_count + 1;
+
+ /* If the driver does not support the MRR API, but uses
+ * a fallback rate, use the long retry limit as indication
+ * that a rate switch has happened */
+ if (!mp->has_mrr && (tries >= local->long_retry_limit))
+ success = 0;
+
mi->r[ndx].success += success;
mi->r[ndx].attempts += tries;
return;

View File

@ -1,98 +0,0 @@
Fix the b43 tx status reporting.
If the hardware uses RTS/CTS reporting and the actual RTS/CTS
handshake failed, it will switch to the fallback rate, even
though the main rate was never actually attempted.
Make sure that this does not screw up rate control statistics.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -778,6 +778,9 @@ struct b43_wldev {
#ifdef CONFIG_B43_DEBUG
struct b43_dfsentry *dfsentry;
#endif
+
+ /* necessary for figuring out the correct tx status */
+ int short_retry;
};
static inline struct b43_wl *hw_to_b43_wl(struct ieee80211_hw *hw)
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1393,7 +1393,7 @@ void b43_dma_handle_txstatus(struct b43_
* Call back to inform the ieee80211 subsystem about
* the status of the transmission.
*/
- frame_succeed = b43_fill_txstatus_report(info, status);
+ frame_succeed = b43_fill_txstatus_report(dev, info, status);
#ifdef CONFIG_B43_DEBUG
if (frame_succeed)
ring->nr_succeed_tx_packets++;
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3892,6 +3892,7 @@ static void b43_set_retry_limits(struct
short_retry);
b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_LRLIMIT,
long_retry);
+ dev->short_retry = short_retry;
}
static void b43_set_synth_pu_delay(struct b43_wldev *dev, bool idle)
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -589,7 +589,7 @@ void b43_pio_handle_txstatus(struct b43_
info = IEEE80211_SKB_CB(pack->skb);
memset(&info->status, 0, sizeof(info->status));
- b43_fill_txstatus_report(info, status);
+ b43_fill_txstatus_report(dev, info, status);
total_len = pack->skb->len + b43_txhdr_size(dev);
total_len = roundup(total_len, 4);
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -687,7 +687,8 @@ void b43_handle_txstatus(struct b43_wlde
/* Fill out the mac80211 TXstatus report based on the b43-specific
* txstatus report data. This returns a boolean whether the frame was
* successfully transmitted. */
-bool b43_fill_txstatus_report(struct ieee80211_tx_info *report,
+bool b43_fill_txstatus_report(struct b43_wldev *dev,
+ struct ieee80211_tx_info *report,
const struct b43_txstatus *status)
{
bool frame_success = 1;
@@ -706,8 +707,19 @@ bool b43_fill_txstatus_report(struct iee
if (status->frame_count == 0) {
/* The frame was not transmitted at all. */
report->status.retry_count = 0;
- } else
+ } else if (status->rts_count > dev->short_retry) {
+ /*
+ * If the short retries (RTS, not data frame) have exceeded
+ * the limit, the hw will not have tried the selected rate,
+ * but will have used the fallback rate instead.
+ * Don't let the rate control count attempts for the selected
+ * rate in this case, otherwise the statistics will be off.
+ */
+ report->tx_rate_idx = 0;
+ report->status.retry_count = 0;
+ } else {
report->status.retry_count = status->frame_count - 1;
+ }
return frame_success;
}
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -294,7 +294,8 @@ void b43_rx(struct b43_wldev *dev, struc
void b43_handle_txstatus(struct b43_wldev *dev,
const struct b43_txstatus *status);
-bool b43_fill_txstatus_report(struct ieee80211_tx_info *report,
+bool b43_fill_txstatus_report(struct b43_wldev *dev,
+ struct ieee80211_tx_info *report,
const struct b43_txstatus *status);
void b43_tx_suspend(struct b43_wldev *dev);

View File

@ -0,0 +1,68 @@
Subject: mac80211: fix debugfs lockup
When debugfs_create_dir fails, sta_info_debugfs_add_work will not
terminate because it will find the same station again and again.
This is possible whenever debugfs fails for whatever reason; one
reason is a race condition in mac80211, unfortunately we cannot
do much about it, so just document it, it just means some station
may be missing from debugfs.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Cc: Robin Holt <holt@sgi.com>
---
net/mac80211/debugfs_sta.c | 11 +++++++++++
net/mac80211/sta_info.c | 7 ++++++-
net/mac80211/sta_info.h | 1 +
3 files changed, 18 insertions(+), 1 deletion(-)
--- everything.orig/net/mac80211/debugfs_sta.c 2008-10-07 20:05:29.000000000 +0200
+++ everything/net/mac80211/debugfs_sta.c 2008-10-07 20:06:39.000000000 +0200
@@ -249,11 +249,22 @@ void ieee80211_sta_debugfs_add(struct st
DECLARE_MAC_BUF(mbuf);
u8 *mac;
+ sta->debugfs.add_has_run = true;
+
if (!stations_dir)
return;
mac = print_mac(mbuf, sta->sta.addr);
+ /*
+ * This might fail due to a race condition:
+ * When mac80211 unlinks a station, the debugfs entries
+ * remain, but it is already possible to link a new
+ * station with the same address which triggers adding
+ * it to debugfs; therefore, if the old station isn't
+ * destroyed quickly enough the old station's debugfs
+ * dir might still be around.
+ */
sta->debugfs.dir = debugfs_create_dir(mac, stations_dir);
if (!sta->debugfs.dir)
return;
--- everything.orig/net/mac80211/sta_info.c 2008-10-07 20:05:29.000000000 +0200
+++ everything/net/mac80211/sta_info.c 2008-10-07 20:06:39.000000000 +0200
@@ -635,7 +635,12 @@ static void sta_info_debugfs_add_work(st
spin_lock_irqsave(&local->sta_lock, flags);
list_for_each_entry(tmp, &local->sta_list, list) {
- if (!tmp->debugfs.dir) {
+ /*
+ * debugfs.add_has_run will be set by
+ * ieee80211_sta_debugfs_add regardless
+ * of what else it does.
+ */
+ if (!tmp->debugfs.add_has_run) {
sta = tmp;
__sta_info_pin(sta);
break;
--- everything.orig/net/mac80211/sta_info.h 2008-10-07 20:05:29.000000000 +0200
+++ everything/net/mac80211/sta_info.h 2008-10-07 20:06:39.000000000 +0200
@@ -300,6 +300,7 @@ struct sta_info {
struct dentry *inactive_ms;
struct dentry *last_seq_ctrl;
struct dentry *agg_status;
+ bool add_has_run;
} debugfs;
#endif

View File

@ -0,0 +1,98 @@
Subject: mac80211: remove aggregation status write support from debugfs
This code uses static variables and thus cannot be kept.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
net/mac80211/debugfs_sta.c | 73 ---------------------------------------------
1 file changed, 1 insertion(+), 72 deletions(-)
--- everything.orig/net/mac80211/debugfs_sta.c 2008-10-07 20:06:39.000000000 +0200
+++ everything/net/mac80211/debugfs_sta.c 2008-10-07 20:06:40.000000000 +0200
@@ -39,13 +39,6 @@ static const struct file_operations sta_
.open = mac80211_open_file_generic, \
}
-#define STA_OPS_WR(name) \
-static const struct file_operations sta_ ##name## _ops = { \
- .read = sta_##name##_read, \
- .write = sta_##name##_write, \
- .open = mac80211_open_file_generic, \
-}
-
#define STA_FILE(name, field, format) \
STA_READ_##format(name, field) \
STA_OPS(name)
@@ -168,71 +161,7 @@ static ssize_t sta_agg_status_read(struc
return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);
}
-
-static ssize_t sta_agg_status_write(struct file *file,
- const char __user *user_buf, size_t count, loff_t *ppos)
-{
- struct sta_info *sta = file->private_data;
- struct ieee80211_local *local = sta->sdata->local;
- struct ieee80211_hw *hw = &local->hw;
- u8 *da = sta->sta.addr;
- static int tid_static_tx[16] = {0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0};
- static int tid_static_rx[16] = {1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1};
- char *endp;
- char buf[32];
- int buf_size, rs;
- unsigned int tid_num;
- char state[4];
-
- memset(buf, 0x00, sizeof(buf));
- buf_size = min(count, (sizeof(buf)-1));
- if (copy_from_user(buf, user_buf, buf_size))
- return -EFAULT;
-
- tid_num = simple_strtoul(buf, &endp, 0);
- if (endp == buf)
- return -EINVAL;
-
- if ((tid_num >= 100) && (tid_num <= 115)) {
- /* toggle Rx aggregation command */
- tid_num = tid_num - 100;
- if (tid_static_rx[tid_num] == 1) {
- strcpy(state, "off ");
- ieee80211_sta_stop_rx_ba_session(sta->sdata, da, tid_num, 0,
- WLAN_REASON_QSTA_REQUIRE_SETUP);
- sta->ampdu_mlme.tid_state_rx[tid_num] |=
- HT_AGG_STATE_DEBUGFS_CTL;
- tid_static_rx[tid_num] = 0;
- } else {
- strcpy(state, "on ");
- sta->ampdu_mlme.tid_state_rx[tid_num] &=
- ~HT_AGG_STATE_DEBUGFS_CTL;
- tid_static_rx[tid_num] = 1;
- }
- printk(KERN_DEBUG "debugfs - try switching tid %u %s\n",
- tid_num, state);
- } else if ((tid_num >= 0) && (tid_num <= 15)) {
- /* toggle Tx aggregation command */
- if (tid_static_tx[tid_num] == 0) {
- strcpy(state, "on ");
- rs = ieee80211_start_tx_ba_session(hw, da, tid_num);
- if (rs == 0)
- tid_static_tx[tid_num] = 1;
- } else {
- strcpy(state, "off");
- rs = ieee80211_stop_tx_ba_session(hw, da, tid_num, 1);
- if (rs == 0)
- tid_static_tx[tid_num] = 0;
- }
- printk(KERN_DEBUG "debugfs - switching tid %u %s, return=%d\n",
- tid_num, state, rs);
- }
-
- return count;
-}
-STA_OPS_WR(agg_status);
+STA_OPS(agg_status);
#define DEBUGFS_ADD(name) \
sta->debugfs.name = debugfs_create_file(#name, 0400, \

View File

@ -0,0 +1,155 @@
Subject: mac80211: remove writable debugs mesh parameters
These parameters shouldn't be configurable via debugfs, if they
need to be configurable nl80211 support has to be added, if not
then they don't need to be writable here either.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Cc: Javier Cardona <javier@cozybit.com>
Cc: Luis Carlos Cobo <luisca@cozybit.com>
---
net/mac80211/debugfs_netdev.c | 112 +++++++++---------------------------------
1 file changed, 24 insertions(+), 88 deletions(-)
--- everything.orig/net/mac80211/debugfs_netdev.c 2008-10-07 20:05:28.000000000 +0200
+++ everything/net/mac80211/debugfs_netdev.c 2008-10-07 20:06:40.000000000 +0200
@@ -41,29 +41,6 @@ static ssize_t ieee80211_if_read(
return ret;
}
-#ifdef CONFIG_MAC80211_MESH
-static ssize_t ieee80211_if_write(
- struct ieee80211_sub_if_data *sdata,
- char const __user *userbuf,
- size_t count, loff_t *ppos,
- int (*format)(struct ieee80211_sub_if_data *, char *))
-{
- char buf[10];
- int buf_size;
-
- memset(buf, 0x00, sizeof(buf));
- buf_size = min(count, (sizeof(buf)-1));
- if (copy_from_user(buf, userbuf, buf_size))
- return count;
- read_lock(&dev_base_lock);
- if (sdata->dev->reg_state == NETREG_REGISTERED)
- (*format)(sdata, buf);
- read_unlock(&dev_base_lock);
-
- return count;
-}
-#endif
-
#define IEEE80211_IF_FMT(name, field, format_string) \
static ssize_t ieee80211_if_fmt_##name( \
const struct ieee80211_sub_if_data *sdata, char *buf, \
@@ -71,19 +48,6 @@ static ssize_t ieee80211_if_fmt_##name(
{ \
return scnprintf(buf, buflen, format_string, sdata->field); \
}
-#define IEEE80211_IF_WFMT(name, field, type) \
-static int ieee80211_if_wfmt_##name( \
- struct ieee80211_sub_if_data *sdata, char *buf) \
-{ \
- unsigned long tmp; \
- char *endp; \
- \
- tmp = simple_strtoul(buf, &endp, 0); \
- if ((endp == buf) || ((type)tmp != tmp)) \
- return -EINVAL; \
- sdata->field = tmp; \
- return 0; \
-}
#define IEEE80211_IF_FMT_DEC(name, field) \
IEEE80211_IF_FMT(name, field, "%d\n")
#define IEEE80211_IF_FMT_HEX(name, field) \
@@ -126,34 +90,6 @@ static const struct file_operations name
IEEE80211_IF_FMT_##format(name, field) \
__IEEE80211_IF_FILE(name)
-#define __IEEE80211_IF_WFILE(name) \
-static ssize_t ieee80211_if_read_##name(struct file *file, \
- char __user *userbuf, \
- size_t count, loff_t *ppos) \
-{ \
- return ieee80211_if_read(file->private_data, \
- userbuf, count, ppos, \
- ieee80211_if_fmt_##name); \
-} \
-static ssize_t ieee80211_if_write_##name(struct file *file, \
- const char __user *userbuf, \
- size_t count, loff_t *ppos) \
-{ \
- return ieee80211_if_write(file->private_data, \
- userbuf, count, ppos, \
- ieee80211_if_wfmt_##name); \
-} \
-static const struct file_operations name##_ops = { \
- .read = ieee80211_if_read_##name, \
- .write = ieee80211_if_write_##name, \
- .open = mac80211_open_file_generic, \
-}
-
-#define IEEE80211_IF_WFILE(name, field, format, type) \
- IEEE80211_IF_FMT_##format(name, field) \
- IEEE80211_IF_WFMT(name, field, type) \
- __IEEE80211_IF_WFILE(name)
-
/* common attributes */
IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC);
IEEE80211_IF_FILE(force_unicast_rateidx, force_unicast_rateidx, DEC);
@@ -212,30 +148,30 @@ IEEE80211_IF_FILE(dropped_frames_no_rout
IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC);
/* Mesh parameters */
-IEEE80211_IF_WFILE(dot11MeshMaxRetries,
- u.mesh.mshcfg.dot11MeshMaxRetries, DEC, u8);
-IEEE80211_IF_WFILE(dot11MeshRetryTimeout,
- u.mesh.mshcfg.dot11MeshRetryTimeout, DEC, u16);
-IEEE80211_IF_WFILE(dot11MeshConfirmTimeout,
- u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC, u16);
-IEEE80211_IF_WFILE(dot11MeshHoldingTimeout,
- u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC, u16);
-IEEE80211_IF_WFILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC, u8);
-IEEE80211_IF_WFILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC, u8);
-IEEE80211_IF_WFILE(dot11MeshMaxPeerLinks,
- u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC, u16);
-IEEE80211_IF_WFILE(dot11MeshHWMPactivePathTimeout,
- u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC, u32);
-IEEE80211_IF_WFILE(dot11MeshHWMPpreqMinInterval,
- u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC, u16);
-IEEE80211_IF_WFILE(dot11MeshHWMPnetDiameterTraversalTime,
- u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC, u16);
-IEEE80211_IF_WFILE(dot11MeshHWMPmaxPREQretries,
- u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC, u8);
-IEEE80211_IF_WFILE(path_refresh_time,
- u.mesh.mshcfg.path_refresh_time, DEC, u32);
-IEEE80211_IF_WFILE(min_discovery_timeout,
- u.mesh.mshcfg.min_discovery_timeout, DEC, u16);
+IEEE80211_IF_FILE(dot11MeshMaxRetries,
+ u.mesh.mshcfg.dot11MeshMaxRetries, DEC);
+IEEE80211_IF_FILE(dot11MeshRetryTimeout,
+ u.mesh.mshcfg.dot11MeshRetryTimeout, DEC);
+IEEE80211_IF_FILE(dot11MeshConfirmTimeout,
+ u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC);
+IEEE80211_IF_FILE(dot11MeshHoldingTimeout,
+ u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC);
+IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC);
+IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC);
+IEEE80211_IF_FILE(dot11MeshMaxPeerLinks,
+ u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC);
+IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout,
+ u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC);
+IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval,
+ u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC);
+IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime,
+ u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC);
+IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries,
+ u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC);
+IEEE80211_IF_FILE(path_refresh_time,
+ u.mesh.mshcfg.path_refresh_time, DEC);
+IEEE80211_IF_FILE(min_discovery_timeout,
+ u.mesh.mshcfg.min_discovery_timeout, DEC);
#endif

View File

@ -0,0 +1,364 @@
Subject: mac80211: minor code cleanups
Nothing very interesting, some checkpatch inspired stuff,
some other things.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
net/mac80211/debugfs_sta.c | 6 +++---
net/mac80211/main.c | 2 +-
net/mac80211/mesh.c | 2 +-
net/mac80211/rc80211_pid.h | 2 +-
net/mac80211/rx.c | 24 +++++++++++++-----------
net/mac80211/sta_info.c | 4 ++--
net/mac80211/wep.c | 26 +++++++++++++-------------
net/mac80211/wep.h | 2 +-
net/mac80211/wpa.c | 29 ++++++++++-------------------
9 files changed, 45 insertions(+), 52 deletions(-)
--- everything.orig/net/mac80211/wep.c 2008-10-07 20:05:49.000000000 +0200
+++ everything/net/mac80211/wep.c 2008-10-07 20:06:41.000000000 +0200
@@ -49,17 +49,19 @@ void ieee80211_wep_free(struct ieee80211
crypto_free_blkcipher(local->wep_rx_tfm);
}
-static inline int ieee80211_wep_weak_iv(u32 iv, int keylen)
+static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen)
{
- /* Fluhrer, Mantin, and Shamir have reported weaknesses in the
+ /*
+ * Fluhrer, Mantin, and Shamir have reported weaknesses in the
* key scheduling algorithm of RC4. At least IVs (KeyByte + 3,
- * 0xff, N) can be used to speedup attacks, so avoid using them. */
+ * 0xff, N) can be used to speedup attacks, so avoid using them.
+ */
if ((iv & 0xff00) == 0xff00) {
u8 B = (iv >> 16) & 0xff;
if (B >= 3 && B < 3 + keylen)
- return 1;
+ return true;
}
- return 0;
+ return false;
}
@@ -268,7 +270,7 @@ int ieee80211_wep_decrypt(struct ieee802
}
-u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key)
+bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
unsigned int hdrlen;
@@ -276,16 +278,13 @@ u8 * ieee80211_wep_is_weak_iv(struct sk_
u32 iv;
if (!ieee80211_has_protected(hdr->frame_control))
- return NULL;
+ return false;
hdrlen = ieee80211_hdrlen(hdr->frame_control);
ivpos = skb->data + hdrlen;
iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2];
- if (ieee80211_wep_weak_iv(iv, key->conf.keylen))
- return ivpos;
-
- return NULL;
+ return ieee80211_wep_weak_iv(iv, key->conf.keylen);
}
ieee80211_rx_result
@@ -329,6 +328,8 @@ static int wep_encrypt_skb(struct ieee80
ieee80211_tx_result
ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx)
{
+ int i;
+
ieee80211_tx_set_protected(tx);
if (wep_encrypt_skb(tx, tx->skb) < 0) {
@@ -337,9 +338,8 @@ ieee80211_crypto_wep_encrypt(struct ieee
}
if (tx->extra_frag) {
- int i;
for (i = 0; i < tx->num_extra_frag; i++) {
- if (wep_encrypt_skb(tx, tx->extra_frag[i]) < 0) {
+ if (wep_encrypt_skb(tx, tx->extra_frag[i])) {
I802_DEBUG_INC(tx->local->
tx_handlers_drop_wep);
return TX_DROP;
--- everything.orig/net/mac80211/wep.h 2008-10-07 20:05:28.000000000 +0200
+++ everything/net/mac80211/wep.h 2008-10-07 20:06:41.000000000 +0200
@@ -26,7 +26,7 @@ int ieee80211_wep_encrypt(struct ieee802
struct ieee80211_key *key);
int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
struct ieee80211_key *key);
-u8 *ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
+bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
ieee80211_rx_result
ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx);
--- everything.orig/net/mac80211/wpa.c 2008-10-07 20:05:49.000000000 +0200
+++ everything/net/mac80211/wpa.c 2008-10-07 20:06:41.000000000 +0200
@@ -49,8 +49,7 @@ ieee80211_tx_h_michael_mic_add(struct ie
!(tx->flags & IEEE80211_TX_FRAGMENTED) &&
!(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) &&
!wpa_test) {
- /* hwaccel - with no need for preallocated room for Michael MIC
- */
+ /* hwaccel - with no need for preallocated room for MMIC */
return TX_CONTINUE;
}
@@ -67,8 +66,6 @@ ieee80211_tx_h_michael_mic_add(struct ie
#else
authenticator = 1;
#endif
- /* At this point we know we're using ALG_TKIP. To get the MIC key
- * we now will rely on the offset from the ieee80211_key_conf::key */
key_offset = authenticator ?
NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY :
NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
@@ -92,9 +89,7 @@ ieee80211_rx_h_michael_mic_verify(struct
int authenticator = 1, wpa_test = 0;
DECLARE_MAC_BUF(mac);
- /*
- * No way to verify the MIC if the hardware stripped it
- */
+ /* No way to verify the MIC if the hardware stripped it */
if (rx->status->flag & RX_FLAG_MMIC_STRIPPED)
return RX_CONTINUE;
@@ -116,8 +111,6 @@ ieee80211_rx_h_michael_mic_verify(struct
#else
authenticator = 1;
#endif
- /* At this point we know we're using ALG_TKIP. To get the MIC key
- * we now will rely on the offset from the ieee80211_key_conf::key */
key_offset = authenticator ?
NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY :
NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
@@ -202,6 +195,7 @@ ieee80211_tx_result
ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx)
{
struct sk_buff *skb = tx->skb;
+ int i;
ieee80211_tx_set_protected(tx);
@@ -209,9 +203,8 @@ ieee80211_crypto_tkip_encrypt(struct iee
return TX_DROP;
if (tx->extra_frag) {
- int i;
for (i = 0; i < tx->num_extra_frag; i++) {
- if (tkip_encrypt_skb(tx, tx->extra_frag[i]) < 0)
+ if (tkip_encrypt_skb(tx, tx->extra_frag[i]))
return TX_DROP;
}
}
@@ -350,7 +343,7 @@ static inline void ccmp_pn2hdr(u8 *hdr,
}
-static inline int ccmp_hdr2pn(u8 *pn, u8 *hdr)
+static inline void ccmp_hdr2pn(u8 *pn, u8 *hdr)
{
pn[0] = hdr[7];
pn[1] = hdr[6];
@@ -358,7 +351,6 @@ static inline int ccmp_hdr2pn(u8 *pn, u8
pn[3] = hdr[4];
pn[4] = hdr[1];
pn[5] = hdr[0];
- return (hdr[3] >> 6) & 0x03;
}
@@ -373,7 +365,7 @@ static int ccmp_encrypt_skb(struct ieee8
if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
!(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
- /* hwaccel - with no need for preallocated room for CCMP "
+ /* hwaccel - with no need for preallocated room for CCMP
* header or MIC fields */
info->control.hw_key = &tx->key->conf;
return 0;
@@ -426,6 +418,7 @@ ieee80211_tx_result
ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx)
{
struct sk_buff *skb = tx->skb;
+ int i;
ieee80211_tx_set_protected(tx);
@@ -433,9 +426,8 @@ ieee80211_crypto_ccmp_encrypt(struct iee
return TX_DROP;
if (tx->extra_frag) {
- int i;
for (i = 0; i < tx->num_extra_frag; i++) {
- if (ccmp_encrypt_skb(tx, tx->extra_frag[i]) < 0)
+ if (ccmp_encrypt_skb(tx, tx->extra_frag[i]))
return TX_DROP;
}
}
@@ -468,7 +460,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
(rx->status->flag & RX_FLAG_IV_STRIPPED))
return RX_CONTINUE;
- (void) ccmp_hdr2pn(pn, skb->data + hdrlen);
+ ccmp_hdr2pn(pn, skb->data + hdrlen);
if (memcmp(pn, key->u.ccmp.rx_pn[rx->queue], CCMP_PN_LEN) <= 0) {
key->u.ccmp.replays++;
@@ -483,9 +475,8 @@ ieee80211_crypto_ccmp_decrypt(struct iee
key->u.ccmp.tfm, key->u.ccmp.rx_crypto_buf,
skb->data + hdrlen + CCMP_HDR_LEN, data_len,
skb->data + skb->len - CCMP_MIC_LEN,
- skb->data + hdrlen + CCMP_HDR_LEN)) {
+ skb->data + hdrlen + CCMP_HDR_LEN))
return RX_DROP_UNUSABLE;
- }
}
memcpy(key->u.ccmp.rx_pn[rx->queue], pn, CCMP_PN_LEN);
--- everything.orig/net/mac80211/debugfs_sta.c 2008-10-07 20:06:40.000000000 +0200
+++ everything/net/mac80211/debugfs_sta.c 2008-10-07 20:06:41.000000000 +0200
@@ -137,7 +137,7 @@ static ssize_t sta_agg_status_read(struc
p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:");
for (i = 0; i < STA_TID_NUM; i++)
p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
- sta->ampdu_mlme.tid_state_rx[i]?
+ sta->ampdu_mlme.tid_state_rx[i] ?
sta->ampdu_mlme.tid_rx[i]->dialog_token : 0);
p += scnprintf(p, sizeof(buf)+buf-p, "\n TX :");
@@ -148,13 +148,13 @@ static ssize_t sta_agg_status_read(struc
p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:");
for (i = 0; i < STA_TID_NUM; i++)
p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
- sta->ampdu_mlme.tid_state_tx[i]?
+ sta->ampdu_mlme.tid_state_tx[i] ?
sta->ampdu_mlme.tid_tx[i]->dialog_token : 0);
p += scnprintf(p, sizeof(buf)+buf-p, "\n SSN :");
for (i = 0; i < STA_TID_NUM; i++)
p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
- sta->ampdu_mlme.tid_state_tx[i]?
+ sta->ampdu_mlme.tid_state_tx[i] ?
sta->ampdu_mlme.tid_tx[i]->ssn : 0);
p += scnprintf(p, sizeof(buf)+buf-p, "\n");
--- everything.orig/net/mac80211/main.c 2008-10-07 20:05:49.000000000 +0200
+++ everything/net/mac80211/main.c 2008-10-07 20:06:41.000000000 +0200
@@ -1013,7 +1013,7 @@ static int __init ieee80211_init(void)
BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb));
BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) +
- IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb));
+ IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb));
ret = rc80211_minstrel_init();
if (ret)
--- everything.orig/net/mac80211/mesh.c 2008-10-07 20:05:28.000000000 +0200
+++ everything/net/mac80211/mesh.c 2008-10-07 20:06:41.000000000 +0200
@@ -473,7 +473,7 @@ static void ieee80211_mesh_rx_bcn_presp(
size_t len,
struct ieee80211_rx_status *rx_status)
{
- struct ieee80211_local *local= sdata->local;
+ struct ieee80211_local *local = sdata->local;
struct ieee802_11_elems elems;
struct ieee80211_channel *channel;
u64 supp_rates = 0;
--- everything.orig/net/mac80211/rc80211_pid.h 2008-10-07 20:05:28.000000000 +0200
+++ everything/net/mac80211/rc80211_pid.h 2008-10-07 20:06:41.000000000 +0200
@@ -49,7 +49,7 @@
/* Arithmetic right shift for positive and negative values for ISO C. */
#define RC_PID_DO_ARITH_RIGHT_SHIFT(x, y) \
- (x) < 0 ? -((-(x)) >> (y)) : (x) >> (y)
+ ((x) < 0 ? -((-(x)) >> (y)) : (x) >> (y))
enum rc_pid_event_type {
RC_PID_EVENT_TYPE_TX_STATUS,
--- everything.orig/net/mac80211/rx.c 2008-10-07 20:06:38.000000000 +0200
+++ everything/net/mac80211/rx.c 2008-10-07 20:06:41.000000000 +0200
@@ -26,10 +26,11 @@
#include "tkip.h"
#include "wme.h"
-u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
- struct tid_ampdu_rx *tid_agg_rx,
- struct sk_buff *skb, u16 mpdu_seq_num,
- int bar_req);
+static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
+ struct tid_ampdu_rx *tid_agg_rx,
+ struct sk_buff *skb,
+ u16 mpdu_seq_num,
+ int bar_req);
/*
* monitor mode reception
*
@@ -2000,17 +2001,17 @@ static void __ieee80211_rx_handle_packet
static inline int seq_less(u16 sq1, u16 sq2)
{
- return (((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1));
+ return ((sq1 - sq2) & SEQ_MASK) > (SEQ_MODULO >> 1);
}
static inline u16 seq_inc(u16 sq)
{
- return ((sq + 1) & SEQ_MASK);
+ return (sq + 1) & SEQ_MASK;
}
static inline u16 seq_sub(u16 sq1, u16 sq2)
{
- return ((sq1 - sq2) & SEQ_MASK);
+ return (sq1 - sq2) & SEQ_MASK;
}
@@ -2018,10 +2019,11 @@ static inline u16 seq_sub(u16 sq1, u16 s
* As it function blongs to Rx path it must be called with
* the proper rcu_read_lock protection for its flow.
*/
-u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
- struct tid_ampdu_rx *tid_agg_rx,
- struct sk_buff *skb, u16 mpdu_seq_num,
- int bar_req)
+static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
+ struct tid_ampdu_rx *tid_agg_rx,
+ struct sk_buff *skb,
+ u16 mpdu_seq_num,
+ int bar_req)
{
struct ieee80211_local *local = hw_to_local(hw);
struct ieee80211_rx_status status;
--- everything.orig/net/mac80211/sta_info.c 2008-10-07 20:06:39.000000000 +0200
+++ everything/net/mac80211/sta_info.c 2008-10-07 20:06:41.000000000 +0200
@@ -294,7 +294,7 @@ int sta_info_insert(struct sta_info *sta
}
if (WARN_ON(compare_ether_addr(sta->sta.addr, sdata->dev->dev_addr) == 0 ||
- is_multicast_ether_addr(sta->sta.addr))) {
+ is_multicast_ether_addr(sta->sta.addr))) {
err = -EINVAL;
goto out_free;
}
@@ -830,7 +830,7 @@ void ieee80211_sta_expire(struct ieee802
}
struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw,
- const u8 *addr)
+ const u8 *addr)
{
struct sta_info *sta = sta_info_get(hw_to_local(hw), addr);

View File

@ -0,0 +1,38 @@
Subject: mac80211: remove wiphy_to_hw
This isn't used by anyone, if we ever need it we can add
it back, until then it's useless.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
include/net/mac80211.h | 2 --
net/mac80211/cfg.c | 7 -------
2 files changed, 9 deletions(-)
--- everything.orig/include/net/mac80211.h 2008-10-07 20:05:49.000000000 +0200
+++ everything/include/net/mac80211.h 2008-10-07 20:06:42.000000000 +0200
@@ -867,8 +867,6 @@ struct ieee80211_hw {
u8 max_altrate_tries;
};
-struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy);
-
/**
* SET_IEEE80211_DEV - set device for 802.11 hardware
*
--- everything.orig/net/mac80211/cfg.c 2008-10-07 20:06:37.000000000 +0200
+++ everything/net/mac80211/cfg.c 2008-10-07 20:06:42.000000000 +0200
@@ -17,13 +17,6 @@
#include "rate.h"
#include "mesh.h"
-struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy)
-{
- struct ieee80211_local *local = wiphy_priv(wiphy);
- return &local->hw;
-}
-EXPORT_SYMBOL(wiphy_to_hw);
-
static bool nl80211_type_check(enum nl80211_iftype type)
{
switch (type) {

View File

@ -0,0 +1,113 @@
Subject: mac80211: clean up ieee80211_hw_config errors
Warn when ieee80211_hw_config returns an error, it shouldn't
happen; remove a number of printks that would happen in such
a case and one printk that is user-triggerable.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
net/mac80211/cfg.c | 3 +--
net/mac80211/main.c | 8 +++++++-
net/mac80211/scan.c | 16 +++-------------
net/mac80211/util.c | 5 +----
net/mac80211/wext.c | 6 +-----
5 files changed, 13 insertions(+), 25 deletions(-)
--- everything.orig/net/mac80211/cfg.c 2008-10-07 20:06:42.000000000 +0200
+++ everything/net/mac80211/cfg.c 2008-10-07 20:06:43.000000000 +0200
@@ -396,8 +396,7 @@ static int ieee80211_config_beacon(struc
*/
if (params->interval) {
sdata->local->hw.conf.beacon_int = params->interval;
- if (ieee80211_hw_config(sdata->local))
- return -EINVAL;
+ ieee80211_hw_config(sdata->local);
/*
* We updated some parameter so if below bails out
* it's not an error.
--- everything.orig/net/mac80211/main.c 2008-10-07 20:06:41.000000000 +0200
+++ everything/net/mac80211/main.c 2008-10-07 20:06:43.000000000 +0200
@@ -222,8 +222,14 @@ int ieee80211_hw_config(struct ieee80211
wiphy_name(local->hw.wiphy), chan->center_freq);
#endif
- if (local->open_count)
+ if (local->open_count) {
ret = local->ops->config(local_to_hw(local), &local->hw.conf);
+ /*
+ * HW reconfiguration should never fail, the driver has told
+ * us what it can support so it should live up to that promise.
+ */
+ WARN_ON(ret);
+ }
return ret;
}
--- everything.orig/net/mac80211/scan.c 2008-10-07 20:05:27.000000000 +0200
+++ everything/net/mac80211/scan.c 2008-10-07 20:06:43.000000000 +0200
@@ -447,18 +447,12 @@ void ieee80211_scan_completed(struct iee
if (local->hw_scanning) {
local->hw_scanning = false;
- if (ieee80211_hw_config(local))
- printk(KERN_DEBUG "%s: failed to restore operational "
- "channel after scan\n", wiphy_name(local->hw.wiphy));
-
+ ieee80211_hw_config(local);
goto done;
}
local->sw_scanning = false;
- if (ieee80211_hw_config(local))
- printk(KERN_DEBUG "%s: failed to restore operational "
- "channel after scan\n", wiphy_name(local->hw.wiphy));
-
+ ieee80211_hw_config(local);
netif_tx_lock_bh(local->mdev);
netif_addr_lock(local->mdev);
@@ -545,12 +539,8 @@ void ieee80211_scan_work(struct work_str
if (!skip) {
local->scan_channel = chan;
- if (ieee80211_hw_config(local)) {
- printk(KERN_DEBUG "%s: failed to set freq to "
- "%d MHz for scan\n", wiphy_name(local->hw.wiphy),
- chan->center_freq);
+ if (ieee80211_hw_config(local))
skip = 1;
- }
}
/* advance state machine to next channel/band */
--- everything.orig/net/mac80211/util.c 2008-10-07 20:05:27.000000000 +0200
+++ everything/net/mac80211/util.c 2008-10-07 20:06:43.000000000 +0200
@@ -638,11 +638,8 @@ int ieee80211_set_freq(struct ieee80211_
if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
- chan->flags & IEEE80211_CHAN_NO_IBSS) {
- printk(KERN_DEBUG "%s: IBSS not allowed on frequency "
- "%d MHz\n", sdata->dev->name, chan->center_freq);
+ chan->flags & IEEE80211_CHAN_NO_IBSS)
return ret;
- }
local->oper_channel = chan;
if (local->sw_scanning || local->hw_scanning)
--- everything.orig/net/mac80211/wext.c 2008-10-07 20:05:27.000000000 +0200
+++ everything/net/mac80211/wext.c 2008-10-07 20:06:43.000000000 +0200
@@ -689,12 +689,8 @@ static int ieee80211_ioctl_siwtxpower(st
ieee80211_led_radio(local, local->hw.conf.radio_enabled);
}
- if (need_reconfig) {
+ if (need_reconfig)
ieee80211_hw_config(local);
- /* The return value of hw_config is not of big interest here,
- * as it doesn't say that it failed because of _this_ config
- * change or something else. Ignore it. */
- }
return 0;
}

View File

@ -0,0 +1,41 @@
Subject: mac80211: remove max_antenna_gain config
The antenna gain isn't exactly configurable, despite the belief of
some unnamed individual who thinks that the EEPROM might influence
it.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
include/net/mac80211.h | 2 --
net/mac80211/main.c | 2 --
2 files changed, 4 deletions(-)
--- everything.orig/include/net/mac80211.h 2008-10-07 20:06:42.000000000 +0200
+++ everything/include/net/mac80211.h 2008-10-07 20:06:43.000000000 +0200
@@ -470,7 +470,6 @@ enum ieee80211_conf_flags {
* @listen_interval: listen interval in units of beacon interval
* @flags: configuration flags defined above
* @power_level: requested transmit power (in dBm)
- * @max_antenna_gain: maximum antenna gain (in dBi)
* @antenna_sel_tx: transmit antenna selection, 0: default/diversity,
* 1/2: antenna 0/1
* @antenna_sel_rx: receive antenna selection, like @antenna_sel_tx
@@ -485,7 +484,6 @@ struct ieee80211_conf {
u16 listen_interval;
u32 flags;
int power_level;
- int max_antenna_gain;
u8 antenna_sel_tx;
u8 antenna_sel_rx;
--- everything.orig/net/mac80211/main.c 2008-10-07 20:06:43.000000000 +0200
+++ everything/net/mac80211/main.c 2008-10-07 20:06:43.000000000 +0200
@@ -215,8 +215,6 @@ int ieee80211_hw_config(struct ieee80211
local->hw.conf.power_level = min(chan->max_power,
local->hw.conf.power_level);
- local->hw.conf.max_antenna_gain = chan->max_antenna_gain;
-
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
printk(KERN_DEBUG "%s: HW CONFIG: freq=%d\n",
wiphy_name(local->hw.wiphy), chan->center_freq);

View File

@ -0,0 +1,201 @@
Subject: mac80211: fix short slot handling
This patch makes mac80211 handle short slot requests from the AP
properly. Also warn about uses of IEEE80211_CONF_SHORT_SLOT_TIME
and optimise out the code since it cannot ever be hit anyway.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
include/net/mac80211.h | 28 ++++++++++--------
net/mac80211/main.c | 9 +++--
net/mac80211/mlme.c | 74 ++++++++++++++++++++++++++-----------------------
3 files changed, 62 insertions(+), 49 deletions(-)
--- everything.orig/net/mac80211/main.c 2008-10-07 20:06:43.000000000 +0200
+++ everything/net/mac80211/main.c 2008-10-08 10:56:29.000000000 +0200
@@ -346,9 +346,12 @@ void ieee80211_bss_info_change_notify(st
u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
{
- sdata->bss_conf.use_cts_prot = 0;
- sdata->bss_conf.use_short_preamble = 0;
- return BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE;
+ sdata->bss_conf.use_cts_prot = false;
+ sdata->bss_conf.use_short_preamble = false;
+ sdata->bss_conf.use_short_slot = false;
+ return BSS_CHANGED_ERP_CTS_PROT |
+ BSS_CHANGED_ERP_PREAMBLE |
+ BSS_CHANGED_ERP_SLOT;
}
void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
--- everything.orig/net/mac80211/mlme.c 2008-10-07 20:05:49.000000000 +0200
+++ everything/net/mac80211/mlme.c 2008-10-08 10:56:38.000000000 +0200
@@ -568,9 +568,8 @@ static void ieee80211_sta_wmm_params(str
}
}
-static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata,
- bool use_protection,
- bool use_short_preamble)
+static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
+ u16 capab, bool erp_valid, u8 erp)
{
struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -578,6 +577,19 @@ static u32 ieee80211_handle_protect_prea
DECLARE_MAC_BUF(mac);
#endif
u32 changed = 0;
+ bool use_protection;
+ bool use_short_preamble;
+ bool use_short_slot;
+
+ if (erp_valid) {
+ use_protection = (erp & WLAN_ERP_USE_PROTECTION) != 0;
+ use_short_preamble = (erp & WLAN_ERP_BARKER_PREAMBLE) == 0;
+ } else {
+ use_protection = false;
+ use_short_preamble = !!(capab & WLAN_CAPABILITY_SHORT_PREAMBLE);
+ }
+
+ use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
if (use_protection != bss_conf->use_cts_prot) {
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -607,30 +619,18 @@ static u32 ieee80211_handle_protect_prea
changed |= BSS_CHANGED_ERP_PREAMBLE;
}
- return changed;
-}
-
-static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata,
- u8 erp_value)
-{
- bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
- bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0;
-
- return ieee80211_handle_protect_preamb(sdata,
- use_protection, use_short_preamble);
-}
-
-static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
- struct ieee80211_bss *bss)
-{
- u32 changed = 0;
-
- if (bss->has_erp_value)
- changed |= ieee80211_handle_erp_ie(sdata, bss->erp_value);
- else {
- u16 capab = bss->capability;
- changed |= ieee80211_handle_protect_preamb(sdata, false,
- (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0);
+ if (use_short_slot != bss_conf->use_short_slot) {
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+ if (net_ratelimit()) {
+ printk(KERN_DEBUG "%s: switched to %s slot"
+ " (BSSID=%s)\n",
+ sdata->dev->name,
+ use_short_slot ? "short" : "long",
+ print_mac(mac, ifsta->bssid));
+ }
+#endif
+ bss_conf->use_short_slot = use_short_slot;
+ changed |= BSS_CHANGED_ERP_SLOT;
}
return changed;
@@ -723,7 +723,8 @@ static void ieee80211_set_associated(str
sdata->bss_conf.timestamp = bss->timestamp;
sdata->bss_conf.dtim_period = bss->dtim_period;
- changed |= ieee80211_handle_bss_capability(sdata, bss);
+ changed |= ieee80211_handle_bss_capability(sdata,
+ bss->capability, bss->has_erp_value, bss->erp_value);
ieee80211_rx_bss_put(local, bss);
}
@@ -1675,6 +1676,8 @@ static void ieee80211_rx_mgmt_beacon(str
struct ieee80211_local *local = sdata->local;
struct ieee80211_conf *conf = &local->hw.conf;
u32 changed = 0;
+ bool erp_valid;
+ u8 erp_value = 0;
/* Process beacon from the current BSS */
baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
@@ -1696,13 +1699,16 @@ static void ieee80211_rx_mgmt_beacon(str
ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param,
elems.wmm_param_len);
- if (elems.erp_info && elems.erp_info_len >= 1)
- changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]);
- else {
- u16 capab = le16_to_cpu(mgmt->u.beacon.capab_info);
- changed |= ieee80211_handle_protect_preamb(sdata, false,
- (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0);
+
+ if (elems.erp_info && elems.erp_info_len >= 1) {
+ erp_valid = true;
+ erp_value = elems.erp_info[0];
+ } else {
+ erp_valid = false;
}
+ changed |= ieee80211_handle_bss_capability(sdata,
+ le16_to_cpu(mgmt->u.beacon.capab_info),
+ erp_valid, erp_value);
if (elems.ht_cap_elem && elems.ht_info_elem &&
elems.wmm_param && conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
--- everything.orig/include/net/mac80211.h 2008-10-07 20:06:43.000000000 +0200
+++ everything/include/net/mac80211.h 2008-10-08 10:57:06.000000000 +0200
@@ -180,8 +180,12 @@ enum ieee80211_bss_change {
* @assoc: association status
* @aid: association ID number, valid only when @assoc is true
* @use_cts_prot: use CTS protection
- * @use_short_preamble: use 802.11b short preamble
- * @use_short_slot: use short slot time (only relevant for ERP)
+ * @use_short_preamble: use 802.11b short preamble;
+ * if the hardware cannot handle this it must set the
+ * IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE hardware flag
+ * @use_short_slot: use short slot time (only relevant for ERP);
+ * if the hardware cannot handle this it must set the
+ * IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE hardware flag
* @dtim_period: num of beacons before the next DTIM, for PSM
* @timestamp: beacon timestamp
* @beacon_int: beacon interval
@@ -442,23 +446,23 @@ struct ieee80211_rx_status {
*
* Flags to define PHY configuration options
*
- * @IEEE80211_CONF_SHORT_SLOT_TIME: use 802.11g short slot time
* @IEEE80211_CONF_RADIOTAP: add radiotap header at receive time (if supported)
* @IEEE80211_CONF_SUPPORT_HT_MODE: use 802.11n HT capabilities (if supported)
* @IEEE80211_CONF_PS: Enable 802.11 power save mode
*/
enum ieee80211_conf_flags {
- /*
- * TODO: IEEE80211_CONF_SHORT_SLOT_TIME will be removed once drivers
- * have been converted to use bss_info_changed() for slot time
- * configuration
- */
- IEEE80211_CONF_SHORT_SLOT_TIME = (1<<0),
- IEEE80211_CONF_RADIOTAP = (1<<1),
- IEEE80211_CONF_SUPPORT_HT_MODE = (1<<2),
- IEEE80211_CONF_PS = (1<<3),
+ IEEE80211_CONF_RADIOTAP = (1<<0),
+ IEEE80211_CONF_SUPPORT_HT_MODE = (1<<1),
+ IEEE80211_CONF_PS = (1<<2),
};
+/* XXX: remove all this once drivers stop trying to use it */
+static inline int __deprecated __IEEE80211_CONF_SHORT_SLOT_TIME(void)
+{
+ return 0;
+}
+#define IEEE80211_CONF_SHORT_SLOT_TIME (__IEEE80211_CONF_SHORT_SLOT_TIME())
+
/**
* struct ieee80211_conf - configuration of the device
*

View File

@ -0,0 +1,77 @@
Subject: mac80211: fix HT information element parsing
There's no checking that the HT IEs are of the right length
which can be used by an attacker to cause an out-of-bounds
access by sending a too short HT information/capability IE.
Fix it by simply pretending those IEs didn't exist when too
short.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
net/mac80211/ieee80211_i.h | 6 ++----
net/mac80211/mlme.c | 3 ---
net/mac80211/util.c | 8 ++++----
3 files changed, 6 insertions(+), 11 deletions(-)
--- everything.orig/net/mac80211/ieee80211_i.h 2008-10-07 20:05:26.000000000 +0200
+++ everything/net/mac80211/ieee80211_i.h 2008-10-07 20:06:45.000000000 +0200
@@ -816,8 +816,8 @@ struct ieee802_11_elems {
u8 *ext_supp_rates;
u8 *wmm_info;
u8 *wmm_param;
- u8 *ht_cap_elem;
- u8 *ht_info_elem;
+ struct ieee80211_ht_cap *ht_cap_elem;
+ struct ieee80211_ht_addt_info *ht_info_elem;
u8 *mesh_config;
u8 *mesh_id;
u8 *peer_link;
@@ -844,8 +844,6 @@ struct ieee802_11_elems {
u8 ext_supp_rates_len;
u8 wmm_info_len;
u8 wmm_param_len;
- u8 ht_cap_elem_len;
- u8 ht_info_elem_len;
u8 mesh_config_len;
u8 mesh_id_len;
u8 peer_link_len;
--- everything.orig/net/mac80211/mlme.c 2008-10-07 20:06:44.000000000 +0200
+++ everything/net/mac80211/mlme.c 2008-10-07 20:06:45.000000000 +0200
@@ -1349,10 +1349,8 @@ static void ieee80211_rx_mgmt_assoc_resp
(ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
struct ieee80211_ht_bss_info bss_info;
ieee80211_ht_cap_ie_to_ht_info(
- (struct ieee80211_ht_cap *)
elems.ht_cap_elem, &sta->sta.ht_info);
ieee80211_ht_addt_info_ie_to_ht_bss_info(
- (struct ieee80211_ht_addt_info *)
elems.ht_info_elem, &bss_info);
ieee80211_handle_ht(local, 1, &sta->sta.ht_info, &bss_info);
}
@@ -1715,7 +1713,6 @@ static void ieee80211_rx_mgmt_beacon(str
struct ieee80211_ht_bss_info bss_info;
ieee80211_ht_addt_info_ie_to_ht_bss_info(
- (struct ieee80211_ht_addt_info *)
elems.ht_info_elem, &bss_info);
changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf,
&bss_info);
--- everything.orig/net/mac80211/util.c 2008-10-07 20:06:43.000000000 +0200
+++ everything/net/mac80211/util.c 2008-10-07 20:06:45.000000000 +0200
@@ -529,12 +529,12 @@ void ieee802_11_parse_elems(u8 *start, s
elems->ext_supp_rates_len = elen;
break;
case WLAN_EID_HT_CAPABILITY:
- elems->ht_cap_elem = pos;
- elems->ht_cap_elem_len = elen;
+ if (elen >= sizeof(struct ieee80211_ht_cap))
+ elems->ht_cap_elem = (void *)pos;
break;
case WLAN_EID_HT_EXTRA_INFO:
- elems->ht_info_elem = pos;
- elems->ht_info_elem_len = elen;
+ if (elen >= sizeof(struct ieee80211_ht_addt_info))
+ elems->ht_info_elem = (void *)pos;
break;
case WLAN_EID_MESH_ID:
elems->mesh_id = pos;

View File

@ -0,0 +1,27 @@
Subject: mac80211: fix debugfs netdev rename
If, for some reason, a netdev has no debugfs dir, we shouldn't
try to rename that dir.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Cc: Robin Holt <holt@sgi.com>
---
net/mac80211/debugfs_netdev.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- everything.orig/net/mac80211/debugfs_netdev.c 2008-10-08 10:08:23.000000000 +0200
+++ everything/net/mac80211/debugfs_netdev.c 2008-10-08 10:22:52.000000000 +0200
@@ -481,8 +481,12 @@ static int netdev_notify(struct notifier
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
- sprintf(buf, "netdev:%s", dev->name);
dir = sdata->debugfsdir;
+
+ if (!dir)
+ return 0;
+
+ sprintf(buf, "netdev:%s", dev->name);
if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf))
printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs "
"dir to %s\n", buf);

View File

@ -0,0 +1,32 @@
Subject: cfg80211: fix debugfs error handling
If something goes wrong creating the debugfs dir or when
debugfs is not compiled in, the current code might lead to
trouble; make it more robust.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
net/wireless/core.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- everything.orig/net/wireless/core.c 2008-10-08 10:13:49.000000000 +0200
+++ everything/net/wireless/core.c 2008-10-08 10:19:10.000000000 +0200
@@ -185,7 +185,8 @@ int cfg80211_dev_rename(struct cfg80211_
if (result)
goto out_unlock;
- if (!debugfs_rename(rdev->wiphy.debugfsdir->d_parent,
+ if (rdev->wiphy.debugfsdir &&
+ !debugfs_rename(rdev->wiphy.debugfsdir->d_parent,
rdev->wiphy.debugfsdir,
rdev->wiphy.debugfsdir->d_parent,
newname))
@@ -318,6 +319,8 @@ int wiphy_register(struct wiphy *wiphy)
drv->wiphy.debugfsdir =
debugfs_create_dir(wiphy_name(&drv->wiphy),
ieee80211_debugfs_dir);
+ if (IS_ERR(drv->wiphy.debugfsdir))
+ drv->wiphy.debugfsdir = NULL;
res = 0;
out_unlock:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,259 @@
Subject: mac80211: kill hw.conf.antenna_sel_{rx,tx}
Never actually used.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
drivers/net/wireless/b43/main.c | 25 +++----------------------
drivers/net/wireless/b43legacy/main.c | 18 ++----------------
drivers/net/wireless/p54/p54common.c | 3 +--
drivers/net/wireless/rt2x00/rt2x00config.c | 20 ++++----------------
drivers/net/wireless/rt2x00/rt2x00dev.c | 6 ++----
include/net/mac80211.h | 7 +------
net/mac80211/debugfs.c | 8 --------
net/mac80211/ieee80211_i.h | 2 --
net/mac80211/tx.c | 1 -
9 files changed, 13 insertions(+), 77 deletions(-)
--- everything.orig/net/mac80211/debugfs.c 2008-10-08 22:35:20.000000000 +0200
+++ everything/net/mac80211/debugfs.c 2008-10-08 22:35:26.000000000 +0200
@@ -47,10 +47,6 @@ static const struct file_operations name
DEBUGFS_READONLY_FILE(frequency, 20, "%d",
local->hw.conf.channel->center_freq);
-DEBUGFS_READONLY_FILE(antenna_sel_tx, 20, "%d",
- local->hw.conf.antenna_sel_tx);
-DEBUGFS_READONLY_FILE(antenna_sel_rx, 20, "%d",
- local->hw.conf.antenna_sel_rx);
DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d",
local->rts_threshold);
DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d",
@@ -202,8 +198,6 @@ void debugfs_hw_add(struct ieee80211_loc
local->debugfs.keys = debugfs_create_dir("keys", phyd);
DEBUGFS_ADD(frequency);
- DEBUGFS_ADD(antenna_sel_tx);
- DEBUGFS_ADD(antenna_sel_rx);
DEBUGFS_ADD(rts_threshold);
DEBUGFS_ADD(fragmentation_threshold);
DEBUGFS_ADD(short_retry_limit);
@@ -258,8 +252,6 @@ void debugfs_hw_add(struct ieee80211_loc
void debugfs_hw_del(struct ieee80211_local *local)
{
DEBUGFS_DEL(frequency);
- DEBUGFS_DEL(antenna_sel_tx);
- DEBUGFS_DEL(antenna_sel_rx);
DEBUGFS_DEL(rts_threshold);
DEBUGFS_DEL(fragmentation_threshold);
DEBUGFS_DEL(short_retry_limit);
--- everything.orig/net/mac80211/ieee80211_i.h 2008-10-08 22:35:01.000000000 +0200
+++ everything/net/mac80211/ieee80211_i.h 2008-10-08 22:35:10.000000000 +0200
@@ -727,8 +727,6 @@ struct ieee80211_local {
struct dentry *rcdir;
struct dentry *rcname;
struct dentry *frequency;
- struct dentry *antenna_sel_tx;
- struct dentry *antenna_sel_rx;
struct dentry *rts_threshold;
struct dentry *fragmentation_threshold;
struct dentry *short_retry_limit;
--- everything.orig/include/net/mac80211.h 2008-10-08 22:35:30.000000000 +0200
+++ everything/include/net/mac80211.h 2008-10-08 22:39:56.000000000 +0200
@@ -324,7 +324,7 @@ struct ieee80211_tx_altrate {
* @flags: transmit info flags, defined above
* @band: TBD
* @tx_rate_idx: TBD
- * @antenna_sel_tx: TBD
+ * @antenna_sel_tx: antenna to use, 0 for automatic diversity
* @control: union for control data
* @status: union for status data
* @driver_data: array of driver_data pointers
@@ -474,9 +474,6 @@ static inline int __deprecated __IEEE802
* @listen_interval: listen interval in units of beacon interval
* @flags: configuration flags defined above
* @power_level: requested transmit power (in dBm)
- * @antenna_sel_tx: transmit antenna selection, 0: default/diversity,
- * 1/2: antenna 0/1
- * @antenna_sel_rx: receive antenna selection, like @antenna_sel_tx
* @ht_cap: describes current self configuration of 802.11n HT capabilities
* @ht_bss_conf: describes current BSS configuration of 802.11n HT parameters
* @channel: the channel to tune to
@@ -488,8 +485,6 @@ struct ieee80211_conf {
u16 listen_interval;
u32 flags;
int power_level;
- u8 antenna_sel_tx;
- u8 antenna_sel_rx;
struct ieee80211_channel *channel;
--- everything.orig/net/mac80211/tx.c 2008-10-08 22:37:05.000000000 +0200
+++ everything/net/mac80211/tx.c 2008-10-08 22:37:22.000000000 +0200
@@ -1975,7 +1975,6 @@ struct sk_buff *ieee80211_beacon_get(str
sband->bitrates[rsel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE)
info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE;
- info->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
info->control.retry_limit = 1;
out:
--- everything.orig/drivers/net/wireless/b43/main.c 2008-10-08 22:40:06.000000000 +0200
+++ everything/drivers/net/wireless/b43/main.c 2008-10-08 22:40:45.000000000 +0200
@@ -1339,25 +1339,6 @@ u8 b43_ieee80211_antenna_sanitize(struct
return antenna_nr;
}
-static int b43_antenna_from_ieee80211(struct b43_wldev *dev, u8 antenna)
-{
- antenna = b43_ieee80211_antenna_sanitize(dev, antenna);
- switch (antenna) {
- case 0: /* default/diversity */
- return B43_ANTENNA_DEFAULT;
- case 1: /* Antenna 0 */
- return B43_ANTENNA0;
- case 2: /* Antenna 1 */
- return B43_ANTENNA1;
- case 3: /* Antenna 2 */
- return B43_ANTENNA2;
- case 4: /* Antenna 3 */
- return B43_ANTENNA3;
- default:
- return B43_ANTENNA_DEFAULT;
- }
-}
-
/* Convert a b43 antenna number value to the PHY TX control value. */
static u16 b43_antenna_to_phyctl(int antenna)
{
@@ -1399,7 +1380,7 @@ static void b43_write_beacon_template(st
len, ram_offset, shm_size_offset, rate);
/* Write the PHY TX control parameters. */
- antenna = b43_antenna_from_ieee80211(dev, info->antenna_sel_tx);
+ antenna = B43_ANTENNA_DEFAULT;
antenna = b43_antenna_to_phyctl(antenna);
ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
/* We can't send beacons with short preamble. Would get PHY errors. */
@@ -3399,9 +3380,9 @@ static int b43_op_config(struct ieee8021
}
/* Antennas for RX and management frame TX. */
- antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_tx);
+ antenna = B43_ANTENNA_DEFAULT;
b43_mgmtframe_txantenna(dev, antenna);
- antenna = b43_antenna_from_ieee80211(dev, conf->antenna_sel_rx);
+ antenna = B43_ANTENNA_DEFAULT;
if (phy->ops->set_rx_antenna)
phy->ops->set_rx_antenna(dev, antenna);
--- everything.orig/drivers/net/wireless/b43legacy/main.c 2008-10-08 22:41:36.000000000 +0200
+++ everything/drivers/net/wireless/b43legacy/main.c 2008-10-08 22:41:59.000000000 +0200
@@ -2556,20 +2556,6 @@ init_failure:
return err;
}
-static int b43legacy_antenna_from_ieee80211(u8 antenna)
-{
- switch (antenna) {
- case 0: /* default/diversity */
- return B43legacy_ANTENNA_DEFAULT;
- case 1: /* Antenna 0 */
- return B43legacy_ANTENNA0;
- case 2: /* Antenna 1 */
- return B43legacy_ANTENNA1;
- default:
- return B43legacy_ANTENNA_DEFAULT;
- }
-}
-
static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
struct ieee80211_conf *conf)
{
@@ -2583,8 +2569,8 @@ static int b43legacy_op_dev_config(struc
int err = 0;
u32 savedirqs;
- antenna_tx = b43legacy_antenna_from_ieee80211(conf->antenna_sel_tx);
- antenna_rx = b43legacy_antenna_from_ieee80211(conf->antenna_sel_rx);
+ antenna_tx = B43legacy_ANTENNA_DEFAULT;
+ antenna_rx = B43legacy_ANTENNA_DEFAULT;
mutex_lock(&wl->mutex);
dev = wl->current_dev;
--- everything.orig/drivers/net/wireless/p54/p54common.c 2008-10-08 22:43:54.000000000 +0200
+++ everything/drivers/net/wireless/p54/p54common.c 2008-10-08 22:44:12.000000000 +0200
@@ -1211,8 +1211,7 @@ static int p54_config(struct ieee80211_h
struct p54_common *priv = dev->priv;
mutex_lock(&priv->conf_mutex);
- priv->rx_antenna = (conf->antenna_sel_rx == 0) ?
- 2 : conf->antenna_sel_tx - 1;
+ priv->rx_antenna = 2; /* automatic */
priv->output_power = conf->power_level << 2;
ret = p54_set_freq(dev, cpu_to_le16(conf->channel->center_freq));
p54_set_vdcf(dev);
--- everything.orig/drivers/net/wireless/rt2x00/rt2x00config.c 2008-10-08 22:44:57.000000000 +0200
+++ everything/drivers/net/wireless/rt2x00/rt2x00config.c 2008-10-08 22:45:36.000000000 +0200
@@ -199,23 +199,15 @@ void rt2x00lib_config(struct rt2x00_dev
* to work with untill the link tuner decides that an antenna
* switch should be performed.
*/
- if (!conf->antenna_sel_rx &&
- default_ant->rx != ANTENNA_SW_DIVERSITY &&
+ if (default_ant->rx != ANTENNA_SW_DIVERSITY &&
default_ant->rx != active_ant->rx)
flags |= CONFIG_UPDATE_ANTENNA;
- else if (conf->antenna_sel_rx &&
- conf->antenna_sel_rx != active_ant->rx)
- flags |= CONFIG_UPDATE_ANTENNA;
else if (active_ant->rx == ANTENNA_SW_DIVERSITY)
flags |= CONFIG_UPDATE_ANTENNA;
- if (!conf->antenna_sel_tx &&
- default_ant->tx != ANTENNA_SW_DIVERSITY &&
+ if (default_ant->tx != ANTENNA_SW_DIVERSITY &&
default_ant->tx != active_ant->tx)
flags |= CONFIG_UPDATE_ANTENNA;
- else if (conf->antenna_sel_tx &&
- conf->antenna_sel_tx != active_ant->tx)
- flags |= CONFIG_UPDATE_ANTENNA;
else if (active_ant->tx == ANTENNA_SW_DIVERSITY)
flags |= CONFIG_UPDATE_ANTENNA;
@@ -252,18 +244,14 @@ config:
}
if (flags & CONFIG_UPDATE_ANTENNA) {
- if (conf->antenna_sel_rx)
- libconf.ant.rx = conf->antenna_sel_rx;
- else if (default_ant->rx != ANTENNA_SW_DIVERSITY)
+ if (default_ant->rx != ANTENNA_SW_DIVERSITY)
libconf.ant.rx = default_ant->rx;
else if (active_ant->rx == ANTENNA_SW_DIVERSITY)
libconf.ant.rx = ANTENNA_B;
else
libconf.ant.rx = active_ant->rx;
- if (conf->antenna_sel_tx)
- libconf.ant.tx = conf->antenna_sel_tx;
- else if (default_ant->tx != ANTENNA_SW_DIVERSITY)
+ if (default_ant->tx != ANTENNA_SW_DIVERSITY)
libconf.ant.tx = default_ant->tx;
else if (active_ant->tx == ANTENNA_SW_DIVERSITY)
libconf.ant.tx = ANTENNA_B;
--- everything.orig/drivers/net/wireless/rt2x00/rt2x00dev.c 2008-10-08 22:44:28.000000000 +0200
+++ everything/drivers/net/wireless/rt2x00/rt2x00dev.c 2008-10-08 22:44:43.000000000 +0200
@@ -249,11 +249,9 @@ static void rt2x00lib_evaluate_antenna(s
rt2x00dev->link.ant.flags &= ~ANTENNA_RX_DIVERSITY;
rt2x00dev->link.ant.flags &= ~ANTENNA_TX_DIVERSITY;
- if (rt2x00dev->hw->conf.antenna_sel_rx == 0 &&
- rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
+ if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
rt2x00dev->link.ant.flags |= ANTENNA_RX_DIVERSITY;
- if (rt2x00dev->hw->conf.antenna_sel_tx == 0 &&
- rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
+ if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
rt2x00dev->link.ant.flags |= ANTENNA_TX_DIVERSITY;
if (!(rt2x00dev->link.ant.flags & ANTENNA_RX_DIVERSITY) &&

View File

@ -0,0 +1,616 @@
Subject: mac80211: introduce hw config change flags
This makes mac80211 notify the driver which configuration
actually changed, e.g. channel etc.
No driver changes, this is just plumbing, driver authors are
expected to act on this if they want to.
Also remove the HW CONFIG debug printk, it's incorrect, often
we configure something else.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
drivers/net/wireless/adm8211.c | 3 +-
drivers/net/wireless/at76_usb.c | 3 +-
drivers/net/wireless/ath5k/base.c | 7 ++----
drivers/net/wireless/ath9k/main.c | 4 +--
drivers/net/wireless/b43/main.c | 3 +-
drivers/net/wireless/b43legacy/main.c | 3 +-
drivers/net/wireless/iwlwifi/iwl-agn.c | 3 +-
drivers/net/wireless/iwlwifi/iwl3945-base.c | 7 +++---
drivers/net/wireless/libertas_tf/main.c | 4 ++-
drivers/net/wireless/mac80211_hwsim.c | 4 +--
drivers/net/wireless/p54/p54common.c | 3 +-
drivers/net/wireless/rt2x00/rt2x00.h | 2 -
drivers/net/wireless/rt2x00/rt2x00dev.c | 2 -
drivers/net/wireless/rt2x00/rt2x00mac.c | 3 +-
drivers/net/wireless/rtl8180_dev.c | 3 +-
drivers/net/wireless/rtl8187_dev.c | 3 +-
drivers/net/wireless/zd1211rw/zd_mac.c | 4 ++-
include/net/mac80211.h | 30 +++++++++++++++++++++++-----
net/mac80211/cfg.c | 3 +-
net/mac80211/ieee80211_i.h | 2 -
net/mac80211/iface.c | 25 +++++++++++++++++------
net/mac80211/main.c | 29 ++++++++++++++-------------
net/mac80211/scan.c | 12 ++++++++---
net/mac80211/util.c | 3 +-
net/mac80211/wext.c | 14 ++++++-------
25 files changed, 118 insertions(+), 61 deletions(-)
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -464,12 +464,32 @@ static inline int __deprecated __IEEE802
#define IEEE80211_CONF_SHORT_SLOT_TIME (__IEEE80211_CONF_SHORT_SLOT_TIME())
/**
+ * enum ieee80211_conf_changed - denotes which configuration changed
+ *
+ * @IEEE80211_CONF_CHANGE_RADIO_ENABLED: the value of radio_enabled changed
+ * @IEEE80211_CONF_CHANGE_BEACON_INTERVAL: the beacon interval changed
+ * @IEEE80211_CONF_CHANGE_LISTEN_INTERVAL: the listen interval changed
+ * @IEEE80211_CONF_CHANGE_RADIOTAP: the radiotap flag changed
+ * @IEEE80211_CONF_CHANGE_PS: the PS flag changed
+ * @IEEE80211_CONF_CHANGE_POWER: the TX power changed
+ * @IEEE80211_CONF_CHANGE_CHANNEL: the channel changed
+ */
+enum ieee80211_conf_changed {
+ IEEE80211_CONF_CHANGE_RADIO_ENABLED = BIT(0),
+ IEEE80211_CONF_CHANGE_BEACON_INTERVAL = BIT(1),
+ IEEE80211_CONF_CHANGE_LISTEN_INTERVAL = BIT(2),
+ IEEE80211_CONF_CHANGE_RADIOTAP = BIT(3),
+ IEEE80211_CONF_CHANGE_PS = BIT(4),
+ IEEE80211_CONF_CHANGE_POWER = BIT(5),
+ IEEE80211_CONF_CHANGE_CHANNEL = BIT(6),
+};
+
+/**
* struct ieee80211_conf - configuration of the device
*
* This struct indicates how the driver shall configure the hardware.
*
* @radio_enabled: when zero, driver is required to switch off the radio.
- * TODO make a flag
* @beacon_int: beacon interval (TODO make interface config)
* @listen_interval: listen interval in units of beacon interval
* @flags: configuration flags defined above
@@ -479,13 +499,13 @@ static inline int __deprecated __IEEE802
* @channel: the channel to tune to
*/
struct ieee80211_conf {
- int radio_enabled;
-
int beacon_int;
- u16 listen_interval;
u32 flags;
int power_level;
+ u16 listen_interval;
+ bool radio_enabled;
+
struct ieee80211_channel *channel;
struct ieee80211_sta_ht_cap ht_cap;
@@ -1213,7 +1233,7 @@ struct ieee80211_ops {
struct ieee80211_if_init_conf *conf);
void (*remove_interface)(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf);
- int (*config)(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
+ int (*config)(struct ieee80211_hw *hw, u32 changed);
int (*config_interface)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_if_conf *conf);
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -394,7 +394,8 @@ static int ieee80211_config_beacon(struc
*/
if (params->interval) {
sdata->local->hw.conf.beacon_int = params->interval;
- ieee80211_hw_config(sdata->local);
+ ieee80211_hw_config(sdata->local,
+ IEEE80211_CONF_CHANGE_BEACON_INTERVAL);
/*
* We updated some parameter so if below bails out
* it's not an error.
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -880,7 +880,7 @@ static inline int ieee80211_bssid_match(
}
-int ieee80211_hw_config(struct ieee80211_local *local);
+int ieee80211_hw_config(struct ieee80211_local *local, u32 changed);
int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed);
void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -65,7 +65,7 @@ static int ieee80211_open(struct net_dev
struct ieee80211_if_init_conf conf;
u32 changed = 0;
int res;
- bool need_hw_reconfig = 0;
+ u32 hw_reconf_flags = 0;
u8 null_addr[ETH_ALEN] = {0};
/* fail early if user set an invalid address */
@@ -152,7 +152,8 @@ static int ieee80211_open(struct net_dev
res = local->ops->start(local_to_hw(local));
if (res)
goto err_del_bss;
- need_hw_reconfig = 1;
+ /* we're brought up, everything changes */
+ hw_reconf_flags = ~0;
ieee80211_led_radio(local, local->hw.conf.radio_enabled);
}
@@ -198,8 +199,10 @@ static int ieee80211_open(struct net_dev
/* must be before the call to ieee80211_configure_filter */
local->monitors++;
- if (local->monitors == 1)
+ if (local->monitors == 1) {
local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
+ hw_reconf_flags |= IEEE80211_CONF_CHANGE_RADIOTAP;
+ }
if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
local->fif_fcsfail++;
@@ -279,8 +282,8 @@ static int ieee80211_open(struct net_dev
atomic_inc(&local->iff_promiscs);
local->open_count++;
- if (need_hw_reconfig) {
- ieee80211_hw_config(local);
+ if (hw_reconf_flags) {
+ ieee80211_hw_config(local, hw_reconf_flags);
/*
* set default queue parameters so drivers don't
* need to initialise the hardware if the hardware
@@ -322,6 +325,7 @@ static int ieee80211_stop(struct net_dev
struct ieee80211_local *local = sdata->local;
struct ieee80211_if_init_conf conf;
struct sta_info *sta;
+ u32 hw_reconf_flags = 0;
/*
* Stop TX on this interface first.
@@ -405,8 +409,10 @@ static int ieee80211_stop(struct net_dev
}
local->monitors--;
- if (local->monitors == 0)
+ if (local->monitors == 0) {
local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
+ hw_reconf_flags |= IEEE80211_CONF_CHANGE_RADIOTAP;
+ }
if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
local->fif_fcsfail--;
@@ -504,8 +510,15 @@ static int ieee80211_stop(struct net_dev
tasklet_disable(&local->tx_pending_tasklet);
tasklet_disable(&local->tasklet);
+
+ /* no reconfiguring after stop! */
+ hw_reconf_flags = 0;
}
+ /* do after stop to avoid reconfiguring when we stop anyway */
+ if (hw_reconf_flags)
+ ieee80211_hw_config(local, hw_reconf_flags);
+
return 0;
}
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -197,31 +197,34 @@ int ieee80211_if_config(struct ieee80211
&sdata->vif, &conf);
}
-int ieee80211_hw_config(struct ieee80211_local *local)
+int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
{
struct ieee80211_channel *chan;
int ret = 0;
+ int power;
if (local->sw_scanning)
chan = local->scan_channel;
else
chan = local->oper_channel;
- local->hw.conf.channel = chan;
+ if (chan != local->hw.conf.channel) {
+ local->hw.conf.channel = chan;
+ changed |= IEEE80211_CONF_CHANGE_CHANNEL;
+ }
+
if (!local->hw.conf.power_level)
- local->hw.conf.power_level = chan->max_power;
+ power = chan->max_power;
else
- local->hw.conf.power_level = min(chan->max_power,
- local->hw.conf.power_level);
-
-#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
- printk(KERN_DEBUG "%s: HW CONFIG: freq=%d\n",
- wiphy_name(local->hw.wiphy), chan->center_freq);
-#endif
+ power = min(chan->max_power, local->hw.conf.power_level);
+ if (local->hw.conf.power_level != power) {
+ changed |= IEEE80211_CONF_CHANGE_POWER;
+ local->hw.conf.power_level = power;
+ }
- if (local->open_count) {
- ret = local->ops->config(local_to_hw(local), &local->hw.conf);
+ if (changed && local->open_count) {
+ ret = local->ops->config(local_to_hw(local), changed);
/*
* HW reconfiguration should never fail, the driver has told
* us what it can support so it should live up to that promise.
@@ -672,7 +675,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(
local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
local->short_retry_limit = 7;
local->long_retry_limit = 4;
- local->hw.conf.radio_enabled = 1;
+ local->hw.conf.radio_enabled = true;
INIT_LIST_HEAD(&local->interfaces);
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -447,12 +447,17 @@ void ieee80211_scan_completed(struct iee
if (local->hw_scanning) {
local->hw_scanning = false;
- ieee80211_hw_config(local);
+ /*
+ * Somebody might have requested channel change during scan
+ * that we won't have acted upon, try now. ieee80211_hw_config
+ * will set the flag based on actual changes.
+ */
+ ieee80211_hw_config(local, 0);
goto done;
}
local->sw_scanning = false;
- ieee80211_hw_config(local);
+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
netif_tx_lock_bh(local->mdev);
netif_addr_lock(local->mdev);
@@ -539,7 +544,8 @@ void ieee80211_scan_work(struct work_str
if (!skip) {
local->scan_channel = chan;
- if (ieee80211_hw_config(local))
+ if (ieee80211_hw_config(local,
+ IEEE80211_CONF_CHANGE_CHANNEL))
skip = 1;
}
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -645,7 +645,8 @@ int ieee80211_set_freq(struct ieee80211_
if (local->sw_scanning || local->hw_scanning)
ret = 0;
else
- ret = ieee80211_hw_config(local);
+ ret = ieee80211_hw_config(
+ local, IEEE80211_CONF_CHANGE_CHANNEL);
rate_control_clear(local);
}
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -656,7 +656,7 @@ static int ieee80211_ioctl_siwtxpower(st
union iwreq_data *data, char *extra)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
- bool need_reconfig = 0;
+ u32 reconf_flags = 0;
int new_power_level;
if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
@@ -680,17 +680,17 @@ static int ieee80211_ioctl_siwtxpower(st
if (local->hw.conf.power_level != new_power_level) {
local->hw.conf.power_level = new_power_level;
- need_reconfig = 1;
+ reconf_flags |= IEEE80211_CONF_CHANGE_POWER;
}
if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) {
local->hw.conf.radio_enabled = !(data->txpower.disabled);
- need_reconfig = 1;
+ reconf_flags |= IEEE80211_CONF_CHANGE_RADIO_ENABLED;
ieee80211_led_radio(local, local->hw.conf.radio_enabled);
}
- if (need_reconfig)
- ieee80211_hw_config(local);
+ if (reconf_flags)
+ ieee80211_hw_config(local, reconf_flags);
return 0;
}
@@ -976,7 +976,7 @@ static int ieee80211_ioctl_siwpower(stru
if (wrq->disabled) {
conf->flags &= ~IEEE80211_CONF_PS;
- return ieee80211_hw_config(local);
+ return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
}
switch (wrq->flags & IW_POWER_MODE) {
@@ -989,7 +989,7 @@ static int ieee80211_ioctl_siwpower(stru
return -EINVAL;
}
- return ieee80211_hw_config(local);
+ return ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
}
static int ieee80211_ioctl_giwpower(struct net_device *dev,
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -1314,9 +1314,10 @@ static int adm8211_set_ssid(struct ieee8
return 0;
}
-static int adm8211_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
+static int adm8211_config(struct ieee80211_hw *dev, u32 changed)
{
struct adm8211_priv *priv = dev->priv;
+ struct ieee80211_conf *conf = &dev->conf;
int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
if (channel != priv->channel) {
--- a/drivers/net/wireless/at76_usb.c
+++ b/drivers/net/wireless/at76_usb.c
@@ -2057,9 +2057,10 @@ exit:
return 0;
}
-static int at76_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
+static int at76_config(struct ieee80211_hw *hw, u32 changed)
{
struct at76_priv *priv = hw->priv;
+ struct ieee80211_conf *conf = &hw->conf;
at76_dbg(DBG_MAC80211, "%s(): channel %d radio %d",
__func__, conf->channel->hw_value, conf->radio_enabled);
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -219,8 +219,7 @@ static int ath5k_add_interface(struct ie
struct ieee80211_if_init_conf *conf);
static void ath5k_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf);
-static int ath5k_config(struct ieee80211_hw *hw,
- struct ieee80211_conf *conf);
+static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
static int ath5k_config_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_if_conf *conf);
@@ -2767,10 +2766,10 @@ end:
* TODO: Phy disable/diversity etc
*/
static int
-ath5k_config(struct ieee80211_hw *hw,
- struct ieee80211_conf *conf)
+ath5k_config(struct ieee80211_hw *hw, u32 changed)
{
struct ath5k_softc *sc = hw->priv;
+ struct ieee80211_conf *conf = &hw->conf;
sc->bintval = conf->beacon_int;
sc->power_level = conf->power_level;
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -1231,11 +1231,11 @@ static void ath9k_remove_interface(struc
__func__, error);
}
-static int ath9k_config(struct ieee80211_hw *hw,
- struct ieee80211_conf *conf)
+static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
{
struct ath_softc *sc = hw->priv;
struct ieee80211_channel *curchan = hw->conf.channel;
+ struct ieee80211_conf *conf = &hw->conf;
int pos;
DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n",
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -3320,11 +3320,12 @@ init_failure:
return err;
}
-static int b43_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
+static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
struct b43_phy *phy;
+ struct ieee80211_conf *conf = &hw->conf;
unsigned long flags;
int antenna;
int err = 0;
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2557,11 +2557,12 @@ init_failure:
}
static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
- struct ieee80211_conf *conf)
+ u32 changed)
{
struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
struct b43legacy_wldev *dev;
struct b43legacy_phy *phy;
+ struct ieee80211_conf *conf = &hw->conf;
unsigned long flags;
unsigned int new_phymode = 0xFFFF;
int antenna_tx;
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2760,10 +2760,11 @@ static int iwl4965_mac_add_interface(str
* be set inappropriately and the driver currently sets the hardware up to
* use it whenever needed.
*/
-static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
+static int iwl4965_mac_config(struct ieee80211_hw *hw, u32 changed)
{
struct iwl_priv *priv = hw->priv;
const struct iwl_channel_info *ch_info;
+ struct ieee80211_conf *conf = &hw->conf;
unsigned long flags;
int ret = 0;
u16 channel;
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -6427,7 +6427,7 @@ static void iwl3945_bg_abort_scan(struct
mutex_unlock(&priv->mutex);
}
-static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
+static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed);
static void iwl3945_bg_scan_completed(struct work_struct *work)
{
@@ -6440,7 +6440,7 @@ static void iwl3945_bg_scan_completed(st
return;
if (test_bit(STATUS_CONF_PENDING, &priv->status))
- iwl3945_mac_config(priv->hw, ieee80211_get_hw_conf(priv->hw));
+ iwl3945_mac_config(priv->hw, 0);
ieee80211_scan_completed(priv->hw);
@@ -6629,10 +6629,11 @@ static int iwl3945_mac_add_interface(str
* be set inappropriately and the driver currently sets the hardware up to
* use it whenever needed.
*/
-static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
+static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
{
struct iwl3945_priv *priv = hw->priv;
const struct iwl3945_channel_info *ch_info;
+ struct ieee80211_conf *conf = &hw->conf;
unsigned long flags;
int ret = 0;
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -361,10 +361,10 @@ static void mac80211_hwsim_beacon(unsign
}
-static int mac80211_hwsim_config(struct ieee80211_hw *hw,
- struct ieee80211_conf *conf)
+static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
{
struct mac80211_hwsim_data *data = hw->priv;
+ struct ieee80211_conf *conf = &hw->conf;
printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d beacon_int=%d)\n",
wiphy_name(hw->wiphy), __func__,
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -1205,10 +1205,11 @@ static void p54_remove_interface(struct
p54_set_filter(dev, 0, NULL);
}
-static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
+static int p54_config(struct ieee80211_hw *dev, u32 changed)
{
int ret;
struct p54_common *priv = dev->priv;
+ struct ieee80211_conf *conf = &dev->conf;
mutex_lock(&priv->conf_mutex);
priv->rx_antenna = 2; /* automatic */
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -997,7 +997,7 @@ int rt2x00mac_add_interface(struct ieee8
struct ieee80211_if_init_conf *conf);
void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_if_init_conf *conf);
-int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
+int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed);
int rt2x00mac_config_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_if_conf *conf);
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -335,9 +335,10 @@ void rt2x00mac_remove_interface(struct i
}
EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface);
-int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
+int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct ieee80211_conf *conf = &hw->conf;
int radio_on;
int status;
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -692,9 +692,10 @@ static void rtl8180_remove_interface(str
priv->vif = NULL;
}
-static int rtl8180_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
+static int rtl8180_config(struct ieee80211_hw *dev, u32 changed)
{
struct rtl8180_priv *priv = dev->priv;
+ struct ieee80211_conf *conf = &dev->conf;
priv->rf->set_chan(dev, conf);
--- a/drivers/net/wireless/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl8187_dev.c
@@ -870,9 +870,10 @@ static void rtl8187_remove_interface(str
mutex_unlock(&priv->conf_mutex);
}
-static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
+static int rtl8187_config(struct ieee80211_hw *dev, u32 changed)
{
struct rtl8187_priv *priv = dev->priv;
+ struct ieee80211_conf *conf = &dev->conf;
u32 reg;
mutex_lock(&priv->conf_mutex);
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -743,9 +743,11 @@ static void zd_op_remove_interface(struc
zd_write_mac_addr(&mac->chip, NULL);
}
-static int zd_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
+static int zd_op_config(struct ieee80211_hw *hw, u32 changed)
{
struct zd_mac *mac = zd_hw_mac(hw);
+ struct ieee80211_conf *conf = &hw->conf;
+
return zd_chip_set_channel(&mac->chip, conf->channel->hw_value);
}
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1245,7 +1245,7 @@ int rt2x00lib_resume(struct rt2x00_dev *
/*
* Reconfigure device.
*/
- retval = rt2x00mac_config(rt2x00dev->hw, &rt2x00dev->hw->conf);
+ retval = rt2x00mac_config(rt2x00dev->hw, ~0);
if (retval)
goto exit;

View File

@ -0,0 +1,64 @@
Subject: nl80211: export HT capabilities
This exports the local HT capabilities in nl80211.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
include/linux/nl80211.h | 12 ++++++++++++
net/wireless/nl80211.c | 13 +++++++++++++
2 files changed, 25 insertions(+)
--- everything.orig/include/linux/nl80211.h 2008-10-09 01:31:09.000000000 +0200
+++ everything/include/linux/nl80211.h 2008-10-09 02:11:44.000000000 +0200
@@ -452,17 +452,29 @@ enum nl80211_mpath_info {
* an array of nested frequency attributes
* @NL80211_BAND_ATTR_RATES: supported bitrates in this band,
* an array of nested bitrate attributes
+ * @NL80211_BAND_ATTR_HT_MCS_SET: 16-byte attribute containing the MCS set as
+ * defined in 802.11n
+ * @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE
+ * @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n
+ * @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n
*/
enum nl80211_band_attr {
__NL80211_BAND_ATTR_INVALID,
NL80211_BAND_ATTR_FREQS,
NL80211_BAND_ATTR_RATES,
+ NL80211_BAND_ATTR_HT_MCS_SET,
+ NL80211_BAND_ATTR_HT_CAPA,
+ NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
+ NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
+
/* keep last */
__NL80211_BAND_ATTR_AFTER_LAST,
NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1
};
+#define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA
+
/**
* enum nl80211_frequency_attr - frequency attributes
* @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz
--- everything.orig/net/wireless/nl80211.c 2008-10-09 01:32:05.000000000 +0200
+++ everything/net/wireless/nl80211.c 2008-10-09 02:12:21.000000000 +0200
@@ -157,6 +157,19 @@ static int nl80211_send_wiphy(struct sk_
if (!nl_band)
goto nla_put_failure;
+ /* add HT info */
+ if (dev->wiphy.bands[band]->ht_cap.ht_supported) {
+ NLA_PUT(msg, NL80211_BAND_ATTR_HT_MCS_SET,
+ sizeof(dev->wiphy.bands[band]->ht_cap.mcs),
+ &dev->wiphy.bands[band]->ht_cap.mcs);
+ NLA_PUT_U16(msg, NL80211_BAND_ATTR_HT_CAPA,
+ dev->wiphy.bands[band]->ht_cap.cap);
+ NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR,
+ dev->wiphy.bands[band]->ht_cap.ampdu_factor);
+ NLA_PUT_U8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY,
+ dev->wiphy.bands[band]->ht_cap.ampdu_density);
+ }
+
/* add frequencies */
nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS);
if (!nl_freqs)

View File

@ -0,0 +1,142 @@
Subject: mac80211: provide sequence numbers
I've come to think that not providing sequence numbers for
the normal STA mode case was a mistake, at least two drivers
now had to implement code they wouldn't otherwise need, and
I believe at76_usb and adm8211 might be broken.
This patch makes mac80211 assign a sequence number to all
those frames that need one except beacons. That means that
if a driver only implements modes that do not do beaconing
it need not worry about the sequence number.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
drivers/net/wireless/p54/p54.h | 1 -
drivers/net/wireless/p54/p54common.c | 18 +++++-------------
drivers/net/wireless/rtl8187.h | 1 -
drivers/net/wireless/rtl8187_dev.c | 18 ++++--------------
net/mac80211/ieee80211_i.h | 2 ++
net/mac80211/tx.c | 10 ++++++++++
6 files changed, 21 insertions(+), 29 deletions(-)
--- everything.orig/net/mac80211/ieee80211_i.h 2008-10-10 15:45:52.000000000 +0200
+++ everything/net/mac80211/ieee80211_i.h 2008-10-10 15:45:56.000000000 +0200
@@ -438,6 +438,8 @@ struct ieee80211_sub_if_data {
struct ieee80211_key *keys[NUM_DEFAULT_KEYS];
struct ieee80211_key *default_key;
+ u16 sequence_number;
+
/* BSS configuration for this interface. */
struct ieee80211_bss_conf bss_conf;
--- everything.orig/net/mac80211/tx.c 2008-10-10 15:45:48.000000000 +0200
+++ everything/net/mac80211/tx.c 2008-10-10 15:45:56.000000000 +0200
@@ -602,8 +602,18 @@ ieee80211_tx_h_sequence(struct ieee80211
if (ieee80211_hdrlen(hdr->frame_control) < 24)
return TX_CONTINUE;
+ /*
+ * Anything but QoS data that has a sequence number field
+ * (is long enough) gets a sequence number from the global
+ * counter.
+ */
if (!ieee80211_is_data_qos(hdr->frame_control)) {
+ /* driver should assign sequence number */
info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
+ /* for pure STA mode without beacons, we can do it */
+ hdr->seq_ctrl = cpu_to_le16(tx->sdata->sequence_number);
+ tx->sdata->sequence_number += 0x10;
+ tx->sdata->sequence_number &= IEEE80211_SCTL_SEQ;
return TX_CONTINUE;
}
--- everything.orig/drivers/net/wireless/p54/p54.h 2008-10-10 15:45:49.000000000 +0200
+++ everything/drivers/net/wireless/p54/p54.h 2008-10-10 15:45:56.000000000 +0200
@@ -67,7 +67,6 @@ struct p54_common {
int (*open)(struct ieee80211_hw *dev);
void (*stop)(struct ieee80211_hw *dev);
int mode;
- u16 seqno;
u16 rx_mtu;
u8 headroom;
u8 tailroom;
--- everything.orig/drivers/net/wireless/p54/p54common.c 2008-10-10 15:45:49.000000000 +0200
+++ everything/drivers/net/wireless/p54/p54common.c 2008-10-10 15:45:56.000000000 +0200
@@ -865,19 +865,6 @@ static int p54_tx(struct ieee80211_hw *d
if (padding)
txhdr->align[0] = padding;
- /* FIXME: The sequence that follows is needed for this driver to
- * work with mac80211 since "mac80211: fix TX sequence numbers".
- * As with the temporary code in rt2x00, changes will be needed
- * to get proper sequence numbers on beacons. In addition, this
- * patch places the sequence number in the hardware state, which
- * limits us to a single virtual state.
- */
- if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
- if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
- priv->seqno += 0x10;
- ieee80211hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
- ieee80211hdr->seq_ctrl |= cpu_to_le16(priv->seqno);
- }
/* modifies skb->cb and with it info, so must be last! */
p54_assign_address(dev, skb, hdr, skb->len);
@@ -1391,6 +1378,11 @@ struct ieee80211_hw *p54_init_common(siz
IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_NOISE_DBM;
+ /*
+ * XXX: when this driver gets support for any mode that
+ * requires beacons (AP, MESH, IBSS) then it must
+ * implement IEEE80211_TX_CTL_ASSIGN_SEQ.
+ */
dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
dev->channel_change_time = 1000; /* TODO: find actual value */
--- everything.orig/drivers/net/wireless/rtl8187_dev.c 2008-10-10 15:45:49.000000000 +0200
+++ everything/drivers/net/wireless/rtl8187_dev.c 2008-10-10 15:45:56.000000000 +0200
@@ -238,20 +238,6 @@ static int rtl8187_tx(struct ieee80211_h
ep = epmap[skb_get_queue_mapping(skb)];
}
- /* FIXME: The sequence that follows is needed for this driver to
- * work with mac80211 since "mac80211: fix TX sequence numbers".
- * As with the temporary code in rt2x00, changes will be needed
- * to get proper sequence numbers on beacons. In addition, this
- * patch places the sequence number in the hardware state, which
- * limits us to a single virtual state.
- */
- if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
- if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
- priv->seqno += 0x10;
- ieee80211hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
- ieee80211hdr->seq_ctrl |= cpu_to_le16(priv->seqno);
- }
-
info->driver_data[0] = dev;
info->driver_data[1] = urb;
@@ -1185,6 +1171,10 @@ static int __devinit rtl8187_probe(struc
dev->max_signal = 65;
}
+ /*
+ * XXX: Once this driver supports anything that requires
+ * beacons it must implement IEEE80211_TX_CTL_ASSIGN_SEQ.
+ */
dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b)
--- everything.orig/drivers/net/wireless/rtl8187.h 2008-10-10 15:45:49.000000000 +0200
+++ everything/drivers/net/wireless/rtl8187.h 2008-10-10 15:45:56.000000000 +0200
@@ -100,7 +100,6 @@ struct rtl8187_priv {
struct usb_device *udev;
u32 rx_conf;
u16 txpwr_base;
- u16 seqno;
u8 asic_rev;
u8 is_rtl8187b;
enum {

View File

@ -0,0 +1,303 @@
Subject: mac80211: move bss_conf into vif
Move bss_conf into the vif struct so that drivers can
access it during ->tx without having to store it in
the private data or similar. No driver updates because
this is only for when they want to start using it.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
include/net/mac80211.h | 3 +++
net/mac80211/cfg.c | 6 +++---
net/mac80211/debugfs_netdev.c | 2 +-
net/mac80211/ieee80211_i.h | 3 ---
net/mac80211/iface.c | 2 +-
net/mac80211/main.c | 8 ++++----
net/mac80211/mlme.c | 30 +++++++++++++++---------------
net/mac80211/tx.c | 16 ++++++++--------
net/mac80211/util.c | 6 +++---
9 files changed, 38 insertions(+), 38 deletions(-)
--- everything.orig/include/net/mac80211.h 2008-10-10 17:09:04.000000000 +0200
+++ everything/include/net/mac80211.h 2008-10-10 17:09:41.000000000 +0200
@@ -519,11 +519,14 @@ struct ieee80211_conf {
* use during the life of a virtual interface.
*
* @type: type of this virtual interface
+ * @bss_conf: BSS configuration for this interface, either our own
+ * or the BSS we're associated to
* @drv_priv: data area for driver use, will always be aligned to
* sizeof(void *).
*/
struct ieee80211_vif {
enum nl80211_iftype type;
+ struct ieee80211_bss_conf bss_conf;
/* must be last */
u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *))));
};
--- everything.orig/net/mac80211/ieee80211_i.h 2008-10-10 17:10:40.000000000 +0200
+++ everything/net/mac80211/ieee80211_i.h 2008-10-10 17:10:45.000000000 +0200
@@ -440,9 +440,6 @@ struct ieee80211_sub_if_data {
u16 sequence_number;
- /* BSS configuration for this interface. */
- struct ieee80211_bss_conf bss_conf;
-
/*
* AP this belongs to: self in AP mode and
* corresponding AP in VLAN mode, NULL for
--- everything.orig/net/mac80211/main.c 2008-10-10 17:10:55.000000000 +0200
+++ everything/net/mac80211/main.c 2008-10-10 17:11:10.000000000 +0200
@@ -249,15 +249,15 @@ void ieee80211_bss_info_change_notify(st
if (local->ops->bss_info_changed)
local->ops->bss_info_changed(local_to_hw(local),
&sdata->vif,
- &sdata->bss_conf,
+ &sdata->vif.bss_conf,
changed);
}
u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
{
- sdata->bss_conf.use_cts_prot = false;
- sdata->bss_conf.use_short_preamble = false;
- sdata->bss_conf.use_short_slot = false;
+ sdata->vif.bss_conf.use_cts_prot = false;
+ sdata->vif.bss_conf.use_short_preamble = false;
+ sdata->vif.bss_conf.use_short_slot = false;
return BSS_CHANGED_ERP_CTS_PROT |
BSS_CHANGED_ERP_PREAMBLE |
BSS_CHANGED_ERP_SLOT;
--- everything.orig/net/mac80211/iface.c 2008-10-10 17:12:11.000000000 +0200
+++ everything/net/mac80211/iface.c 2008-10-10 17:12:13.000000000 +0200
@@ -695,7 +695,7 @@ int ieee80211_if_change_type(struct ieee
ieee80211_setup_sdata(sdata, type);
/* reset some values that shouldn't be kept across type changes */
- sdata->bss_conf.basic_rates =
+ sdata->vif.bss_conf.basic_rates =
ieee80211_mandatory_rates(sdata->local,
sdata->local->hw.conf.channel->band);
sdata->drop_unencrypted = 0;
--- everything.orig/net/mac80211/mlme.c 2008-10-10 17:11:49.000000000 +0200
+++ everything/net/mac80211/mlme.c 2008-10-10 17:11:58.000000000 +0200
@@ -572,7 +572,7 @@ static void ieee80211_sta_wmm_params(str
static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
u16 capab, bool erp_valid, u8 erp)
{
- struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
+ struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
struct ieee80211_if_sta *ifsta = &sdata->u.sta;
DECLARE_MAC_BUF(mac);
@@ -720,9 +720,9 @@ static void ieee80211_set_associated(str
ifsta->ssid, ifsta->ssid_len);
if (bss) {
/* set timing information */
- sdata->bss_conf.beacon_int = bss->beacon_int;
- sdata->bss_conf.timestamp = bss->timestamp;
- sdata->bss_conf.dtim_period = bss->dtim_period;
+ sdata->vif.bss_conf.beacon_int = bss->beacon_int;
+ sdata->vif.bss_conf.timestamp = bss->timestamp;
+ sdata->vif.bss_conf.dtim_period = bss->dtim_period;
changed |= ieee80211_handle_bss_capability(sdata,
bss->capability, bss->has_erp_value, bss->erp_value);
@@ -732,9 +732,9 @@ static void ieee80211_set_associated(str
if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
changed |= BSS_CHANGED_HT;
- sdata->bss_conf.assoc_ht = 1;
- sdata->bss_conf.ht_cap = &conf->ht_cap;
- sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf;
+ sdata->vif.bss_conf.assoc_ht = 1;
+ sdata->vif.bss_conf.ht_cap = &conf->ht_cap;
+ sdata->vif.bss_conf.ht_bss_conf = &conf->ht_bss_conf;
}
ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET;
@@ -744,7 +744,7 @@ static void ieee80211_set_associated(str
ifsta->last_probe = jiffies;
ieee80211_led_assoc(local, 1);
- sdata->bss_conf.assoc = 1;
+ sdata->vif.bss_conf.assoc = 1;
/*
* For now just always ask the driver to update the basic rateset
* when we have associated, we aren't checking whether it actually
@@ -853,15 +853,15 @@ static void ieee80211_set_disassoc(struc
ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
changed |= ieee80211_reset_erp_info(sdata);
- if (sdata->bss_conf.assoc_ht)
+ if (sdata->vif.bss_conf.assoc_ht)
changed |= BSS_CHANGED_HT;
- sdata->bss_conf.assoc_ht = 0;
- sdata->bss_conf.ht_cap = NULL;
- sdata->bss_conf.ht_bss_conf = NULL;
+ sdata->vif.bss_conf.assoc_ht = 0;
+ sdata->vif.bss_conf.ht_cap = NULL;
+ sdata->vif.bss_conf.ht_bss_conf = NULL;
ieee80211_led_assoc(local, 0);
- sdata->bss_conf.assoc = 0;
+ sdata->vif.bss_conf.assoc = 0;
ieee80211_sta_send_apinfo(sdata, ifsta);
@@ -1194,7 +1194,7 @@ static void ieee80211_rx_mgmt_assoc_resp
u64 rates, basic_rates;
u16 capab_info, status_code, aid;
struct ieee802_11_elems elems;
- struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
+ struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
u8 *pos;
int i, j;
DECLARE_MAC_BUF(mac);
@@ -1337,7 +1337,7 @@ static void ieee80211_rx_mgmt_assoc_resp
}
sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
- sdata->bss_conf.basic_rates = basic_rates;
+ sdata->vif.bss_conf.basic_rates = basic_rates;
/* cf. IEEE 802.11 9.2.12 */
if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
--- everything.orig/net/mac80211/cfg.c 2008-10-10 17:12:29.000000000 +0200
+++ everything/net/mac80211/cfg.c 2008-10-10 17:12:31.000000000 +0200
@@ -966,16 +966,16 @@ static int ieee80211_change_bss(struct w
return -EINVAL;
if (params->use_cts_prot >= 0) {
- sdata->bss_conf.use_cts_prot = params->use_cts_prot;
+ sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot;
changed |= BSS_CHANGED_ERP_CTS_PROT;
}
if (params->use_short_preamble >= 0) {
- sdata->bss_conf.use_short_preamble =
+ sdata->vif.bss_conf.use_short_preamble =
params->use_short_preamble;
changed |= BSS_CHANGED_ERP_PREAMBLE;
}
if (params->use_short_slot_time >= 0) {
- sdata->bss_conf.use_short_slot =
+ sdata->vif.bss_conf.use_short_slot =
params->use_short_slot_time;
changed |= BSS_CHANGED_ERP_SLOT;
}
--- everything.orig/net/mac80211/debugfs_netdev.c 2008-10-10 17:13:26.000000000 +0200
+++ everything/net/mac80211/debugfs_netdev.c 2008-10-10 17:13:28.000000000 +0200
@@ -120,7 +120,7 @@ static ssize_t ieee80211_if_fmt_flags(
sdata->u.sta.flags & IEEE80211_STA_AUTHENTICATED ? "AUTH\n" : "",
sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED ? "ASSOC\n" : "",
sdata->u.sta.flags & IEEE80211_STA_PROBEREQ_POLL ? "PROBEREQ POLL\n" : "",
- sdata->bss_conf.use_cts_prot ? "CTS prot\n" : "");
+ sdata->vif.bss_conf.use_cts_prot ? "CTS prot\n" : "");
}
__IEEE80211_IF_FILE(flags);
--- everything.orig/net/mac80211/tx.c 2008-10-10 17:12:46.000000000 +0200
+++ everything/net/mac80211/tx.c 2008-10-10 17:12:49.000000000 +0200
@@ -116,7 +116,7 @@ static __le16 ieee80211_duration(struct
if (r->bitrate > txrate->bitrate)
break;
- if (tx->sdata->bss_conf.basic_rates & BIT(i))
+ if (tx->sdata->vif.bss_conf.basic_rates & BIT(i))
rate = r->bitrate;
switch (sband->band) {
@@ -150,7 +150,7 @@ static __le16 ieee80211_duration(struct
* to closest integer */
dur = ieee80211_frame_duration(local, 10, rate, erp,
- tx->sdata->bss_conf.use_short_preamble);
+ tx->sdata->vif.bss_conf.use_short_preamble);
if (next_frag_len) {
/* Frame is fragmented: duration increases with time needed to
@@ -159,7 +159,7 @@ static __le16 ieee80211_duration(struct
/* next fragment */
dur += ieee80211_frame_duration(local, next_frag_len,
txrate->bitrate, erp,
- tx->sdata->bss_conf.use_short_preamble);
+ tx->sdata->vif.bss_conf.use_short_preamble);
}
return cpu_to_le16(dur);
@@ -465,7 +465,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021
} else
info->control.retries[0].rate_idx = -1;
- if (tx->sdata->bss_conf.use_cts_prot &&
+ if (tx->sdata->vif.bss_conf.use_cts_prot &&
(tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) {
tx->last_frag_rate_idx = tx->rate_idx;
if (rsel.probe_idx >= 0)
@@ -531,7 +531,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_
if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) &&
(sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_ERP_G) &&
(tx->flags & IEEE80211_TX_UNICAST) &&
- tx->sdata->bss_conf.use_cts_prot &&
+ tx->sdata->vif.bss_conf.use_cts_prot &&
!(info->flags & IEEE80211_TX_CTL_USE_RTS_CTS))
info->flags |= IEEE80211_TX_CTL_USE_CTS_PROTECT;
@@ -540,7 +540,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_
* available on the network at the current point in time. */
if (ieee80211_is_data(hdr->frame_control) &&
(sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
- tx->sdata->bss_conf.use_short_preamble &&
+ tx->sdata->vif.bss_conf.use_short_preamble &&
(!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) {
info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE;
}
@@ -560,7 +560,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_
for (idx = 0; idx < sband->n_bitrates; idx++) {
if (sband->bitrates[idx].bitrate > rate->bitrate)
continue;
- if (tx->sdata->bss_conf.basic_rates & BIT(idx) &&
+ if (tx->sdata->vif.bss_conf.basic_rates & BIT(idx) &&
(baserate < 0 ||
(sband->bitrates[baserate].bitrate
< sband->bitrates[idx].bitrate)))
@@ -1981,7 +1981,7 @@ struct sk_buff *ieee80211_beacon_get(str
info->flags |= IEEE80211_TX_CTL_NO_ACK;
info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
- if (sdata->bss_conf.use_short_preamble &&
+ if (sdata->vif.bss_conf.use_short_preamble &&
sband->bitrates[rsel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE)
info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE;
--- everything.orig/net/mac80211/util.c 2008-10-10 17:13:03.000000000 +0200
+++ everything/net/mac80211/util.c 2008-10-10 17:13:06.000000000 +0200
@@ -239,7 +239,7 @@ __le16 ieee80211_generic_frame_duration(
erp = 0;
if (vif) {
sdata = vif_to_sdata(vif);
- short_preamble = sdata->bss_conf.use_short_preamble;
+ short_preamble = sdata->vif.bss_conf.use_short_preamble;
if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
erp = rate->flags & IEEE80211_RATE_ERP_G;
}
@@ -272,7 +272,7 @@ __le16 ieee80211_rts_duration(struct iee
erp = 0;
if (vif) {
sdata = vif_to_sdata(vif);
- short_preamble = sdata->bss_conf.use_short_preamble;
+ short_preamble = sdata->vif.bss_conf.use_short_preamble;
if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
erp = rate->flags & IEEE80211_RATE_ERP_G;
}
@@ -312,7 +312,7 @@ __le16 ieee80211_ctstoself_duration(stru
erp = 0;
if (vif) {
sdata = vif_to_sdata(vif);
- short_preamble = sdata->bss_conf.use_short_preamble;
+ short_preamble = sdata->vif.bss_conf.use_short_preamble;
if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
erp = rate->flags & IEEE80211_RATE_ERP_G;
}

View File

@ -0,0 +1,506 @@
---
drivers/net/wireless/ath9k/main.c | 1
drivers/net/wireless/b43/main.c | 67 +++++++++++++-----------------
drivers/net/wireless/b43legacy/main.c | 70 ++++++++++++++------------------
drivers/net/wireless/rt2x00/rt2400pci.c | 2
drivers/net/wireless/rt2x00/rt2500pci.c | 2
drivers/net/wireless/rt2x00/rt2x00.h | 3 +
drivers/net/wireless/rt2x00/rt2x00mac.c | 9 ++++
drivers/net/wireless/rt2x00/rt61pci.c | 2
drivers/net/wireless/rt2x00/rt73usb.c | 2
include/net/mac80211.h | 14 ++++--
net/mac80211/debugfs.c | 4 -
net/mac80211/ieee80211_i.h | 2
net/mac80211/main.c | 4 -
net/mac80211/tx.c | 4 -
net/mac80211/wext.c | 28 +++++-------
15 files changed, 106 insertions(+), 108 deletions(-)
--- everything.orig/include/net/mac80211.h 2008-10-10 23:27:46.000000000 +0200
+++ everything/include/net/mac80211.h 2008-10-10 23:31:21.000000000 +0200
@@ -473,6 +473,7 @@ static inline int __deprecated __IEEE802
* @IEEE80211_CONF_CHANGE_PS: the PS flag changed
* @IEEE80211_CONF_CHANGE_POWER: the TX power changed
* @IEEE80211_CONF_CHANGE_CHANNEL: the channel changed
+ * @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed
*/
enum ieee80211_conf_changed {
IEEE80211_CONF_CHANGE_RADIO_ENABLED = BIT(0),
@@ -482,6 +483,7 @@ enum ieee80211_conf_changed {
IEEE80211_CONF_CHANGE_PS = BIT(4),
IEEE80211_CONF_CHANGE_POWER = BIT(5),
IEEE80211_CONF_CHANGE_CHANNEL = BIT(6),
+ IEEE80211_CONF_CHANGE_RETRY_LIMITS = BIT(7),
};
/**
@@ -497,6 +499,12 @@ enum ieee80211_conf_changed {
* @ht_cap: describes current self configuration of 802.11n HT capabilities
* @ht_bss_conf: describes current BSS configuration of 802.11n HT parameters
* @channel: the channel to tune to
+ * @long_frame_max_tx_count: Maximum number of transmissions for a "long" frame
+ * (a frame not RTS protected), called "dot11LongRetryLimit" in 802.11,
+ * but actually means the number of transmissions not the number of retries
+ * @short_frame_max_tx_count: Maximum number of transmissions for a "short" frame,
+ * called "dot11ShortRetryLimit" in 802.11, but actually means the number
+ * of transmissions not the number of retries
*/
struct ieee80211_conf {
int beacon_int;
@@ -506,6 +514,8 @@ struct ieee80211_conf {
u16 listen_interval;
bool radio_enabled;
+ u8 long_frame_max_tx_count, short_frame_max_tx_count;
+
struct ieee80211_channel *channel;
struct ieee80211_sta_ht_cap ht_cap;
@@ -1192,8 +1202,6 @@ enum ieee80211_ampdu_mlme_action {
* the device does fragmentation by itself; if this method is assigned then
* the stack will not do fragmentation.
*
- * @set_retry_limit: Configuration of retry limits (if device needs it)
- *
* @sta_notify: Notifies low level driver about addition or removal
* of assocaited station or AP.
*
@@ -1263,8 +1271,6 @@ struct ieee80211_ops {
u32 *iv32, u16 *iv16);
int (*set_rts_threshold)(struct ieee80211_hw *hw, u32 value);
int (*set_frag_threshold)(struct ieee80211_hw *hw, u32 value);
- int (*set_retry_limit)(struct ieee80211_hw *hw,
- u32 short_retry, u32 long_retr);
void (*sta_notify)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
enum sta_notify_cmd, struct ieee80211_sta *sta);
int (*conf_tx)(struct ieee80211_hw *hw, u16 queue,
--- everything.orig/net/mac80211/ieee80211_i.h 2008-10-10 23:27:46.000000000 +0200
+++ everything/net/mac80211/ieee80211_i.h 2008-10-10 23:31:22.000000000 +0200
@@ -632,8 +632,6 @@ struct ieee80211_local {
int rts_threshold;
int fragmentation_threshold;
- int short_retry_limit; /* dot11ShortRetryLimit */
- int long_retry_limit; /* dot11LongRetryLimit */
struct crypto_blkcipher *wep_tx_tfm;
struct crypto_blkcipher *wep_rx_tfm;
--- everything.orig/net/mac80211/main.c 2008-10-10 23:27:46.000000000 +0200
+++ everything/net/mac80211/main.c 2008-10-10 23:31:22.000000000 +0200
@@ -673,8 +673,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(
local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
- local->short_retry_limit = 7;
- local->long_retry_limit = 4;
+ local->hw.conf.long_frame_max_tx_count = 4;
+ local->hw.conf.short_frame_max_tx_count = 7;
local->hw.conf.radio_enabled = true;
INIT_LIST_HEAD(&local->interfaces);
--- everything.orig/net/mac80211/wext.c 2008-10-10 23:27:46.000000000 +0200
+++ everything/net/mac80211/wext.c 2008-10-10 23:31:22.000000000 +0200
@@ -802,21 +802,16 @@ static int ieee80211_ioctl_siwretry(stru
(retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
return -EINVAL;
- if (retry->flags & IW_RETRY_MAX)
- local->long_retry_limit = retry->value;
- else if (retry->flags & IW_RETRY_MIN)
- local->short_retry_limit = retry->value;
- else {
- local->long_retry_limit = retry->value;
- local->short_retry_limit = retry->value;
+ if (retry->flags & IW_RETRY_MAX) {
+ local->hw.conf.long_frame_max_tx_count = retry->value;
+ } else if (retry->flags & IW_RETRY_MIN) {
+ local->hw.conf.short_frame_max_tx_count = retry->value;
+ } else {
+ local->hw.conf.long_frame_max_tx_count = retry->value;
+ local->hw.conf.short_frame_max_tx_count = retry->value;
}
- if (local->ops->set_retry_limit) {
- return local->ops->set_retry_limit(
- local_to_hw(local),
- local->short_retry_limit,
- local->long_retry_limit);
- }
+ ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
return 0;
}
@@ -833,14 +828,15 @@ static int ieee80211_ioctl_giwretry(stru
/* first return min value, iwconfig will ask max value
* later if needed */
retry->flags |= IW_RETRY_LIMIT;
- retry->value = local->short_retry_limit;
- if (local->long_retry_limit != local->short_retry_limit)
+ retry->value = local->hw.conf.short_frame_max_tx_count;
+ if (local->hw.conf.long_frame_max_tx_count !=
+ local->hw.conf.short_frame_max_tx_count)
retry->flags |= IW_RETRY_MIN;
return 0;
}
if (retry->flags & IW_RETRY_MAX) {
retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
- retry->value = local->long_retry_limit;
+ retry->value = local->hw.conf.long_frame_max_tx_count;
}
return 0;
--- everything.orig/drivers/net/wireless/ath9k/main.c 2008-10-10 23:27:47.000000000 +0200
+++ everything/drivers/net/wireless/ath9k/main.c 2008-10-10 23:31:23.000000000 +0200
@@ -1657,7 +1657,6 @@ static struct ieee80211_ops ath9k_ops =
.get_tkip_seq = NULL,
.set_rts_threshold = NULL,
.set_frag_threshold = NULL,
- .set_retry_limit = NULL,
.get_tsf = ath9k_get_tsf,
.reset_tsf = ath9k_reset_tsf,
.tx_last_beacon = NULL,
--- everything.orig/drivers/net/wireless/b43/main.c 2008-10-10 23:27:47.000000000 +0200
+++ everything/drivers/net/wireless/b43/main.c 2008-10-10 23:31:23.000000000 +0200
@@ -3320,6 +3320,22 @@ init_failure:
return err;
}
+/* Write the short and long frame retry limit values. */
+static void b43_set_retry_limits(struct b43_wldev *dev,
+ unsigned int short_retry,
+ unsigned int long_retry)
+{
+ /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing
+ * the chip-internal counter. */
+ short_retry = min(short_retry, (unsigned int)0xF);
+ long_retry = min(long_retry, (unsigned int)0xF);
+
+ b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_SRLIMIT,
+ short_retry);
+ b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_LRLIMIT,
+ long_retry);
+}
+
static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
@@ -3333,6 +3349,20 @@ static int b43_op_config(struct ieee8021
mutex_lock(&wl->mutex);
+ if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
+ dev = wl->current_dev;
+ if (unlikely(!dev || (b43_status(dev) < B43_STAT_INITIALIZED))) {
+ err = -ENODEV;
+ goto out_unlock_mutex;
+ }
+ b43_set_retry_limits(dev, conf->short_frame_max_tx_count,
+ conf->long_frame_max_tx_count);
+ changed &= ~IEEE80211_CONF_CHANGE_RETRY_LIMITS;
+ }
+
+ if (!changed)
+ goto out_unlock_mutex;
+
/* Switch the band (if necessary). This might change the active core. */
err = b43_switch_band(wl, conf->channel);
if (err)
@@ -3860,22 +3890,6 @@ static void b43_imcfglo_timeouts_workaro
#endif /* CONFIG_SSB_DRIVER_PCICORE */
}
-/* Write the short and long frame retry limit values. */
-static void b43_set_retry_limits(struct b43_wldev *dev,
- unsigned int short_retry,
- unsigned int long_retry)
-{
- /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing
- * the chip-internal counter. */
- short_retry = min(short_retry, (unsigned int)0xF);
- long_retry = min(long_retry, (unsigned int)0xF);
-
- b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_SRLIMIT,
- short_retry);
- b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_LRLIMIT,
- long_retry);
-}
-
static void b43_set_synth_pu_delay(struct b43_wldev *dev, bool idle)
{
u16 pu_delay;
@@ -4196,26 +4210,6 @@ static void b43_op_stop(struct ieee80211
cancel_work_sync(&(wl->txpower_adjust_work));
}
-static int b43_op_set_retry_limit(struct ieee80211_hw *hw,
- u32 short_retry_limit, u32 long_retry_limit)
-{
- struct b43_wl *wl = hw_to_b43_wl(hw);
- struct b43_wldev *dev;
- int err = 0;
-
- mutex_lock(&wl->mutex);
- dev = wl->current_dev;
- if (unlikely(!dev || (b43_status(dev) < B43_STAT_INITIALIZED))) {
- err = -ENODEV;
- goto out_unlock;
- }
- b43_set_retry_limits(dev, short_retry_limit, long_retry_limit);
-out_unlock:
- mutex_unlock(&wl->mutex);
-
- return err;
-}
-
static int b43_op_beacon_set_tim(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, bool set)
{
@@ -4252,7 +4246,6 @@ static const struct ieee80211_ops b43_hw
.get_tx_stats = b43_op_get_tx_stats,
.start = b43_op_start,
.stop = b43_op_stop,
- .set_retry_limit = b43_op_set_retry_limit,
.set_tim = b43_op_beacon_set_tim,
.sta_notify = b43_op_sta_notify,
};
--- everything.orig/drivers/net/wireless/b43legacy/main.c 2008-10-10 23:27:47.000000000 +0200
+++ everything/drivers/net/wireless/b43legacy/main.c 2008-10-10 23:31:23.000000000 +0200
@@ -2556,6 +2556,20 @@ init_failure:
return err;
}
+/* Write the short and long frame retry limit values. */
+static void b43legacy_set_retry_limits(struct b43legacy_wldev *dev,
+ unsigned int short_retry,
+ unsigned int long_retry)
+{
+ /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing
+ * the chip-internal counter. */
+ short_retry = min(short_retry, (unsigned int)0xF);
+ long_retry = min(long_retry, (unsigned int)0xF);
+
+ b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0006, short_retry);
+ b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0007, long_retry);
+}
+
static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
u32 changed)
{
@@ -2570,10 +2584,27 @@ static int b43legacy_op_dev_config(struc
int err = 0;
u32 savedirqs;
+ mutex_lock(&wl->mutex);
+ dev = wl->current_dev;
+
+ if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
+ if (unlikely(!dev ||
+ (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED))) {
+ err = -ENODEV;
+ goto out_unlock_mutex;
+ }
+ b43legacy_set_retry_limits(dev,
+ conf->short_frame_max_tx_count,
+ conf->long_frame_max_tx_count);
+ changed &= ~IEEE80211_CONF_CHANGE_RETRY_LIMITS;
+ }
+
+ if (!changed)
+ goto out_unlock_mutex;
+
antenna_tx = B43legacy_ANTENNA_DEFAULT;
antenna_rx = B43legacy_ANTENNA_DEFAULT;
- mutex_lock(&wl->mutex);
dev = wl->current_dev;
phy = &dev->phy;
@@ -2989,20 +3020,6 @@ static void b43legacy_imcfglo_timeouts_w
#endif /* CONFIG_SSB_DRIVER_PCICORE */
}
-/* Write the short and long frame retry limit values. */
-static void b43legacy_set_retry_limits(struct b43legacy_wldev *dev,
- unsigned int short_retry,
- unsigned int long_retry)
-{
- /* The retry limit is a 4-bit counter. Enforce this to avoid overflowing
- * the chip-internal counter. */
- short_retry = min(short_retry, (unsigned int)0xF);
- long_retry = min(long_retry, (unsigned int)0xF);
-
- b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0006, short_retry);
- b43legacy_shm_write16(dev, B43legacy_SHM_WIRELESS, 0x0007, long_retry);
-}
-
static void b43legacy_set_synth_pu_delay(struct b43legacy_wldev *dev,
bool idle) {
u16 pu_delay = 1050;
@@ -3367,28 +3384,6 @@ static void b43legacy_op_stop(struct iee
mutex_unlock(&wl->mutex);
}
-static int b43legacy_op_set_retry_limit(struct ieee80211_hw *hw,
- u32 short_retry_limit,
- u32 long_retry_limit)
-{
- struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
- struct b43legacy_wldev *dev;
- int err = 0;
-
- mutex_lock(&wl->mutex);
- dev = wl->current_dev;
- if (unlikely(!dev ||
- (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED))) {
- err = -ENODEV;
- goto out_unlock;
- }
- b43legacy_set_retry_limits(dev, short_retry_limit, long_retry_limit);
-out_unlock:
- mutex_unlock(&wl->mutex);
-
- return err;
-}
-
static int b43legacy_op_beacon_set_tim(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, bool set)
{
@@ -3414,7 +3409,6 @@ static const struct ieee80211_ops b43leg
.get_tx_stats = b43legacy_op_get_tx_stats,
.start = b43legacy_op_start,
.stop = b43legacy_op_stop,
- .set_retry_limit = b43legacy_op_set_retry_limit,
.set_tim = b43legacy_op_beacon_set_tim,
};
--- everything.orig/drivers/net/wireless/rt2x00/rt2400pci.c 2008-10-10 23:27:46.000000000 +0200
+++ everything/drivers/net/wireless/rt2x00/rt2400pci.c 2008-10-10 23:27:48.000000000 +0200
@@ -1576,7 +1576,6 @@ static const struct ieee80211_ops rt2400
.config_interface = rt2x00mac_config_interface,
.configure_filter = rt2x00mac_configure_filter,
.get_stats = rt2x00mac_get_stats,
- .set_retry_limit = rt2400pci_set_retry_limit,
.bss_info_changed = rt2x00mac_bss_info_changed,
.conf_tx = rt2400pci_conf_tx,
.get_tx_stats = rt2x00mac_get_tx_stats,
@@ -1605,6 +1604,7 @@ static const struct rt2x00lib_ops rt2400
.config_intf = rt2400pci_config_intf,
.config_erp = rt2400pci_config_erp,
.config = rt2400pci_config,
+ .set_retry_limit = rt2400pci_set_retry_limit,
};
static const struct data_queue_desc rt2400pci_queue_rx = {
--- everything.orig/drivers/net/wireless/rt2x00/rt2x00.h 2008-10-10 23:27:47.000000000 +0200
+++ everything/drivers/net/wireless/rt2x00/rt2x00.h 2008-10-10 23:27:48.000000000 +0200
@@ -599,6 +599,9 @@ struct rt2x00lib_ops {
#define CONFIG_UPDATE_SLOT_TIME ( 1 << 5 )
#define CONFIG_UPDATE_BEACON_INT ( 1 << 6 )
#define CONFIG_UPDATE_ALL 0xffff
+
+ int (*set_retry_limit) (struct ieee80211_hw *hw,
+ u32 short_limit, u32 long_limit);
};
/*
--- everything.orig/drivers/net/wireless/rt2x00/rt2500pci.c 2008-10-10 23:27:46.000000000 +0200
+++ everything/drivers/net/wireless/rt2x00/rt2500pci.c 2008-10-10 23:27:48.000000000 +0200
@@ -1877,7 +1877,6 @@ static const struct ieee80211_ops rt2500
.config_interface = rt2x00mac_config_interface,
.configure_filter = rt2x00mac_configure_filter,
.get_stats = rt2x00mac_get_stats,
- .set_retry_limit = rt2500pci_set_retry_limit,
.bss_info_changed = rt2x00mac_bss_info_changed,
.conf_tx = rt2x00mac_conf_tx,
.get_tx_stats = rt2x00mac_get_tx_stats,
@@ -1906,6 +1905,7 @@ static const struct rt2x00lib_ops rt2500
.config_intf = rt2500pci_config_intf,
.config_erp = rt2500pci_config_erp,
.config = rt2500pci_config,
+ .set_retry_limit = rt2500pci_set_retry_limit,
};
static const struct data_queue_desc rt2500pci_queue_rx = {
--- everything.orig/drivers/net/wireless/rt2x00/rt61pci.c 2008-10-10 23:27:47.000000000 +0200
+++ everything/drivers/net/wireless/rt2x00/rt61pci.c 2008-10-10 23:27:48.000000000 +0200
@@ -2726,7 +2726,6 @@ static const struct ieee80211_ops rt61pc
.configure_filter = rt2x00mac_configure_filter,
.set_key = rt2x00mac_set_key,
.get_stats = rt2x00mac_get_stats,
- .set_retry_limit = rt61pci_set_retry_limit,
.bss_info_changed = rt2x00mac_bss_info_changed,
.conf_tx = rt61pci_conf_tx,
.get_tx_stats = rt2x00mac_get_tx_stats,
@@ -2759,6 +2758,7 @@ static const struct rt2x00lib_ops rt61pc
.config_intf = rt61pci_config_intf,
.config_erp = rt61pci_config_erp,
.config = rt61pci_config,
+ .set_retry_limit = rt61pci_set_retry_limit,
};
static const struct data_queue_desc rt61pci_queue_rx = {
--- everything.orig/drivers/net/wireless/rt2x00/rt73usb.c 2008-10-10 23:27:47.000000000 +0200
+++ everything/drivers/net/wireless/rt2x00/rt73usb.c 2008-10-10 23:27:48.000000000 +0200
@@ -2317,7 +2317,6 @@ static const struct ieee80211_ops rt73us
.configure_filter = rt2x00mac_configure_filter,
.set_key = rt2x00mac_set_key,
.get_stats = rt2x00mac_get_stats,
- .set_retry_limit = rt73usb_set_retry_limit,
.bss_info_changed = rt2x00mac_bss_info_changed,
.conf_tx = rt73usb_conf_tx,
.get_tx_stats = rt2x00mac_get_tx_stats,
@@ -2349,6 +2348,7 @@ static const struct rt2x00lib_ops rt73us
.config_intf = rt73usb_config_intf,
.config_erp = rt73usb_config_erp,
.config = rt73usb_config,
+ .set_retry_limit = rt73usb_set_retry_limit,
};
static const struct data_queue_desc rt73usb_queue_rx = {
--- everything.orig/drivers/net/wireless/rt2x00/rt2x00mac.c 2008-10-10 23:27:46.000000000 +0200
+++ everything/drivers/net/wireless/rt2x00/rt2x00mac.c 2008-10-10 23:31:23.000000000 +0200
@@ -349,6 +349,15 @@ int rt2x00mac_config(struct ieee80211_hw
if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
return 0;
+ if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
+ rt2x00dev->ops->lib->set_retry_limit(hw,
+ conf->short_frame_max_tx_count,
+ conf->long_frame_max_tx_count);
+ }
+ changed &= ~IEEE80211_CONF_CHANGE_RETRY_LIMITS;
+ if (!changed)
+ return 0;
+
/*
* Only change device state when the radio is enabled. It does not
* matter what parameters we have configured when the radio is disabled
--- everything.orig/net/mac80211/debugfs.c 2008-10-10 23:27:46.000000000 +0200
+++ everything/net/mac80211/debugfs.c 2008-10-10 23:27:48.000000000 +0200
@@ -52,9 +52,9 @@ DEBUGFS_READONLY_FILE(rts_threshold, 20,
DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d",
local->fragmentation_threshold);
DEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d",
- local->short_retry_limit);
+ local->hw.conf.short_frame_max_tx_count);
DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d",
- local->long_retry_limit);
+ local->hw.conf.long_frame_max_tx_count);
DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d",
local->total_ps_buffered);
DEBUGFS_READONLY_FILE(wep_iv, 20, "%#06x",
--- everything.orig/net/mac80211/tx.c 2008-10-10 23:27:46.000000000 +0200
+++ everything/net/mac80211/tx.c 2008-10-10 23:31:22.000000000 +0200
@@ -507,10 +507,10 @@ ieee80211_tx_h_misc(struct ieee80211_tx_
info->flags |=
IEEE80211_TX_CTL_LONG_RETRY_LIMIT;
info->control.retry_limit =
- tx->local->long_retry_limit;
+ tx->local->hw.conf.long_frame_max_tx_count - 1;
} else {
info->control.retry_limit =
- tx->local->short_retry_limit;
+ tx->local->hw.conf.short_frame_max_tx_count - 1;
}
} else {
info->control.retry_limit = 1;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,100 @@
This patch enhances minstrel's performance for non-MRR setups,
by preventing it from sampling slower rates with >95% success
probability and by putting at least 1 non-sample frame between
several sample frames.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -126,7 +126,9 @@ minstrel_update_stats(struct minstrel_pr
mr->adjusted_retry_count = mr->retry_count >> 1;
if (mr->adjusted_retry_count > 2)
mr->adjusted_retry_count = 2;
+ mr->sample_limit = 4;
} else {
+ mr->sample_limit = -1;
mr->adjusted_retry_count = mr->retry_count;
}
if (!mr->adjusted_retry_count)
@@ -265,7 +267,8 @@ minstrel_get_rate(void *priv, struct iee
(mi->sample_count + mi->sample_deferred / 2);
/* delta > 0: sampling required */
- if (delta > 0) {
+ if ((delta > 0) && (mrr || !mi->prev_sample)) {
+ struct minstrel_rate *msr;
if (mi->packet_count >= 10000) {
mi->sample_deferred = 0;
mi->sample_count = 0;
@@ -284,13 +287,20 @@ minstrel_get_rate(void *priv, struct iee
}
sample_ndx = minstrel_get_next_sample(mi);
+ msr = &mi->r[sample_ndx];
sample = true;
- sample_slower = mrr && (mi->r[sample_ndx].perfect_tx_time >
+ sample_slower = mrr && (msr->perfect_tx_time >
mi->r[ndx].perfect_tx_time);
if (!sample_slower) {
- ndx = sample_ndx;
- mi->sample_count++;
+ if (msr->sample_limit != 0) {
+ ndx = sample_ndx;
+ mi->sample_count++;
+ if (msr->sample_limit > 0)
+ msr->sample_limit--;
+ } else {
+ sample = false;
+ }
} else {
/* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark
* packets that have the sampling rate deferred to the
@@ -302,10 +312,20 @@ minstrel_get_rate(void *priv, struct iee
mi->sample_deferred++;
}
}
+ mi->prev_sample = sample;
+
+ /* If we're not using MRR and the sampling rate already
+ * has a probability of >95%, we shouldn't be attempting
+ * to use it, as this only wastes precious airtime */
+ if (!mrr && sample && (mi->r[ndx].probability > 17100))
+ ndx = mi->max_tp_rate;
+
ar[0].idx = mi->r[ndx].rix;
ar[0].count = minstrel_get_retry_count(&mi->r[ndx], info);
if (!mrr) {
+ if (!sample)
+ ar[0].count = mp->max_retry;
ar[1].idx = mi->lowest_rix;
ar[1].count = mp->max_retry;
return;
@@ -401,6 +421,7 @@ minstrel_rate_init(void *priv, struct ie
/* calculate maximum number of retransmissions before
* fallback (based on maximum segment size) */
+ mr->sample_limit = -1;
mr->retry_count = 1;
mr->retry_count_cts = 1;
mr->retry_count_rtscts = 1;
--- a/net/mac80211/rc80211_minstrel.h
+++ b/net/mac80211/rc80211_minstrel.h
@@ -16,6 +16,7 @@ struct minstrel_rate {
unsigned int perfect_tx_time;
unsigned int ack_time;
+ int sample_limit;
unsigned int retry_count;
unsigned int retry_count_cts;
unsigned int retry_count_rtscts;
@@ -57,6 +58,7 @@ struct minstrel_sta_info {
int n_rates;
struct minstrel_rate *r;
+ bool prev_sample;
/* sampling table */
u8 *sample_table;