aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2500usb.c
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-03-25 09:13:18 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-03-25 16:42:00 -0400
commit3a643d244f09fa1fdd25d48a56a073c1a69583ee (patch)
tree3cd8423f72f37d66fdd2738409f72779da3911fc /drivers/net/wireless/rt2x00/rt2500usb.c
parent866a05038481d77cac6fc0186250b4c44e691b42 (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.c118
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 */
319static 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, &reg);
331 rt2x00_set_field16(&reg, TXRX_CSR2_DROP_CRC,
332 !(filter_flags & FIF_FCSFAIL));
333 rt2x00_set_field16(&reg, TXRX_CSR2_DROP_PHYSICAL,
334 !(filter_flags & FIF_PLCPFAIL));
335 rt2x00_set_field16(&reg, TXRX_CSR2_DROP_CONTROL,
336 !(filter_flags & FIF_CONTROL));
337 rt2x00_set_field16(&reg, TXRX_CSR2_DROP_NOT_TO_ME,
338 !(filter_flags & FIF_PROMISC_IN_BSS));
339 rt2x00_set_field16(&reg, TXRX_CSR2_DROP_TODS,
340 !(filter_flags & FIF_PROMISC_IN_BSS));
341 rt2x00_set_field16(&reg, TXRX_CSR2_DROP_VERSION_ERROR, 1);
342 rt2x00_set_field16(&reg, TXRX_CSR2_DROP_MULTICAST,
343 !(filter_flags & FIF_ALLMULTI));
344 rt2x00_set_field16(&reg, TXRX_CSR2_DROP_BROADCAST, 0);
345 rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
346}
347
319static void rt2500usb_config_intf(struct rt2x00_dev *rt2x00dev, 348static 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
361static int rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev, 390static 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, &reg); 395 rt2500usb_register_read(rt2x00dev, TXRX_CSR1, &reg);
374 rt2x00_set_field16(&reg, TXRX_CSR1_ACK_TIMEOUT, erp->ack_timeout); 396 rt2x00_set_field16(&reg, 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(&reg, TXRX_CSR10_AUTORESPOND_PREAMBLE, 400 rt2x00_set_field16(&reg, 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
385static void rt2500usb_config_phymode(struct rt2x00_dev *rt2x00dev, 405static 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 */
1659static 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, &reg);
1714 rt2x00_set_field16(&reg, TXRX_CSR2_DROP_CRC,
1715 !(*total_flags & FIF_FCSFAIL));
1716 rt2x00_set_field16(&reg, TXRX_CSR2_DROP_PHYSICAL,
1717 !(*total_flags & FIF_PLCPFAIL));
1718 rt2x00_set_field16(&reg, TXRX_CSR2_DROP_CONTROL,
1719 !(*total_flags & FIF_CONTROL));
1720 rt2x00_set_field16(&reg, TXRX_CSR2_DROP_NOT_TO_ME,
1721 !(*total_flags & FIF_PROMISC_IN_BSS));
1722 rt2x00_set_field16(&reg, TXRX_CSR2_DROP_TODS,
1723 !(*total_flags & FIF_PROMISC_IN_BSS));
1724 rt2x00_set_field16(&reg, TXRX_CSR2_DROP_VERSION_ERROR, 1);
1725 rt2x00_set_field16(&reg, TXRX_CSR2_DROP_MULTICAST,
1726 !(*total_flags & FIF_ALLMULTI));
1727 rt2x00_set_field16(&reg, TXRX_CSR2_DROP_BROADCAST, 0);
1728 rt2500usb_register_write(rt2x00dev, TXRX_CSR2, reg);
1729}
1730
1731static int rt2500usb_beacon_update(struct ieee80211_hw *hw, 1680static 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,