2
0

470-ath5k_decrease_irq_load.patch 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. --- a/drivers/net/wireless/ath/ath5k/ath5k.h
  2. +++ b/drivers/net/wireless/ath/ath5k/ath5k.h
  3. @@ -872,6 +872,19 @@ enum ath5k_int {
  4. AR5K_INT_QTRIG = 0x40000000, /* Non common */
  5. AR5K_INT_GLOBAL = 0x80000000,
  6. + AR5K_INT_TX_ALL = AR5K_INT_TXOK
  7. + | AR5K_INT_TXDESC
  8. + | AR5K_INT_TXERR
  9. + | AR5K_INT_TXEOL
  10. + | AR5K_INT_TXURN,
  11. +
  12. + AR5K_INT_RX_ALL = AR5K_INT_RXOK
  13. + | AR5K_INT_RXDESC
  14. + | AR5K_INT_RXERR
  15. + | AR5K_INT_RXNOFRM
  16. + | AR5K_INT_RXEOL
  17. + | AR5K_INT_RXORN,
  18. +
  19. AR5K_INT_COMMON = AR5K_INT_RXOK
  20. | AR5K_INT_RXDESC
  21. | AR5K_INT_RXERR
  22. --- a/drivers/net/wireless/ath/ath5k/base.c
  23. +++ b/drivers/net/wireless/ath/ath5k/base.c
  24. @@ -1444,6 +1444,21 @@ ath5k_receive_frame_ok(struct ath5k_soft
  25. }
  26. static void
  27. +ath5k_set_current_imask(struct ath5k_softc *sc)
  28. +{
  29. + enum ath5k_int imask = sc->imask;
  30. + unsigned long flags;
  31. +
  32. + spin_lock_irqsave(&sc->irqlock, flags);
  33. + if (sc->rx_pending)
  34. + imask &= ~AR5K_INT_RX_ALL;
  35. + if (sc->tx_pending)
  36. + imask &= ~AR5K_INT_TX_ALL;
  37. + ath5k_hw_set_imr(sc->ah, imask);
  38. + spin_unlock_irqrestore(&sc->irqlock, flags);
  39. +}
  40. +
  41. +static void
  42. ath5k_tasklet_rx(unsigned long data)
  43. {
  44. struct ath5k_rx_status rs = {};
  45. @@ -1506,6 +1521,8 @@ next:
  46. } while (ath5k_rxbuf_setup(sc, bf) == 0);
  47. unlock:
  48. spin_unlock(&sc->rxbuflock);
  49. + sc->rx_pending = false;
  50. + ath5k_set_current_imask(sc);
  51. }
  52. @@ -1693,6 +1710,9 @@ ath5k_tasklet_tx(unsigned long data)
  53. for (i=0; i < AR5K_NUM_TX_QUEUES; i++)
  54. if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i)))
  55. ath5k_tx_processq(sc, &sc->txqs[i]);
  56. +
  57. + sc->tx_pending = false;
  58. + ath5k_set_current_imask(sc);
  59. }
  60. @@ -2122,6 +2142,20 @@ ath5k_intr_calibration_poll(struct ath5k
  61. * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */
  62. }
  63. +static void
  64. +ath5k_schedule_rx(struct ath5k_softc *sc)
  65. +{
  66. + sc->rx_pending = true;
  67. + tasklet_schedule(&sc->rxtq);
  68. +}
  69. +
  70. +static void
  71. +ath5k_schedule_tx(struct ath5k_softc *sc)
  72. +{
  73. + sc->tx_pending = true;
  74. + tasklet_schedule(&sc->txtq);
  75. +}
  76. +
  77. irqreturn_t
  78. ath5k_intr(int irq, void *dev_id)
  79. {
  80. @@ -2164,7 +2198,7 @@ ath5k_intr(int irq, void *dev_id)
  81. ieee80211_queue_work(sc->hw, &sc->reset_work);
  82. }
  83. else
  84. - tasklet_schedule(&sc->rxtq);
  85. + ath5k_schedule_rx(sc);
  86. } else {
  87. if (status & AR5K_INT_SWBA) {
  88. tasklet_hi_schedule(&sc->beacontq);
  89. @@ -2182,10 +2216,10 @@ ath5k_intr(int irq, void *dev_id)
  90. ath5k_hw_update_tx_triglevel(ah, true);
  91. }
  92. if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR))
  93. - tasklet_schedule(&sc->rxtq);
  94. + ath5k_schedule_rx(sc);
  95. if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC
  96. | AR5K_INT_TXERR | AR5K_INT_TXEOL))
  97. - tasklet_schedule(&sc->txtq);
  98. + ath5k_schedule_tx(sc);
  99. if (status & AR5K_INT_BMISS) {
  100. /* TODO */
  101. }
  102. @@ -2204,6 +2238,9 @@ ath5k_intr(int irq, void *dev_id)
  103. } while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
  104. + if (sc->rx_pending || sc->tx_pending)
  105. + ath5k_set_current_imask(sc);
  106. +
  107. if (unlikely(!counter))
  108. ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
  109. @@ -2575,6 +2612,8 @@ done:
  110. static void stop_tasklets(struct ath5k_softc *sc)
  111. {
  112. + sc->rx_pending = false;
  113. + sc->tx_pending = false;
  114. tasklet_kill(&sc->rxtq);
  115. tasklet_kill(&sc->txtq);
  116. tasklet_kill(&sc->calib);
  117. --- a/drivers/net/wireless/ath/ath5k/base.h
  118. +++ b/drivers/net/wireless/ath/ath5k/base.h
  119. @@ -207,6 +207,10 @@ struct ath5k_softc {
  120. enum ath5k_int imask; /* interrupt mask copy */
  121. + spinlock_t irqlock;
  122. + bool rx_pending; /* rx tasklet pending */
  123. + bool tx_pending; /* tx tasklet pending */
  124. +
  125. u8 lladdr[ETH_ALEN];
  126. u8 bssidmask[ETH_ALEN];