aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSujith Manoharan <c_manoha@qca.qualcomm.com>2013-12-24 00:14:25 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-01-03 15:36:58 -0500
commit415ec61b66198f93962b76107f3324571475a3e2 (patch)
tree7ab89ba603e5e92095b9f4223eb0b51b34a19a16
parent6549a8606d0a6cc45d0984893c859a6161c227b7 (diff)
ath9k: Remove RX Poll
This patch removes the convoluted and hacky method of monitoring for connectivity. We rely on mac80211's connection loss logic and doing it in the driver is not necessary. The HW check for MAC/BB hangs is also simplified, there is no need to have a separate work instance for it. Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/link.c63
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/wow.c1
7 files changed, 17 insertions, 77 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index f2202e78fa7b..f622a986c8cc 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -455,10 +455,8 @@ bool ath9k_csa_is_finished(struct ath_softc *sc);
455 455
456void ath_tx_complete_poll_work(struct work_struct *work); 456void ath_tx_complete_poll_work(struct work_struct *work);
457void ath_reset_work(struct work_struct *work); 457void ath_reset_work(struct work_struct *work);
458void ath_hw_check(struct work_struct *work); 458bool ath_hw_check(struct ath_softc *sc);
459void ath_hw_pll_work(struct work_struct *work); 459void ath_hw_pll_work(struct work_struct *work);
460void ath_rx_poll(unsigned long data);
461void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon);
462void ath_paprd_calibrate(struct work_struct *work); 460void ath_paprd_calibrate(struct work_struct *work);
463void ath_ani_calibrate(unsigned long data); 461void ath_ani_calibrate(unsigned long data);
464void ath_start_ani(struct ath_softc *sc); 462void ath_start_ani(struct ath_softc *sc);
@@ -722,12 +720,10 @@ struct ath_softc {
722 spinlock_t sc_pcu_lock; 720 spinlock_t sc_pcu_lock;
723 struct mutex mutex; 721 struct mutex mutex;
724 struct work_struct paprd_work; 722 struct work_struct paprd_work;
725 struct work_struct hw_check_work;
726 struct work_struct hw_reset_work; 723 struct work_struct hw_reset_work;
727 struct completion paprd_complete; 724 struct completion paprd_complete;
728 wait_queue_head_t tx_wait; 725 wait_queue_head_t tx_wait;
729 726
730 unsigned int hw_busy_count;
731 unsigned long sc_flags; 727 unsigned long sc_flags;
732 unsigned long driver_data; 728 unsigned long driver_data;
733 729
@@ -761,7 +757,6 @@ struct ath_softc {
761 struct ath_beacon_config cur_beacon_conf; 757 struct ath_beacon_config cur_beacon_conf;
762 struct delayed_work tx_complete_work; 758 struct delayed_work tx_complete_work;
763 struct delayed_work hw_pll_work; 759 struct delayed_work hw_pll_work;
764 struct timer_list rx_poll_timer;
765 struct timer_list sleep_timer; 760 struct timer_list sleep_timer;
766 761
767#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 762#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 112aff720e13..2e8bba0eb361 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -337,8 +337,14 @@ void ath9k_beacon_tasklet(unsigned long data)
337 337
338 ath9k_hw_check_nav(ah); 338 ath9k_hw_check_nav(ah);
339 339
340 if (!ath9k_hw_check_alive(ah)) 340 /*
341 ieee80211_queue_work(sc->hw, &sc->hw_check_work); 341 * If the previous beacon has not been transmitted
342 * and a MAC/BB hang has been identified, return
343 * here because a chip reset would have been
344 * initiated.
345 */
346 if (!ath_hw_check(sc))
347 return;
342 348
343 if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) { 349 if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) {
344 ath_dbg(common, BSTUCK, 350 ath_dbg(common, BSTUCK,
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index e63465b7eab9..f2a17fcf1ae4 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -763,10 +763,8 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
763 763
764 setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc); 764 setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc);
765 INIT_WORK(&sc->hw_reset_work, ath_reset_work); 765 INIT_WORK(&sc->hw_reset_work, ath_reset_work);
766 INIT_WORK(&sc->hw_check_work, ath_hw_check);
767 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); 766 INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
768 INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); 767 INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
769 setup_timer(&sc->rx_poll_timer, ath_rx_poll, (unsigned long)sc);
770 768
771 /* 769 /*
772 * Cache line size is used to size and align various 770 * Cache line size is used to size and align various
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c
index aed7e29dc50f..c92ca81350de 100644
--- a/drivers/net/wireless/ath/ath9k/link.c
+++ b/drivers/net/wireless/ath/ath9k/link.c
@@ -65,50 +65,26 @@ void ath_tx_complete_poll_work(struct work_struct *work)
65/* 65/*
66 * Checks if the BB/MAC is hung. 66 * Checks if the BB/MAC is hung.
67 */ 67 */
68void ath_hw_check(struct work_struct *work) 68bool ath_hw_check(struct ath_softc *sc)
69{ 69{
70 struct ath_softc *sc = container_of(work, struct ath_softc, hw_check_work);
71 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 70 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
72 unsigned long flags;
73 int busy;
74 u8 is_alive, nbeacon = 1;
75 enum ath_reset_type type; 71 enum ath_reset_type type;
72 bool is_alive;
76 73
77 ath9k_ps_wakeup(sc); 74 ath9k_ps_wakeup(sc);
75
78 is_alive = ath9k_hw_check_alive(sc->sc_ah); 76 is_alive = ath9k_hw_check_alive(sc->sc_ah);
79 77
80 if ((is_alive && !AR_SREV_9300(sc->sc_ah)) || sc->tx99_state) 78 if (!is_alive) {
81 goto out;
82 else if (!is_alive && AR_SREV_9300(sc->sc_ah)) {
83 ath_dbg(common, RESET, 79 ath_dbg(common, RESET,
84 "DCU stuck is detected. Schedule chip reset\n"); 80 "HW hang detected, schedule chip reset\n");
85 type = RESET_TYPE_MAC_HANG; 81 type = RESET_TYPE_MAC_HANG;
86 goto sched_reset; 82 ath9k_queue_reset(sc, type);
87 }
88
89 spin_lock_irqsave(&common->cc_lock, flags);
90 busy = ath_update_survey_stats(sc);
91 spin_unlock_irqrestore(&common->cc_lock, flags);
92
93 ath_dbg(common, RESET, "Possible baseband hang, busy=%d (try %d)\n",
94 busy, sc->hw_busy_count + 1);
95 if (busy >= 99) {
96 if (++sc->hw_busy_count >= 3) {
97 type = RESET_TYPE_BB_HANG;
98 goto sched_reset;
99 }
100 } else if (busy >= 0) {
101 sc->hw_busy_count = 0;
102 nbeacon = 3;
103 } 83 }
104 84
105 ath_start_rx_poll(sc, nbeacon);
106 goto out;
107
108sched_reset:
109 ath9k_queue_reset(sc, type);
110out:
111 ath9k_ps_restore(sc); 85 ath9k_ps_restore(sc);
86
87 return is_alive;
112} 88}
113 89
114/* 90/*
@@ -162,29 +138,6 @@ void ath_hw_pll_work(struct work_struct *work)
162} 138}
163 139
164/* 140/*
165 * RX Polling - monitors baseband hangs.
166 */
167void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon)
168{
169 if (!AR_SREV_9300(sc->sc_ah))
170 return;
171
172 if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags))
173 return;
174
175 mod_timer(&sc->rx_poll_timer, jiffies + msecs_to_jiffies
176 (nbeacon * sc->cur_beacon_conf.beacon_interval));
177}
178
179void ath_rx_poll(unsigned long data)
180{
181 struct ath_softc *sc = (struct ath_softc *)data;
182
183 if (!test_bit(SC_OP_INVALID, &sc->sc_flags))
184 ieee80211_queue_work(sc->hw, &sc->hw_check_work);
185}
186
187/*
188 * PA Pre-distortion. 141 * PA Pre-distortion.
189 */ 142 */
190static void ath_paprd_activate(struct ath_softc *sc) 143static void ath_paprd_activate(struct ath_softc *sc)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index c19182b8dd03..39d3af410834 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -170,7 +170,6 @@ void ath9k_ps_restore(struct ath_softc *sc)
170static void __ath_cancel_work(struct ath_softc *sc) 170static void __ath_cancel_work(struct ath_softc *sc)
171{ 171{
172 cancel_work_sync(&sc->paprd_work); 172 cancel_work_sync(&sc->paprd_work);
173 cancel_work_sync(&sc->hw_check_work);
174 cancel_delayed_work_sync(&sc->tx_complete_work); 173 cancel_delayed_work_sync(&sc->tx_complete_work);
175 cancel_delayed_work_sync(&sc->hw_pll_work); 174 cancel_delayed_work_sync(&sc->hw_pll_work);
176 175
@@ -194,7 +193,6 @@ void ath_restart_work(struct ath_softc *sc)
194 ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, 193 ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work,
195 msecs_to_jiffies(ATH_PLL_WORK_INTERVAL)); 194 msecs_to_jiffies(ATH_PLL_WORK_INTERVAL));
196 195
197 ath_start_rx_poll(sc, 3);
198 ath_start_ani(sc); 196 ath_start_ani(sc);
199} 197}
200 198
@@ -204,11 +202,7 @@ static bool ath_prepare_reset(struct ath_softc *sc)
204 bool ret = true; 202 bool ret = true;
205 203
206 ieee80211_stop_queues(sc->hw); 204 ieee80211_stop_queues(sc->hw);
207
208 sc->hw_busy_count = 0;
209 ath_stop_ani(sc); 205 ath_stop_ani(sc);
210 del_timer_sync(&sc->rx_poll_timer);
211
212 ath9k_hw_disable_interrupts(ah); 206 ath9k_hw_disable_interrupts(ah);
213 207
214 if (!ath_drain_all_txq(sc)) 208 if (!ath_drain_all_txq(sc))
@@ -867,7 +861,6 @@ static void ath9k_stop(struct ieee80211_hw *hw)
867 mutex_lock(&sc->mutex); 861 mutex_lock(&sc->mutex);
868 862
869 ath_cancel_work(sc); 863 ath_cancel_work(sc);
870 del_timer_sync(&sc->rx_poll_timer);
871 864
872 if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { 865 if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
873 ath_dbg(common, ANY, "Device not present\n"); 866 ath_dbg(common, ANY, "Device not present\n");
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 3692b2a501a2..470e1c0e7c57 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1077,10 +1077,6 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
1077 } 1077 }
1078 1078
1079 rx_stats->is_mybeacon = ath9k_is_mybeacon(sc, hdr); 1079 rx_stats->is_mybeacon = ath9k_is_mybeacon(sc, hdr);
1080 if (rx_stats->is_mybeacon) {
1081 sc->hw_busy_count = 0;
1082 ath_start_rx_poll(sc, 3);
1083 }
1084 1080
1085 if (ath9k_process_rate(common, hw, rx_stats, rx_status)) { 1081 if (ath9k_process_rate(common, hw, rx_stats, rx_status)) {
1086 ret =-EINVAL; 1082 ret =-EINVAL;
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index f1cde81bb7a2..1b3230fa3651 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -197,7 +197,6 @@ int ath9k_suspend(struct ieee80211_hw *hw,
197 197
198 ath_cancel_work(sc); 198 ath_cancel_work(sc);
199 ath_stop_ani(sc); 199 ath_stop_ani(sc);
200 del_timer_sync(&sc->rx_poll_timer);
201 200
202 if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { 201 if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
203 ath_dbg(common, ANY, "Device not present\n"); 202 ath_dbg(common, ANY, "Device not present\n");