rt2x00: Fix rate detection for invalid signals
PATCH 1/2 rt2x00: Fix rate detection for invalid signals
It has been observed on rt2500pci hardware that some frames received with signal 0x0C do not have the OFDM flag set.
Signals can have 2 meanings:
1) The PLCP value
2) The bitrate * 10
For rt2500pci (1) is for frames received with a OFDM rate, and (2) is for frames received with a CCK rate. But 0x0C is a invalid bitrate value but is a valid PLCP value for 54Mbs (obvious OFDM rate).
This means that it is possible that the hardware does not set the OFDM bit correctly under all circumstances. This results in rt2x00 failing to detect the rate and mac80211 triggering a WARN_ON() and dropping the frame.
To bypass this, print a warning when such a frame is received, and reset the rate to the lowest supported rate for the current band.
--- drivers/net/wireless/rt2x00/rt2x00dev.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
drivers/net/wireless/rt2x00/rt2x00dev.c +7 -0
@@ -589,6 +589,13 @@ void rt2x00lib_rxdone(struct queue_entry *entry, } } +if (idx <0 ) { +WARNING (rt2x00dev,"Frame received with unrecognized signal," +"signal=0x%.2x, plcp=%d.\n" , rxdesc->signal, + !!(rxdesc->dev_flags &RXDONE_SIGNAL_PLCP )); + idx =0 ; + } +/* * Only update link status if this is a beacon frame carrying our bssid. */
Signature · 1 line
1.5.4.4
PATCH 2/2 rt2x00: Fix in_atomic() usage
rt73usb and rt2500usb used in_atomic to determine if a configuration step should be rescheduled or not. Since in_atomic() is not a valid method to determine if sleeping is allowed we should fix the way this is handled by adding a new flag to rt2x00.
In addition mark LED class support for the drivers broken since that also uses the broken in_atomic() method but so far no solution exists to have LED triggers work only in scheduled context.
--- drivers/net/wireless/rt2x00/Kconfig | 4 +- drivers/net/wireless/rt2x00/rt2400pci.c | 92 +++++++-------------- drivers/net/wireless/rt2x00/rt2500pci.c | 101 ++++++++--------------- drivers/net/wireless/rt2x00/rt2500usb.c | 118 ++++++++------------------- drivers/net/wireless/rt2x00/rt2x00.h | 11 ++- drivers/net/wireless/rt2x00/rt2x00config.c | 10 +-- drivers/net/wireless/rt2x00/rt2x00mac.c | 57 +++++++++++++- drivers/net/wireless/rt2x00/rt61pci.c | 105 ++++++++---------------- drivers/net/wireless/rt2x00/rt73usb.c | 122 ++++++++------------------- 9 files changed, 234 insertions(+), 386 deletions(-)
drivers/net/wireless/rt2x00/Kconfig +2 -2
@@ -134,7 +134,7 @@ config RT2500USB config RT2500USB_LEDS bool "RT2500 leds support" - depends on RT2500USB + depends on RT2500USB && BROKEN select RT2X00_LIB_LEDS ---help--- This adds support for led triggers provided my mac80211.
@@ -152,7 +152,7 @@ config RT73USB config RT73USB_LEDS bool "RT73 leds support" - depends on RT73USB + depends on RT73USB && BROKEN select RT2X00_LIB_LEDS ---help--- This adds support for led triggers provided my mac80211.
drivers/net/wireless/rt2x00/rt2400pci.c +29 -63
128 lines not on this page · raw message
drivers/net/wireless/rt2x00/rt2500pci.c +33 -68
137 lines not on this page · raw message
drivers/net/wireless/rt2x00/rt2500usb.c +34 -84
163 lines not on this page · raw message
drivers/net/wireless/rt2x00/rt2x00.h +9 -2
@@ -560,6 +560,8 @@ struct rt2x00lib_ops {/* * Configuration handlers. */ +void (*config_filter) (struct rt2x00_dev *rt2x00dev, +const unsigned int filter_flags); void (*config_intf) (struct rt2x00_dev *rt2x00dev, struct rt2x00_intf *intf, struct rt2x00intf_conf *conf,
@@ -568,8 +570,8 @@ struct rt2x00lib_ops {#define CONFIG_UPDATE_MAC ( 1 << 2 )#define CONFIG_UPDATE_BSSID ( 1 << 3 ) -int (*config_erp) (struct rt2x00_dev *rt2x00dev, -struct rt2x00lib_erp *erp); +void (*config_erp) (struct rt2x00_dev *rt2x00dev, +struct rt2x00lib_erp *erp);void (*config) (struct rt2x00_dev *rt2x00dev,struct rt2x00lib_conf *libconf,const unsigned int flags);
@@ -624,6 +626,7 @@ enum rt2x00_flags {DRIVER_REQUIRE_FIRMWARE ,DRIVER_REQUIRE_BEACON_GUARD ,DRIVER_REQUIRE_ATIM_QUEUE , + DRIVER_REQUIRE_SCHEDULED,/* * Driver configuration
@@ -988,6 +991,10 @@ int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);int rt2x00mac_config_interface (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_if_conf *conf); +void rt2x00mac_configure_filter (struct ieee80211_hw *hw, +unsigned int changed_flags, +unsigned int *total_flags, +int mc_count,struct dev_addr_list *mc_list);int rt2x00mac_get_stats (struct ieee80211_hw *hw,struct ieee80211_low_level_stats *stats); int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
drivers/net/wireless/rt2x00/rt2x00config.c +1 -9
@@ -80,7 +80,6 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, struct ieee80211_bss_conf *bss_conf) {struct rt2x00lib_erp erp; -int retval;memset (&erp,0 ,sizeof (erp));
@@ -101,14 +100,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, erp.ack_consume_time +=PREAMBLE ; } - retval = rt2x00dev->ops->lib->config_erp (rt2x00dev, &erp); - -if (retval) { -spin_lock (&intf->lock); - intf->delayed_flags |=DELAYED_CONFIG_ERP ; -queue_work (rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); -spin_unlock (&intf->lock); - } + rt2x00dev->ops->lib->config_erp (rt2x00dev, &erp); } void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
drivers/net/wireless/rt2x00/rt2x00mac.c +55 -2
78 lines not on this page · raw message
drivers/net/wireless/rt2x00/rt61pci.c +35 -70
141 lines not on this page · raw message
drivers/net/wireless/rt2x00/rt73usb.c +36 -86
167 lines not on this page · raw message
Signature · 1 line
1.5.4.4