* Please pull 'upstream' branch of rt2x00
@ 2007-09-25 18:52 Ivo van Doorn
2007-09-25 18:53 ` [PATCH 1/12] rt2x00: Correct error in calculating rssi for link tuner Ivo van Doorn
` (11 more replies)
0 siblings, 12 replies; 13+ messages in thread
From: Ivo van Doorn @ 2007-09-25 18:52 UTC (permalink / raw)
To: John W. Linville, linux-wireless, rt2400-devel
Hi John,
(Finally) the rt2x00 2.0.9 release containing the patches
for the API changes from the mac80211-misc git tree.
NOTE: currently rt2x00.git is branched off from the mac80211-misc
tree to make the porting easier and to allow early testing.
So you might want to pull that tree before pulling rt2x00.
This release contains several bug fixes especially some kernel
panics during rmmod have been fixed by Modestas Vainius.
---
The following changes since commit 4cceb887147261d7fd9fe7ce3b6d6f236c8300bc:
Michael Wu (1):
adm8211: Adapt to filter configuration API
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/ivd/rt2x00.git/ upstream
Ivo van Doorn (11):
rt2x00: Correct error in calculating rssi for link tuner
rt2x00: Make *_beacon_update static
rt2x00: Increase rt2x00usb_vendor_request timeout.
rt2x00: Correctly identify rt2561turbo
rt2x00: adapt to filter configuration API
rt2x00: Reorganize rt2x00dev->flags
rt2x00: Add rt2x00dev->flags to debugfs
rt2x00: Stop link tuning when radio is down
rt2x00: Fix obvious typo in comment
rt2x00: Fix panic on rmmod with rfkill enabled
rt2x00: Release rt2x00 2.0.9
Modestas Vainius (1):
rt2x00: make rt2x00lib_stop_link_tuner() reentrant with link_tuner work
drivers/net/wireless/rt2x00/rt2400pci.c | 159 +++++++++++++-----------
drivers/net/wireless/rt2x00/rt2500pci.c | 171 ++++++++++++++------------
drivers/net/wireless/rt2x00/rt2500usb.c | 181 ++++++++++++++++------------
drivers/net/wireless/rt2x00/rt2x00.h | 70 ++++-------
drivers/net/wireless/rt2x00/rt2x00config.c | 75 +-----------
drivers/net/wireless/rt2x00/rt2x00debug.c | 37 ++++++
drivers/net/wireless/rt2x00/rt2x00dev.c | 109 +++++++++++++-----
drivers/net/wireless/rt2x00/rt2x00lib.h | 4 +-
drivers/net/wireless/rt2x00/rt2x00mac.c | 155 ++++++++----------------
drivers/net/wireless/rt2x00/rt2x00pci.c | 31 ++---
drivers/net/wireless/rt2x00/rt2x00rfkill.c | 14 +--
drivers/net/wireless/rt2x00/rt2x00ring.h | 17 +++-
drivers/net/wireless/rt2x00/rt2x00usb.c | 26 ++---
drivers/net/wireless/rt2x00/rt2x00usb.h | 8 +-
drivers/net/wireless/rt2x00/rt61pci.c | 172 ++++++++++++++------------
drivers/net/wireless/rt2x00/rt73usb.c | 179 ++++++++++++++++------------
drivers/net/wireless/rt2x00/rt73usb.h | 2 +-
17 files changed, 728 insertions(+), 682 deletions(-)
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 1/12] rt2x00: Correct error in calculating rssi for link tuner
2007-09-25 18:52 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
@ 2007-09-25 18:53 ` Ivo van Doorn
2007-09-25 18:53 ` [PATCH 2/12] rt2x00: Make *_beacon_update static Ivo van Doorn
` (10 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Ivo van Doorn @ 2007-09-25 18:53 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
The call to rt2x00lib_precalculate_link_signal resets link.rx_success which is needed
when calculating the average rssi for the link tuner. Change the call order so the link
tuner runs first as it doesn't need the result of the precalculate.
Signed-off-by: Adam Baker <linux@baker-net.org.uk>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00dev.c | 8 ++++++--
1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index cd82eef..5780d6a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -240,8 +240,6 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
rt2x00dev->low_level_stats.dot11FCSErrorCount +=
rt2x00dev->link.rx_failed;
- rt2x00lib_precalculate_link_signal(&rt2x00dev->link);
-
/*
* Only perform the link tuning when Link tuning
* has been enabled (This could have been disabled from the EEPROM).
@@ -250,6 +248,12 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
rt2x00dev->ops->lib->link_tuner(rt2x00dev);
/*
+ * Precalculate a portion of the link signal which is
+ * in based on the tx/rx success/failure counters.
+ */
+ rt2x00lib_precalculate_link_signal(&rt2x00dev->link);
+
+ /*
* Increase tuner counter, and reschedule the next link tuner run.
*/
rt2x00dev->link.count++;
--
1.5.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 2/12] rt2x00: Make *_beacon_update static
2007-09-25 18:52 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
2007-09-25 18:53 ` [PATCH 1/12] rt2x00: Correct error in calculating rssi for link tuner Ivo van Doorn
@ 2007-09-25 18:53 ` Ivo van Doorn
2007-09-25 18:54 ` [PATCH 3/12] rt2x00: Increase rt2x00usb_vendor_request timeout Ivo van Doorn
` (9 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Ivo van Doorn @ 2007-09-25 18:53 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
Make rt61pci_beacon_update and rt73usb_beacon_update static,
they are only used inside their own source file and then only
for setting it as callback funtion for mac80211.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt61pci.c | 2 +-
drivers/net/wireless/rt2x00/rt73usb.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 09c8c96..69ed178 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2462,7 +2462,7 @@ static void rt61pci_reset_tsf(struct ieee80211_hw *hw)
rt2x00pci_register_write(rt2x00dev, TXRX_CSR13, 0);
}
-int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
+static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ieee80211_tx_control *control)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 3397881..890b449 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1939,7 +1939,7 @@ static void rt73usb_reset_tsf(struct ieee80211_hw *hw)
rt73usb_register_write(rt2x00dev, TXRX_CSR13, 0);
}
-int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
+static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ieee80211_tx_control *control)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
--
1.5.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 3/12] rt2x00: Increase rt2x00usb_vendor_request timeout.
2007-09-25 18:52 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
2007-09-25 18:53 ` [PATCH 1/12] rt2x00: Correct error in calculating rssi for link tuner Ivo van Doorn
2007-09-25 18:53 ` [PATCH 2/12] rt2x00: Make *_beacon_update static Ivo van Doorn
@ 2007-09-25 18:54 ` Ivo van Doorn
2007-09-25 18:54 ` [PATCH 4/12] rt2x00: Correctly identify rt2561turbo Ivo van Doorn
` (8 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Ivo van Doorn @ 2007-09-25 18:54 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
By increasing the timeout for rt2x00usb_vendor_request,
we should limit the number of loops required to send
a signal to the device succefully.
500ms timeout is specified by the Ralink legacy drivers
for rt2500usb. For rt73usb 1000ms is specified, but that
includes the timeout for the firmware which is already
specified in a different define.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00usb.c | 10 ++++------
drivers/net/wireless/rt2x00/rt2x00usb.h | 8 ++++----
2 files changed, 8 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index a0f05ca..248144f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -42,7 +42,7 @@ int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev,
const u8 request, const u8 requesttype,
const u16 offset, const u16 value,
void *buffer, const u16 buffer_length,
- u16 timeout)
+ const int timeout)
{
struct usb_device *usb_dev =
interface_to_usbdev(rt2x00dev_usb(rt2x00dev));
@@ -60,12 +60,10 @@ int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev,
return 0;
/*
- * Check for errors,
- * -ETIMEDOUT: We need a bit more time to complete.
+ * Check for errors
* -ENODEV: Device has disappeared, no point continuing.
+ * All other errors: Try again.
*/
- if (status == -ETIMEDOUT)
- timeout *= 2;
else if (status == -ENODEV)
break;
}
@@ -81,7 +79,7 @@ EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request);
int rt2x00usb_vendor_request_buff(const struct rt2x00_dev *rt2x00dev,
const u8 request, const u8 requesttype,
const u16 offset, void *buffer,
- const u16 buffer_length, u16 timeout)
+ const u16 buffer_length, const int timeout)
{
int status;
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index d4113e5..2681abe 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -44,7 +44,7 @@
*/
#define REGISTER_BUSY_COUNT 5
#define REGISTER_BUSY_DELAY 100
-#define REGISTER_TIMEOUT 20
+#define REGISTER_TIMEOUT 500
#define REGISTER_TIMEOUT_FIRMWARE 1000
/*
@@ -95,7 +95,7 @@ int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev,
const u8 request, const u8 requesttype,
const u16 offset, const u16 value,
void *buffer, const u16 buffer_length,
- u16 timeout);
+ const int timeout);
/*
* Used to read/write from/to the device.
@@ -110,7 +110,7 @@ int rt2x00usb_vendor_request(const struct rt2x00_dev *rt2x00dev,
int rt2x00usb_vendor_request_buff(const struct rt2x00_dev *rt2x00dev,
const u8 request, const u8 requesttype,
const u16 offset, void *buffer,
- const u16 buffer_length, u16 timeout);
+ const u16 buffer_length, const int timeout);
/*
* Simple wrapper around rt2x00usb_vendor_request to write a single
@@ -122,7 +122,7 @@ static inline int rt2x00usb_vendor_request_sw(const struct rt2x00_dev
const u8 request,
const u16 offset,
const u16 value,
- int timeout)
+ const int timeout)
{
return rt2x00usb_vendor_request(rt2x00dev, request,
USB_VENDOR_REQUEST_OUT, offset,
--
1.5.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 4/12] rt2x00: Correctly identify rt2561turbo
2007-09-25 18:52 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (2 preceding siblings ...)
2007-09-25 18:54 ` [PATCH 3/12] rt2x00: Increase rt2x00usb_vendor_request timeout Ivo van Doorn
@ 2007-09-25 18:54 ` Ivo van Doorn
2007-09-25 18:55 ` [PATCH 5/12] rt2x00: adapt to filter configuration API Ivo van Doorn
` (7 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Ivo van Doorn @ 2007-09-25 18:54 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
Apparently rt2561s actually has PCI ID 0x0301
and rt2561 actually has PCI ID 0x0302.
Where rt2561s supports Turbo.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 80b079d..2609d4a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -159,8 +159,8 @@ struct rt2x00_chip {
#define RT2460 0x0101
#define RT2560 0x0201
#define RT2570 0x1201
-#define RT2561 0x0301
-#define RT2561s 0x0302
+#define RT2561s 0x0301 /* Turbo */
+#define RT2561 0x0302
#define RT2661 0x0401
#define RT2571 0x1300
--
1.5.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 5/12] rt2x00: adapt to filter configuration API
2007-09-25 18:52 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (3 preceding siblings ...)
2007-09-25 18:54 ` [PATCH 4/12] rt2x00: Correctly identify rt2561turbo Ivo van Doorn
@ 2007-09-25 18:55 ` Ivo van Doorn
2007-09-25 18:55 ` [PATCH 6/12] rt2x00: Reorganize rt2x00dev->flags Ivo van Doorn
` (6 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Ivo van Doorn @ 2007-09-25 18:55 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
This will make sure rt2x00 will follow the new mac80211 API
concerning the packet filter.
This new API cleans up quite a lot of code in rt2x00.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 155 +++++++++++++-----------
drivers/net/wireless/rt2x00/rt2500pci.c | 165 ++++++++++++++------------
drivers/net/wireless/rt2x00/rt2500usb.c | 179 ++++++++++++++++------------
drivers/net/wireless/rt2x00/rt2x00.h | 37 ++----
drivers/net/wireless/rt2x00/rt2x00config.c | 60 +---------
drivers/net/wireless/rt2x00/rt2x00dev.c | 33 ++++--
drivers/net/wireless/rt2x00/rt2x00lib.h | 1 -
drivers/net/wireless/rt2x00/rt2x00mac.c | 104 ++--------------
drivers/net/wireless/rt2x00/rt2x00pci.c | 31 ++---
drivers/net/wireless/rt2x00/rt2x00rfkill.c | 6 +-
drivers/net/wireless/rt2x00/rt2x00ring.h | 17 +++-
drivers/net/wireless/rt2x00/rt2x00usb.c | 16 +--
drivers/net/wireless/rt2x00/rt61pci.c | 164 ++++++++++++++------------
drivers/net/wireless/rt2x00/rt73usb.c | 175 +++++++++++++++------------
drivers/net/wireless/rt2x00/rt73usb.h | 2 +-
15 files changed, 556 insertions(+), 589 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 398c201..03a94a3 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -277,55 +277,14 @@ static void rt2400pci_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid)
rt2x00pci_register_multiwrite(rt2x00dev, CSR5, ®, sizeof(reg));
}
-static void rt2400pci_config_packet_filter(struct rt2x00_dev *rt2x00dev,
- const unsigned int filter)
-{
- int promisc = !!(filter & IFF_PROMISC);
- u32 reg;
-
- rt2x00pci_register_read(rt2x00dev, RXCSR0, ®);
- rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, !promisc);
- rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
-}
-
static void rt2400pci_config_type(struct rt2x00_dev *rt2x00dev, int type)
{
+ struct interface *intf = &rt2x00dev->interface;
u32 reg;
rt2x00pci_register_write(rt2x00dev, CSR14, 0);
/*
- * Apply hardware packet filter.
- */
- rt2x00pci_register_read(rt2x00dev, RXCSR0, ®);
-
- if (!is_monitor_present(&rt2x00dev->interface) &&
- (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_STA))
- rt2x00_set_field32(®, RXCSR0_DROP_TODS, 1);
- else
- rt2x00_set_field32(®, RXCSR0_DROP_TODS, 0);
-
- /*
- * If there is a non-monitor interface present
- * the packet should be strict (even if a monitor interface is present!).
- * When there is only 1 interface present which is in monitor mode
- * we should start accepting _all_ frames.
- */
- if (is_interface_present(&rt2x00dev->interface)) {
- rt2x00_set_field32(®, RXCSR0_DROP_CRC, 1);
- rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, 1);
- rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, 1);
- rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1);
- } else if (is_monitor_present(&rt2x00dev->interface)) {
- rt2x00_set_field32(®, RXCSR0_DROP_CRC, 0);
- rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, 0);
- rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, 0);
- rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 0);
- }
-
- rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
-
- /*
* Enable beacon config
*/
rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®);
@@ -337,20 +296,16 @@ static void rt2400pci_config_type(struct rt2x00_dev *rt2x00dev, int type)
* Enable synchronisation.
*/
rt2x00pci_register_read(rt2x00dev, CSR14, ®);
- if (is_interface_present(&rt2x00dev->interface)) {
- rt2x00_set_field32(®, CSR14_TSF_COUNT, 1);
- rt2x00_set_field32(®, CSR14_TBCN, 1);
- }
-
+ rt2x00_set_field32(®, CSR14_TSF_COUNT, 1);
+ rt2x00_set_field32(®, CSR14_TBCN, 1);
rt2x00_set_field32(®, CSR14_BEACON_GEN, 0);
- if (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_AP)
+ if (is_interface_type(intf, IEEE80211_IF_TYPE_IBSS) ||
+ is_interface_type(intf, IEEE80211_IF_TYPE_AP))
rt2x00_set_field32(®, CSR14_TSF_SYNC, 2);
- else if (type == IEEE80211_IF_TYPE_STA)
+ else if (is_interface_type(intf, IEEE80211_IF_TYPE_STA))
rt2x00_set_field32(®, CSR14_TSF_SYNC, 1);
- else if (is_monitor_present(&rt2x00dev->interface) &&
- !is_interface_present(&rt2x00dev->interface))
+ else
rt2x00_set_field32(®, CSR14_TSF_SYNC, 0);
-
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
}
@@ -1104,7 +1059,7 @@ static int rt2400pci_set_device_state(struct rt2x00_dev *rt2x00dev,
*/
static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct data_desc *txd,
- struct data_entry_desc *desc,
+ struct txdata_entry_desc *desc,
struct ieee80211_hdr *ieee80211hdr,
unsigned int length,
struct ieee80211_tx_control *control)
@@ -1200,8 +1155,8 @@ static void rt2400pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
/*
* RX control handlers
*/
-static int rt2400pci_fill_rxdone(struct data_entry *entry,
- int *signal, int *rssi, int *ofdm, int *size)
+static void rt2400pci_fill_rxdone(struct data_entry *entry,
+ struct rxdata_entry_desc *desc)
{
struct data_desc *rxd = entry->priv;
u32 word0;
@@ -1210,20 +1165,20 @@ static int rt2400pci_fill_rxdone(struct data_entry *entry,
rt2x00_desc_read(rxd, 0, &word0);
rt2x00_desc_read(rxd, 2, &word2);
- if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR) ||
- rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))
- return -EINVAL;
+ desc->flags = 0;
+ if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
+ desc->flags |= RX_FLAG_FAILED_FCS_CRC;
+ if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))
+ desc->flags |= RX_FLAG_FAILED_PLCP_CRC;
/*
* Obtain the status about this packet.
*/
- *signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL);
- *rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) -
+ desc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL);
+ desc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) -
entry->ring->rt2x00dev->rssi_offset;
- *ofdm = 0;
- *size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
-
- return 0;
+ desc->ofdm = 0;
+ desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
}
/*
@@ -1460,10 +1415,7 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Initialize all hw fields.
*/
- rt2x00dev->hw->flags =
- IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_MONITOR_DURING_OPER |
- IEEE80211_HW_NO_PROBE_FILTERING;
+ rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
rt2x00dev->hw->extra_tx_headroom = 0;
rt2x00dev->hw->max_signal = MAX_SIGNAL;
rt2x00dev->hw->max_rssi = MAX_RX_SSI;
@@ -1530,6 +1482,68 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* IEEE80211 stack callback functions.
*/
+static void rt2400pci_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ int mc_count,
+ struct dev_addr_list *mc_list)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct interface *intf = &rt2x00dev->interface;
+ u32 reg;
+
+ /*
+ * Mask off any flags we are going to ignore from
+ * the total_flags field.
+ */
+ *total_flags &=
+ FIF_ALLMULTI |
+ FIF_FCSFAIL |
+ FIF_PLCPFAIL |
+ FIF_CONTROL |
+ FIF_OTHER_BSS |
+ FIF_PROMISC_IN_BSS;
+
+ /*
+ * Apply some rules to the filters:
+ * - Some filters imply different filters to be set.
+ * - Some things we can't filter out at all.
+ * - Some filters are set based on interface type.
+ */
+ *total_flags |= FIF_ALLMULTI;
+ if (changed_flags & FIF_OTHER_BSS ||
+ changed_flags & FIF_PROMISC_IN_BSS)
+ *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
+ if (is_interface_type(intf, IEEE80211_IF_TYPE_AP))
+ *total_flags |= FIF_PROMISC_IN_BSS;
+
+ /*
+ * Check if there is any work left for us.
+ */
+ if (intf->filter == *total_flags)
+ return;
+ intf->filter = *total_flags;
+
+ /*
+ * Start configuration steps.
+ * Note that the version error will always be dropped
+ * since there is no filter for it at this time.
+ */
+ rt2x00pci_register_read(rt2x00dev, RXCSR0, ®);
+ rt2x00_set_field32(®, RXCSR0_DROP_CRC,
+ !(*total_flags & FIF_FCSFAIL));
+ rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL,
+ !(*total_flags & FIF_PLCPFAIL));
+ rt2x00_set_field32(®, RXCSR0_DROP_CONTROL,
+ !(*total_flags & FIF_CONTROL));
+ rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME,
+ !(*total_flags & FIF_PROMISC_IN_BSS));
+ rt2x00_set_field32(®, RXCSR0_DROP_TODS,
+ !(*total_flags & FIF_PROMISC_IN_BSS));
+ rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1);
+ rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
+}
+
static int rt2400pci_set_retry_limit(struct ieee80211_hw *hw,
u32 short_retry, u32 long_retry)
{
@@ -1602,11 +1616,13 @@ static int rt2400pci_tx_last_beacon(struct ieee80211_hw *hw)
static const struct ieee80211_ops rt2400pci_mac80211_ops = {
.tx = rt2x00mac_tx,
+ .start = rt2x00mac_start,
+ .stop = rt2x00mac_stop,
.add_interface = rt2x00mac_add_interface,
.remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config,
.config_interface = rt2x00mac_config_interface,
- .set_multicast_list = rt2x00mac_set_multicast_list,
+ .configure_filter = rt2400pci_configure_filter,
.get_stats = rt2x00mac_get_stats,
.set_retry_limit = rt2400pci_set_retry_limit,
.conf_tx = rt2400pci_conf_tx,
@@ -1635,7 +1651,6 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
.fill_rxdone = rt2400pci_fill_rxdone,
.config_mac_addr = rt2400pci_config_mac_addr,
.config_bssid = rt2400pci_config_bssid,
- .config_packet_filter = rt2400pci_config_packet_filter,
.config_type = rt2400pci_config_type,
.config = rt2400pci_config,
};
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index e8d63aa..892baa9 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -277,59 +277,14 @@ static void rt2500pci_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid)
rt2x00pci_register_multiwrite(rt2x00dev, CSR5, ®, sizeof(reg));
}
-static void rt2500pci_config_packet_filter(struct rt2x00_dev *rt2x00dev,
- const unsigned int filter)
-{
- int promisc = !!(filter & IFF_PROMISC);
- int multicast = !!(filter & IFF_MULTICAST);
- int broadcast = !!(filter & IFF_BROADCAST);
- u32 reg;
-
- rt2x00pci_register_read(rt2x00dev, RXCSR0, ®);
- rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, !promisc);
- rt2x00_set_field32(®, RXCSR0_DROP_MCAST, !multicast);
- rt2x00_set_field32(®, RXCSR0_DROP_BCAST, !broadcast);
- rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
-}
-
static void rt2500pci_config_type(struct rt2x00_dev *rt2x00dev, const int type)
{
+ struct interface *intf = &rt2x00dev->interface;
u32 reg;
rt2x00pci_register_write(rt2x00dev, CSR14, 0);
/*
- * Apply hardware packet filter.
- */
- rt2x00pci_register_read(rt2x00dev, RXCSR0, ®);
-
- if (!is_monitor_present(&rt2x00dev->interface) &&
- (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_STA))
- rt2x00_set_field32(®, RXCSR0_DROP_TODS, 1);
- else
- rt2x00_set_field32(®, RXCSR0_DROP_TODS, 0);
-
- /*
- * If there is a non-monitor interface present
- * the packet should be strict (even if a monitor interface is present!).
- * When there is only 1 interface present which is in monitor mode
- * we should start accepting _all_ frames.
- */
- if (is_interface_present(&rt2x00dev->interface)) {
- rt2x00_set_field32(®, RXCSR0_DROP_CRC, 1);
- rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, 1);
- rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, 1);
- rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1);
- } else if (is_monitor_present(&rt2x00dev->interface)) {
- rt2x00_set_field32(®, RXCSR0_DROP_CRC, 0);
- rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL, 0);
- rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, 0);
- rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 0);
- }
-
- rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
-
- /*
* Enable beacon config
*/
rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®);
@@ -345,20 +300,16 @@ static void rt2500pci_config_type(struct rt2x00_dev *rt2x00dev, const int type)
* Enable synchronisation.
*/
rt2x00pci_register_read(rt2x00dev, CSR14, ®);
- if (is_interface_present(&rt2x00dev->interface)) {
- rt2x00_set_field32(®, CSR14_TSF_COUNT, 1);
- rt2x00_set_field32(®, CSR14_TBCN, 1);
- }
-
+ rt2x00_set_field32(®, CSR14_TSF_COUNT, 1);
+ rt2x00_set_field32(®, CSR14_TBCN, 1);
rt2x00_set_field32(®, CSR14_BEACON_GEN, 0);
- if (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_AP)
+ if (is_interface_type(intf, IEEE80211_IF_TYPE_IBSS) ||
+ is_interface_type(intf, IEEE80211_IF_TYPE_AP))
rt2x00_set_field32(®, CSR14_TSF_SYNC, 2);
- else if (type == IEEE80211_IF_TYPE_STA)
+ else if (is_interface_type(intf, IEEE80211_IF_TYPE_STA))
rt2x00_set_field32(®, CSR14_TSF_SYNC, 1);
- else if (is_monitor_present(&rt2x00dev->interface) &&
- !is_interface_present(&rt2x00dev->interface))
+ else
rt2x00_set_field32(®, CSR14_TSF_SYNC, 0);
-
rt2x00pci_register_write(rt2x00dev, CSR14, reg);
}
@@ -1269,7 +1220,7 @@ static int rt2500pci_set_device_state(struct rt2x00_dev *rt2x00dev,
*/
static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct data_desc *txd,
- struct data_entry_desc *desc,
+ struct txdata_entry_desc *desc,
struct ieee80211_hdr *ieee80211hdr,
unsigned int length,
struct ieee80211_tx_control *control)
@@ -1349,8 +1300,8 @@ static void rt2500pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
/*
* RX control handlers
*/
-static int rt2500pci_fill_rxdone(struct data_entry *entry,
- int *signal, int *rssi, int *ofdm, int *size)
+static void rt2500pci_fill_rxdone(struct data_entry *entry,
+ struct rxdata_entry_desc *desc)
{
struct data_desc *rxd = entry->priv;
u32 word0;
@@ -1359,18 +1310,17 @@ static int rt2500pci_fill_rxdone(struct data_entry *entry,
rt2x00_desc_read(rxd, 0, &word0);
rt2x00_desc_read(rxd, 2, &word2);
- if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR) ||
- rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR) ||
- rt2x00_get_field32(word0, RXD_W0_ICV_ERROR))
- return -EINVAL;
+ desc->flags = 0;
+ if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
+ desc->flags |= RX_FLAG_FAILED_FCS_CRC;
+ if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))
+ desc->flags |= RX_FLAG_FAILED_PLCP_CRC;
- *signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL);
- *rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) -
+ desc->signal = rt2x00_get_field32(word2, RXD_W2_SIGNAL);
+ desc->rssi = rt2x00_get_field32(word2, RXD_W2_RSSI) -
entry->ring->rt2x00dev->rssi_offset;
- *ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
- *size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
-
- return 0;
+ desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
+ desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
}
/*
@@ -1779,10 +1729,7 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
/*
* Initialize all hw fields.
*/
- rt2x00dev->hw->flags =
- IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_MONITOR_DURING_OPER |
- IEEE80211_HW_NO_PROBE_FILTERING;
+ rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
rt2x00dev->hw->extra_tx_headroom = 0;
rt2x00dev->hw->max_signal = MAX_SIGNAL;
rt2x00dev->hw->max_rssi = MAX_RX_SSI;
@@ -1867,6 +1814,73 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* IEEE80211 stack callback functions.
*/
+static void rt2500pci_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ int mc_count,
+ struct dev_addr_list *mc_list)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct interface *intf = &rt2x00dev->interface;
+ u32 reg;
+
+ /*
+ * Mask off any flags we are going to ignore from
+ * the total_flags field.
+ */
+ *total_flags &=
+ FIF_ALLMULTI |
+ FIF_FCSFAIL |
+ FIF_PLCPFAIL |
+ FIF_CONTROL |
+ FIF_OTHER_BSS |
+ FIF_PROMISC_IN_BSS;
+
+ /*
+ * Apply some rules to the filters:
+ * - Some filters imply different filters to be set.
+ * - Some things we can't filter out at all.
+ * - Some filters are set based on interface type.
+ */
+ if (mc_count)
+ *total_flags |= FIF_ALLMULTI;
+ if (changed_flags & FIF_OTHER_BSS ||
+ changed_flags & FIF_PROMISC_IN_BSS)
+ *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
+ if (is_interface_type(intf, IEEE80211_IF_TYPE_AP))
+ *total_flags |= FIF_PROMISC_IN_BSS;
+
+ /*
+ * Check if there is any work left for us.
+ */
+ if (intf->filter == *total_flags)
+ return;
+ intf->filter = *total_flags;
+
+ /*
+ * Start configuration steps.
+ * Note that the version error will always be dropped
+ * and broadcast frames will always be accepted since
+ * there is no filter for it at this time.
+ */
+ rt2x00pci_register_read(rt2x00dev, RXCSR0, ®);
+ rt2x00_set_field32(®, RXCSR0_DROP_CRC,
+ !(*total_flags & FIF_FCSFAIL));
+ rt2x00_set_field32(®, RXCSR0_DROP_PHYSICAL,
+ !(*total_flags & FIF_PLCPFAIL));
+ rt2x00_set_field32(®, RXCSR0_DROP_CONTROL,
+ !(*total_flags & FIF_CONTROL));
+ rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME,
+ !(*total_flags & FIF_PROMISC_IN_BSS));
+ rt2x00_set_field32(®, RXCSR0_DROP_TODS,
+ !(*total_flags & FIF_PROMISC_IN_BSS));
+ rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1);
+ rt2x00_set_field32(®, RXCSR0_DROP_MCAST,
+ !(*total_flags & FIF_ALLMULTI));
+ rt2x00_set_field32(®, RXCSR0_DROP_BCAST, 0);
+ rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
+}
+
static int rt2500pci_set_retry_limit(struct ieee80211_hw *hw,
u32 short_retry, u32 long_retry)
{
@@ -1914,11 +1928,13 @@ static int rt2500pci_tx_last_beacon(struct ieee80211_hw *hw)
static const struct ieee80211_ops rt2500pci_mac80211_ops = {
.tx = rt2x00mac_tx,
+ .start = rt2x00mac_start,
+ .stop = rt2x00mac_stop,
.add_interface = rt2x00mac_add_interface,
.remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config,
.config_interface = rt2x00mac_config_interface,
- .set_multicast_list = rt2x00mac_set_multicast_list,
+ .configure_filter = rt2500pci_configure_filter,
.get_stats = rt2x00mac_get_stats,
.set_retry_limit = rt2500pci_set_retry_limit,
.conf_tx = rt2x00mac_conf_tx,
@@ -1947,7 +1963,6 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
.fill_rxdone = rt2500pci_fill_rxdone,
.config_mac_addr = rt2500pci_config_mac_addr,
.config_bssid = rt2500pci_config_bssid,
- .config_packet_filter = rt2500pci_config_packet_filter,
.config_type = rt2500pci_config_type,
.config = rt2500pci_config,
};
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 614600c..f4e6f6e 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -282,65 +282,20 @@ static void rt2500usb_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid)
rt2500usb_register_multiwrite(rt2x00dev, MAC_CSR5, ®, sizeof(reg));
}
-static void rt2500usb_config_packet_filter(struct rt2x00_dev *rt2x00dev,
- const unsigned int filter)
-{
- int promisc = !!(filter & IFF_PROMISC);
- int multicast = !!(filter & IFF_MULTICAST);
- int broadcast = !!(filter & IFF_BROADCAST);
- u16 reg;
-
- rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®);
- rt2x00_set_field16(®, TXRX_CSR2_DROP_NOT_TO_ME, !promisc);
- rt2x00_set_field16(®, TXRX_CSR2_DROP_MULTICAST, !multicast);
- rt2x00_set_field16(®, TXRX_CSR2_DROP_BROADCAST, !broadcast);
- rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
-}
-
static void rt2500usb_config_type(struct rt2x00_dev *rt2x00dev, const int type)
{
+ struct interface *intf = &rt2x00dev->interface;
u16 reg;
rt2500usb_register_write(rt2x00dev, TXRX_CSR19, 0);
/*
- * Apply hardware packet filter.
- */
- rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®);
-
- if (!is_monitor_present(&rt2x00dev->interface) &&
- (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_STA))
- rt2x00_set_field16(®, TXRX_CSR2_DROP_TODS, 1);
- else
- rt2x00_set_field16(®, TXRX_CSR2_DROP_TODS, 0);
-
- /*
- * If there is a non-monitor interface present
- * the packet should be strict (even if a monitor interface is present!).
- * When there is only 1 interface present which is in monitor mode
- * we should start accepting _all_ frames.
- */
- if (is_interface_present(&rt2x00dev->interface)) {
- rt2x00_set_field16(®, TXRX_CSR2_DROP_CRC, 1);
- rt2x00_set_field16(®, TXRX_CSR2_DROP_PHYSICAL, 1);
- rt2x00_set_field16(®, TXRX_CSR2_DROP_CONTROL, 1);
- rt2x00_set_field16(®, TXRX_CSR2_DROP_VERSION_ERROR, 1);
- } else if (is_monitor_present(&rt2x00dev->interface)) {
- rt2x00_set_field16(®, TXRX_CSR2_DROP_CRC, 0);
- rt2x00_set_field16(®, TXRX_CSR2_DROP_PHYSICAL, 0);
- rt2x00_set_field16(®, TXRX_CSR2_DROP_CONTROL, 0);
- rt2x00_set_field16(®, TXRX_CSR2_DROP_VERSION_ERROR, 0);
- }
-
- rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
-
- /*
* Enable beacon config
*/
rt2500usb_register_read(rt2x00dev, TXRX_CSR20, ®);
rt2x00_set_field16(®, TXRX_CSR20_OFFSET,
(PREAMBLE + get_duration(IEEE80211_HEADER, 2)) >> 6);
- if (type == IEEE80211_IF_TYPE_STA)
+ if (is_interface_type(intf, IEEE80211_IF_TYPE_STA))
rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, 0);
else
rt2x00_set_field16(®, TXRX_CSR20_BCN_EXPECT_WINDOW, 2);
@@ -354,20 +309,16 @@ static void rt2500usb_config_type(struct rt2x00_dev *rt2x00dev, const int type)
rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg);
rt2500usb_register_read(rt2x00dev, TXRX_CSR19, ®);
- if (is_interface_present(&rt2x00dev->interface)) {
- rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1);
- rt2x00_set_field16(®, TXRX_CSR19_TBCN, 1);
- }
-
+ rt2x00_set_field16(®, TXRX_CSR19_TSF_COUNT, 1);
+ rt2x00_set_field16(®, TXRX_CSR19_TBCN, 1);
rt2x00_set_field16(®, TXRX_CSR19_BEACON_GEN, 0);
- if (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_AP)
+ if (is_interface_type(intf, IEEE80211_IF_TYPE_IBSS) ||
+ is_interface_type(intf, IEEE80211_IF_TYPE_AP))
rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, 2);
- else if (type == IEEE80211_IF_TYPE_STA)
+ else if (is_interface_type(intf, IEEE80211_IF_TYPE_STA))
rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, 1);
- else if (is_monitor_present(&rt2x00dev->interface) &&
- !is_interface_present(&rt2x00dev->interface))
+ else
rt2x00_set_field16(®, TXRX_CSR19_TSF_SYNC, 0);
-
rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
}
@@ -1084,7 +1035,7 @@ static int rt2500usb_set_device_state(struct rt2x00_dev *rt2x00dev,
*/
static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct data_desc *txd,
- struct data_entry_desc *desc,
+ struct txdata_entry_desc *desc,
struct ieee80211_hdr *ieee80211hdr,
unsigned int length,
struct ieee80211_tx_control *control)
@@ -1156,8 +1107,8 @@ static void rt2500usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
/*
* RX control handlers
*/
-static int rt2500usb_fill_rxdone(struct data_entry *entry,
- int *signal, int *rssi, int *ofdm, int *size)
+static void rt2500usb_fill_rxdone(struct data_entry *entry,
+ struct rxdata_entry_desc *desc)
{
struct urb *urb = entry->priv;
struct data_desc *rxd = (struct data_desc *)(entry->skb->data +
@@ -1169,21 +1120,22 @@ static int rt2500usb_fill_rxdone(struct data_entry *entry,
rt2x00_desc_read(rxd, 0, &word0);
rt2x00_desc_read(rxd, 1, &word1);
- if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR) ||
- rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR) ||
- rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR))
- return -EINVAL;
+ desc->flags = 0;
+ if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
+ desc->flags |= RX_FLAG_FAILED_FCS_CRC;
+ if (rt2x00_get_field32(word0, RXD_W0_PHYSICAL_ERROR))
+ desc->flags |= RX_FLAG_FAILED_PLCP_CRC;
/*
* Obtain the status about this packet.
*/
- *signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
- *rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) -
+ desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
+ desc->rssi = rt2x00_get_field32(word1, RXD_W1_RSSI) -
entry->ring->rt2x00dev->rssi_offset;
- *ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
- *size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
+ desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
+ desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
- return 0;
+ return;
}
/*
@@ -1549,9 +1501,7 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
rt2x00dev->hw->flags =
IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_MONITOR_DURING_OPER |
- IEEE80211_HW_NO_PROBE_FILTERING;
+ IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
rt2x00dev->hw->max_signal = MAX_SIGNAL;
rt2x00dev->hw->max_rssi = MAX_RX_SSI;
@@ -1621,10 +1571,8 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
rt2500usb_probe_hw_mode(rt2x00dev);
/*
- * USB devices require scheduled packet filter toggling
- *This device requires the beacon ring
+ * This device requires the beacon ring
*/
- __set_bit(PACKET_FILTER_SCHEDULED, &rt2x00dev->flags);
__set_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags);
/*
@@ -1638,6 +1586,82 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* IEEE80211 stack callback functions.
*/
+static void rt2500usb_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ int mc_count,
+ struct dev_addr_list *mc_list)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct interface *intf = &rt2x00dev->interface;
+ u16 reg;
+
+ /*
+ * Mask off any flags we are going to ignore from
+ * the total_flags field.
+ */
+ *total_flags &=
+ FIF_ALLMULTI |
+ FIF_FCSFAIL |
+ FIF_PLCPFAIL |
+ FIF_CONTROL |
+ FIF_OTHER_BSS |
+ FIF_PROMISC_IN_BSS;
+
+ /*
+ * Apply some rules to the filters:
+ * - Some filters imply different filters to be set.
+ * - Some things we can't filter out at all.
+ * - Some filters are set based on interface type.
+ */
+ if (mc_count)
+ *total_flags |= FIF_ALLMULTI;
+ if (changed_flags & FIF_OTHER_BSS ||
+ changed_flags & FIF_PROMISC_IN_BSS)
+ *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
+ if (is_interface_type(intf, IEEE80211_IF_TYPE_AP))
+ *total_flags |= FIF_PROMISC_IN_BSS;
+
+ /*
+ * Check if there is any work left for us.
+ */
+ if (intf->filter == *total_flags)
+ return;
+ intf->filter = *total_flags;
+
+ /*
+ * When in atomic context, reschedule and let rt2x00lib
+ * call this function again.
+ */
+ if (in_atomic()) {
+ queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work);
+ return;
+ }
+
+ /*
+ * Start configuration steps.
+ * Note that the version error will always be dropped
+ * and broadcast frames will always be accepted since
+ * there is no filter for it at this time.
+ */
+ rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®);
+ rt2x00_set_field16(®, TXRX_CSR2_DROP_CRC,
+ !(*total_flags & FIF_FCSFAIL));
+ rt2x00_set_field16(®, TXRX_CSR2_DROP_PHYSICAL,
+ !(*total_flags & FIF_PLCPFAIL));
+ rt2x00_set_field16(®, TXRX_CSR2_DROP_CONTROL,
+ !(*total_flags & FIF_CONTROL));
+ rt2x00_set_field16(®, TXRX_CSR2_DROP_NOT_TO_ME,
+ !(*total_flags & FIF_PROMISC_IN_BSS));
+ rt2x00_set_field16(®, TXRX_CSR2_DROP_TODS,
+ !(*total_flags & FIF_PROMISC_IN_BSS));
+ rt2x00_set_field16(®, TXRX_CSR2_DROP_VERSION_ERROR, 1);
+ rt2x00_set_field16(®, TXRX_CSR2_DROP_MULTICAST,
+ !(*total_flags & FIF_ALLMULTI));
+ rt2x00_set_field16(®, TXRX_CSR2_DROP_BROADCAST, 0);
+ rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
+}
+
static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
struct sk_buff *skb,
struct ieee80211_tx_control *control)
@@ -1714,11 +1738,13 @@ static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
static const struct ieee80211_ops rt2500usb_mac80211_ops = {
.tx = rt2x00mac_tx,
+ .start = rt2x00mac_start,
+ .stop = rt2x00mac_stop,
.add_interface = rt2x00mac_add_interface,
.remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config,
.config_interface = rt2x00mac_config_interface,
- .set_multicast_list = rt2x00mac_set_multicast_list,
+ .configure_filter = rt2500usb_configure_filter,
.get_stats = rt2x00mac_get_stats,
.conf_tx = rt2x00mac_conf_tx,
.get_tx_stats = rt2x00mac_get_tx_stats,
@@ -1739,7 +1765,6 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
.fill_rxdone = rt2500usb_fill_rxdone,
.config_mac_addr = rt2500usb_config_mac_addr,
.config_bssid = rt2500usb_config_bssid,
- .config_packet_filter = rt2500usb_config_packet_filter,
.config_type = rt2500usb_config_type,
.config = rt2500usb_config,
};
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 2609d4a..5f05c7e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -294,9 +294,6 @@ struct interface {
/*
* Current working type (IEEE80211_IF_TYPE_*).
- * This excludes the type IEEE80211_IF_TYPE_MNTR
- * since that is counted seperately in the monitor_count
- * field.
* When set to INVALID_INTERFACE, no interface is configured.
*/
int type;
@@ -314,18 +311,8 @@ struct interface {
/*
* Store the packet filter mode for the current interface.
- * monitor mode always disabled filtering. But in such
- * cases we still need to store the value here in case
- * the monitor mode interfaces are removed, while a
- * non-monitor mode interface remains.
*/
- unsigned short filter;
-
- /*
- * Monitor mode count, the number of interfaces
- * in monitor mode that that have been added.
- */
- unsigned short monitor_count;
+ unsigned int filter;
};
static inline int is_interface_present(struct interface *intf)
@@ -333,9 +320,9 @@ static inline int is_interface_present(struct interface *intf)
return !!intf->id;
}
-static inline int is_monitor_present(struct interface *intf)
+static inline int is_interface_type(struct interface *intf, int type)
{
- return !!intf->monitor_count;
+ return intf->type == type;
}
/*
@@ -402,7 +389,7 @@ struct rt2x00lib_ops {
*/
void (*write_tx_desc) (struct rt2x00_dev *rt2x00dev,
struct data_desc *txd,
- struct data_entry_desc *desc,
+ struct txdata_entry_desc *desc,
struct ieee80211_hdr *ieee80211hdr,
unsigned int length,
struct ieee80211_tx_control *control);
@@ -415,8 +402,8 @@ struct rt2x00lib_ops {
/*
* RX control handlers
*/
- int (*fill_rxdone) (struct data_entry *entry,
- int *signal, int *rssi, int *ofdm, int *size);
+ void (*fill_rxdone) (struct data_entry *entry,
+ struct rxdata_entry_desc *desc);
/*
* Configuration handlers.
@@ -511,11 +498,10 @@ struct rt2x00_dev {
#define DEVICE_INITIALIZED 3
#define DEVICE_INITIALIZED_HW 4
#define REQUIRE_FIRMWARE 5
-#define PACKET_FILTER_SCHEDULED 6
-#define PACKET_FILTER_PENDING 7
+/* Hole: Add new Flag here */
#define INTERFACE_RESUME 8
#define INTERFACE_ENABLED 9
-#define INTERFACE_ENABLED_MONITOR 10
+/* Hole: Add new Flag here */
#define REQUIRE_BEACON_RING 11
#define DEVICE_SUPPORT_HW_BUTTON 12
#define CONFIG_FRAME_TYPE 13
@@ -606,9 +592,10 @@ struct rt2x00_dev {
struct ieee80211_rx_status rx_status;
/*
- * Beacon scheduled work.
+ * Scheduled work.
*/
struct work_struct beacon_work;
+ struct work_struct filter_work;
/*
* Data ring arrays for RX, TX and Beacon.
@@ -760,7 +747,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_txdone(struct data_entry *entry,
const int status, const int retry);
void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb,
- const int signal, const int rssi, const int ofdm);
+ struct rxdata_entry_desc *desc);
/*
* TX descriptor initializer
@@ -785,8 +772,6 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
int rt2x00mac_config_interface(struct ieee80211_hw *hw, int if_id,
struct ieee80211_if_conf *conf);
-void rt2x00mac_set_multicast_list(struct ieee80211_hw *hw,
- unsigned short flags, int mc_count);
int rt2x00mac_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats);
int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index de890a1..f962ce4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -46,72 +46,24 @@ void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid)
rt2x00dev->ops->lib->config_bssid(rt2x00dev, bssid);
}
-void rt2x00lib_config_packet_filter(struct rt2x00_dev *rt2x00dev, int filter)
-{
- /*
- * Only configure the device when something has changed,
- * or if we are in RESUME state in which case all configuration
- * will be forced upon the device.
- */
- if (!test_bit(INTERFACE_RESUME, &rt2x00dev->flags) &&
- !test_bit(PACKET_FILTER_PENDING, &rt2x00dev->flags))
- return;
-
- /*
- * Write configuration to device and clear the update flag.
- */
- rt2x00dev->ops->lib->config_packet_filter(rt2x00dev, filter);
- __clear_bit(PACKET_FILTER_PENDING, &rt2x00dev->flags);
-}
-
void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, int type)
{
struct interface *intf = &rt2x00dev->interface;
- /*
- * Fallback when a invalid interface is attempted to
- * be configured. If a monitor interface is present,
- * we are going configure that, otherwise exit.
- */
- if (type == INVALID_INTERFACE) {
- if (is_monitor_present(intf))
- type = IEEE80211_IF_TYPE_MNTR;
- else
- return;
- }
-
- /*
- * Only configure the device when something has changed,
- * or if we are in RESUME state in which case all configuration
- * will be forced upon the device.
- */
if (!test_bit(INTERFACE_RESUME, &rt2x00dev->flags) &&
- (!(is_interface_present(intf) ^
- test_bit(INTERFACE_ENABLED, &rt2x00dev->flags)) &&
- !(is_monitor_present(intf) ^
- test_bit(INTERFACE_ENABLED_MONITOR, &rt2x00dev->flags))))
+ (!!test_bit(INTERFACE_ENABLED, &rt2x00dev->flags) ==
+ !!is_interface_present(intf)))
return;
- /*
- * Configure device.
- */
rt2x00dev->ops->lib->config_type(rt2x00dev, type);
/*
* Update the configuration flags.
*/
- if (type != IEEE80211_IF_TYPE_MNTR) {
- if (is_interface_present(intf))
- __set_bit(INTERFACE_ENABLED, &rt2x00dev->flags);
- else
- __clear_bit(INTERFACE_ENABLED, &rt2x00dev->flags);
- } else {
- if (is_monitor_present(intf))
- __set_bit(INTERFACE_ENABLED_MONITOR, &rt2x00dev->flags);
- else
- __clear_bit(INTERFACE_ENABLED_MONITOR,
- &rt2x00dev->flags);
- }
+ if (is_interface_present(intf))
+ __set_bit(INTERFACE_ENABLED, &rt2x00dev->flags);
+ else
+ __clear_bit(INTERFACE_ENABLED, &rt2x00dev->flags);
}
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf)
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 5780d6a..4f66adc 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -135,10 +135,12 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
return;
/*
- * Stop beacon generation.
+ * Stop all scheduled work.
*/
if (work_pending(&rt2x00dev->beacon_work))
cancel_work_sync(&rt2x00dev->beacon_work);
+ if (work_pending(&rt2x00dev->filter_work))
+ cancel_work_sync(&rt2x00dev->filter_work);
/*
* Stop the TX queues.
@@ -261,6 +263,17 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
LINK_TUNE_INTERVAL);
}
+static void rt2x00lib_packetfilter_scheduled(struct work_struct *work)
+{
+ struct rt2x00_dev *rt2x00dev =
+ container_of(work, struct rt2x00_dev, filter_work);
+
+ rt2x00dev->ops->hw->configure_filter(rt2x00dev->hw,
+ rt2x00dev->interface.filter,
+ &rt2x00dev->interface.filter,
+ 0, NULL);
+}
+
/*
* Interrupt context handlers.
*/
@@ -341,7 +354,7 @@ void rt2x00lib_txdone(struct data_entry *entry,
EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb,
- const int signal, const int rssi, const int ofdm)
+ struct rxdata_entry_desc *desc)
{
struct rt2x00_dev *rt2x00dev = entry->ring->rt2x00dev;
struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
@@ -362,22 +375,24 @@ void rt2x00lib_rxdone(struct data_entry *entry, struct sk_buff *skb,
* the signal is the PLCP value. If it was received with
* a CCK bitrate the signal is the rate in 0.5kbit/s.
*/
- if (!ofdm)
+ if (!desc->ofdm)
val = DEVICE_GET_RATE_FIELD(rate->val, RATE);
else
val = DEVICE_GET_RATE_FIELD(rate->val, PLCP);
- if (val == signal) {
+ if (val == desc->signal) {
val = rate->val;
break;
}
}
- rt2x00_update_link_rssi(&rt2x00dev->link, rssi);
+ rt2x00_update_link_rssi(&rt2x00dev->link, desc->rssi);
rt2x00dev->link.rx_success++;
rx_status->rate = val;
- rx_status->signal = rt2x00lib_calculate_link_signal(rt2x00dev, rssi);
- rx_status->ssi = rssi;
+ rx_status->signal =
+ rt2x00lib_calculate_link_signal(rt2x00dev, desc->rssi);
+ rx_status->ssi = desc->rssi;
+ rx_status->flag = desc->flags;
/*
* Send frame to mac80211
@@ -395,7 +410,7 @@ void rt2x00lib_write_tx_desc(struct rt2x00_dev *rt2x00dev,
unsigned int length,
struct ieee80211_tx_control *control)
{
- struct data_entry_desc desc;
+ struct txdata_entry_desc desc;
struct data_ring *ring;
int tx_rate;
int bitrate;
@@ -960,6 +975,7 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
* Initialize configuration work.
*/
INIT_WORK(&rt2x00dev->beacon_work, rt2x00lib_beacondone_scheduled);
+ INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled);
INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner);
/*
@@ -1102,7 +1118,6 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
rt2x00lib_config_mac_addr(rt2x00dev, intf->mac);
rt2x00lib_config_bssid(rt2x00dev, intf->bssid);
rt2x00lib_config_type(rt2x00dev, intf->type);
- rt2x00lib_config_packet_filter(rt2x00dev, intf->filter);
/*
* When in Master or Ad-hoc mode,
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 3324090..fcc2ffd 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -51,7 +51,6 @@ void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev);
*/
void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac);
void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid);
-void rt2x00lib_config_packet_filter(struct rt2x00_dev *rt2x00dev, int filter);
void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, int type);
void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf);
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 778ed41..17802f6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -176,46 +176,26 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
{
struct rt2x00_dev *rt2x00dev = hw->priv;
struct interface *intf = &rt2x00dev->interface;
- int retval;
/*
* We only support 1 non-monitor interface.
*/
- if (conf->type != IEEE80211_IF_TYPE_MNTR && is_interface_present(intf))
+ if (is_interface_present(intf))
return -ENOBUFS;
- /*
- * HACK: Placeholder until start/stop handler has been
- * added to the mac80211 callback functions structure.
- */
- retval = rt2x00mac_start(hw);
- if (retval)
- return retval;
-
- /*
- * We support muliple monitor mode interfaces.
- * All we need to do is increase the monitor_count.
- */
- if (conf->type == IEEE80211_IF_TYPE_MNTR) {
- intf->monitor_count++;
- } else {
- intf->id = conf->if_id;
- intf->type = conf->type;
- if (conf->type == IEEE80211_IF_TYPE_AP)
- memcpy(&intf->bssid, conf->mac_addr, ETH_ALEN);
- memcpy(&intf->mac, conf->mac_addr, ETH_ALEN);
- intf->filter = 0;
- }
+ intf->id = conf->if_id;
+ intf->type = conf->type;
+ if (conf->type == IEEE80211_IF_TYPE_AP)
+ memcpy(&intf->bssid, conf->mac_addr, ETH_ALEN);
+ memcpy(&intf->mac, conf->mac_addr, ETH_ALEN);
/*
- * Configure interface.
* The MAC adddress must be configured after the device
- * has been initialized. Else the device can reset the
- * MAC registers.
+ * has been initialized. Otherwise the device can reset
+ * the MAC registers.
*/
rt2x00lib_config_mac_addr(rt2x00dev, intf->mac);
rt2x00lib_config_type(rt2x00dev, conf->type);
- rt2x00lib_config_packet_filter(rt2x00dev, intf->filter);
return 0;
}
@@ -230,22 +210,13 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
/*
* We only support 1 non-monitor interface.
*/
- if (conf->type != IEEE80211_IF_TYPE_MNTR && !is_interface_present(intf))
+ if (!is_interface_present(intf))
return;
- /*
- * When removing an monitor interface, decrease monitor_count.
- * For non-monitor interfaces, all interface data needs to be reset.
- */
- if (conf->type == IEEE80211_IF_TYPE_MNTR) {
- intf->monitor_count--;
- } else if (intf->type == conf->type) {
- intf->id = 0;
- intf->type = INVALID_INTERFACE;
- memset(&intf->bssid, 0x00, ETH_ALEN);
- memset(&intf->mac, 0x00, ETH_ALEN);
- intf->filter = 0;
- }
+ intf->id = 0;
+ intf->type = INVALID_INTERFACE;
+ memset(&intf->bssid, 0x00, ETH_ALEN);
+ memset(&intf->mac, 0x00, ETH_ALEN);
/*
* Make sure the bssid and mac address registers
@@ -254,12 +225,6 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
rt2x00lib_config_mac_addr(rt2x00dev, intf->mac);
rt2x00lib_config_bssid(rt2x00dev, intf->bssid);
rt2x00lib_config_type(rt2x00dev, intf->type);
-
- /*
- * HACK: Placeholder untill start/stop handler has been
- * added to the mac80211 callback functions structure.
- */
- rt2x00mac_stop(hw);
}
EXPORT_SYMBOL_GPL(rt2x00mac_remove_interface);
@@ -290,14 +255,6 @@ int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
rt2x00lib_config(rt2x00dev, conf);
/*
- * If promisc mode cannot be configured in irq context,
- * then it is now the time to configure it.
- */
- if (test_bit(PACKET_FILTER_SCHEDULED, &rt2x00dev->flags))
- rt2x00lib_config_packet_filter(rt2x00dev,
- rt2x00dev->interface.filter);
-
- /*
* Reenable RX only if the radio should be on.
*/
if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
@@ -326,13 +283,10 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, int if_id,
return 0;
/*
- * Monitor mode does not need configuring.
* If the given type does not match the configured type,
* there has been a problem.
*/
- if (conf->type == IEEE80211_IF_TYPE_MNTR)
- return 0;
- else if (conf->type != intf->type)
+ if (conf->type != intf->type)
return -EINVAL;
/*
@@ -360,36 +314,6 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, int if_id,
}
EXPORT_SYMBOL_GPL(rt2x00mac_config_interface);
-void rt2x00mac_set_multicast_list(struct ieee80211_hw *hw,
- unsigned short flags, int mc_count)
-{
- struct rt2x00_dev *rt2x00dev = hw->priv;
-
- /*
- * Check if the new state is different then the old state.
- */
- if (rt2x00dev->interface.filter == flags)
- return;
-
- rt2x00dev->interface.filter = flags;
-
- /*
- * Raise the pending bit to indicate the
- * packet filter should be updated.
- */
- __set_bit(PACKET_FILTER_PENDING, &rt2x00dev->flags);
-
- /*
- * Check if Packet filter actions are allowed in
- * atomic context. If not, raise the pending flag and
- * let it be.
- */
- if (!test_bit(PACKET_FILTER_SCHEDULED, &rt2x00dev->flags) ||
- !in_atomic())
- rt2x00lib_config_packet_filter(rt2x00dev, flags);
-}
-EXPORT_SYMBOL_GPL(rt2x00mac_set_multicast_list);
-
int rt2x00mac_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats)
{
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 85629f1..2780df0 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -124,47 +124,40 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
struct data_entry *entry;
struct data_desc *rxd;
struct sk_buff *skb;
- u32 desc;
- int retval;
- int signal;
- int rssi;
- int ofdm;
- int size;
+ struct rxdata_entry_desc desc;
+ u32 word;
while (1) {
entry = rt2x00_get_data_entry(ring);
rxd = entry->priv;
- rt2x00_desc_read(rxd, 0, &desc);
+ rt2x00_desc_read(rxd, 0, &word);
- if (rt2x00_get_field32(desc, RXD_ENTRY_OWNER_NIC))
+ if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC))
break;
- retval = rt2x00dev->ops->lib->fill_rxdone(entry, &signal,
- &rssi, &ofdm, &size);
- if (retval)
- goto skip_entry;
+ memset(&desc, 0x00, sizeof(desc));
+ rt2x00dev->ops->lib->fill_rxdone(entry, &desc);
/*
* Allocate the sk_buffer, initialize it and copy
* all data into it.
*/
- skb = dev_alloc_skb(size + NET_IP_ALIGN);
+ skb = dev_alloc_skb(desc.size + NET_IP_ALIGN);
if (!skb)
return;
skb_reserve(skb, NET_IP_ALIGN);
- skb_put(skb, size);
- memcpy(skb->data, entry->data_addr, size);
+ skb_put(skb, desc.size);
+ memcpy(skb->data, entry->data_addr, desc.size);
/*
* Send the frame to rt2x00lib for further processing.
*/
- rt2x00lib_rxdone(entry, skb, signal, rssi, ofdm);
+ rt2x00lib_rxdone(entry, skb, &desc);
-skip_entry:
if (test_bit(DEVICE_ENABLED_RADIO, &ring->rt2x00dev->flags)) {
- rt2x00_set_field32(&desc, RXD_ENTRY_OWNER_NIC, 1);
- rt2x00_desc_write(rxd, 0, desc);
+ rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1);
+ rt2x00_desc_write(rxd, 0, word);
}
rt2x00_ring_index_inc(ring);
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
index dc5b696..b54457c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
+++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
@@ -45,11 +45,9 @@ static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state)
return 0;
/*
- * Only continue if we have an active interface,
- * either monitor or non-monitor should be present.
+ * Only continue if we have an active interface.
*/
- if (!is_interface_present(&rt2x00dev->interface) &&
- !is_monitor_present(&rt2x00dev->interface))
+ if (!is_interface_present(&rt2x00dev->interface))
return 0;
if (state == RFKILL_STATE_ON) {
diff --git a/drivers/net/wireless/rt2x00/rt2x00ring.h b/drivers/net/wireless/rt2x00/rt2x00ring.h
index 122c752..1a864d3 100644
--- a/drivers/net/wireless/rt2x00/rt2x00ring.h
+++ b/drivers/net/wireless/rt2x00/rt2x00ring.h
@@ -41,11 +41,24 @@ struct data_desc {
};
/*
- * data_entry_desc
+ * rxdata_entry_desc
+ * Summary of information that has been read from the
+ * RX frame descriptor.
+ */
+struct rxdata_entry_desc {
+ int signal;
+ int rssi;
+ int ofdm;
+ int size;
+ int flags;
+};
+
+/*
+ * txdata_entry_desc
* Summary of information that should be written into the
* descriptor for sending a TX frame.
*/
-struct data_entry_desc {
+struct txdata_entry_desc {
unsigned long flags;
#define ENTRY_TXDONE 1
#define ENTRY_TXD_RTS_FRAME 2
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index 248144f..66e4761 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -218,11 +218,7 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
struct data_ring *ring = entry->ring;
struct rt2x00_dev *rt2x00dev = ring->rt2x00dev;
struct sk_buff *skb;
- int retval;
- int signal;
- int rssi;
- int ofdm;
- int size;
+ struct rxdata_entry_desc desc;
int frame_size;
if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
@@ -237,10 +233,8 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
if (urb->actual_length < entry->ring->desc_size || urb->status)
goto skip_entry;
- retval = rt2x00dev->ops->lib->fill_rxdone(entry, &signal, &rssi,
- &ofdm, &size);
- if (retval)
- goto skip_entry;
+ memset(&desc, 0x00, sizeof(desc));
+ rt2x00dev->ops->lib->fill_rxdone(entry, &desc);
/*
* Allocate a new sk buffer to replace the current one.
@@ -259,12 +253,12 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
* Trim the skb_buffer to only contain the valid
* frame data (so ignore the device's descriptor).
*/
- skb_trim(entry->skb, size);
+ skb_trim(entry->skb, desc.size);
/*
* Send the frame to rt2x00lib for further processing.
*/
- rt2x00lib_rxdone(entry, entry->skb, signal, rssi, ofdm);
+ rt2x00lib_rxdone(entry, entry->skb, &desc);
/*
* Replace current entry's skb with the newly allocated one,
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 69ed178..3edcd74 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -312,23 +312,9 @@ static void rt61pci_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid)
rt2x00pci_register_multiwrite(rt2x00dev, MAC_CSR4, ®, sizeof(reg));
}
-static void rt61pci_config_packet_filter(struct rt2x00_dev *rt2x00dev,
- const unsigned int filter)
-{
- int promisc = !!(filter & IFF_PROMISC);
- int multicast = !!(filter & IFF_MULTICAST);
- int broadcast = !!(filter & IFF_BROADCAST);
- u32 reg;
-
- rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, !promisc);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, !multicast);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_BORADCAST, !broadcast);
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
-}
-
static void rt61pci_config_type(struct rt2x00_dev *rt2x00dev, const int type)
{
+ struct interface *intf = &rt2x00dev->interface;
u32 reg;
/*
@@ -344,56 +330,19 @@ static void rt61pci_config_type(struct rt2x00_dev *rt2x00dev, const int type)
rt2x00pci_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
/*
- * Apply hardware packet filter.
- */
- rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®);
-
- if (!is_monitor_present(&rt2x00dev->interface) &&
- (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_STA))
- rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, 1);
- else
- rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, 0);
-
- /*
- * If there is a non-monitor interface present
- * the packet should be strict (even if a monitor interface is present!).
- * When there is only 1 interface present which is in monitor mode
- * we should start accepting _all_ frames.
- */
- if (is_interface_present(&rt2x00dev->interface)) {
- rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, 1);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, 1);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, 1);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 1);
- } else if (is_monitor_present(&rt2x00dev->interface)) {
- rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, 0);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, 0);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, 0);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 0);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 0);
- }
-
- rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
-
- /*
* Enable synchronisation.
*/
rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®);
- if (is_interface_present(&rt2x00dev->interface)) {
- rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1);
- rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1);
- }
-
+ rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1);
+ rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1);
rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);
- if (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_AP)
+ if (is_interface_type(intf, IEEE80211_IF_TYPE_IBSS) ||
+ is_interface_type(intf, IEEE80211_IF_TYPE_AP))
rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 2);
- else if (type == IEEE80211_IF_TYPE_STA)
+ else if (is_interface_type(intf, IEEE80211_IF_TYPE_STA))
rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 1);
- else if (is_monitor_present(&rt2x00dev->interface) &&
- !is_interface_present(&rt2x00dev->interface))
+ else
rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 0);
-
rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
}
@@ -1686,7 +1635,7 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
*/
static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct data_desc *txd,
- struct data_entry_desc *desc,
+ struct txdata_entry_desc *desc,
struct ieee80211_hdr *ieee80211hdr,
unsigned int length,
struct ieee80211_tx_control *control)
@@ -1826,8 +1775,8 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset;
}
-static int rt61pci_fill_rxdone(struct data_entry *entry,
- int *signal, int *rssi, int *ofdm, int *size)
+static void rt61pci_fill_rxdone(struct data_entry *entry,
+ struct rxdata_entry_desc *desc)
{
struct data_desc *rxd = entry->priv;
u32 word0;
@@ -1836,19 +1785,19 @@ static int rt61pci_fill_rxdone(struct data_entry *entry,
rt2x00_desc_read(rxd, 0, &word0);
rt2x00_desc_read(rxd, 1, &word1);
- if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR) ||
- rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR))
- return -EINVAL;
+ desc->flags = 0;
+ if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
+ desc->flags |= RX_FLAG_FAILED_FCS_CRC;
/*
* Obtain the status about this packet.
*/
- *signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
- *rssi = rt61pci_agc_to_rssi(entry->ring->rt2x00dev, word1);
- *ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
- *size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
+ desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
+ desc->rssi = rt61pci_agc_to_rssi(entry->ring->rt2x00dev, word1);
+ desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
+ desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
- return 0;
+ return;
}
/*
@@ -2340,9 +2289,7 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
*/
rt2x00dev->hw->flags =
IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
- IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_MONITOR_DURING_OPER |
- IEEE80211_HW_NO_PROBE_FILTERING;
+ IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
rt2x00dev->hw->extra_tx_headroom = 0;
rt2x00dev->hw->max_signal = MAX_SIGNAL;
rt2x00dev->hw->max_rssi = MAX_RX_SSI;
@@ -2426,6 +2373,74 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* IEEE80211 stack callback functions.
*/
+static void rt61pci_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ int mc_count,
+ struct dev_addr_list *mc_list)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct interface *intf = &rt2x00dev->interface;
+ u32 reg;
+
+ /*
+ * Mask off any flags we are going to ignore from
+ * the total_flags field.
+ */
+ *total_flags &=
+ FIF_ALLMULTI |
+ FIF_FCSFAIL |
+ FIF_PLCPFAIL |
+ FIF_CONTROL |
+ FIF_OTHER_BSS |
+ FIF_PROMISC_IN_BSS;
+
+ /*
+ * Apply some rules to the filters:
+ * - Some filters imply different filters to be set.
+ * - Some things we can't filter out at all.
+ * - Some filters are set based on interface type.
+ */
+ if (mc_count)
+ *total_flags |= FIF_ALLMULTI;
+ if (changed_flags & FIF_OTHER_BSS ||
+ changed_flags & FIF_PROMISC_IN_BSS)
+ *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
+ if (is_interface_type(intf, IEEE80211_IF_TYPE_AP))
+ *total_flags |= FIF_PROMISC_IN_BSS;
+
+ /*
+ * Check if there is any work left for us.
+ */
+ if (intf->filter == *total_flags)
+ return;
+ intf->filter = *total_flags;
+
+ /*
+ * Start configuration steps.
+ * Note that the version error will always be dropped
+ * and broadcast frames will always be accepted since
+ * there is no filter for it at this time.
+ */
+ rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®);
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC,
+ !(*total_flags & FIF_FCSFAIL));
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL,
+ !(*total_flags & FIF_PLCPFAIL));
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL,
+ !(*total_flags & FIF_CONTROL));
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME,
+ !(*total_flags & FIF_PROMISC_IN_BSS));
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS,
+ !(*total_flags & FIF_PROMISC_IN_BSS));
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1);
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST,
+ !(*total_flags & FIF_ALLMULTI));
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_BORADCAST, 0);
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 1);
+ rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
+}
+
static int rt61pci_set_retry_limit(struct ieee80211_hw *hw,
u32 short_retry, u32 long_retry)
{
@@ -2506,11 +2521,13 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
static const struct ieee80211_ops rt61pci_mac80211_ops = {
.tx = rt2x00mac_tx,
+ .start = rt2x00mac_start,
+ .stop = rt2x00mac_stop,
.add_interface = rt2x00mac_add_interface,
.remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config,
.config_interface = rt2x00mac_config_interface,
- .set_multicast_list = rt2x00mac_set_multicast_list,
+ .configure_filter = rt61pci_configure_filter,
.get_stats = rt2x00mac_get_stats,
.set_retry_limit = rt61pci_set_retry_limit,
.conf_tx = rt2x00mac_conf_tx,
@@ -2540,7 +2557,6 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
.fill_rxdone = rt61pci_fill_rxdone,
.config_mac_addr = rt61pci_config_mac_addr,
.config_bssid = rt61pci_config_bssid,
- .config_packet_filter = rt61pci_config_packet_filter,
.config_type = rt61pci_config_type,
.config = rt61pci_config,
};
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 890b449..b18cc93 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -293,23 +293,9 @@ static void rt73usb_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid)
rt73usb_register_multiwrite(rt2x00dev, MAC_CSR4, ®, sizeof(reg));
}
-static void rt73usb_config_packet_filter(struct rt2x00_dev *rt2x00dev,
- const unsigned int filter)
-{
- int promisc = !!(filter & IFF_PROMISC);
- int multicast = !!(filter & IFF_MULTICAST);
- int broadcast = !!(filter & IFF_BROADCAST);
- u32 reg;
-
- rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, !promisc);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, !multicast);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_BORADCAST, !broadcast);
- rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
-}
-
static void rt73usb_config_type(struct rt2x00_dev *rt2x00dev, const int type)
{
+ struct interface *intf = &rt2x00dev->interface;
u32 reg;
/*
@@ -325,56 +311,19 @@ static void rt73usb_config_type(struct rt2x00_dev *rt2x00dev, const int type)
rt73usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
/*
- * Apply hardware packet filter.
- */
- rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®);
-
- if (!is_monitor_present(&rt2x00dev->interface) &&
- (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_STA))
- rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, 1);
- else
- rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, 0);
-
- /*
- * If there is a non-monitor interface present
- * the packet should be strict (even if a monitor interface is present!).
- * When there is only 1 interface present which is in monitor mode
- * we should start accepting _all_ frames.
- */
- if (is_interface_present(&rt2x00dev->interface)) {
- rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, 1);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, 1);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, 1);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 1);
- } else if (is_monitor_present(&rt2x00dev->interface)) {
- rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, 0);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, 0);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, 0);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 0);
- rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 0);
- }
-
- rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
-
- /*
* Enable synchronisation.
*/
rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®);
- if (is_interface_present(&rt2x00dev->interface)) {
- rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1);
- rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1);
- }
-
+ rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 1);
+ rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 1);
rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0);
- if (type == IEEE80211_IF_TYPE_IBSS || type == IEEE80211_IF_TYPE_AP)
+ if (is_interface_type(intf, IEEE80211_IF_TYPE_IBSS) ||
+ is_interface_type(intf, IEEE80211_IF_TYPE_AP))
rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 2);
- else if (type == IEEE80211_IF_TYPE_STA)
+ else if (is_interface_type(intf, IEEE80211_IF_TYPE_STA))
rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 1);
- else if (is_monitor_present(&rt2x00dev->interface) &&
- !is_interface_present(&rt2x00dev->interface))
+ else
rt2x00_set_field32(®, TXRX_CSR9_TSF_SYNC, 0);
-
rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
}
@@ -1301,7 +1250,7 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev,
*/
static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
struct data_desc *txd,
- struct data_entry_desc *desc,
+ struct txdata_entry_desc *desc,
struct ieee80211_hdr *ieee80211hdr,
unsigned int length,
struct ieee80211_tx_control *control)
@@ -1429,8 +1378,8 @@ static int rt73usb_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1)
return rt2x00_get_field32(rxd_w1, RXD_W1_RSSI_AGC) * 2 - offset;
}
-static int rt73usb_fill_rxdone(struct data_entry *entry,
- int *signal, int *rssi, int *ofdm, int *size)
+static void rt73usb_fill_rxdone(struct data_entry *entry,
+ struct rxdata_entry_desc *desc)
{
struct data_desc *rxd = (struct data_desc *)entry->skb->data;
u32 word0;
@@ -1439,24 +1388,24 @@ static int rt73usb_fill_rxdone(struct data_entry *entry,
rt2x00_desc_read(rxd, 0, &word0);
rt2x00_desc_read(rxd, 1, &word1);
- if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR) ||
- rt2x00_get_field32(word0, RXD_W0_CIPHER_ERROR))
- return -EINVAL;
+ desc->flags = 0;
+ if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR))
+ desc->flags |= RX_FLAG_FAILED_FCS_CRC;
/*
* Obtain the status about this packet.
*/
- *signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
- *rssi = rt73usb_agc_to_rssi(entry->ring->rt2x00dev, word1);
- *ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
- *size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
+ desc->signal = rt2x00_get_field32(word1, RXD_W1_SIGNAL);
+ desc->rssi = rt73usb_agc_to_rssi(entry->ring->rt2x00dev, word1);
+ desc->ofdm = rt2x00_get_field32(word0, RXD_W0_OFDM);
+ desc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT);
/*
* Pull the skb to clear the descriptor area.
*/
skb_pull(entry->skb, entry->ring->desc_size);
- return 0;
+ return;
}
/*
@@ -1802,9 +1751,7 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
*/
rt2x00dev->hw->flags =
IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |
- IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
- IEEE80211_HW_MONITOR_DURING_OPER |
- IEEE80211_HW_NO_PROBE_FILTERING;
+ IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
rt2x00dev->hw->max_signal = MAX_SIGNAL;
rt2x00dev->hw->max_rssi = MAX_RX_SSI;
@@ -1878,11 +1825,9 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
rt73usb_probe_hw_mode(rt2x00dev);
/*
- * USB devices require scheduled packet filter toggling
* This device requires firmware
*/
__set_bit(REQUIRE_FIRMWARE, &rt2x00dev->flags);
- __set_bit(PACKET_FILTER_SCHEDULED, &rt2x00dev->flags);
/*
* Set the rssi offset.
@@ -1895,6 +1840,83 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* IEEE80211 stack callback functions.
*/
+static void rt73usb_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ int mc_count,
+ struct dev_addr_list *mc_list)
+{
+ struct rt2x00_dev *rt2x00dev = hw->priv;
+ struct interface *intf = &rt2x00dev->interface;
+ u32 reg;
+
+ /*
+ * Mask off any flags we are going to ignore from
+ * the total_flags field.
+ */
+ *total_flags &=
+ FIF_ALLMULTI |
+ FIF_FCSFAIL |
+ FIF_PLCPFAIL |
+ FIF_CONTROL |
+ FIF_OTHER_BSS |
+ FIF_PROMISC_IN_BSS;
+
+ /*
+ * Apply some rules to the filters:
+ * - Some filters imply different filters to be set.
+ * - Some things we can't filter out at all.
+ * - Some filters are set based on interface type.
+ */
+ if (mc_count)
+ *total_flags |= FIF_ALLMULTI;
+ if (changed_flags & FIF_OTHER_BSS ||
+ changed_flags & FIF_PROMISC_IN_BSS)
+ *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
+ if (is_interface_type(intf, IEEE80211_IF_TYPE_AP))
+ *total_flags |= FIF_PROMISC_IN_BSS;
+
+ /*
+ * Check if there is any work left for us.
+ */
+ if (intf->filter == *total_flags)
+ return;
+ intf->filter = *total_flags;
+
+ /*
+ * When in atomic context, reschedule and let rt2x00lib
+ * call this function again.
+ */
+ if (in_atomic()) {
+ queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work);
+ return;
+ }
+
+ /*
+ * Start configuration steps.
+ * Note that the version error will always be dropped
+ * and broadcast frames will always be accepted since
+ * there is no filter for it at this time.
+ */
+ rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®);
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC,
+ !(*total_flags & FIF_FCSFAIL));
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL,
+ !(*total_flags & FIF_PLCPFAIL));
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL,
+ !(*total_flags & FIF_CONTROL));
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME,
+ !(*total_flags & FIF_PROMISC_IN_BSS));
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS,
+ !(*total_flags & FIF_PROMISC_IN_BSS));
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1);
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST,
+ !(*total_flags & FIF_ALLMULTI));
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0);
+ rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, 1);
+ rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
+}
+
static int rt73usb_set_retry_limit(struct ieee80211_hw *hw,
u32 short_retry, u32 long_retry)
{
@@ -1977,11 +1999,13 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
static const struct ieee80211_ops rt73usb_mac80211_ops = {
.tx = rt2x00mac_tx,
+ .start = rt2x00mac_start,
+ .stop = rt2x00mac_stop,
.add_interface = rt2x00mac_add_interface,
.remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config,
.config_interface = rt2x00mac_config_interface,
- .set_multicast_list = rt2x00mac_set_multicast_list,
+ .configure_filter = rt73usb_configure_filter,
.get_stats = rt2x00mac_get_stats,
.set_retry_limit = rt73usb_set_retry_limit,
.conf_tx = rt2x00mac_conf_tx,
@@ -2012,7 +2036,6 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
.fill_rxdone = rt73usb_fill_rxdone,
.config_mac_addr = rt73usb_config_mac_addr,
.config_bssid = rt73usb_config_bssid,
- .config_packet_filter = rt73usb_config_packet_filter,
.config_type = rt73usb_config_type,
.config = rt73usb_config,
};
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index 5d63a1a..f095151 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -290,7 +290,7 @@ struct hw_pairwise_ta_entry {
#define TXRX_CSR0_DROP_TO_DS FIELD32(0x00200000)
#define TXRX_CSR0_DROP_VERSION_ERROR FIELD32(0x00400000)
#define TXRX_CSR0_DROP_MULTICAST FIELD32(0x00800000)
-#define TXRX_CSR0_DROP_BORADCAST FIELD32(0x01000000)
+#define TXRX_CSR0_DROP_BROADCAST FIELD32(0x01000000)
#define TXRX_CSR0_DROP_ACK_CTS FIELD32(0x02000000)
#define TXRX_CSR0_TX_WITHOUT_WAITING FIELD32(0x04000000)
--
1.5.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 6/12] rt2x00: Reorganize rt2x00dev->flags
2007-09-25 18:52 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (4 preceding siblings ...)
2007-09-25 18:55 ` [PATCH 5/12] rt2x00: adapt to filter configuration API Ivo van Doorn
@ 2007-09-25 18:55 ` Ivo van Doorn
2007-09-25 18:56 ` [PATCH 7/12] rt2x00: Add rt2x00dev->flags to debugfs Ivo van Doorn
` (5 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Ivo van Doorn @ 2007-09-25 18:55 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
The rt2x00dev->flags has become a chaos over time,
this will reorganize the flags by renaming, deleting, adding
and properly implement the flags.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2400pci.c | 4 +-
drivers/net/wireless/rt2x00/rt2500pci.c | 4 +-
drivers/net/wireless/rt2x00/rt2500usb.c | 2 +-
drivers/net/wireless/rt2x00/rt2x00.h | 31 +++++++---------
drivers/net/wireless/rt2x00/rt2x00config.c | 27 ++++----------
drivers/net/wireless/rt2x00/rt2x00dev.c | 55 ++++++++++++++++++++--------
drivers/net/wireless/rt2x00/rt2x00lib.h | 3 +-
drivers/net/wireless/rt2x00/rt2x00mac.c | 55 +++++++++++++++++++---------
drivers/net/wireless/rt2x00/rt2x00rfkill.c | 12 +++---
drivers/net/wireless/rt2x00/rt61pci.c | 4 +-
drivers/net/wireless/rt2x00/rt73usb.c | 2 +-
11 files changed, 115 insertions(+), 84 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 03a94a3..faa4711 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1374,7 +1374,7 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
* Detect if this device has an hardware controlled radio.
*/
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
- __set_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+ __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
/*
* Check if the BBP tuning should be enabled.
@@ -1469,7 +1469,7 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* This device requires the beacon ring
*/
- __set_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags);
+ __set_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags);
/*
* Set the rssi offset.
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 892baa9..929257d 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1545,7 +1545,7 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
* Detect if this device has an hardware controlled radio.
*/
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
- __set_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+ __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
/*
* Check if the BBP tuning should be enabled.
@@ -1801,7 +1801,7 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* This device requires the beacon ring
*/
- __set_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags);
+ __set_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags);
/*
* Set the rssi offset.
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index f4e6f6e..7aacc7b 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1573,7 +1573,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* This device requires the beacon ring
*/
- __set_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags);
+ __set_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags);
/*
* Set the rssi offset.
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 5f05c7e..ea20f3a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -493,24 +493,21 @@ struct rt2x00_dev {
* of the device capabilities are stored.
*/
unsigned long flags;
-#define DEVICE_ENABLED_RADIO 1
-#define DEVICE_ENABLED_RADIO_HW 2
+#define DEVICE_PRESENT 1
+#define DEVICE_REGISTERED_HW 2
#define DEVICE_INITIALIZED 3
-#define DEVICE_INITIALIZED_HW 4
-#define REQUIRE_FIRMWARE 5
-/* Hole: Add new Flag here */
-#define INTERFACE_RESUME 8
-#define INTERFACE_ENABLED 9
-/* Hole: Add new Flag here */
-#define REQUIRE_BEACON_RING 11
-#define DEVICE_SUPPORT_HW_BUTTON 12
-#define CONFIG_FRAME_TYPE 13
-#define CONFIG_RF_SEQUENCE 14
-/* Hole: Add new Flag here */
-#define CONFIG_EXTERNAL_LNA_A 16
-#define CONFIG_EXTERNAL_LNA_BG 17
-#define CONFIG_DOUBLE_ANTENNA 18
-#define CONFIG_DISABLE_LINK_TUNING 19
+#define DEVICE_STARTED 4
+#define DEVICE_ENABLED_RADIO 5
+#define DEVICE_ENABLED_RADIO_HW 6
+#define DRIVER_REQUIRE_FIRMWARE 7
+#define DRIVER_REQUIRE_BEACON_RING 8
+#define CONFIG_SUPPORT_HW_BUTTON 9
+#define CONFIG_FRAME_TYPE 10
+#define CONFIG_RF_SEQUENCE 11
+#define CONFIG_EXTERNAL_LNA_A 12
+#define CONFIG_EXTERNAL_LNA_BG 13
+#define CONFIG_DOUBLE_ANTENNA 14
+#define CONFIG_DISABLE_LINK_TUNING 15
/*
* Chipset identification.
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index f962ce4..13b5106 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -48,33 +48,20 @@ void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid)
void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, int type)
{
- struct interface *intf = &rt2x00dev->interface;
-
- if (!test_bit(INTERFACE_RESUME, &rt2x00dev->flags) &&
- (!!test_bit(INTERFACE_ENABLED, &rt2x00dev->flags) ==
- !!is_interface_present(intf)))
- return;
-
- rt2x00dev->ops->lib->config_type(rt2x00dev, type);
-
- /*
- * Update the configuration flags.
- */
- if (is_interface_present(intf))
- __set_bit(INTERFACE_ENABLED, &rt2x00dev->flags);
- else
- __clear_bit(INTERFACE_ENABLED, &rt2x00dev->flags);
+ if (type != INVALID_INTERFACE)
+ rt2x00dev->ops->lib->config_type(rt2x00dev, type);
}
-void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf)
+void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_conf *conf, const int force_config)
{
int flags = 0;
/*
- * If we are in RESUME state we should
- * force all configuration options.
+ * In some situations we want to force all configurations
+ * to be reloaded (When resuming for instance).
*/
- if (test_bit(INTERFACE_RESUME, &rt2x00dev->flags)) {
+ if (force_config) {
flags = CONFIG_UPDATE_ALL;
goto config;
}
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 4f66adc..f8f7e6e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -40,7 +40,7 @@
struct data_ring *rt2x00lib_get_ring(struct rt2x00_dev *rt2x00dev,
const unsigned int queue)
{
- int beacon = test_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags);
+ int beacon = test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags);
/*
* Check if we are requesting a reqular TX ring,
@@ -102,7 +102,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
* And check if the hardware button has been disabled.
*/
if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
- (test_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags) &&
+ (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags) &&
!test_bit(DEVICE_ENABLED_RADIO_HW, &rt2x00dev->flags)))
return 0;
@@ -162,6 +162,9 @@ void rt2x00lib_toggle_rx(struct rt2x00_dev *rt2x00dev, int enable)
{
enum dev_state state = enable ? STATE_RADIO_RX_ON : STATE_RADIO_RX_OFF;
+ if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
+ return;
+
/*
* When we are disabling the RX, we should also stop the link tuner.
*/
@@ -721,7 +724,7 @@ exit:
static void rt2x00lib_remove_hw(struct rt2x00_dev *rt2x00dev)
{
- if (test_bit(DEVICE_INITIALIZED_HW, &rt2x00dev->flags))
+ if (test_bit(DEVICE_REGISTERED_HW, &rt2x00dev->flags))
ieee80211_unregister_hw(rt2x00dev->hw);
if (likely(rt2x00dev->hwmodes)) {
@@ -753,7 +756,7 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
return status;
}
- __set_bit(DEVICE_INITIALIZED_HW, &rt2x00dev->flags);
+ __set_bit(DEVICE_REGISTERED_HW, &rt2x00dev->flags);
return 0;
}
@@ -810,7 +813,7 @@ static int rt2x00lib_alloc_ring_entries(struct rt2x00_dev *rt2x00dev)
return -ENOMEM;
}
- if (!test_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags))
+ if (!test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags))
return 0;
/*
@@ -919,7 +922,7 @@ static int rt2x00lib_alloc_rings(struct rt2x00_dev *rt2x00dev)
* Atim: 1 (if required)
*/
rt2x00dev->data_rings = 1 + rt2x00dev->hw->queues +
- (2 * test_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags));
+ (2 * test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags));
ring = kzalloc(rt2x00dev->data_rings * sizeof(*ring), GFP_KERNEL);
if (!ring) {
@@ -932,7 +935,7 @@ static int rt2x00lib_alloc_rings(struct rt2x00_dev *rt2x00dev)
*/
rt2x00dev->rx = ring;
rt2x00dev->tx = &rt2x00dev->rx[1];
- if (test_bit(REQUIRE_BEACON_RING, &rt2x00dev->flags))
+ if (test_bit(DRIVER_REQUIRE_BEACON_RING, &rt2x00dev->flags))
rt2x00dev->bcn = &rt2x00dev->tx[rt2x00dev->hw->queues];
/*
@@ -1011,6 +1014,8 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
*/
rt2x00debug_register(rt2x00dev);
+ __set_bit(DEVICE_PRESENT, &rt2x00dev->flags);
+
return 0;
exit:
@@ -1022,6 +1027,8 @@ EXPORT_SYMBOL_GPL(rt2x00lib_probe_dev);
void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
{
+ __clear_bit(DEVICE_PRESENT, &rt2x00dev->flags);
+
/*
* Disable radio.
*/
@@ -1068,6 +1075,13 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
int retval;
NOTICE(rt2x00dev, "Going to sleep.\n");
+ __clear_bit(DEVICE_PRESENT, &rt2x00dev->flags);
+
+ /*
+ * Only continue if mac80211 has open interfaces.
+ */
+ if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags))
+ goto exit;
/*
* Disable radio and unitialize all items
@@ -1077,6 +1091,7 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
rt2x00lib_uninitialize(rt2x00dev);
rt2x00debug_deregister(rt2x00dev);
+exit:
/*
* Set device mode to sleep for power management.
*/
@@ -1094,7 +1109,7 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
int retval;
NOTICE(rt2x00dev, "Waking up.\n");
- __set_bit(INTERFACE_RESUME, &rt2x00dev->flags);
+ __set_bit(DEVICE_PRESENT, &rt2x00dev->flags);
/*
* Open the debugfs entry.
@@ -1102,6 +1117,12 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
rt2x00debug_register(rt2x00dev);
/*
+ * Only continue if mac80211 has open interfaces.
+ */
+ if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags))
+ return 0;
+
+ /*
* Reinitialize device and all active interfaces.
*/
retval = rt2x00mac_start(rt2x00dev->hw);
@@ -1111,15 +1132,23 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
/*
* Reconfigure device.
*/
- retval = rt2x00mac_config(rt2x00dev->hw, &rt2x00dev->hw->conf);
- if (retval)
- goto exit;
+ rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf, 1);
+ if (!rt2x00dev->hw->conf.radio_enabled)
+ rt2x00lib_disable_radio(rt2x00dev);
rt2x00lib_config_mac_addr(rt2x00dev, intf->mac);
rt2x00lib_config_bssid(rt2x00dev, intf->bssid);
rt2x00lib_config_type(rt2x00dev, intf->type);
/*
+ * It is possible that during that mac80211 has attempted
+ * to send frames while we were suspending or resuming.
+ * In that case we have disabled the TX queue and should
+ * now enable it again
+ */
+ ieee80211_start_queues(rt2x00dev->hw);
+
+ /*
* When in Master or Ad-hoc mode,
* restart Beacon transmitting by faking a beacondone event.
*/
@@ -1127,8 +1156,6 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
intf->type == IEEE80211_IF_TYPE_IBSS)
rt2x00lib_beacondone(rt2x00dev);
- __clear_bit(INTERFACE_RESUME, &rt2x00dev->flags);
-
return 0;
exit:
@@ -1136,8 +1163,6 @@ exit:
rt2x00lib_uninitialize(rt2x00dev);
rt2x00debug_deregister(rt2x00dev);
- __clear_bit(INTERFACE_RESUME, &rt2x00dev->flags);
-
return retval;
}
EXPORT_SYMBOL_GPL(rt2x00lib_resume);
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index fcc2ffd..6dd92eb 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -52,7 +52,8 @@ void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev);
void rt2x00lib_config_mac_addr(struct rt2x00_dev *rt2x00dev, u8 *mac);
void rt2x00lib_config_bssid(struct rt2x00_dev *rt2x00dev, u8 *bssid);
void rt2x00lib_config_type(struct rt2x00_dev *rt2x00dev, int type);
-void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, struct ieee80211_conf *conf);
+void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
+ struct ieee80211_conf *conf, const int force_config);
/*
* Firmware handlers.
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 17802f6..e98d013 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -82,6 +82,17 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
u16 frame_control;
/*
+ * Mac80211 might be calling this function while we are trying
+ * to remove the device or perhaps suspending it.
+ * Note that we can only stop the TX queues inside the TX path
+ * due to possible race conditions in mac80211.
+ */
+ if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) {
+ ieee80211_stop_queues(hw);
+ return 0;
+ }
+
+ /*
* Determine which ring to put packet on.
*/
ring = rt2x00lib_get_ring(rt2x00dev, control->queue);
@@ -126,14 +137,15 @@ int rt2x00mac_start(struct ieee80211_hw *hw)
struct rt2x00_dev *rt2x00dev = hw->priv;
int status;
- if (test_bit(DEVICE_INITIALIZED, &rt2x00dev->flags))
+ if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) ||
+ test_bit(DEVICE_STARTED, &rt2x00dev->flags))
return 0;
/*
* If this is the first interface which is added,
* we should load the firmware now.
*/
- if (test_bit(REQUIRE_FIRMWARE, &rt2x00dev->flags)) {
+ if (test_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags)) {
status = rt2x00lib_load_firmware(rt2x00dev);
if (status)
return status;
@@ -155,6 +167,8 @@ int rt2x00mac_start(struct ieee80211_hw *hw)
return status;
}
+ __set_bit(DEVICE_STARTED, &rt2x00dev->flags);
+
return 0;
}
EXPORT_SYMBOL_GPL(rt2x00mac_start);
@@ -163,11 +177,16 @@ void rt2x00mac_stop(struct ieee80211_hw *hw)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
+ if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags))
+ return;
+
/*
* Perhaps we can add something smarter here,
* but for now just disabling the radio should do.
*/
rt2x00lib_disable_radio(rt2x00dev);
+
+ __clear_bit(DEVICE_STARTED, &rt2x00dev->flags);
}
EXPORT_SYMBOL_GPL(rt2x00mac_stop);
@@ -178,9 +197,12 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
struct interface *intf = &rt2x00dev->interface;
/*
- * We only support 1 non-monitor interface.
+ * Don't allow interfaces to be added while
+ * either the device has disappeared or when
+ * another interface is already present.
*/
- if (is_interface_present(intf))
+ if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) ||
+ is_interface_present(intf))
return -ENOBUFS;
intf->id = conf->if_id;
@@ -208,9 +230,12 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
struct interface *intf = &rt2x00dev->interface;
/*
- * We only support 1 non-monitor interface.
+ * Don't allow interfaces to be remove while
+ * either the device has disappeared or when
+ * no interface is present.
*/
- if (!is_interface_present(intf))
+ if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) ||
+ !is_interface_present(intf))
return;
intf->id = 0;
@@ -233,12 +258,10 @@ int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
struct rt2x00_dev *rt2x00dev = hw->priv;
/*
- * If the device is not initialized we shouldn't accept
- * any configuration changes. Mac80211 might be calling
- * this function while we are trying to remove the device
- * or perhaps suspending it.
+ * Mac80211 might be calling this function while we are trying
+ * to remove the device or perhaps suspending it.
*/
- if (!test_bit(DEVICE_INITIALIZED, &rt2x00dev->flags))
+ if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags))
return 0;
/*
@@ -252,7 +275,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
rt2x00lib_toggle_rx(rt2x00dev, 0);
}
- rt2x00lib_config(rt2x00dev, conf);
+ rt2x00lib_config(rt2x00dev, conf, 0);
/*
* Reenable RX only if the radio should be on.
@@ -274,12 +297,10 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, int if_id,
int status;
/*
- * If the device is not initialized we shouldn't accept
- * any configuration changes. Mac80211 might be calling
- * this function while we are trying to remove the device
- * or perhaps suspending it.
+ * Mac80211 might be calling this function while we are trying
+ * to remove the device or perhaps suspending it.
*/
- if (!test_bit(DEVICE_INITIALIZED, &rt2x00dev->flags))
+ if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags))
return 0;
/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
index b54457c..06af014 100644
--- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
+++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
@@ -45,9 +45,9 @@ static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state)
return 0;
/*
- * Only continue if we have an active interface.
+ * Only continue if there are enabled interfaces.
*/
- if (!is_interface_present(&rt2x00dev->interface))
+ if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags))
return 0;
if (state == RFKILL_STATE_ON) {
@@ -76,7 +76,7 @@ int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
{
int retval;
- if (!test_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
+ if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
return 0;
retval = rfkill_register(rt2x00dev->rfkill);
@@ -97,7 +97,7 @@ int rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
{
- if (!test_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
+ if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
return;
input_unregister_polled_device(rt2x00dev->poll_dev);
@@ -108,7 +108,7 @@ int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
{
struct device *device = wiphy_dev(rt2x00dev->hw->wiphy);
- if (!test_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
+ if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
return 0;
rt2x00dev->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
@@ -138,7 +138,7 @@ int rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
void rt2x00rfkill_free(struct rt2x00_dev *rt2x00dev)
{
- if (!test_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
+ if (!test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
return;
input_free_polled_device(rt2x00dev->poll_dev);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 3edcd74..4c5e317 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2105,7 +2105,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
* Detect if this device has an hardware controlled radio.
*/
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
- __set_bit(DEVICE_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+ __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
/*
* Read frequency offset and RF programming sequence.
@@ -2360,7 +2360,7 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* This device requires firmware
*/
- __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->flags);
+ __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
/*
* Set the rssi offset.
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index b18cc93..ffed3ec 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1827,7 +1827,7 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
/*
* This device requires firmware
*/
- __set_bit(REQUIRE_FIRMWARE, &rt2x00dev->flags);
+ __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
/*
* Set the rssi offset.
--
1.5.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 7/12] rt2x00: Add rt2x00dev->flags to debugfs
2007-09-25 18:52 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (5 preceding siblings ...)
2007-09-25 18:55 ` [PATCH 6/12] rt2x00: Reorganize rt2x00dev->flags Ivo van Doorn
@ 2007-09-25 18:56 ` Ivo van Doorn
2007-09-25 18:56 ` [PATCH 8/12] rt2x00: make rt2x00lib_stop_link_tuner() reentrant with link_tuner work Ivo van Doorn
` (4 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Ivo van Doorn @ 2007-09-25 18:56 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
>From aff2d533a74a6346d704321ff87b8874353ed5fa Mon Sep 17 00:00:00 2001
From: Ivo van Doorn <IvDoorn@gmail.com>
Date: Tue, 25 Sep 2007 20:13:51 +0200
Subject: [PATCH] rt2x00: Add rt2x00dev->flags to debugfs
Loosely based on the patch by Matthijs Kooijman,
this will add the dev_flags entry into debugfs which
will display rt2x00dev->flags.
This will allow easier debugging of flag handling.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00debug.c | 37 +++++++++++++++++++++++++++++
1 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 4d2aaec..9275d6f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -57,6 +57,7 @@ struct rt2x00debug_intf {
* - driver folder
* - driver file
* - chipset file
+ * - device flags file
* - register offset/value files
* - eeprom offset/value files
* - bbp offset/value files
@@ -65,6 +66,7 @@ struct rt2x00debug_intf {
struct dentry *driver_folder;
struct dentry *driver_entry;
struct dentry *chipset_entry;
+ struct dentry *dev_flags;
struct dentry *csr_off_entry;
struct dentry *csr_val_entry;
struct dentry *eeprom_off_entry;
@@ -193,6 +195,34 @@ RT2X00DEBUGFS_OPS(eeprom, "0x%.4x\n", u16);
RT2X00DEBUGFS_OPS(bbp, "0x%.2x\n", u8);
RT2X00DEBUGFS_OPS(rf, "0x%.8x\n", u32);
+static ssize_t rt2x00debug_read_dev_flags(struct file *file,
+ char __user *buf,
+ size_t length,
+ loff_t *offset)
+{
+ struct rt2x00debug_intf *intf = file->private_data;
+ char line[16];
+ size_t size;
+
+ if (*offset)
+ return 0;
+
+ size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->flags);
+
+ if (copy_to_user(buf, line, size))
+ return -EFAULT;
+
+ *offset += size;
+ return size;
+}
+
+static const struct file_operations rt2x00debug_fop_dev_flags = {
+ .owner = THIS_MODULE,
+ .read = rt2x00debug_read_dev_flags,
+ .open = rt2x00debug_file_open,
+ .release = rt2x00debug_file_release,
+};
+
static struct dentry *rt2x00debug_create_file_driver(const char *name,
struct rt2x00debug_intf
*intf,
@@ -270,6 +300,12 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
if (IS_ERR(intf->chipset_entry))
goto exit;
+ intf->dev_flags = debugfs_create_file("dev_flags", S_IRUGO,
+ intf->driver_folder, intf,
+ &rt2x00debug_fop_dev_flags);
+ if (IS_ERR(intf->dev_flags))
+ goto exit;
+
#define RT2X00DEBUGFS_CREATE_ENTRY(__intf, __name) \
({ \
(__intf)->__name##_off_entry = \
@@ -320,6 +356,7 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
debugfs_remove(intf->eeprom_off_entry);
debugfs_remove(intf->csr_val_entry);
debugfs_remove(intf->csr_off_entry);
+ debugfs_remove(intf->dev_flags);
debugfs_remove(intf->chipset_entry);
debugfs_remove(intf->driver_entry);
debugfs_remove(intf->driver_folder);
--
1.5.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 8/12] rt2x00: make rt2x00lib_stop_link_tuner() reentrant with link_tuner work
2007-09-25 18:52 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (6 preceding siblings ...)
2007-09-25 18:56 ` [PATCH 7/12] rt2x00: Add rt2x00dev->flags to debugfs Ivo van Doorn
@ 2007-09-25 18:56 ` Ivo van Doorn
2007-09-25 18:57 ` [PATCH 9/12] rt2x00: Stop link tuning when radio is down Ivo van Doorn
` (3 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Ivo van Doorn @ 2007-09-25 18:56 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
Calling cancel_delayed_work_sync() unconditionally won't hurt
and it will avoid race conditions when another CPU is already
executing link_tuner work.
Signed-off-by: Modestas Vainius <modestas@vainius.eu>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00dev.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index f8f7e6e..e8c91fb 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -80,8 +80,7 @@ static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
static void rt2x00lib_stop_link_tuner(struct rt2x00_dev *rt2x00dev)
{
- if (delayed_work_pending(&rt2x00dev->link.work))
- cancel_rearming_delayed_work(&rt2x00dev->link.work);
+ cancel_delayed_work_sync(&rt2x00dev->link.work);
}
void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev)
--
1.5.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 9/12] rt2x00: Stop link tuning when radio is down
2007-09-25 18:52 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (7 preceding siblings ...)
2007-09-25 18:56 ` [PATCH 8/12] rt2x00: make rt2x00lib_stop_link_tuner() reentrant with link_tuner work Ivo van Doorn
@ 2007-09-25 18:57 ` Ivo van Doorn
2007-09-25 18:57 ` [PATCH 10/12] rt2x00: Fix obvious typo in comment Ivo van Doorn
` (2 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Ivo van Doorn @ 2007-09-25 18:57 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
As pointed out by Modestas Vainius the link tuner
could continue working while the radio is already
down. This because at the start of disable_radio
the ENABLED_RADIO flag is cleared and causes the
toggle_rx to skip the stop_link_tuner() call.
This will add a check to the start of the link tuner
which will automatically stop the link tuner when the
radio is disabled.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00dev.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index e8c91fb..92b7252 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -237,6 +237,13 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
container_of(work, struct rt2x00_dev, link.work.work);
/*
+ * When the radio is shutting down we should
+ * immediately cease all link tuning.
+ */
+ if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
+ return;
+
+ /*
* Update statistics.
*/
rt2x00dev->ops->lib->link_stats(rt2x00dev);
--
1.5.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 10/12] rt2x00: Fix obvious typo in comment
2007-09-25 18:52 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (8 preceding siblings ...)
2007-09-25 18:57 ` [PATCH 9/12] rt2x00: Stop link tuning when radio is down Ivo van Doorn
@ 2007-09-25 18:57 ` Ivo van Doorn
2007-09-25 18:57 ` [PATCH 11/12] rt2x00: Fix panic on rmmod with rfkill enabled Ivo van Doorn
2007-09-25 18:58 ` [PATCH 12/12] rt2x00: Release rt2x00 2.0.9 Ivo van Doorn
11 siblings, 0 replies; 13+ messages in thread
From: Ivo van Doorn @ 2007-09-25 18:57 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
Signed-off-by: Modestas Vainius <modestas@vainius.eu>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2500pci.c | 2 +-
drivers/net/wireless/rt2x00/rt61pci.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 929257d..842da90 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -244,7 +244,7 @@ static int rt2500pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
rt2x00pci_register_read(rt2x00dev, GPIOCSR, ®);
return rt2x00_get_field32(reg, GPIOCSR_BIT0);
}
-#endif /* CONFIG_RT2400PCI_RFKILL */
+#endif /* CONFIG_RT2500PCI_RFKILL */
/*
* Configuration handlers.
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 4c5e317..6aa5176 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -269,7 +269,7 @@ static int rt61pci_rfkill_poll(struct rt2x00_dev *rt2x00dev)
rt2x00pci_register_read(rt2x00dev, MAC_CSR13, ®);
return rt2x00_get_field32(reg, MAC_CSR13_BIT5);;
}
-#endif /* CONFIG_RT2400PCI_RFKILL */
+#endif /* CONFIG_RT61PCI_RFKILL */
/*
* Configuration handlers.
--
1.5.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 11/12] rt2x00: Fix panic on rmmod with rfkill enabled
2007-09-25 18:52 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (9 preceding siblings ...)
2007-09-25 18:57 ` [PATCH 10/12] rt2x00: Fix obvious typo in comment Ivo van Doorn
@ 2007-09-25 18:57 ` Ivo van Doorn
2007-09-25 18:58 ` [PATCH 12/12] rt2x00: Release rt2x00 2.0.9 Ivo van Doorn
11 siblings, 0 replies; 13+ messages in thread
From: Ivo van Doorn @ 2007-09-25 18:57 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
When ieee80211_hw.config indicates that the radio
is enabled and is configuring options that require
the link tuner to be restarted the link tuner will
cause a kernel panic when rfkill has indicated the
radio was in fact disabled.
Signed-off-by: Modestas Vainius <modestas@vainius.eu>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00dev.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 92b7252..0216096 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -85,6 +85,9 @@ static void rt2x00lib_stop_link_tuner(struct rt2x00_dev *rt2x00dev)
void rt2x00lib_reset_link_tuner(struct rt2x00_dev *rt2x00dev)
{
+ if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
+ return;
+
rt2x00lib_stop_link_tuner(rt2x00dev);
rt2x00lib_start_link_tuner(rt2x00dev);
}
--
1.5.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH 12/12] rt2x00: Release rt2x00 2.0.9
2007-09-25 18:52 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
` (10 preceding siblings ...)
2007-09-25 18:57 ` [PATCH 11/12] rt2x00: Fix panic on rmmod with rfkill enabled Ivo van Doorn
@ 2007-09-25 18:58 ` Ivo van Doorn
11 siblings, 0 replies; 13+ messages in thread
From: Ivo van Doorn @ 2007-09-25 18:58 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, rt2400-devel
Version bump
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
---
drivers/net/wireless/rt2x00/rt2x00.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index ea20f3a..511c11c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -42,7 +42,7 @@
* Module information.
* DRV_NAME should be set within the individual module source files.
*/
-#define DRV_VERSION "2.0.8"
+#define DRV_VERSION "2.0.9"
#define DRV_PROJECT "http://rt2x00.serialmonkey.com"
/*
--
1.5.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2007-09-25 18:44 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-09-25 18:52 Please pull 'upstream' branch of rt2x00 Ivo van Doorn
2007-09-25 18:53 ` [PATCH 1/12] rt2x00: Correct error in calculating rssi for link tuner Ivo van Doorn
2007-09-25 18:53 ` [PATCH 2/12] rt2x00: Make *_beacon_update static Ivo van Doorn
2007-09-25 18:54 ` [PATCH 3/12] rt2x00: Increase rt2x00usb_vendor_request timeout Ivo van Doorn
2007-09-25 18:54 ` [PATCH 4/12] rt2x00: Correctly identify rt2561turbo Ivo van Doorn
2007-09-25 18:55 ` [PATCH 5/12] rt2x00: adapt to filter configuration API Ivo van Doorn
2007-09-25 18:55 ` [PATCH 6/12] rt2x00: Reorganize rt2x00dev->flags Ivo van Doorn
2007-09-25 18:56 ` [PATCH 7/12] rt2x00: Add rt2x00dev->flags to debugfs Ivo van Doorn
2007-09-25 18:56 ` [PATCH 8/12] rt2x00: make rt2x00lib_stop_link_tuner() reentrant with link_tuner work Ivo van Doorn
2007-09-25 18:57 ` [PATCH 9/12] rt2x00: Stop link tuning when radio is down Ivo van Doorn
2007-09-25 18:57 ` [PATCH 10/12] rt2x00: Fix obvious typo in comment Ivo van Doorn
2007-09-25 18:57 ` [PATCH 11/12] rt2x00: Fix panic on rmmod with rfkill enabled Ivo van Doorn
2007-09-25 18:58 ` [PATCH 12/12] rt2x00: Release rt2x00 2.0.9 Ivo van Doorn
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).