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/rt73usb.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/rt73usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 122 |
1 files changed, 36 insertions, 86 deletions
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index b50f476e4bd1..187e832bab2e 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -333,6 +333,37 @@ static void rt73usb_led_brightness(struct led_classdev *led_cdev, | |||
333 | /* | 333 | /* |
334 | * Configuration handlers. | 334 | * Configuration handlers. |
335 | */ | 335 | */ |
336 | static void rt73usb_config_filter(struct rt2x00_dev *rt2x00dev, | ||
337 | const unsigned int filter_flags) | ||
338 | { | ||
339 | u32 reg; | ||
340 | |||
341 | /* | ||
342 | * Start configuration steps. | ||
343 | * Note that the version error will always be dropped | ||
344 | * and broadcast frames will always be accepted since | ||
345 | * there is no filter for it at this time. | ||
346 | */ | ||
347 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
348 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, | ||
349 | !(filter_flags & FIF_FCSFAIL)); | ||
350 | rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, | ||
351 | !(filter_flags & FIF_PLCPFAIL)); | ||
352 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, | ||
353 | !(filter_flags & FIF_CONTROL)); | ||
354 | rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, | ||
355 | !(filter_flags & FIF_PROMISC_IN_BSS)); | ||
356 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, | ||
357 | !(filter_flags & FIF_PROMISC_IN_BSS)); | ||
358 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); | ||
359 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, | ||
360 | !(filter_flags & FIF_ALLMULTI)); | ||
361 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); | ||
362 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, | ||
363 | !(filter_flags & FIF_CONTROL)); | ||
364 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
365 | } | ||
366 | |||
336 | static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, | 367 | static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, |
337 | struct rt2x00_intf *intf, | 368 | struct rt2x00_intf *intf, |
338 | struct rt2x00intf_conf *conf, | 369 | struct rt2x00intf_conf *conf, |
@@ -380,18 +411,11 @@ static void rt73usb_config_intf(struct rt2x00_dev *rt2x00dev, | |||
380 | } | 411 | } |
381 | } | 412 | } |
382 | 413 | ||
383 | static int rt73usb_config_erp(struct rt2x00_dev *rt2x00dev, | 414 | static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev, |
384 | struct rt2x00lib_erp *erp) | 415 | struct rt2x00lib_erp *erp) |
385 | { | 416 | { |
386 | u32 reg; | 417 | u32 reg; |
387 | 418 | ||
388 | /* | ||
389 | * When in atomic context, we should let rt2x00lib | ||
390 | * try this configuration again later. | ||
391 | */ | ||
392 | if (in_atomic()) | ||
393 | return -EAGAIN; | ||
394 | |||
395 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | 419 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); |
396 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout); | 420 | rt2x00_set_field32(®, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout); |
397 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | 421 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); |
@@ -400,8 +424,6 @@ static int rt73usb_config_erp(struct rt2x00_dev *rt2x00dev, | |||
400 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, | 424 | rt2x00_set_field32(®, TXRX_CSR4_AUTORESPOND_PREAMBLE, |
401 | !!erp->short_preamble); | 425 | !!erp->short_preamble); |
402 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); | 426 | rt73usb_register_write(rt2x00dev, TXRX_CSR4, reg); |
403 | |||
404 | return 0; | ||
405 | } | 427 | } |
406 | 428 | ||
407 | static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev, | 429 | static void rt73usb_config_phymode(struct rt2x00_dev *rt2x00dev, |
@@ -1872,6 +1894,7 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1872 | * This device requires firmware. | 1894 | * This device requires firmware. |
1873 | */ | 1895 | */ |
1874 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 1896 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); |
1897 | __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags); | ||
1875 | 1898 | ||
1876 | /* | 1899 | /* |
1877 | * Set the rssi offset. | 1900 | * Set the rssi offset. |
@@ -1884,80 +1907,6 @@ static int rt73usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1884 | /* | 1907 | /* |
1885 | * IEEE80211 stack callback functions. | 1908 | * IEEE80211 stack callback functions. |
1886 | */ | 1909 | */ |
1887 | static void rt73usb_configure_filter(struct ieee80211_hw *hw, | ||
1888 | unsigned int changed_flags, | ||
1889 | unsigned int *total_flags, | ||
1890 | int mc_count, | ||
1891 | struct dev_addr_list *mc_list) | ||
1892 | { | ||
1893 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1894 | u32 reg; | ||
1895 | |||
1896 | /* | ||
1897 | * Mask off any flags we are going to ignore from | ||
1898 | * the total_flags field. | ||
1899 | */ | ||
1900 | *total_flags &= | ||
1901 | FIF_ALLMULTI | | ||
1902 | FIF_FCSFAIL | | ||
1903 | FIF_PLCPFAIL | | ||
1904 | FIF_CONTROL | | ||
1905 | FIF_OTHER_BSS | | ||
1906 | FIF_PROMISC_IN_BSS; | ||
1907 | |||
1908 | /* | ||
1909 | * Apply some rules to the filters: | ||
1910 | * - Some filters imply different filters to be set. | ||
1911 | * - Some things we can't filter out at all. | ||
1912 | * - Multicast filter seems to kill broadcast traffic so never use it. | ||
1913 | */ | ||
1914 | *total_flags |= FIF_ALLMULTI; | ||
1915 | if (*total_flags & FIF_OTHER_BSS || | ||
1916 | *total_flags & FIF_PROMISC_IN_BSS) | ||
1917 | *total_flags |= FIF_PROMISC_IN_BSS | FIF_OTHER_BSS; | ||
1918 | |||
1919 | /* | ||
1920 | * Check if there is any work left for us. | ||
1921 | */ | ||
1922 | if (rt2x00dev->packet_filter == *total_flags) | ||
1923 | return; | ||
1924 | rt2x00dev->packet_filter = *total_flags; | ||
1925 | |||
1926 | /* | ||
1927 | * When in atomic context, reschedule and let rt2x00lib | ||
1928 | * call this function again. | ||
1929 | */ | ||
1930 | if (in_atomic()) { | ||
1931 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work); | ||
1932 | return; | ||
1933 | } | ||
1934 | |||
1935 | /* | ||
1936 | * Start configuration steps. | ||
1937 | * Note that the version error will always be dropped | ||
1938 | * and broadcast frames will always be accepted since | ||
1939 | * there is no filter for it at this time. | ||
1940 | */ | ||
1941 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | ||
1942 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CRC, | ||
1943 | !(*total_flags & FIF_FCSFAIL)); | ||
1944 | rt2x00_set_field32(®, TXRX_CSR0_DROP_PHYSICAL, | ||
1945 | !(*total_flags & FIF_PLCPFAIL)); | ||
1946 | rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, | ||
1947 | !(*total_flags & FIF_CONTROL)); | ||
1948 | rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, | ||
1949 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
1950 | rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, | ||
1951 | !(*total_flags & FIF_PROMISC_IN_BSS)); | ||
1952 | rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); | ||
1953 | rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, | ||
1954 | !(*total_flags & FIF_ALLMULTI)); | ||
1955 | rt2x00_set_field32(®, TXRX_CSR0_DROP_BROADCAST, 0); | ||
1956 | rt2x00_set_field32(®, TXRX_CSR0_DROP_ACK_CTS, | ||
1957 | !(*total_flags & FIF_CONTROL)); | ||
1958 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | ||
1959 | } | ||
1960 | |||
1961 | static int rt73usb_set_retry_limit(struct ieee80211_hw *hw, | 1910 | static int rt73usb_set_retry_limit(struct ieee80211_hw *hw, |
1962 | u32 short_retry, u32 long_retry) | 1911 | u32 short_retry, u32 long_retry) |
1963 | { | 1912 | { |
@@ -2067,7 +2016,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { | |||
2067 | .remove_interface = rt2x00mac_remove_interface, | 2016 | .remove_interface = rt2x00mac_remove_interface, |
2068 | .config = rt2x00mac_config, | 2017 | .config = rt2x00mac_config, |
2069 | .config_interface = rt2x00mac_config_interface, | 2018 | .config_interface = rt2x00mac_config_interface, |
2070 | .configure_filter = rt73usb_configure_filter, | 2019 | .configure_filter = rt2x00mac_configure_filter, |
2071 | .get_stats = rt2x00mac_get_stats, | 2020 | .get_stats = rt2x00mac_get_stats, |
2072 | .set_retry_limit = rt73usb_set_retry_limit, | 2021 | .set_retry_limit = rt73usb_set_retry_limit, |
2073 | .bss_info_changed = rt2x00mac_bss_info_changed, | 2022 | .bss_info_changed = rt2x00mac_bss_info_changed, |
@@ -2096,6 +2045,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | |||
2096 | .get_tx_data_len = rt73usb_get_tx_data_len, | 2045 | .get_tx_data_len = rt73usb_get_tx_data_len, |
2097 | .kick_tx_queue = rt73usb_kick_tx_queue, | 2046 | .kick_tx_queue = rt73usb_kick_tx_queue, |
2098 | .fill_rxdone = rt73usb_fill_rxdone, | 2047 | .fill_rxdone = rt73usb_fill_rxdone, |
2048 | .config_filter = rt73usb_config_filter, | ||
2099 | .config_intf = rt73usb_config_intf, | 2049 | .config_intf = rt73usb_config_intf, |
2100 | .config_erp = rt73usb_config_erp, | 2050 | .config_erp = rt73usb_config_erp, |
2101 | .config = rt73usb_config, | 2051 | .config = rt73usb_config, |