diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2008-03-25 09:13:18 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-03-25 16:42:00 -0400 |
commit | 3a643d244f09fa1fdd25d48a56a073c1a69583ee (patch) | |
tree | 3cd8423f72f37d66fdd2738409f72779da3911fc /drivers/net/wireless/rt2x00/rt2500usb.c | |
parent | 866a05038481d77cac6fc0186250b4c44e691b42 (diff) |
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: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2500usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 118 |
1 files changed, 34 insertions, 84 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 8959a684f40b..f5c18f011e93 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -316,6 +316,35 @@ static void rt2500usb_led_brightness(struct led_classdev *led_cdev, | |||
316 | /* | 316 | /* |
317 | * Configuration handlers. | 317 | * Configuration handlers. |
318 | */ | 318 | */ |
319 | static void rt2500usb_config_filter(struct rt2x00_dev *rt2x00dev, | ||
320 | const unsigned int filter_flags) | ||
321 | { | ||
322 | u16 reg; | ||
323 | |||
324 | /* | ||
325 | * Start configuration steps. | ||
326 | * Note that the version error will always be dropped | ||
327 | * and broadcast frames will always be accepted since | ||
328 | * there is no filter for it at this time. | ||
329 | */ | ||
330 | rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®); | ||
331 | rt2x00_set_field16(®, TXRX_CSR2_DROP_CRC, | ||
332 | !(filter_flags & FIF_FCSFAIL)); | ||
333 | rt2x00_set_field16(®, TXRX_CSR2_DROP_PHYSICAL, | ||
334 | !(filter_flags & FIF_PLCPFAIL)); | ||
335 | rt2x00_set_field16(®, TXRX_CSR2_DROP_CONTROL, | ||
336 | !(filter_flags & FIF_CONTROL)); | ||
337 | rt2x00_set_field16(®, TXRX_CSR2_DROP_NOT_TO_ME, | ||
338 | !(filter_flags & FIF_PROMISC_IN_BSS)); | ||
339 | rt2x00_set_field16(®, TXRX_CSR2_DROP_TODS, | ||
340 | !(filter_flags & FIF_PROMISC_IN_BSS)); | ||
341 | rt2x00_set_field16(®, TXRX_CSR2_DROP_VERSION_ERROR, 1); | ||
342 | rt2x00_set_field16(®, TXRX_CSR2_DROP_MULTICAST, | ||
343 | !(filter_flags & FIF_ALLMULTI)); | ||
344 | rt2x00_set_field16(®, TXRX_CSR2_DROP_BROADCAST, 0); | ||
345 | rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); | ||
346 | } | ||
347 | |||
319 | static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, | 348 | static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, |
320 | struct rt2x00_intf *intf, | 349 | struct rt2x00_intf *intf, |
321 | struct rt2x00intf_conf *conf, | 350 | struct rt2x00intf_conf *conf, |
@@ -358,18 +387,11 @@ static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, | |||
358 | (3 * sizeof(__le16))); | 387 | (3 * sizeof(__le16))); |
359 | } | 388 | } |
360 | 389 | ||
361 | static int rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev, | 390 | static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev, |
362 | struct rt2x00lib_erp *erp) | 391 | struct rt2x00lib_erp *erp) |
363 | { | 392 | { |
364 | u16 reg; | 393 | u16 reg; |
365 | 394 | ||
366 | /* | ||
367 | * When in atomic context, we should let rt2x00lib | ||
368 | * try this configuration again later. | ||
369 | */ | ||
370 | if (in_atomic()) | ||
371 | return -EAGAIN; | ||
372 | |||
373 | rt2500usb_register_read(rt2x00dev, TXRX_CSR1, ®); | 395 | rt2500usb_register_read(rt2x00dev, TXRX_CSR1, ®); |
374 | rt2x00_set_field16(®, TXRX_CSR1_ACK_TIMEOUT, erp->ack_timeout); | 396 | rt2x00_set_field16(®, TXRX_CSR1_ACK_TIMEOUT, erp->ack_timeout); |
375 | rt2500usb_register_write(rt2x00dev, TXRX_CSR1, reg); | 397 | rt2500usb_register_write(rt2x00dev, TXRX_CSR1, reg); |
@@ -378,8 +400,6 @@ static int rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev, | |||
378 | rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, | 400 | rt2x00_set_field16(®, TXRX_CSR10_AUTORESPOND_PREAMBLE, |
379 | !!erp->short_preamble); | 401 | !!erp->short_preamble); |
380 | rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); | 402 | rt2500usb_register_write(rt2x00dev, TXRX_CSR10, reg); |
381 | |||
382 | return 0; | ||
383 | } | 403 | } |
384 | 404 | ||
385 | static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev, | 405 | static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -1644,6 +1664,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1644 | */ | 1664 | */ |
1645 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | 1665 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1646 | __set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); | 1666 | __set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags); |
1667 | __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags); | ||
1647 | 1668 | ||
1648 | /* | 1669 | /* |
1649 | * Set the rssi offset. | 1670 | * Set the rssi offset. |
@@ -1656,78 +1677,6 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1656 | /* | 1677 | /* |
1657 | * IEEE80211 stack callback functions. | 1678 | * IEEE80211 stack callback functions. |
1658 | */ | 1679 | */ |
1659 | static void rt2500usb_configure_filter(struct ieee80211_hw *hw, | ||
1660 | unsigned int changed_flags, | ||
1661 | unsigned int *total_flags, | ||
1662 | int mc_count, | ||
1663 | struct dev_addr_list *mc_list) | ||
1664 | { | ||
1665 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1666 | u16 reg; | ||
1667 | |||
1668 | /* | ||
1669 | * Mask off any flags we are going to ignore from | ||
1670 | * the total_flags field. | ||
1671 | */ | ||
1672 | *total_flags &= | ||
1673 | FIF_ALLMULTI | | ||
1674 | FIF_FCSFAIL | | ||
1675 | FIF_PLCPFAIL | | ||
1676 | FIF_CONTROL | | ||
1677 | FIF_OTHER_BSS | | ||
1678 | FIF_PROMISC_IN_BSS; | ||
1679 | |||
1680 | /* | ||
1681 | * Apply some rules to the filters: | ||
1682 | * - Some filters imply different filters to be set. | ||
1683 | * - Some things we can't filter out at all. | ||
1684 | */ | ||
1685 | if (mc_count) | ||
1686 | *total_flags |= FIF_ALLMULTI; | ||
1687 | if (*total_flags & FIF_OTHER_BSS || | ||
1688 | *total_flags & FIF_PROMISC_IN_BSS) | ||
1689 | *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; | ||
1690 | |||
1691 | /* | ||
1692 | * Check if there is any work left for us. | ||
1693 | */ | ||
1694 | if (rt2x00dev->packet_filter == *total_flags) | ||
1695 | return; | ||
1696 | rt2x00dev->packet_filter = *total_flags; | ||
1697 | |||
1698 | /* | ||
1699 | * When in atomic context, reschedule and let rt2x00lib | ||
1700 | * call this function again. | ||
1701 | */ | ||
1702 | if (in_atomic()) { | ||
1703 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work); | ||
1704 | return; | ||
1705 | } | ||
1706 | |||
1707 | /* | ||
1708 | * Start configuration steps. | ||
1709 | * Note that the version error will always be dropped | ||
1710 | * and broadcast frames will always be accepted since | ||
1711 | * there is no filter for it at this time. | ||
1712 | */ | ||
1713 | rt2500usb_register_read(rt2x00dev, TXRX_CSR2, ®); | ||
1714 | rt2x00_set_field16(®, TXRX_CSR2_DROP_CRC, | ||
1715 | !(*total_flags & FIF_FCSFAIL)); | ||
1716 | rt2x00_set_field16(®, TXRX_CSR2_DROP_PHYSICAL, | ||
1717 | !(*total_flags & FIF_PLCPFAIL)); | ||
1718 | rt2x00_set_field16(®, TXRX_CSR2_DROP_CONTROL, | ||
1719 | !(*total_flags & FIF_CONTROL)); | ||
1720 | rt2x00_set_field16(®, TXRX_CSR2_DROP_NOT_TO_ME, | ||
1721 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
1722 | rt2x00_set_field16(®, TXRX_CSR2_DROP_TODS, | ||
1723 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
1724 | rt2x00_set_field16(®, TXRX_CSR2_DROP_VERSION_ERROR, 1); | ||
1725 | rt2x00_set_field16(®, TXRX_CSR2_DROP_MULTICAST, | ||
1726 | !(*total_flags & FIF_ALLMULTI)); | ||
1727 | rt2x00_set_field16(®, TXRX_CSR2_DROP_BROADCAST, 0); | ||
1728 | rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg); | ||
1729 | } | ||
1730 | |||
1731 | static int rt2500usb_beacon_update(struct ieee80211_hw *hw, | 1680 | static int rt2500usb_beacon_update(struct ieee80211_hw *hw, |
1732 | struct sk_buff *skb, | 1681 | struct sk_buff *skb, |
1733 | struct ieee80211_tx_control *control) | 1682 | struct ieee80211_tx_control *control) |
@@ -1824,7 +1773,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = { | |||
1824 | .remove_interface = rt2x00mac_remove_interface, | 1773 | .remove_interface = rt2x00mac_remove_interface, |
1825 | .config = rt2x00mac_config, | 1774 | .config = rt2x00mac_config, |
1826 | .config_interface = rt2x00mac_config_interface, | 1775 | .config_interface = rt2x00mac_config_interface, |
1827 | .configure_filter = rt2500usb_configure_filter, | 1776 | .configure_filter = rt2x00mac_configure_filter, |
1828 | .get_stats = rt2x00mac_get_stats, | 1777 | .get_stats = rt2x00mac_get_stats, |
1829 | .bss_info_changed = rt2x00mac_bss_info_changed, | 1778 | .bss_info_changed = rt2x00mac_bss_info_changed, |
1830 | .conf_tx = rt2x00mac_conf_tx, | 1779 | .conf_tx = rt2x00mac_conf_tx, |
@@ -1848,6 +1797,7 @@ static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = { | |||
1848 | .get_tx_data_len = rt2500usb_get_tx_data_len, | 1797 | .get_tx_data_len = rt2500usb_get_tx_data_len, |
1849 | .kick_tx_queue = rt2500usb_kick_tx_queue, | 1798 | .kick_tx_queue = rt2500usb_kick_tx_queue, |
1850 | .fill_rxdone = rt2500usb_fill_rxdone, | 1799 | .fill_rxdone = rt2500usb_fill_rxdone, |
1800 | .config_filter = rt2500usb_config_filter, | ||
1851 | .config_intf = rt2500usb_config_intf, | 1801 | .config_intf = rt2500usb_config_intf, |
1852 | .config_erp = rt2500usb_config_erp, | 1802 | .config_erp = rt2500usb_config_erp, |
1853 | .config = rt2500usb_config, | 1803 | .config = rt2500usb_config, |