Commit 3a643d24 authored by Ivo van Doorn's avatar Ivo van Doorn Committed by John W. Linville

rt2x00: Fix in_atomic() usage

rt73usb and rt2500usb used in_atomic to determine
if a configuration step should be rescheduled or not.
Since in_atomic() is not a valid method to determine
if sleeping is allowed we should fix the way this is handled
by adding a new flag to rt2x00.

In addition mark LED class support for the drivers broken
since that also uses the broken in_atomic() method but
so far no solution exists to have LED triggers work only
in scheduled context.
Signed-off-by: default avatarIvo van Doorn <IvDoorn@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 866a0503
...@@ -134,7 +134,7 @@ config RT2500USB ...@@ -134,7 +134,7 @@ config RT2500USB
config RT2500USB_LEDS config RT2500USB_LEDS
bool "RT2500 leds support" bool "RT2500 leds support"
depends on RT2500USB depends on RT2500USB && BROKEN
select RT2X00_LIB_LEDS select RT2X00_LIB_LEDS
---help--- ---help---
This adds support for led triggers provided my mac80211. This adds support for led triggers provided my mac80211.
...@@ -152,7 +152,7 @@ config RT73USB ...@@ -152,7 +152,7 @@ config RT73USB
config RT73USB_LEDS config RT73USB_LEDS
bool "RT73 leds support" bool "RT73 leds support"
depends on RT73USB depends on RT73USB && BROKEN
select RT2X00_LIB_LEDS select RT2X00_LIB_LEDS
---help--- ---help---
This adds support for led triggers provided my mac80211. This adds support for led triggers provided my mac80211.
......
...@@ -270,6 +270,31 @@ static void rt2400pci_led_brightness(struct led_classdev *led_cdev, ...@@ -270,6 +270,31 @@ static void rt2400pci_led_brightness(struct led_classdev *led_cdev,
/* /*
* Configuration handlers. * Configuration handlers.
*/ */
static void rt2400pci_config_filter(struct rt2x00_dev *rt2x00dev,
const unsigned int filter_flags)
{
u32 reg;
/*
* 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, &reg);
rt2x00_set_field32(&reg, RXCSR0_DROP_CRC,
!(filter_flags & FIF_FCSFAIL));
rt2x00_set_field32(&reg, RXCSR0_DROP_PHYSICAL,
!(filter_flags & FIF_PLCPFAIL));
rt2x00_set_field32(&reg, RXCSR0_DROP_CONTROL,
!(filter_flags & FIF_CONTROL));
rt2x00_set_field32(&reg, RXCSR0_DROP_NOT_TO_ME,
!(filter_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field32(&reg, RXCSR0_DROP_TODS,
!(filter_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field32(&reg, RXCSR0_DROP_VERSION_ERROR, 1);
rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
}
static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf, struct rt2x00_intf *intf,
struct rt2x00intf_conf *conf, struct rt2x00intf_conf *conf,
...@@ -306,7 +331,7 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, ...@@ -306,7 +331,7 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev,
conf->bssid, sizeof(conf->bssid)); conf->bssid, sizeof(conf->bssid));
} }
static int rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_erp *erp) struct rt2x00lib_erp *erp)
{ {
int preamble_mask; int preamble_mask;
...@@ -347,8 +372,6 @@ static int rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, ...@@ -347,8 +372,6 @@ static int rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84); rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110));
rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
return 0;
} }
static void rt2400pci_config_phymode(struct rt2x00_dev *rt2x00dev, static void rt2400pci_config_phymode(struct rt2x00_dev *rt2x00dev,
...@@ -1397,64 +1420,6 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) ...@@ -1397,64 +1420,6 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev)
/* /*
* IEEE80211 stack callback functions. * 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;
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.
*/
*total_flags |= FIF_ALLMULTI;
if (*total_flags & FIF_OTHER_BSS ||
*total_flags & FIF_PROMISC_IN_BSS)
*total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
/*
* Check if there is any work left for us.
*/
if (rt2x00dev->packet_filter == *total_flags)
return;
rt2x00dev->packet_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, &reg);
rt2x00_set_field32(&reg, RXCSR0_DROP_CRC,
!(*total_flags & FIF_FCSFAIL));
rt2x00_set_field32(&reg, RXCSR0_DROP_PHYSICAL,
!(*total_flags & FIF_PLCPFAIL));
rt2x00_set_field32(&reg, RXCSR0_DROP_CONTROL,
!(*total_flags & FIF_CONTROL));
rt2x00_set_field32(&reg, RXCSR0_DROP_NOT_TO_ME,
!(*total_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field32(&reg, RXCSR0_DROP_TODS,
!(*total_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field32(&reg, RXCSR0_DROP_VERSION_ERROR, 1);
rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
}
static int rt2400pci_set_retry_limit(struct ieee80211_hw *hw, static int rt2400pci_set_retry_limit(struct ieee80211_hw *hw,
u32 short_retry, u32 long_retry) u32 short_retry, u32 long_retry)
{ {
...@@ -1580,7 +1545,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = { ...@@ -1580,7 +1545,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
.remove_interface = rt2x00mac_remove_interface, .remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config, .config = rt2x00mac_config,
.config_interface = rt2x00mac_config_interface, .config_interface = rt2x00mac_config_interface,
.configure_filter = rt2400pci_configure_filter, .configure_filter = rt2x00mac_configure_filter,
.get_stats = rt2x00mac_get_stats, .get_stats = rt2x00mac_get_stats,
.set_retry_limit = rt2400pci_set_retry_limit, .set_retry_limit = rt2400pci_set_retry_limit,
.bss_info_changed = rt2x00mac_bss_info_changed, .bss_info_changed = rt2x00mac_bss_info_changed,
...@@ -1608,6 +1573,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { ...@@ -1608,6 +1573,7 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
.write_tx_data = rt2x00pci_write_tx_data, .write_tx_data = rt2x00pci_write_tx_data,
.kick_tx_queue = rt2400pci_kick_tx_queue, .kick_tx_queue = rt2400pci_kick_tx_queue,
.fill_rxdone = rt2400pci_fill_rxdone, .fill_rxdone = rt2400pci_fill_rxdone,
.config_filter = rt2400pci_config_filter,
.config_intf = rt2400pci_config_intf, .config_intf = rt2400pci_config_intf,
.config_erp = rt2400pci_config_erp, .config_erp = rt2400pci_config_erp,
.config = rt2400pci_config, .config = rt2400pci_config,
......
...@@ -270,6 +270,35 @@ static void rt2500pci_led_brightness(struct led_classdev *led_cdev, ...@@ -270,6 +270,35 @@ static void rt2500pci_led_brightness(struct led_classdev *led_cdev,
/* /*
* Configuration handlers. * Configuration handlers.
*/ */
static void rt2500pci_config_filter(struct rt2x00_dev *rt2x00dev,
const unsigned int filter_flags)
{
u32 reg;
/*
* 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, &reg);
rt2x00_set_field32(&reg, RXCSR0_DROP_CRC,
!(filter_flags & FIF_FCSFAIL));
rt2x00_set_field32(&reg, RXCSR0_DROP_PHYSICAL,
!(filter_flags & FIF_PLCPFAIL));
rt2x00_set_field32(&reg, RXCSR0_DROP_CONTROL,
!(filter_flags & FIF_CONTROL));
rt2x00_set_field32(&reg, RXCSR0_DROP_NOT_TO_ME,
!(filter_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field32(&reg, RXCSR0_DROP_TODS,
!(filter_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field32(&reg, RXCSR0_DROP_VERSION_ERROR, 1);
rt2x00_set_field32(&reg, RXCSR0_DROP_MCAST,
!(filter_flags & FIF_ALLMULTI));
rt2x00_set_field32(&reg, RXCSR0_DROP_BCAST, 0);
rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
}
static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf, struct rt2x00_intf *intf,
struct rt2x00intf_conf *conf, struct rt2x00intf_conf *conf,
...@@ -309,7 +338,7 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev, ...@@ -309,7 +338,7 @@ static void rt2500pci_config_intf(struct rt2x00_dev *rt2x00dev,
conf->bssid, sizeof(conf->bssid)); conf->bssid, sizeof(conf->bssid));
} }
static int rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_erp *erp) struct rt2x00lib_erp *erp)
{ {
int preamble_mask; int preamble_mask;
...@@ -350,8 +379,6 @@ static int rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev, ...@@ -350,8 +379,6 @@ static int rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84); rt2x00_set_field32(&reg, ARCSR5_SERVICE, 0x84);
rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); rt2x00_set_field32(&reg, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110));
rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); rt2x00pci_register_write(rt2x00dev, ARCSR5, reg);
return 0;
} }
static void rt2500pci_config_phymode(struct rt2x00_dev *rt2x00dev, static void rt2500pci_config_phymode(struct rt2x00_dev *rt2x00dev,
...@@ -1731,69 +1758,6 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) ...@@ -1731,69 +1758,6 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev)
/* /*
* IEEE80211 stack callback functions. * 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;
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.
*/
if (mc_count)
*total_flags |= FIF_ALLMULTI;
if (*total_flags & FIF_OTHER_BSS ||
*total_flags & FIF_PROMISC_IN_BSS)
*total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
/*
* Check if there is any work left for us.
*/
if (rt2x00dev->packet_filter == *total_flags)
return;
rt2x00dev->packet_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, &reg);
rt2x00_set_field32(&reg, RXCSR0_DROP_CRC,
!(*total_flags & FIF_FCSFAIL));
rt2x00_set_field32(&reg, RXCSR0_DROP_PHYSICAL,
!(*total_flags & FIF_PLCPFAIL));
rt2x00_set_field32(&reg, RXCSR0_DROP_CONTROL,
!(*total_flags & FIF_CONTROL));
rt2x00_set_field32(&reg, RXCSR0_DROP_NOT_TO_ME,
!(*total_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field32(&reg, RXCSR0_DROP_TODS,
!(*total_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field32(&reg, RXCSR0_DROP_VERSION_ERROR, 1);
rt2x00_set_field32(&reg, RXCSR0_DROP_MCAST,
!(*total_flags & FIF_ALLMULTI));
rt2x00_set_field32(&reg, RXCSR0_DROP_BCAST, 0);
rt2x00pci_register_write(rt2x00dev, RXCSR0, reg);
}
static int rt2500pci_set_retry_limit(struct ieee80211_hw *hw, static int rt2500pci_set_retry_limit(struct ieee80211_hw *hw,
u32 short_retry, u32 long_retry) u32 short_retry, u32 long_retry)
{ {
...@@ -1894,7 +1858,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = { ...@@ -1894,7 +1858,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
.remove_interface = rt2x00mac_remove_interface, .remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config, .config = rt2x00mac_config,
.config_interface = rt2x00mac_config_interface, .config_interface = rt2x00mac_config_interface,
.configure_filter = rt2500pci_configure_filter, .configure_filter = rt2x00mac_configure_filter,
.get_stats = rt2x00mac_get_stats, .get_stats = rt2x00mac_get_stats,
.set_retry_limit = rt2500pci_set_retry_limit, .set_retry_limit = rt2500pci_set_retry_limit,
.bss_info_changed = rt2x00mac_bss_info_changed, .bss_info_changed = rt2x00mac_bss_info_changed,
...@@ -1922,6 +1886,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = { ...@@ -1922,6 +1886,7 @@ static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
.write_tx_data = rt2x00pci_write_tx_data, .write_tx_data = rt2x00pci_write_tx_data,
.kick_tx_queue = rt2500pci_kick_tx_queue, .kick_tx_queue = rt2500pci_kick_tx_queue,
.fill_rxdone = rt2500pci_fill_rxdone, .fill_rxdone = rt2500pci_fill_rxdone,
.config_filter = rt2500pci_config_filter,
.config_intf = rt2500pci_config_intf, .config_intf = rt2500pci_config_intf,
.config_erp = rt2500pci_config_erp, .config_erp = rt2500pci_config_erp,
.config = rt2500pci_config, .config = rt2500pci_config,
......
...@@ -316,6 +316,35 @@ static void rt2500usb_led_brightness(struct led_classdev *led_cdev, ...@@ -316,6 +316,35 @@ static void rt2500usb_led_brightness(struct led_classdev *led_cdev,
/* /*
* Configuration handlers. * Configuration handlers.
*/ */
static void rt2500usb_config_filter(struct rt2x00_dev *rt2x00dev,
const unsigned int filter_flags)
{
u16 reg;
/*
* 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, &reg);
rt2x00_set_field16(&reg, TXRX_CSR2_DROP_CRC,
!(filter_flags & FIF_FCSFAIL));
rt2x00_set_field16(&reg, TXRX_CSR2_DROP_PHYSICAL,
!(filter_flags & FIF_PLCPFAIL));
rt2x00_set_field16(&reg, TXRX_CSR2_DROP_CONTROL,
!(filter_flags & FIF_CONTROL));
rt2x00_set_field16(&reg, TXRX_CSR2_DROP_NOT_TO_ME,
!(filter_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field16(&reg, TXRX_CSR2_DROP_TODS,
!(filter_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field16(&reg, TXRX_CSR2_DROP_VERSION_ERROR, 1);
rt2x00_set_field16(&reg, TXRX_CSR2_DROP_MULTICAST,
!(filter_flags & FIF_ALLMULTI));
rt2x00_set_field16(&reg, TXRX_CSR2_DROP_BROADCAST, 0);
rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
}
static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf, struct rt2x00_intf *intf,
struct rt2x00intf_conf *conf, struct rt2x00intf_conf *conf,
...@@ -358,18 +387,11 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, ...@@ -358,18 +387,11 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev,
(3 * sizeof(__le16))); (3 * sizeof(__le16)));
} }
static int rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev, static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_erp *erp) struct rt2x00lib_erp *erp)
{ {
u16 reg; u16 reg;
/*
* When in atomic context, we should let rt2x00lib
* try this configuration again later.
*/
if (in_atomic())
return -EAGAIN;
rt2500usb_register_read(rt2x00dev, TXRX_CSR1, &reg); rt2500usb_register_read(rt2x00dev, TXRX_CSR1, &reg);
rt2x00_set_field16(&reg, TXRX_CSR1_ACK_TIMEOUT, erp->ack_timeout); rt2x00_set_field16(&reg, TXRX_CSR1_ACK_TIMEOUT, erp->ack_timeout);
rt2500usb_register_write(rt2x00dev, TXRX_CSR1, reg); rt2500usb_register_write(rt2x00dev, TXRX_CSR1, reg);
...@@ -378,8 +400,6 @@ static int rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev, ...@@ -378,8 +400,6 @@ static int rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field16(&reg, TXRX_CSR10_AUTORESPOND_PREAMBLE, rt2x00_set_field16(&reg, TXRX_CSR10_AUTORESPOND_PREAMBLE,
!!erp->short_preamble); !!erp->short_preamble);
rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg);
return 0;
} }
static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev, static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev,
...@@ -1644,6 +1664,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) ...@@ -1644,6 +1664,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
*/ */
__set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
__set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags);
__set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
/* /*
* Set the rssi offset. * Set the rssi offset.
...@@ -1656,78 +1677,6 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) ...@@ -1656,78 +1677,6 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev)
/* /*
* IEEE80211 stack callback functions. * 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;
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.
*/
if (mc_count)
*total_flags |= FIF_ALLMULTI;
if (*total_flags & FIF_OTHER_BSS ||
*total_flags & FIF_PROMISC_IN_BSS)
*total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
/*
* Check if there is any work left for us.
*/
if (rt2x00dev->packet_filter == *total_flags)
return;
rt2x00dev->packet_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, &reg);
rt2x00_set_field16(&reg, TXRX_CSR2_DROP_CRC,
!(*total_flags & FIF_FCSFAIL));
rt2x00_set_field16(&reg, TXRX_CSR2_DROP_PHYSICAL,
!(*total_flags & FIF_PLCPFAIL));
rt2x00_set_field16(&reg, TXRX_CSR2_DROP_CONTROL,
!(*total_flags & FIF_CONTROL));
rt2x00_set_field16(&reg, TXRX_CSR2_DROP_NOT_TO_ME,
!(*total_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field16(&reg, TXRX_CSR2_DROP_TODS,
!(*total_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field16(&reg, TXRX_CSR2_DROP_VERSION_ERROR, 1);
rt2x00_set_field16(&reg, TXRX_CSR2_DROP_MULTICAST,
!(*total_flags & FIF_ALLMULTI));
rt2x00_set_field16(&reg, TXRX_CSR2_DROP_BROADCAST, 0);
rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
}
static int rt2500usb_beacon_update(struct ieee80211_hw *hw, static int rt2500usb_beacon_update(struct ieee80211_hw *hw,
struct sk_buff *skb, struct sk_buff *skb,
struct ieee80211_tx_control *control) struct ieee80211_tx_control *control)
...@@ -1824,7 +1773,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = { ...@@ -1824,7 +1773,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
.remove_interface = rt2x00mac_remove_interface, .remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config, .config = rt2x00mac_config,
.config_interface = rt2x00mac_config_interface, .config_interface = rt2x00mac_config_interface,
.configure_filter = rt2500usb_configure_filter, .configure_filter = rt2x00mac_configure_filter,
.get_stats = rt2x00mac_get_stats, .get_stats = rt2x00mac_get_stats,
.bss_info_changed = rt2x00mac_bss_info_changed, .bss_info_changed = rt2x00mac_bss_info_changed,
.conf_tx = rt2x00mac_conf_tx, .conf_tx = rt2x00mac_conf_tx,
...@@ -1848,6 +1797,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { ...@@ -1848,6 +1797,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
.get_tx_data_len = rt2500usb_get_tx_data_len, .get_tx_data_len = rt2500usb_get_tx_data_len,
.kick_tx_queue = rt2500usb_kick_tx_queue, .kick_tx_queue = rt2500usb_kick_tx_queue,
.fill_rxdone = rt2500usb_fill_rxdone, .fill_rxdone = rt2500usb_fill_rxdone,
.config_filter = rt2500usb_config_filter,
.config_intf = rt2500usb_config_intf, .config_intf = rt2500usb_config_intf,
.config_erp = rt2500usb_config_erp, .config_erp = rt2500usb_config_erp,
.config = rt2500usb_config, .config = rt2500usb_config,
......
...@@ -560,6 +560,8 @@ struct rt2x00lib_ops { ...@@ -560,6 +560,8 @@ struct rt2x00lib_ops {
/* /*
* Configuration handlers. * Configuration handlers.
*/ */
void (*config_filter) (struct rt2x00_dev *rt2x00dev,
const unsigned int filter_flags);
void (*config_intf) (struct rt2x00_dev *rt2x00dev, void (*config_intf) (struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf, struct rt2x00_intf *intf,
struct rt2x00intf_conf *conf, struct rt2x00intf_conf *conf,
...@@ -568,7 +570,7 @@ struct rt2x00lib_ops { ...@@ -568,7 +570,7 @@ struct rt2x00lib_ops {
#define CONFIG_UPDATE_MAC ( 1 << 2 ) #define CONFIG_UPDATE_MAC ( 1 << 2 )
#define CONFIG_UPDATE_BSSID ( 1 << 3 ) #define CONFIG_UPDATE_BSSID ( 1 << 3 )
int (*config_erp) (struct rt2x00_dev *rt2x00dev, void (*config_erp) (struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_erp *erp); struct rt2x00lib_erp *erp);
void (*config) (struct rt2x00_dev *rt2x00dev, void (*config) (struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_conf *libconf, struct rt2x00lib_conf *libconf,
...@@ -624,6 +626,7 @@ enum rt2x00_flags { ...@@ -624,6 +626,7 @@ enum rt2x00_flags {
DRIVER_REQUIRE_FIRMWARE, DRIVER_REQUIRE_FIRMWARE,
DRIVER_REQUIRE_BEACON_GUARD, DRIVER_REQUIRE_BEACON_GUARD,
DRIVER_REQUIRE_ATIM_QUEUE, DRIVER_REQUIRE_ATIM_QUEUE,
DRIVER_REQUIRE_SCHEDULED,
/* /*
* Driver configuration * Driver configuration
...@@ -987,6 +990,10 @@ int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf); ...@@ -987,6 +990,10 @@ int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
int rt2x00mac_config_interface(struct ieee80211_hw *hw, int rt2x00mac_config_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
struct ieee80211_if_conf *conf); struct ieee80211_if_conf *conf);
void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *total_flags,
int mc_count, struct dev_addr_list *mc_list);
int rt2x00mac_get_stats(struct ieee80211_hw *hw, int rt2x00mac_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats); struct ieee80211_low_level_stats *stats);
int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw, int rt2x00mac_get_tx_stats(struct ieee80211_hw *hw,
......
...@@ -80,7 +80,6 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, ...@@ -80,7 +80,6 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
struct ieee80211_bss_conf *bss_conf) struct ieee80211_bss_conf *bss_conf)
{ {
struct rt2x00lib_erp erp; struct rt2x00lib_erp erp;
int retval;
memset(&erp, 0, sizeof(erp)); memset(&erp, 0, sizeof(erp));
...@@ -101,14 +100,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, ...@@ -101,14 +100,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
erp.ack_consume_time += PREAMBLE; erp.ack_consume_time += PREAMBLE;
} }
retval = rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp); rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp);
if (retval) {
spin_lock(&intf->lock);
intf->delayed_flags |= DELAYED_CONFIG_ERP;
queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work);
spin_unlock(&intf->lock);
}
} }
void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
......
...@@ -380,6 +380,50 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw, ...@@ -380,6 +380,50 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw,
} }
EXPORT_SYMBOL_GPL(rt2x00mac_config_interface); EXPORT_SYMBOL_GPL(rt2x00mac_config_interface);
void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *total_flags,
int mc_count, struct dev_addr_list *mc_list)
{
struct rt2x00_dev *rt2x00dev = hw->priv;
/*
* 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.
* - Multicast filter seems to kill broadcast traffic so never use it.
*/
*total_flags |= FIF_ALLMULTI;
if (*total_flags & FIF_OTHER_BSS ||
*total_flags & FIF_PROMISC_IN_BSS)
*total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
/*
* Check if there is any work left for us.
*/
if (rt2x00dev->packet_filter == *total_flags)
return;
rt2x00dev->packet_filter = *total_flags;
if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work);
else
rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags);
}
EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
int rt2x00mac_get_stats(struct ieee80211_hw *hw, int rt2x00mac_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats) struct ieee80211_low_level_stats *stats)
{ {
...@@ -419,6 +463,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, ...@@ -419,6 +463,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
{ {
struct rt2x00_dev *rt2x00dev = hw->priv; struct rt2x00_dev *rt2x00dev = hw->priv;
struct rt2x00_intf *intf = vif_to_intf(vif); struct rt2x00_intf *intf = vif_to_intf(vif);
unsigned int delayed = 0;
/* /*
* When the association status has changed we must reset the link * When the association status has changed we must reset the link
...@@ -439,11 +484,19 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, ...@@ -439,11 +484,19 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
* When the erp information has changed, we should perform * When the erp information has changed, we should perform
* additional configuration steps. For all other changes we are done. * additional configuration steps. For all other changes we are done.
*/ */
if (changes & BSS_CHANGED_ERP_PREAMBLE) if (changes & BSS_CHANGED_ERP_PREAMBLE) {
if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
rt2x00lib_config_erp(rt2x00dev, intf, bss_conf); rt2x00lib_config_erp(rt2x00dev, intf, bss_conf);
else
delayed |= DELAYED_CONFIG_ERP;
}
spin_lock(&intf->lock); spin_lock(&intf->lock);
memcpy(&intf->conf, bss_conf, sizeof(*bss_conf)); memcpy(&intf->conf, bss_conf, sizeof(*bss_conf));
if (delayed) {
intf->delayed_flags |= delayed;
queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work);
}
spin_unlock(&intf->lock); spin_unlock(&intf->lock);
} }
EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed); EXPORT_SYMBOL_GPL(rt2x00mac_bss_info_changed);
......
...@@ -321,6 +321,37 @@ static void rt61pci_led_brightness(struct led_classdev *led_cdev, ...@@ -321,6 +321,37 @@ static void rt61pci_led_brightness(struct led_classdev *led_cdev,
/* /*
* Configuration handlers. * Configuration handlers.
*/ */
static void rt61pci_config_filter(struct rt2x00_dev *rt2x00dev,
const unsigned int filter_flags)
{
u32 reg;
/*
* 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, &reg);
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CRC,
!(filter_flags & FIF_FCSFAIL));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_PHYSICAL,
!(filter_flags & FIF_PLCPFAIL));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CONTROL,
!(filter_flags & FIF_CONTROL));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_NOT_TO_ME,
!(filter_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_TO_DS,
!(filter_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_VERSION_ERROR, 1);
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_MULTICAST,
!(filter_flags & FIF_ALLMULTI));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_BROADCAST, 0);
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_ACK_CTS,
!(filter_flags & FIF_CONTROL));
rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
}
static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf, struct rt2x00_intf *intf,
struct rt2x00intf_conf *conf, struct rt2x00intf_conf *conf,
...@@ -368,7 +399,7 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev, ...@@ -368,7 +399,7 @@ static void rt61pci_config_intf(struct rt2x00_dev *rt2x00dev,
} }
} }
static int rt61pci_config_erp(struct rt2x00_dev *rt2x00dev, static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_erp *erp) struct rt2x00lib_erp *erp)
{ {
u32 reg; u32 reg;
...@@ -381,8 +412,6 @@ static int rt61pci_config_erp(struct rt2x00_dev *rt2x00dev, ...@@ -381,8 +412,6 @@ static int rt61pci_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE, rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
!!erp->short_preamble); !!erp->short_preamble);
rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg); rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
return 0;
} }
static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev, static void rt61pci_config_phymode(struct rt2x00_dev *rt2x00dev,
...@@ -2284,71 +2313,6 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) ...@@ -2284,71 +2313,6 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
/* /*
* IEEE80211 stack callback functions. * 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;
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.
* - Multicast filter seems to kill broadcast traffic so never use it.
*/
*total_flags |= FIF_ALLMULTI;
if (*total_flags & FIF_OTHER_BSS ||
*total_flags & FIF_PROMISC_IN_BSS)
*total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
/*
* Check if there is any work left for us.
*/
if (rt2x00dev->packet_filter == *total_flags)
return;
rt2x00dev->packet_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, &reg);
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CRC,
!(*total_flags & FIF_FCSFAIL));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_PHYSICAL,
!(*total_flags & FIF_PLCPFAIL));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CONTROL,
!(*total_flags & FIF_CONTROL));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_NOT_TO_ME,
!(*total_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_TO_DS,
!(*total_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_VERSION_ERROR, 1);
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_MULTICAST,
!(*total_flags & FIF_ALLMULTI));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_BROADCAST, 0);
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_ACK_CTS,
!(*total_flags & FIF_CONTROL));
rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
}
static int rt61pci_set_retry_limit(struct ieee80211_hw *hw, static int rt61pci_set_retry_limit(struct ieee80211_hw *hw,
u32 short_retry, u32 long_retry) u32 short_retry, u32 long_retry)
{ {
...@@ -2457,7 +2421,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { ...@@ -2457,7 +2421,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
.remove_interface = rt2x00mac_remove_interface, .remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config, .config = rt2x00mac_config,
.config_interface = rt2x00mac_config_interface, .config_interface = rt2x00mac_config_interface,
.configure_filter = rt61pci_configure_filter, .configure_filter = rt2x00mac_configure_filter,
.get_stats = rt2x00mac_get_stats, .get_stats = rt2x00mac_get_stats,
.set_retry_limit = rt61pci_set_retry_limit, .set_retry_limit = rt61pci_set_retry_limit,
.bss_info_changed = rt2x00mac_bss_info_changed, .bss_info_changed = rt2x00mac_bss_info_changed,
...@@ -2487,6 +2451,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { ...@@ -2487,6 +2451,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
.write_tx_data = rt2x00pci_write_tx_data, .write_tx_data = rt2x00pci_write_tx_data,
.kick_tx_queue = rt61pci_kick_tx_queue, .kick_tx_queue = rt61pci_kick_tx_queue,
.fill_rxdone = rt61pci_fill_rxdone, .fill_rxdone = rt61pci_fill_rxdone,
.config_filter = rt61pci_config_filter,
.config_intf = rt61pci_config_intf, .config_intf = rt61pci_config_intf,
.config_erp = rt61pci_config_erp, .config_erp = rt61pci_config_erp,
.config = rt61pci_config, .config = rt61pci_config,
......
...@@ -333,6 +333,37 @@ static void rt73usb_led_brightness(struct led_classdev *led_cdev, ...@@ -333,6 +333,37 @@ static void rt73usb_led_brightness(struct led_classdev *led_cdev,
/* /*
* Configuration handlers. * Configuration handlers.
*/ */
static void rt73usb_config_filter(struct rt2x00_dev *rt2x00dev,
const unsigned int filter_flags)
{
u32 reg;
/*
* 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, &reg);
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CRC,
!(filter_flags & FIF_FCSFAIL));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_PHYSICAL,
!(filter_flags & FIF_PLCPFAIL));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CONTROL,
!(filter_flags & FIF_CONTROL));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_NOT_TO_ME,
!(filter_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_TO_DS,
!(filter_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_VERSION_ERROR, 1);
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_MULTICAST,
!(filter_flags & FIF_ALLMULTI));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_BROADCAST, 0);
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_ACK_CTS,
!(filter_flags & FIF_CONTROL));
rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
}
static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,
struct rt2x00_intf *intf, struct rt2x00_intf *intf,
struct rt2x00intf_conf *conf, struct rt2x00intf_conf *conf,
...@@ -380,18 +411,11 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, ...@@ -380,18 +411,11 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev,
} }
} }
static int rt73usb_config_erp(struct rt2x00_dev *rt2x00dev, static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,
struct rt2x00lib_erp *erp) struct rt2x00lib_erp *erp)
{ {
u32 reg; u32 reg;
/*
* When in atomic context, we should let rt2x00lib
* try this configuration again later.
*/
if (in_atomic())
return -EAGAIN;
rt73usb_register_read(rt2x00dev, TXRX_CSR0, &reg); rt73usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout); rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout);
rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
...@@ -400,8 +424,6 @@ static int rt73usb_config_erp(struct rt2x00_dev *rt2x00dev, ...@@ -400,8 +424,6 @@ static int rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,
rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE, rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
!!erp->short_preamble); !!erp->short_preamble);
rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg);
return 0;
} }
static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev, static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev,
...@@ -1872,6 +1894,7 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) ...@@ -1872,6 +1894,7 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
* This device requires firmware. * This device requires firmware.
*/ */
__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
__set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
/* /*
* Set the rssi offset. * Set the rssi offset.
...@@ -1884,80 +1907,6 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) ...@@ -1884,80 +1907,6 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev)
/* /*
* IEEE80211 stack callback functions. * 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;
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.
* - Multicast filter seems to kill broadcast traffic so never use it.
*/
*total_flags |= FIF_ALLMULTI;
if (*total_flags & FIF_OTHER_BSS ||
*total_flags & FIF_PROMISC_IN_BSS)
*total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS;
/*
* Check if there is any work left for us.
*/
if (rt2x00dev->packet_filter == *total_flags)
return;
rt2x00dev->packet_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, &reg);
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CRC,
!(*total_flags & FIF_FCSFAIL));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_PHYSICAL,
!(*total_flags & FIF_PLCPFAIL));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_CONTROL,
!(*total_flags & FIF_CONTROL));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_NOT_TO_ME,
!(*total_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_TO_DS,
!(*total_flags & FIF_PROMISC_IN_BSS));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_VERSION_ERROR, 1);
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_MULTICAST,
!(*total_flags & FIF_ALLMULTI));
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_BROADCAST, 0);
rt2x00_set_field32(&reg, TXRX_CSR0_DROP_ACK_CTS,
!(*total_flags & FIF_CONTROL));
rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg);
}
static int rt73usb_set_retry_limit(struct ieee80211_hw *hw, static int rt73usb_set_retry_limit(struct ieee80211_hw *hw,
u32 short_retry, u32 long_retry) u32 short_retry, u32 long_retry)
{ {
...@@ -2067,7 +2016,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { ...@@ -2067,7 +2016,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
.remove_interface = rt2x00mac_remove_interface, .remove_interface = rt2x00mac_remove_interface,
.config = rt2x00mac_config, .config = rt2x00mac_config,
.config_interface = rt2x00mac_config_interface, .config_interface = rt2x00mac_config_interface,
.configure_filter = rt73usb_configure_filter, .configure_filter = rt2x00mac_configure_filter,
.get_stats = rt2x00mac_get_stats, .get_stats = rt2x00mac_get_stats,
.set_retry_limit = rt73usb_set_retry_limit, .set_retry_limit = rt73usb_set_retry_limit,
.bss_info_changed = rt2x00mac_bss_info_changed, .bss_info_changed = rt2x00mac_bss_info_changed,
...@@ -2096,6 +2045,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { ...@@ -2096,6 +2045,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
.get_tx_data_len = rt73usb_get_tx_data_len, .get_tx_data_len = rt73usb_get_tx_data_len,
.kick_tx_queue = rt73usb_kick_tx_queue, .kick_tx_queue = rt73usb_kick_tx_queue,
.fill_rxdone = rt73usb_fill_rxdone, .fill_rxdone = rt73usb_fill_rxdone,
.config_filter = rt73usb_config_filter,
.config_intf = rt73usb_config_intf, .config_intf = rt73usb_config_intf,
.config_erp = rt73usb_config_erp, .config_erp = rt73usb_config_erp,
.config = rt73usb_config, .config = rt73usb_config,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment