aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c281
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c290
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h2
7 files changed, 310 insertions, 286 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index b229597e54cd..15f1b0f0d070 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -30,6 +30,11 @@ static void ar9003_hw_get_desc_link(void *ds, u32 **ds_link)
30 *ds_link = &((struct ar9003_txc *) ds)->link; 30 *ds_link = &((struct ar9003_txc *) ds)->link;
31} 31}
32 32
33static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
34{
35 return true;
36}
37
33void ar9003_hw_attach_mac_ops(struct ath_hw *hw) 38void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
34{ 39{
35 struct ath_hw_ops *ops = ath9k_hw_ops(hw); 40 struct ath_hw_ops *ops = ath9k_hw_ops(hw);
@@ -37,6 +42,7 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
37 ops->rx_enable = ar9003_hw_rx_enable; 42 ops->rx_enable = ar9003_hw_rx_enable;
38 ops->set_desc_link = ar9003_hw_set_desc_link; 43 ops->set_desc_link = ar9003_hw_set_desc_link;
39 ops->get_desc_link = ar9003_hw_get_desc_link; 44 ops->get_desc_link = ar9003_hw_get_desc_link;
45 ops->get_isr = ar9003_hw_get_isr;
40} 46}
41 47
42void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) 48void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size)
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index 3848c0d3f99e..b777fd1894f0 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -52,6 +52,11 @@ static inline bool ath9k_hw_calibrate(struct ath_hw *ah,
52 return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal); 52 return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal);
53} 53}
54 54
55static inline bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
56{
57 return ath9k_hw_ops(ah)->get_isr(ah, masked);
58}
59
55/* Private hardware call ops */ 60/* Private hardware call ops */
56 61
57/* PHY ops */ 62/* PHY ops */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 127546c42223..ac57a975d014 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1780,287 +1780,6 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
1780} 1780}
1781EXPORT_SYMBOL(ath9k_hw_setpower); 1781EXPORT_SYMBOL(ath9k_hw_setpower);
1782 1782
1783/**********************/
1784/* Interrupt Handling */
1785/**********************/
1786
1787bool ath9k_hw_intrpend(struct ath_hw *ah)
1788{
1789 u32 host_isr;
1790
1791 if (AR_SREV_9100(ah))
1792 return true;
1793
1794 host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
1795 if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
1796 return true;
1797
1798 host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
1799 if ((host_isr & AR_INTR_SYNC_DEFAULT)
1800 && (host_isr != AR_INTR_SPURIOUS))
1801 return true;
1802
1803 return false;
1804}
1805EXPORT_SYMBOL(ath9k_hw_intrpend);
1806
1807bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
1808{
1809 u32 isr = 0;
1810 u32 mask2 = 0;
1811 struct ath9k_hw_capabilities *pCap = &ah->caps;
1812 u32 sync_cause = 0;
1813 bool fatal_int = false;
1814 struct ath_common *common = ath9k_hw_common(ah);
1815
1816 if (!AR_SREV_9100(ah)) {
1817 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
1818 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
1819 == AR_RTC_STATUS_ON) {
1820 isr = REG_READ(ah, AR_ISR);
1821 }
1822 }
1823
1824 sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
1825 AR_INTR_SYNC_DEFAULT;
1826
1827 *masked = 0;
1828
1829 if (!isr && !sync_cause)
1830 return false;
1831 } else {
1832 *masked = 0;
1833 isr = REG_READ(ah, AR_ISR);
1834 }
1835
1836 if (isr) {
1837 if (isr & AR_ISR_BCNMISC) {
1838 u32 isr2;
1839 isr2 = REG_READ(ah, AR_ISR_S2);
1840 if (isr2 & AR_ISR_S2_TIM)
1841 mask2 |= ATH9K_INT_TIM;
1842 if (isr2 & AR_ISR_S2_DTIM)
1843 mask2 |= ATH9K_INT_DTIM;
1844 if (isr2 & AR_ISR_S2_DTIMSYNC)
1845 mask2 |= ATH9K_INT_DTIMSYNC;
1846 if (isr2 & (AR_ISR_S2_CABEND))
1847 mask2 |= ATH9K_INT_CABEND;
1848 if (isr2 & AR_ISR_S2_GTT)
1849 mask2 |= ATH9K_INT_GTT;
1850 if (isr2 & AR_ISR_S2_CST)
1851 mask2 |= ATH9K_INT_CST;
1852 if (isr2 & AR_ISR_S2_TSFOOR)
1853 mask2 |= ATH9K_INT_TSFOOR;
1854 }
1855
1856 isr = REG_READ(ah, AR_ISR_RAC);
1857 if (isr == 0xffffffff) {
1858 *masked = 0;
1859 return false;
1860 }
1861
1862 *masked = isr & ATH9K_INT_COMMON;
1863
1864 if (ah->config.rx_intr_mitigation) {
1865 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
1866 *masked |= ATH9K_INT_RX;
1867 }
1868
1869 if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
1870 *masked |= ATH9K_INT_RX;
1871 if (isr &
1872 (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
1873 AR_ISR_TXEOL)) {
1874 u32 s0_s, s1_s;
1875
1876 *masked |= ATH9K_INT_TX;
1877
1878 s0_s = REG_READ(ah, AR_ISR_S0_S);
1879 ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
1880 ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
1881
1882 s1_s = REG_READ(ah, AR_ISR_S1_S);
1883 ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
1884 ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
1885 }
1886
1887 if (isr & AR_ISR_RXORN) {
1888 ath_print(common, ATH_DBG_INTERRUPT,
1889 "receive FIFO overrun interrupt\n");
1890 }
1891
1892 if (!AR_SREV_9100(ah)) {
1893 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
1894 u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
1895 if (isr5 & AR_ISR_S5_TIM_TIMER)
1896 *masked |= ATH9K_INT_TIM_TIMER;
1897 }
1898 }
1899
1900 *masked |= mask2;
1901 }
1902
1903 if (AR_SREV_9100(ah))
1904 return true;
1905
1906 if (isr & AR_ISR_GENTMR) {
1907 u32 s5_s;
1908
1909 s5_s = REG_READ(ah, AR_ISR_S5_S);
1910 if (isr & AR_ISR_GENTMR) {
1911 ah->intr_gen_timer_trigger =
1912 MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);
1913
1914 ah->intr_gen_timer_thresh =
1915 MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
1916
1917 if (ah->intr_gen_timer_trigger)
1918 *masked |= ATH9K_INT_GENTIMER;
1919
1920 }
1921 }
1922
1923 if (sync_cause) {
1924 fatal_int =
1925 (sync_cause &
1926 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
1927 ? true : false;
1928
1929 if (fatal_int) {
1930 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
1931 ath_print(common, ATH_DBG_ANY,
1932 "received PCI FATAL interrupt\n");
1933 }
1934 if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
1935 ath_print(common, ATH_DBG_ANY,
1936 "received PCI PERR interrupt\n");
1937 }
1938 *masked |= ATH9K_INT_FATAL;
1939 }
1940 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
1941 ath_print(common, ATH_DBG_INTERRUPT,
1942 "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
1943 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
1944 REG_WRITE(ah, AR_RC, 0);
1945 *masked |= ATH9K_INT_FATAL;
1946 }
1947 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
1948 ath_print(common, ATH_DBG_INTERRUPT,
1949 "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
1950 }
1951
1952 REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
1953 (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
1954 }
1955
1956 return true;
1957}
1958EXPORT_SYMBOL(ath9k_hw_getisr);
1959
1960enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
1961{
1962 enum ath9k_int omask = ah->imask;
1963 u32 mask, mask2;
1964 struct ath9k_hw_capabilities *pCap = &ah->caps;
1965 struct ath_common *common = ath9k_hw_common(ah);
1966
1967 ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
1968
1969 if (omask & ATH9K_INT_GLOBAL) {
1970 ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
1971 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
1972 (void) REG_READ(ah, AR_IER);
1973 if (!AR_SREV_9100(ah)) {
1974 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
1975 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
1976
1977 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
1978 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
1979 }
1980 }
1981
1982 mask = ints & ATH9K_INT_COMMON;
1983 mask2 = 0;
1984
1985 if (ints & ATH9K_INT_TX) {
1986 if (ah->txok_interrupt_mask)
1987 mask |= AR_IMR_TXOK;
1988 if (ah->txdesc_interrupt_mask)
1989 mask |= AR_IMR_TXDESC;
1990 if (ah->txerr_interrupt_mask)
1991 mask |= AR_IMR_TXERR;
1992 if (ah->txeol_interrupt_mask)
1993 mask |= AR_IMR_TXEOL;
1994 }
1995 if (ints & ATH9K_INT_RX) {
1996 mask |= AR_IMR_RXERR;
1997 if (ah->config.rx_intr_mitigation)
1998 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
1999 else
2000 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
2001 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
2002 mask |= AR_IMR_GENTMR;
2003 }
2004
2005 if (ints & (ATH9K_INT_BMISC)) {
2006 mask |= AR_IMR_BCNMISC;
2007 if (ints & ATH9K_INT_TIM)
2008 mask2 |= AR_IMR_S2_TIM;
2009 if (ints & ATH9K_INT_DTIM)
2010 mask2 |= AR_IMR_S2_DTIM;
2011 if (ints & ATH9K_INT_DTIMSYNC)
2012 mask2 |= AR_IMR_S2_DTIMSYNC;
2013 if (ints & ATH9K_INT_CABEND)
2014 mask2 |= AR_IMR_S2_CABEND;
2015 if (ints & ATH9K_INT_TSFOOR)
2016 mask2 |= AR_IMR_S2_TSFOOR;
2017 }
2018
2019 if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
2020 mask |= AR_IMR_BCNMISC;
2021 if (ints & ATH9K_INT_GTT)
2022 mask2 |= AR_IMR_S2_GTT;
2023 if (ints & ATH9K_INT_CST)
2024 mask2 |= AR_IMR_S2_CST;
2025 }
2026
2027 ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
2028 REG_WRITE(ah, AR_IMR, mask);
2029 ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC |
2030 AR_IMR_S2_CABEND | AR_IMR_S2_CABTO |
2031 AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST);
2032 ah->imrs2_reg |= mask2;
2033 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
2034
2035 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
2036 if (ints & ATH9K_INT_TIM_TIMER)
2037 REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
2038 else
2039 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
2040 }
2041
2042 if (ints & ATH9K_INT_GLOBAL) {
2043 ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
2044 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
2045 if (!AR_SREV_9100(ah)) {
2046 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
2047 AR_INTR_MAC_IRQ);
2048 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
2049
2050
2051 REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
2052 AR_INTR_SYNC_DEFAULT);
2053 REG_WRITE(ah, AR_INTR_SYNC_MASK,
2054 AR_INTR_SYNC_DEFAULT);
2055 }
2056 ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
2057 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
2058 }
2059
2060 return omask;
2061}
2062EXPORT_SYMBOL(ath9k_hw_set_interrupts);
2063
2064/*******************/ 1783/*******************/
2065/* Beacon Handling */ 1784/* Beacon Handling */
2066/*******************/ 1785/*******************/
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index b27e76b82dcf..7a32733108a2 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -227,6 +227,7 @@ struct ath9k_ops_config {
227 u32 enable_ani; 227 u32 enable_ani;
228 int serialize_regmode; 228 int serialize_regmode;
229 bool rx_intr_mitigation; 229 bool rx_intr_mitigation;
230 bool tx_intr_mitigation;
230#define SPUR_DISABLE 0 231#define SPUR_DISABLE 0
231#define SPUR_ENABLE_IOCTL 1 232#define SPUR_ENABLE_IOCTL 1
232#define SPUR_ENABLE_EEPROM 2 233#define SPUR_ENABLE_EEPROM 2
@@ -549,6 +550,7 @@ struct ath_hw_ops {
549 struct ath9k_channel *chan, 550 struct ath9k_channel *chan,
550 u8 rxchainmask, 551 u8 rxchainmask,
551 bool longcal); 552 bool longcal);
553 bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked);
552}; 554};
553 555
554struct ath_hw { 556struct ath_hw {
@@ -810,11 +812,6 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
810 812
811bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); 813bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
812 814
813/* Interrupt Handling */
814bool ath9k_hw_intrpend(struct ath_hw *ah);
815bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
816enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
817
818/* Generic hw timer primitives */ 815/* Generic hw timer primitives */
819struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, 816struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
820 void (*trigger)(void *), 817 void (*trigger)(void *),
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index a8dab23622f1..4a36ec53f732 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -31,6 +31,158 @@ static void ar9002_hw_get_desc_link(void *ds, u32 **ds_link)
31 *ds_link = &((struct ath_desc *)ds)->ds_link; 31 *ds_link = &((struct ath_desc *)ds)->ds_link;
32} 32}
33 33
34static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
35{
36 u32 isr = 0;
37 u32 mask2 = 0;
38 struct ath9k_hw_capabilities *pCap = &ah->caps;
39 u32 sync_cause = 0;
40 bool fatal_int = false;
41 struct ath_common *common = ath9k_hw_common(ah);
42
43 if (!AR_SREV_9100(ah)) {
44 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
45 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
46 == AR_RTC_STATUS_ON) {
47 isr = REG_READ(ah, AR_ISR);
48 }
49 }
50
51 sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
52 AR_INTR_SYNC_DEFAULT;
53
54 *masked = 0;
55
56 if (!isr && !sync_cause)
57 return false;
58 } else {
59 *masked = 0;
60 isr = REG_READ(ah, AR_ISR);
61 }
62
63 if (isr) {
64 if (isr & AR_ISR_BCNMISC) {
65 u32 isr2;
66 isr2 = REG_READ(ah, AR_ISR_S2);
67 if (isr2 & AR_ISR_S2_TIM)
68 mask2 |= ATH9K_INT_TIM;
69 if (isr2 & AR_ISR_S2_DTIM)
70 mask2 |= ATH9K_INT_DTIM;
71 if (isr2 & AR_ISR_S2_DTIMSYNC)
72 mask2 |= ATH9K_INT_DTIMSYNC;
73 if (isr2 & (AR_ISR_S2_CABEND))
74 mask2 |= ATH9K_INT_CABEND;
75 if (isr2 & AR_ISR_S2_GTT)
76 mask2 |= ATH9K_INT_GTT;
77 if (isr2 & AR_ISR_S2_CST)
78 mask2 |= ATH9K_INT_CST;
79 if (isr2 & AR_ISR_S2_TSFOOR)
80 mask2 |= ATH9K_INT_TSFOOR;
81 }
82
83 isr = REG_READ(ah, AR_ISR_RAC);
84 if (isr == 0xffffffff) {
85 *masked = 0;
86 return false;
87 }
88
89 *masked = isr & ATH9K_INT_COMMON;
90
91 if (ah->config.rx_intr_mitigation) {
92 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
93 *masked |= ATH9K_INT_RX;
94 }
95
96 if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
97 *masked |= ATH9K_INT_RX;
98 if (isr &
99 (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
100 AR_ISR_TXEOL)) {
101 u32 s0_s, s1_s;
102
103 *masked |= ATH9K_INT_TX;
104
105 s0_s = REG_READ(ah, AR_ISR_S0_S);
106 ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
107 ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
108
109 s1_s = REG_READ(ah, AR_ISR_S1_S);
110 ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
111 ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
112 }
113
114 if (isr & AR_ISR_RXORN) {
115 ath_print(common, ATH_DBG_INTERRUPT,
116 "receive FIFO overrun interrupt\n");
117 }
118
119 if (!AR_SREV_9100(ah)) {
120 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
121 u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
122 if (isr5 & AR_ISR_S5_TIM_TIMER)
123 *masked |= ATH9K_INT_TIM_TIMER;
124 }
125 }
126
127 *masked |= mask2;
128 }
129
130 if (AR_SREV_9100(ah))
131 return true;
132
133 if (isr & AR_ISR_GENTMR) {
134 u32 s5_s;
135
136 s5_s = REG_READ(ah, AR_ISR_S5_S);
137 if (isr & AR_ISR_GENTMR) {
138 ah->intr_gen_timer_trigger =
139 MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);
140
141 ah->intr_gen_timer_thresh =
142 MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
143
144 if (ah->intr_gen_timer_trigger)
145 *masked |= ATH9K_INT_GENTIMER;
146
147 }
148 }
149
150 if (sync_cause) {
151 fatal_int =
152 (sync_cause &
153 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
154 ? true : false;
155
156 if (fatal_int) {
157 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
158 ath_print(common, ATH_DBG_ANY,
159 "received PCI FATAL interrupt\n");
160 }
161 if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
162 ath_print(common, ATH_DBG_ANY,
163 "received PCI PERR interrupt\n");
164 }
165 *masked |= ATH9K_INT_FATAL;
166 }
167 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
168 ath_print(common, ATH_DBG_INTERRUPT,
169 "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
170 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
171 REG_WRITE(ah, AR_RC, 0);
172 *masked |= ATH9K_INT_FATAL;
173 }
174 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
175 ath_print(common, ATH_DBG_INTERRUPT,
176 "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
177 }
178
179 REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
180 (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
181 }
182
183 return true;
184}
185
34void ar9002_hw_attach_mac_ops(struct ath_hw *ah) 186void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
35{ 187{
36 struct ath_hw_ops *ops = ath9k_hw_ops(ah); 188 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
@@ -38,6 +190,7 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
38 ops->rx_enable = ar9002_hw_rx_enable; 190 ops->rx_enable = ar9002_hw_rx_enable;
39 ops->set_desc_link = ar9002_hw_set_desc_link; 191 ops->set_desc_link = ar9002_hw_set_desc_link;
40 ops->get_desc_link = ar9002_hw_get_desc_link; 192 ops->get_desc_link = ar9002_hw_get_desc_link;
193 ops->get_isr = ar9002_hw_get_isr;
41} 194}
42 195
43static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah, 196static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
@@ -1089,3 +1242,140 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah)
1089 return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); 1242 return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
1090} 1243}
1091EXPORT_SYMBOL(ath9k_hw_beaconq_setup); 1244EXPORT_SYMBOL(ath9k_hw_beaconq_setup);
1245
1246bool ath9k_hw_intrpend(struct ath_hw *ah)
1247{
1248 u32 host_isr;
1249
1250 if (AR_SREV_9100(ah))
1251 return true;
1252
1253 host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
1254 if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
1255 return true;
1256
1257 host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
1258 if ((host_isr & AR_INTR_SYNC_DEFAULT)
1259 && (host_isr != AR_INTR_SPURIOUS))
1260 return true;
1261
1262 return false;
1263}
1264EXPORT_SYMBOL(ath9k_hw_intrpend);
1265
1266enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
1267 enum ath9k_int ints)
1268{
1269 enum ath9k_int omask = ah->imask;
1270 u32 mask, mask2;
1271 struct ath9k_hw_capabilities *pCap = &ah->caps;
1272 struct ath_common *common = ath9k_hw_common(ah);
1273
1274 ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
1275
1276 if (omask & ATH9K_INT_GLOBAL) {
1277 ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
1278 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
1279 (void) REG_READ(ah, AR_IER);
1280 if (!AR_SREV_9100(ah)) {
1281 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
1282 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
1283
1284 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
1285 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
1286 }
1287 }
1288
1289 /* TODO: global int Ref count */
1290 mask = ints & ATH9K_INT_COMMON;
1291 mask2 = 0;
1292
1293 if (ints & ATH9K_INT_TX) {
1294 if (ah->config.tx_intr_mitigation)
1295 mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM;
1296 if (ah->txok_interrupt_mask)
1297 mask |= AR_IMR_TXOK;
1298 if (ah->txdesc_interrupt_mask)
1299 mask |= AR_IMR_TXDESC;
1300 if (ah->txerr_interrupt_mask)
1301 mask |= AR_IMR_TXERR;
1302 if (ah->txeol_interrupt_mask)
1303 mask |= AR_IMR_TXEOL;
1304 }
1305 if (ints & ATH9K_INT_RX) {
1306 if (AR_SREV_9300_20_OR_LATER(ah)) {
1307 mask |= AR_IMR_RXERR | AR_IMR_RXOK_HP;
1308 if (ah->config.rx_intr_mitigation) {
1309 mask &= ~AR_IMR_RXOK_LP;
1310 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
1311 } else {
1312 mask |= AR_IMR_RXOK_LP;
1313 }
1314 } else {
1315 if (ah->config.rx_intr_mitigation)
1316 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
1317 else
1318 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
1319 }
1320 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
1321 mask |= AR_IMR_GENTMR;
1322 }
1323
1324 if (ints & (ATH9K_INT_BMISC)) {
1325 mask |= AR_IMR_BCNMISC;
1326 if (ints & ATH9K_INT_TIM)
1327 mask2 |= AR_IMR_S2_TIM;
1328 if (ints & ATH9K_INT_DTIM)
1329 mask2 |= AR_IMR_S2_DTIM;
1330 if (ints & ATH9K_INT_DTIMSYNC)
1331 mask2 |= AR_IMR_S2_DTIMSYNC;
1332 if (ints & ATH9K_INT_CABEND)
1333 mask2 |= AR_IMR_S2_CABEND;
1334 if (ints & ATH9K_INT_TSFOOR)
1335 mask2 |= AR_IMR_S2_TSFOOR;
1336 }
1337
1338 if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
1339 mask |= AR_IMR_BCNMISC;
1340 if (ints & ATH9K_INT_GTT)
1341 mask2 |= AR_IMR_S2_GTT;
1342 if (ints & ATH9K_INT_CST)
1343 mask2 |= AR_IMR_S2_CST;
1344 }
1345
1346 ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
1347 REG_WRITE(ah, AR_IMR, mask);
1348 ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC |
1349 AR_IMR_S2_CABEND | AR_IMR_S2_CABTO |
1350 AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST);
1351 ah->imrs2_reg |= mask2;
1352 REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
1353
1354 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
1355 if (ints & ATH9K_INT_TIM_TIMER)
1356 REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
1357 else
1358 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
1359 }
1360
1361 if (ints & ATH9K_INT_GLOBAL) {
1362 ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
1363 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
1364 if (!AR_SREV_9100(ah)) {
1365 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
1366 AR_INTR_MAC_IRQ);
1367 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
1368
1369
1370 REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
1371 AR_INTR_SYNC_DEFAULT);
1372 REG_WRITE(ah, AR_INTR_SYNC_MASK,
1373 AR_INTR_SYNC_DEFAULT);
1374 }
1375 ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
1376 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
1377 }
1378
1379 return omask;
1380}
1381EXPORT_SYMBOL(ath9k_hw_set_interrupts);
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 99f81ebb35bf..7c0d75490211 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -736,6 +736,11 @@ void ath9k_hw_stoppcurecv(struct ath_hw *ah);
736bool ath9k_hw_stopdmarecv(struct ath_hw *ah); 736bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
737int ath9k_hw_beaconq_setup(struct ath_hw *ah); 737int ath9k_hw_beaconq_setup(struct ath_hw *ah);
738 738
739/* Interrupt Handling */
740bool ath9k_hw_intrpend(struct ath_hw *ah);
741enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
742 enum ath9k_int ints);
743
739void ar9002_hw_attach_mac_ops(struct ath_hw *ah); 744void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
740 745
741#endif /* MAC_H */ 746#endif /* MAC_H */
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 96b2cfee8e33..7f856334a28a 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -253,6 +253,8 @@
253#define AR_IMR 0x00a0 253#define AR_IMR 0x00a0
254#define AR_IMR_RXOK 0x00000001 254#define AR_IMR_RXOK 0x00000001
255#define AR_IMR_RXDESC 0x00000002 255#define AR_IMR_RXDESC 0x00000002
256#define AR_IMR_RXOK_HP 0x00000001
257#define AR_IMR_RXOK_LP 0x00000002
256#define AR_IMR_RXERR 0x00000004 258#define AR_IMR_RXERR 0x00000004
257#define AR_IMR_RXNOPKT 0x00000008 259#define AR_IMR_RXNOPKT 0x00000008
258#define AR_IMR_RXEOL 0x00000010 260#define AR_IMR_RXEOL 0x00000010