aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/wil6210/interrupt.c
diff options
context:
space:
mode:
authorVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>2014-12-23 02:47:19 -0500
committerKalle Valo <kvalo@codeaurora.org>2015-01-15 07:31:38 -0500
commit78366f69beb604717a12191eee35300057b6bcfc (patch)
tree968f841cbfecd728d3ac5de7f0451ad3c074b8fc /drivers/net/wireless/ath/wil6210/interrupt.c
parent1aeda13be061d005b4b84c2a974bf11d0b8675ad (diff)
wil6210: add advanced interrupt moderation
Add advanced interrupt moderation support available since "Sparrow B0". Legacy interrupt moderation used only one counter to moderate tx, rx, and misc interrupts. Advanced interrupt moderation bypasses misc, and handles separately tx and rx interrupts. In addition it has two timers for each interrupt type. Max burst duration timer which defines how long to postpone interrupt after first event (receive event for rx and tx complete event for tx), and interframe timeout which defines how to determine the end of the burst and issue interrupt even if the first timer still pending. Capabilities flags in wil_priv is set on initialization according to HW. The rest of the code checks for advanced interrupt capability bit in capabilities flags field. Debugfs is split accordingly: "legacy" interrupt moderation remains unchanged, new debugs files added for advanced interrupt moderation support. Module params are aligned to support advanced interrupt moderation (tx & rx). When not available (for legacy interrupt moderation) will use only rx configuration; Tx configuration will be ignored in this case. Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/ath/wil6210/interrupt.c')
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c82
1 files changed, 79 insertions, 3 deletions
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index 384bb3171c45..a6f923086f31 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -157,15 +157,91 @@ void wil_unmask_irq(struct wil6210_priv *wil)
157 iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) + 157 iowrite32(WIL_ICR_ICC_VALUE, wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) +
158 offsetof(struct RGF_ICR, ICC)); 158 offsetof(struct RGF_ICR, ICC));
159 159
160 /* interrupt moderation parameters */
161 wil_set_itr_trsh(wil);
162
163 wil6210_unmask_irq_pseudo(wil); 160 wil6210_unmask_irq_pseudo(wil);
164 wil6210_unmask_irq_tx(wil); 161 wil6210_unmask_irq_tx(wil);
165 wil6210_unmask_irq_rx(wil); 162 wil6210_unmask_irq_rx(wil);
166 wil6210_unmask_irq_misc(wil); 163 wil6210_unmask_irq_misc(wil);
167} 164}
168 165
166/* target write operation */
167#define W(a, v) do { iowrite32(v, wil->csr + HOSTADDR(a)); wmb(); } while (0)
168
169static
170void wil_configure_interrupt_moderation_new(struct wil6210_priv *wil)
171{
172 /* Disable and clear tx counter before (re)configuration */
173 W(RGF_DMA_ITR_TX_CNT_CTL, BIT_DMA_ITR_TX_CNT_CTL_CLR);
174 W(RGF_DMA_ITR_TX_CNT_TRSH, wil->tx_max_burst_duration);
175 wil_info(wil, "set ITR_TX_CNT_TRSH = %d usec\n",
176 wil->tx_max_burst_duration);
177 /* Configure TX max burst duration timer to use usec units */
178 W(RGF_DMA_ITR_TX_CNT_CTL,
179 BIT_DMA_ITR_TX_CNT_CTL_EN | BIT_DMA_ITR_TX_CNT_CTL_EXT_TIC_SEL);
180
181 /* Disable and clear tx idle counter before (re)configuration */
182 W(RGF_DMA_ITR_TX_IDL_CNT_CTL, BIT_DMA_ITR_TX_IDL_CNT_CTL_CLR);
183 W(RGF_DMA_ITR_TX_IDL_CNT_TRSH, wil->tx_interframe_timeout);
184 wil_info(wil, "set ITR_TX_IDL_CNT_TRSH = %d usec\n",
185 wil->tx_interframe_timeout);
186 /* Configure TX max burst duration timer to use usec units */
187 W(RGF_DMA_ITR_TX_IDL_CNT_CTL, BIT_DMA_ITR_TX_IDL_CNT_CTL_EN |
188 BIT_DMA_ITR_TX_IDL_CNT_CTL_EXT_TIC_SEL);
189
190 /* Disable and clear rx counter before (re)configuration */
191 W(RGF_DMA_ITR_RX_CNT_CTL, BIT_DMA_ITR_RX_CNT_CTL_CLR);
192 W(RGF_DMA_ITR_RX_CNT_TRSH, wil->rx_max_burst_duration);
193 wil_info(wil, "set ITR_RX_CNT_TRSH = %d usec\n",
194 wil->rx_max_burst_duration);
195 /* Configure TX max burst duration timer to use usec units */
196 W(RGF_DMA_ITR_RX_CNT_CTL,
197 BIT_DMA_ITR_RX_CNT_CTL_EN | BIT_DMA_ITR_RX_CNT_CTL_EXT_TIC_SEL);
198
199 /* Disable and clear rx idle counter before (re)configuration */
200 W(RGF_DMA_ITR_RX_IDL_CNT_CTL, BIT_DMA_ITR_RX_IDL_CNT_CTL_CLR);
201 W(RGF_DMA_ITR_RX_IDL_CNT_TRSH, wil->rx_interframe_timeout);
202 wil_info(wil, "set ITR_RX_IDL_CNT_TRSH = %d usec\n",
203 wil->rx_interframe_timeout);
204 /* Configure TX max burst duration timer to use usec units */
205 W(RGF_DMA_ITR_RX_IDL_CNT_CTL, BIT_DMA_ITR_RX_IDL_CNT_CTL_EN |
206 BIT_DMA_ITR_RX_IDL_CNT_CTL_EXT_TIC_SEL);
207}
208
209static
210void wil_configure_interrupt_moderation_lgc(struct wil6210_priv *wil)
211{
212 /* disable, use usec resolution */
213 W(RGF_DMA_ITR_CNT_CRL, BIT_DMA_ITR_CNT_CRL_CLR);
214
215 wil_info(wil, "set ITR_TRSH = %d usec\n", wil->rx_max_burst_duration);
216 W(RGF_DMA_ITR_CNT_TRSH, wil->rx_max_burst_duration);
217 /* start it */
218 W(RGF_DMA_ITR_CNT_CRL,
219 BIT_DMA_ITR_CNT_CRL_EN | BIT_DMA_ITR_CNT_CRL_EXT_TICK);
220}
221
222#undef W
223
224void wil_configure_interrupt_moderation(struct wil6210_priv *wil)
225{
226 wil_dbg_irq(wil, "%s()\n", __func__);
227
228 /* disable interrupt moderation for monitor
229 * to get better timestamp precision
230 */
231 if (wil->wdev->iftype == NL80211_IFTYPE_MONITOR)
232 return;
233
234 if (test_bit(hw_capability_advanced_itr_moderation,
235 wil->hw_capabilities))
236 wil_configure_interrupt_moderation_new(wil);
237 else {
238 /* Advanced interrupt moderation is not available before
239 * Sparrow v2. Will use legacy interrupt moderation
240 */
241 wil_configure_interrupt_moderation_lgc(wil);
242 }
243}
244
169static irqreturn_t wil6210_irq_rx(int irq, void *cookie) 245static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
170{ 246{
171 struct wil6210_priv *wil = cookie; 247 struct wil6210_priv *wil = cookie;