diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt61pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 68 |
1 files changed, 47 insertions, 21 deletions
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 0123fbc22ca2..e539c6cb636f 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1622,7 +1622,8 @@ static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev, | |||
1622 | static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | 1622 | static void rt61pci_toggle_irq(struct rt2x00_dev *rt2x00dev, |
1623 | enum dev_state state) | 1623 | enum dev_state state) |
1624 | { | 1624 | { |
1625 | int mask = (state == STATE_RADIO_IRQ_OFF); | 1625 | int mask = (state == STATE_RADIO_IRQ_OFF) || |
1626 | (state == STATE_RADIO_IRQ_OFF_ISR); | ||
1626 | u32 reg; | 1627 | u32 reg; |
1627 | 1628 | ||
1628 | /* | 1629 | /* |
@@ -1739,7 +1740,9 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1739 | rt61pci_toggle_rx(rt2x00dev, state); | 1740 | rt61pci_toggle_rx(rt2x00dev, state); |
1740 | break; | 1741 | break; |
1741 | case STATE_RADIO_IRQ_ON: | 1742 | case STATE_RADIO_IRQ_ON: |
1743 | case STATE_RADIO_IRQ_ON_ISR: | ||
1742 | case STATE_RADIO_IRQ_OFF: | 1744 | case STATE_RADIO_IRQ_OFF: |
1745 | case STATE_RADIO_IRQ_OFF_ISR: | ||
1743 | rt61pci_toggle_irq(rt2x00dev, state); | 1746 | rt61pci_toggle_irq(rt2x00dev, state); |
1744 | break; | 1747 | break; |
1745 | case STATE_DEEP_SLEEP: | 1748 | case STATE_DEEP_SLEEP: |
@@ -2147,27 +2150,11 @@ static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev) | |||
2147 | rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); | 2150 | rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); |
2148 | } | 2151 | } |
2149 | 2152 | ||
2150 | static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) | 2153 | static irqreturn_t rt61pci_interrupt_thread(int irq, void *dev_instance) |
2151 | { | 2154 | { |
2152 | struct rt2x00_dev *rt2x00dev = dev_instance; | 2155 | struct rt2x00_dev *rt2x00dev = dev_instance; |
2153 | u32 reg_mcu; | 2156 | u32 reg = rt2x00dev->irqvalue[0]; |
2154 | u32 reg; | 2157 | u32 reg_mcu = rt2x00dev->irqvalue[1]; |
2155 | |||
2156 | /* | ||
2157 | * Get the interrupt sources & saved to local variable. | ||
2158 | * Write register value back to clear pending interrupts. | ||
2159 | */ | ||
2160 | rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®_mcu); | ||
2161 | rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg_mcu); | ||
2162 | |||
2163 | rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); | ||
2164 | rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); | ||
2165 | |||
2166 | if (!reg && !reg_mcu) | ||
2167 | return IRQ_NONE; | ||
2168 | |||
2169 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
2170 | return IRQ_HANDLED; | ||
2171 | 2158 | ||
2172 | /* | 2159 | /* |
2173 | * Handle interrupts, walk through all bits | 2160 | * Handle interrupts, walk through all bits |
@@ -2206,9 +2193,45 @@ static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) | |||
2206 | if (rt2x00_get_field32(reg, INT_SOURCE_CSR_BEACON_DONE)) | 2193 | if (rt2x00_get_field32(reg, INT_SOURCE_CSR_BEACON_DONE)) |
2207 | rt2x00lib_beacondone(rt2x00dev); | 2194 | rt2x00lib_beacondone(rt2x00dev); |
2208 | 2195 | ||
2196 | /* Enable interrupts again. */ | ||
2197 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, | ||
2198 | STATE_RADIO_IRQ_ON_ISR); | ||
2209 | return IRQ_HANDLED; | 2199 | return IRQ_HANDLED; |
2210 | } | 2200 | } |
2211 | 2201 | ||
2202 | |||
2203 | static irqreturn_t rt61pci_interrupt(int irq, void *dev_instance) | ||
2204 | { | ||
2205 | struct rt2x00_dev *rt2x00dev = dev_instance; | ||
2206 | u32 reg_mcu; | ||
2207 | u32 reg; | ||
2208 | |||
2209 | /* | ||
2210 | * Get the interrupt sources & saved to local variable. | ||
2211 | * Write register value back to clear pending interrupts. | ||
2212 | */ | ||
2213 | rt2x00pci_register_read(rt2x00dev, MCU_INT_SOURCE_CSR, ®_mcu); | ||
2214 | rt2x00pci_register_write(rt2x00dev, MCU_INT_SOURCE_CSR, reg_mcu); | ||
2215 | |||
2216 | rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, ®); | ||
2217 | rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg); | ||
2218 | |||
2219 | if (!reg && !reg_mcu) | ||
2220 | return IRQ_NONE; | ||
2221 | |||
2222 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
2223 | return IRQ_HANDLED; | ||
2224 | |||
2225 | /* Store irqvalues for use in the interrupt thread. */ | ||
2226 | rt2x00dev->irqvalue[0] = reg; | ||
2227 | rt2x00dev->irqvalue[1] = reg_mcu; | ||
2228 | |||
2229 | /* Disable interrupts, will be enabled again in the interrupt thread. */ | ||
2230 | rt2x00dev->ops->lib->set_device_state(rt2x00dev, | ||
2231 | STATE_RADIO_IRQ_OFF_ISR); | ||
2232 | return IRQ_WAKE_THREAD; | ||
2233 | } | ||
2234 | |||
2212 | /* | 2235 | /* |
2213 | * Device probe functions. | 2236 | * Device probe functions. |
2214 | */ | 2237 | */ |
@@ -2690,6 +2713,7 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2690 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); | 2713 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); |
2691 | if (!modparam_nohwcrypt) | 2714 | if (!modparam_nohwcrypt) |
2692 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); | 2715 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); |
2716 | __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); | ||
2693 | 2717 | ||
2694 | /* | 2718 | /* |
2695 | * Set the rssi offset. | 2719 | * Set the rssi offset. |
@@ -2781,8 +2805,9 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { | |||
2781 | .remove_interface = rt2x00mac_remove_interface, | 2805 | .remove_interface = rt2x00mac_remove_interface, |
2782 | .config = rt2x00mac_config, | 2806 | .config = rt2x00mac_config, |
2783 | .configure_filter = rt2x00mac_configure_filter, | 2807 | .configure_filter = rt2x00mac_configure_filter, |
2784 | .set_tim = rt2x00mac_set_tim, | ||
2785 | .set_key = rt2x00mac_set_key, | 2808 | .set_key = rt2x00mac_set_key, |
2809 | .sw_scan_start = rt2x00mac_sw_scan_start, | ||
2810 | .sw_scan_complete = rt2x00mac_sw_scan_complete, | ||
2786 | .get_stats = rt2x00mac_get_stats, | 2811 | .get_stats = rt2x00mac_get_stats, |
2787 | .bss_info_changed = rt2x00mac_bss_info_changed, | 2812 | .bss_info_changed = rt2x00mac_bss_info_changed, |
2788 | .conf_tx = rt61pci_conf_tx, | 2813 | .conf_tx = rt61pci_conf_tx, |
@@ -2792,6 +2817,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { | |||
2792 | 2817 | ||
2793 | static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | 2818 | static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { |
2794 | .irq_handler = rt61pci_interrupt, | 2819 | .irq_handler = rt61pci_interrupt, |
2820 | .irq_handler_thread = rt61pci_interrupt_thread, | ||
2795 | .probe_hw = rt61pci_probe_hw, | 2821 | .probe_hw = rt61pci_probe_hw, |
2796 | .get_firmware_name = rt61pci_get_firmware_name, | 2822 | .get_firmware_name = rt61pci_get_firmware_name, |
2797 | .check_firmware = rt61pci_check_firmware, | 2823 | .check_firmware = rt61pci_check_firmware, |