iPXE
Functions
ath5k_dma.c File Reference
#include <unistd.h>
#include "ath5k.h"
#include "reg.h"
#include "base.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (MIT)
 
void ath5k_hw_start_rx_dma (struct ath5k_hw *ah)
 ath5k_hw_start_rx_dma - Start DMA receive More...
 
int ath5k_hw_stop_rx_dma (struct ath5k_hw *ah)
 ath5k_hw_stop_rx_dma - Stop DMA receive More...
 
u32 ath5k_hw_get_rxdp (struct ath5k_hw *ah)
 ath5k_hw_get_rxdp - Get RX Descriptor's address More...
 
void ath5k_hw_set_rxdp (struct ath5k_hw *ah, u32 phys_addr)
 ath5k_hw_set_rxdp - Set RX Descriptor's address More...
 
int ath5k_hw_start_tx_dma (struct ath5k_hw *ah, unsigned int queue)
 ath5k_hw_start_tx_dma - Start DMA transmit for a specific queue More...
 
int ath5k_hw_stop_tx_dma (struct ath5k_hw *ah, unsigned int queue)
 ath5k_hw_stop_tx_dma - Stop DMA transmit on a specific queue More...
 
u32 ath5k_hw_get_txdp (struct ath5k_hw *ah, unsigned int queue)
 ath5k_hw_get_txdp - Get TX Descriptor's address for a specific queue More...
 
int ath5k_hw_set_txdp (struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)
 ath5k_hw_set_txdp - Set TX Descriptor's address for a specific queue More...
 
int ath5k_hw_update_tx_triglevel (struct ath5k_hw *ah, int increase)
 ath5k_hw_update_tx_triglevel - Update tx trigger level More...
 
int ath5k_hw_is_intr_pending (struct ath5k_hw *ah)
 ath5k_hw_is_intr_pending - Check if we have pending interrupts More...
 
int ath5k_hw_get_isr (struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
 
enum ath5k_int ath5k_hw_set_imr (struct ath5k_hw *ah, enum ath5k_int new_mask)
 ath5k_hw_set_imr - Set interrupt mask More...
 

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( MIT  )

◆ ath5k_hw_start_rx_dma()

void ath5k_hw_start_rx_dma ( struct ath5k_hw ah)

ath5k_hw_start_rx_dma - Start DMA receive

@ah: The &struct ath5k_hw

Definition at line 54 of file ath5k_dma.c.

55 {
58 }
#define AR5K_CR_RXE
Definition: reg.h:56
#define AR5K_CR
Definition: reg.h:53
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
uint8_t ah
Definition: registers.h:85
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214

References ah, AR5K_CR, AR5K_CR_RXE, ath5k_hw_reg_read(), and ath5k_hw_reg_write().

Referenced by ath5k_rx_start().

◆ ath5k_hw_stop_rx_dma()

int ath5k_hw_stop_rx_dma ( struct ath5k_hw ah)

ath5k_hw_stop_rx_dma - Stop DMA receive

@ah: The &struct ath5k_hw

Definition at line 65 of file ath5k_dma.c.

66 {
67  unsigned int i;
68 
70 
71  /*
72  * It may take some time to disable the DMA receive unit
73  */
74  for (i = 1000; i > 0 &&
76  i--)
77  udelay(10);
78 
79  return i ? 0 : -EBUSY;
80 }
#define AR5K_CR_RXE
Definition: reg.h:56
#define EBUSY
Device or resource busy.
Definition: errno.h:338
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition: timer.c:60
#define AR5K_CR
Definition: reg.h:53
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
uint8_t ah
Definition: registers.h:85
#define AR5K_CR_RXD
Definition: reg.h:59
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214

References ah, AR5K_CR, AR5K_CR_RXD, AR5K_CR_RXE, ath5k_hw_reg_read(), ath5k_hw_reg_write(), EBUSY, and udelay().

Referenced by ath5k_rx_stop().

◆ ath5k_hw_get_rxdp()

u32 ath5k_hw_get_rxdp ( struct ath5k_hw ah)

ath5k_hw_get_rxdp - Get RX Descriptor's address

@ah: The &struct ath5k_hw

XXX: Is RXDP read and clear ?

Definition at line 89 of file ath5k_dma.c.

90 {
92 }
#define AR5K_RXDP
Definition: reg.h:65
uint8_t ah
Definition: registers.h:85
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214

References ah, AR5K_RXDP, and ath5k_hw_reg_read().

◆ ath5k_hw_set_rxdp()

void ath5k_hw_set_rxdp ( struct ath5k_hw ah,
u32  phys_addr 
)

ath5k_hw_set_rxdp - Set RX Descriptor's address

@ah: The &struct ath5k_hw @phys_addr: RX descriptor address

XXX: Should we check if rx is enabled before setting rxdp ?

Definition at line 102 of file ath5k_dma.c.

103 {
104  ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
105 }
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
#define AR5K_RXDP
Definition: reg.h:65
uint8_t ah
Definition: registers.h:85

References ah, AR5K_RXDP, and ath5k_hw_reg_write().

Referenced by ath5k_rx_start().

◆ ath5k_hw_start_tx_dma()

int ath5k_hw_start_tx_dma ( struct ath5k_hw ah,
unsigned int  queue 
)

ath5k_hw_start_tx_dma - Start DMA transmit for a specific queue

@ah: The &struct ath5k_hw @queue: The hw queue number

Start DMA transmit for a specific queue and since 5210 doesn't have QCU/DCU, set up queue parameters for 5210 here based on queue type (one queue for normal data and one queue for beacons). For queue setup on newer chips check out qcu.c. Returns -EINVAL if queue number is out of range or if queue is already disabled.

NOTE: Must be called after setting up tx control descriptor for that queue (see below).

Definition at line 127 of file ath5k_dma.c.

128 {
129  u32 tx_queue;
130 
131  /* Return if queue is declared inactive */
132  if (ah->ah_txq.tqi_type == AR5K_TX_QUEUE_INACTIVE)
133  return -EIO;
134 
135  if (ah->ah_version == AR5K_AR5210) {
136  tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
137 
138  /* Assume always a data queue */
139  tx_queue |= AR5K_CR_TXE0 & ~AR5K_CR_TXD0;
140 
141  /* Start queue */
142  ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
144  } else {
145  /* Return if queue is disabled */
147  return -EIO;
148 
149  /* Start queue */
151  }
152 
153  return 0;
154 }
#define AR5K_QCU_TXE
Definition: reg.h:559
#define AR5K_REG_WRITE_Q(ah, _reg, _queue)
Definition: ath5k.h:121
#define AR5K_CR_TXD0
Definition: reg.h:57
#define AR5K_QCU_TXD
Definition: reg.h:566
#define AR5K_CR
Definition: reg.h:53
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
#define AR5K_REG_READ_Q(ah, _reg, _queue)
Definition: ath5k.h:118
#define EIO
Input/output error.
Definition: errno.h:433
uint8_t ah
Definition: registers.h:85
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214
uint16_t queue
Queue ID.
Definition: ena.h:22
uint32_t u32
Definition: stdint.h:23
#define AR5K_CR_TXE0
Definition: reg.h:54

References ah, AR5K_AR5210, AR5K_CR, AR5K_CR_TXD0, AR5K_CR_TXE0, AR5K_QCU_TXD, AR5K_QCU_TXE, AR5K_REG_READ_Q, AR5K_REG_WRITE_Q, AR5K_TX_QUEUE_INACTIVE, ath5k_hw_reg_read(), ath5k_hw_reg_write(), EIO, and queue.

Referenced by ath5k_txbuf_setup().

◆ ath5k_hw_stop_tx_dma()

int ath5k_hw_stop_tx_dma ( struct ath5k_hw ah,
unsigned int  queue 
)

ath5k_hw_stop_tx_dma - Stop DMA transmit on a specific queue

@ah: The &struct ath5k_hw @queue: The hw queue number

Stop DMA transmit on a specific hw queue and drain queue so we don't have any pending frames. Returns -EBUSY if we still have pending frames, -EINVAL if queue number is out of range.

Definition at line 167 of file ath5k_dma.c.

168 {
169  unsigned int i = 40;
170  u32 tx_queue, pending;
171 
172  /* Return if queue is declared inactive */
173  if (ah->ah_txq.tqi_type == AR5K_TX_QUEUE_INACTIVE)
174  return -EIO;
175 
176  if (ah->ah_version == AR5K_AR5210) {
177  tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
178 
179  /* Assume a data queue */
180  tx_queue |= AR5K_CR_TXD0 & ~AR5K_CR_TXE0;
181 
182  /* Stop queue */
183  ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
185  } else {
186  /*
187  * Schedule TX disable and wait until queue is empty
188  */
190 
191  /*Check for pending frames*/
192  do {
196  udelay(100);
197  } while (--i && pending);
198 
199  /* For 2413+ order PCU to drop packets using
200  * QUIET mechanism */
201  if (ah->ah_mac_version >= (AR5K_SREV_AR2414 >> 4) && pending) {
202  /* Set periodicity and duration */
207 
208  /* Enable quiet period for current TSF */
212  AR5K_TSF_L32_5211) >> 10,
215 
216  /* Force channel idle high */
219 
220  /* Wait a while and disable mechanism */
221  udelay(200);
224 
225  /* Re-check for pending frames */
226  i = 40;
227  do {
231  udelay(100);
232  } while (--i && pending);
233 
236  }
237 
238  /* Clear register */
240  if (pending)
241  return -EBUSY;
242  }
243 
244  /* TODO: Check for success on 5210 else return error */
245  return 0;
246 }
#define AR5K_QUIET_CTL1
Definition: reg.h:1680
#define EBUSY
Device or resource busy.
Definition: errno.h:338
#define AR5K_QUIET_CTL2_QT_DUR
Definition: reg.h:1689
uint32_t pending
Pending events.
Definition: hyperv.h:12
#define AR5K_REG_WRITE_Q(ah, _reg, _queue)
Definition: ath5k.h:121
#define AR5K_QCU_STS_FRMPENDCNT
Definition: reg.h:627
#define AR5K_CR_TXD0
Definition: reg.h:57
#define AR5K_QUIET_CTL2_QT_PER
Definition: reg.h:1687
void udelay(unsigned long usecs)
Delay for a fixed number of microseconds.
Definition: timer.c:60
#define AR5K_DIAG_SW_CHANEL_IDLE_HIGH
Definition: reg.h:1433
#define AR5K_QCU_TXD
Definition: reg.h:566
#define AR5K_CR
Definition: reg.h:53
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
#define AR5K_QUIET_CTL1_QT_EN
Definition: reg.h:1683
#define AR5K_REG_DISABLE_BITS(ah, _reg, _flags)
Definition: ath5k.h:107
#define AR5K_QUEUE_STATUS(_q)
Definition: reg.h:629
#define AR5K_DIAG_SW_5211
Definition: reg.h:1391
#define EIO
Input/output error.
Definition: errno.h:433
#define AR5K_QUIET_CTL2
Definition: reg.h:1686
uint8_t ah
Definition: registers.h:85
#define AR5K_QUIET_CTL1_NEXT_QT_TSF
Definition: reg.h:1681
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214
uint16_t queue
Queue ID.
Definition: ena.h:22
#define AR5K_TSF_L32_5211
Definition: reg.h:1440
uint32_t u32
Definition: stdint.h:23
#define AR5K_SREV_AR2414
Definition: ath5k.h:297
#define AR5K_CR_TXE0
Definition: reg.h:54
#define AR5K_REG_ENABLE_BITS(ah, _reg, _flags)
Definition: ath5k.h:104
#define AR5K_REG_SM(_val, _flags)
Definition: ath5k.h:84

References ah, AR5K_AR5210, AR5K_CR, AR5K_CR_TXD0, AR5K_CR_TXE0, AR5K_DIAG_SW_5211, AR5K_DIAG_SW_CHANEL_IDLE_HIGH, AR5K_QCU_STS_FRMPENDCNT, AR5K_QCU_TXD, AR5K_QUEUE_STATUS, AR5K_QUIET_CTL1, AR5K_QUIET_CTL1_NEXT_QT_TSF, AR5K_QUIET_CTL1_QT_EN, AR5K_QUIET_CTL2, AR5K_QUIET_CTL2_QT_DUR, AR5K_QUIET_CTL2_QT_PER, AR5K_REG_DISABLE_BITS, AR5K_REG_ENABLE_BITS, AR5K_REG_SM, AR5K_REG_WRITE_Q, AR5K_SREV_AR2414, AR5K_TSF_L32_5211, AR5K_TX_QUEUE_INACTIVE, ath5k_hw_reg_read(), ath5k_hw_reg_write(), EBUSY, EIO, pending, queue, and udelay().

Referenced by ath5k_txq_cleanup().

◆ ath5k_hw_get_txdp()

u32 ath5k_hw_get_txdp ( struct ath5k_hw ah,
unsigned int  queue 
)

ath5k_hw_get_txdp - Get TX Descriptor's address for a specific queue

@ah: The &struct ath5k_hw @queue: The hw queue number

Get TX descriptor's address for a specific queue. For 5210 we ignore the queue number and use tx queue type since we only have 2 queues. We use TXDP0 for normal data queue and TXDP1 for beacon queue. For newer chips with QCU/DCU we just read the corresponding TXDP register.

XXX: Is TXDP read and clear ?

Definition at line 261 of file ath5k_dma.c.

262 {
263  u16 tx_reg;
264 
265  /*
266  * Get the transmit queue descriptor pointer from the selected queue
267  */
268  /*5210 doesn't have QCU*/
269  if (ah->ah_version == AR5K_AR5210) {
270  /* Assume a data queue */
271  tx_reg = AR5K_NOQCU_TXDP0;
272  } else {
273  tx_reg = AR5K_QUEUE_TXDP(queue);
274  }
275 
276  return ath5k_hw_reg_read(ah, tx_reg);
277 }
uint16_t u16
Definition: stdint.h:21
#define AR5K_NOQCU_TXDP0
Definition: reg.h:47
uint8_t ah
Definition: registers.h:85
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214
#define AR5K_QUEUE_TXDP(_q)
Definition: reg.h:554
uint16_t queue
Queue ID.
Definition: ena.h:22

References ah, AR5K_AR5210, AR5K_NOQCU_TXDP0, AR5K_QUEUE_TXDP, ath5k_hw_reg_read(), and queue.

Referenced by ath5k_txq_cleanup().

◆ ath5k_hw_set_txdp()

int ath5k_hw_set_txdp ( struct ath5k_hw ah,
unsigned int  queue,
u32  phys_addr 
)

ath5k_hw_set_txdp - Set TX Descriptor's address for a specific queue

@ah: The &struct ath5k_hw @queue: The hw queue number

Set TX descriptor's address for a specific queue. For 5210 we ignore the queue number and we use tx queue type since we only have 2 queues so as above we use TXDP0 for normal data queue and TXDP1 for beacon queue. For newer chips with QCU/DCU we just set the corresponding TXDP register. Returns -EINVAL if queue type is invalid for 5210 and -EIO if queue is still active.

Definition at line 292 of file ath5k_dma.c.

293 {
294  u16 tx_reg;
295 
296  /*
297  * Set the transmit queue descriptor pointer register by type
298  * on 5210
299  */
300  if (ah->ah_version == AR5K_AR5210) {
301  /* Assume a data queue */
302  tx_reg = AR5K_NOQCU_TXDP0;
303  } else {
304  /*
305  * Set the transmit queue descriptor pointer for
306  * the selected queue on QCU for 5211+
307  * (this won't work if the queue is still active)
308  */
310  return -EIO;
311 
312  tx_reg = AR5K_QUEUE_TXDP(queue);
313  }
314 
315  /* Set descriptor pointer */
316  ath5k_hw_reg_write(ah, phys_addr, tx_reg);
317 
318  return 0;
319 }
uint16_t u16
Definition: stdint.h:21
#define AR5K_QCU_TXE
Definition: reg.h:559
#define AR5K_NOQCU_TXDP0
Definition: reg.h:47
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
#define AR5K_REG_READ_Q(ah, _reg, _queue)
Definition: ath5k.h:118
#define EIO
Input/output error.
Definition: errno.h:433
uint8_t ah
Definition: registers.h:85
#define AR5K_QUEUE_TXDP(_q)
Definition: reg.h:554
uint16_t queue
Queue ID.
Definition: ena.h:22

References ah, AR5K_AR5210, AR5K_NOQCU_TXDP0, AR5K_QCU_TXE, AR5K_QUEUE_TXDP, AR5K_REG_READ_Q, ath5k_hw_reg_write(), EIO, and queue.

Referenced by ath5k_txbuf_setup().

◆ ath5k_hw_update_tx_triglevel()

int ath5k_hw_update_tx_triglevel ( struct ath5k_hw ah,
int  increase 
)

ath5k_hw_update_tx_triglevel - Update tx trigger level

@ah: The &struct ath5k_hw @increase: Flag to force increase of trigger level

This function increases/decreases the tx trigger level for the tx fifo buffer (aka FIFO threshold) that is used to indicate when PCU flushes the buffer and transmits it's data. Lowering this results sending small frames more quickly but can lead to tx underruns, raising it a lot can result other problems (i think bmiss is related). Right now we start with the lowest possible (64Bytes) and if we get tx underrun we increase it using the increase flag. Returns -EIO if we have have reached maximum/minimum.

XXX: Link this with tx DMA size ? XXX: Use it to save interrupts ? TODO: Needs testing, i think it's related to bmiss...

Definition at line 339 of file ath5k_dma.c.

340 {
341  u32 trigger_level, imr;
342  int ret = -EIO;
343 
344  /*
345  * Disable interrupts by setting the mask
346  */
347  imr = ath5k_hw_set_imr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL);
348 
349  trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG),
351 
352  if (!increase) {
353  if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
354  goto done;
355  } else
356  trigger_level +=
357  ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
358 
359  /*
360  * Update trigger level on success
361  */
362  if (ah->ah_version == AR5K_AR5210)
363  ath5k_hw_reg_write(ah, trigger_level, AR5K_TRIG_LVL);
364  else
366  AR5K_TXCFG_TXFULL, trigger_level);
367 
368  ret = 0;
369 
370 done:
371  /*
372  * Restore interrupt mask
373  */
375 
376  return ret;
377 }
Definition: sis900.h:27
#define AR5K_REG_MS(_val, _flags)
Definition: ath5k.h:88
#define AR5K_TXCFG
Definition: reg.h:169
#define AR5K_REG_WRITE_BITS(ah, _reg, _flags, _val)
Definition: ath5k.h:96
#define AR5K_TUNE_MIN_TX_FIFO_THRES
Definition: ath5k.h:167
#define AR5K_TRIG_LVL
Definition: reg.h:1381
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
#define AR5K_TXCFG_TXFULL
Definition: reg.h:174
#define EIO
Input/output error.
Definition: errno.h:433
uint8_t ah
Definition: registers.h:85
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214
#define AR5K_TUNE_MAX_TX_FIFO_THRES
Definition: ath5k.h:168
enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
ath5k_hw_set_imr - Set interrupt mask
Definition: ath5k_dma.c:548
struct bofm_section_header done
Definition: bofm_test.c:46
uint32_t u32
Definition: stdint.h:23

References ah, AR5K_AR5210, AR5K_INT_GLOBAL, AR5K_REG_MS, AR5K_REG_WRITE_BITS, AR5K_TRIG_LVL, AR5K_TUNE_MAX_TX_FIFO_THRES, AR5K_TUNE_MIN_TX_FIFO_THRES, AR5K_TXCFG, AR5K_TXCFG_TXFULL, ath5k_hw_reg_read(), ath5k_hw_reg_write(), ath5k_hw_set_imr(), done, EIO, and imr.

Referenced by ath5k_poll().

◆ ath5k_hw_is_intr_pending()

int ath5k_hw_is_intr_pending ( struct ath5k_hw ah)

ath5k_hw_is_intr_pending - Check if we have pending interrupts

@ah: The &struct ath5k_hw

Check if we have pending interrupts to process. Returns 1 if we have pending interrupts and 0 if we haven't.

Definition at line 391 of file ath5k_dma.c.

392 {
393  return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0;
394 }
#define AR5K_INTPEND
Definition: reg.h:867
uint8_t ah
Definition: registers.h:85
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214

References ah, AR5K_INTPEND, and ath5k_hw_reg_read().

Referenced by ath5k_poll().

◆ ath5k_hw_get_isr()

int ath5k_hw_get_isr ( struct ath5k_hw ah,
enum ath5k_int interrupt_mask 
)

Definition at line 412 of file ath5k_dma.c.

413 {
414  u32 data;
415 
416  /*
417  * Read interrupt status from the Interrupt Status register
418  * on 5210
419  */
420  if (ah->ah_version == AR5K_AR5210) {
422  if (data == AR5K_INT_NOCARD) {
423  *interrupt_mask = data;
424  return -ENODEV;
425  }
426  } else {
427  /*
428  * Read interrupt status from Interrupt
429  * Status Register shadow copy (Read And Clear)
430  *
431  * Note: PISR/SISR Not available on 5210
432  */
434  if (data == AR5K_INT_NOCARD) {
435  *interrupt_mask = data;
436  return -ENODEV;
437  }
438  }
439 
440  /*
441  * Get abstract interrupt mask (driver-compatible)
442  */
443  *interrupt_mask = (data & AR5K_INT_COMMON) & ah->ah_imr;
444 
445  if (ah->ah_version != AR5K_AR5210) {
447 
448  /*HIU = Host Interface Unit (PCI etc)*/
449  if (data & (AR5K_ISR_HIUERR))
450  *interrupt_mask |= AR5K_INT_FATAL;
451 
452  /*Beacon Not Ready*/
453  if (data & (AR5K_ISR_BNR))
454  *interrupt_mask |= AR5K_INT_BNR;
455 
456  if (sisr2 & (AR5K_SISR2_SSERR | AR5K_SISR2_DPERR |
458  *interrupt_mask |= AR5K_INT_FATAL;
459 
460  if (data & AR5K_ISR_TIM)
461  *interrupt_mask |= AR5K_INT_TIM;
462 
463  if (data & AR5K_ISR_BCNMISC) {
464  if (sisr2 & AR5K_SISR2_TIM)
465  *interrupt_mask |= AR5K_INT_TIM;
466  if (sisr2 & AR5K_SISR2_DTIM)
467  *interrupt_mask |= AR5K_INT_DTIM;
468  if (sisr2 & AR5K_SISR2_DTIM_SYNC)
469  *interrupt_mask |= AR5K_INT_DTIM_SYNC;
470  if (sisr2 & AR5K_SISR2_BCN_TIMEOUT)
471  *interrupt_mask |= AR5K_INT_BCN_TIMEOUT;
472  if (sisr2 & AR5K_SISR2_CAB_TIMEOUT)
473  *interrupt_mask |= AR5K_INT_CAB_TIMEOUT;
474  }
475 
476  if (data & AR5K_ISR_RXDOPPLER)
477  *interrupt_mask |= AR5K_INT_RX_DOPPLER;
478  if (data & AR5K_ISR_QCBRORN) {
479  *interrupt_mask |= AR5K_INT_QCBRORN;
480  ah->ah_txq_isr |= AR5K_REG_MS(
483  }
484  if (data & AR5K_ISR_QCBRURN) {
485  *interrupt_mask |= AR5K_INT_QCBRURN;
486  ah->ah_txq_isr |= AR5K_REG_MS(
489  }
490  if (data & AR5K_ISR_QTRIG) {
491  *interrupt_mask |= AR5K_INT_QTRIG;
492  ah->ah_txq_isr |= AR5K_REG_MS(
495  }
496 
497  if (data & AR5K_ISR_TXOK)
498  ah->ah_txq_isr |= AR5K_REG_MS(
501 
502  if (data & AR5K_ISR_TXDESC)
503  ah->ah_txq_isr |= AR5K_REG_MS(
506 
507  if (data & AR5K_ISR_TXERR)
508  ah->ah_txq_isr |= AR5K_REG_MS(
511 
512  if (data & AR5K_ISR_TXEOL)
513  ah->ah_txq_isr |= AR5K_REG_MS(
516 
517  if (data & AR5K_ISR_TXURN)
518  ah->ah_txq_isr |= AR5K_REG_MS(
521  } else {
524  *interrupt_mask |= AR5K_INT_FATAL;
525 
526  /*
527  * XXX: BMISS interrupts may occur after association.
528  * I found this on 5210 code but it needs testing. If this is
529  * true we should disable them before assoc and re-enable them
530  * after a successful assoc + some jiffies.
531  interrupt_mask &= ~AR5K_INT_BMISS;
532  */
533  }
534 
535  return 0;
536 }
#define AR5K_SISR2_TIM
Definition: reg.h:345
#define AR5K_ISR_QCBRURN
Definition: reg.h:318
#define AR5K_RAC_SISR3
Definition: reg.h:370
#define AR5K_ISR_HIUERR
Definition: reg.h:306
#define AR5K_SISR2_CAB_TIMEOUT
Definition: reg.h:349
#define AR5K_SISR2_DPERR
Definition: reg.h:344
#define AR5K_ISR_MCABT
Definition: reg.h:308
#define AR5K_ISR_TIM
Definition: reg.h:313
#define AR5K_REG_MS(_val, _flags)
Definition: ath5k.h:88
#define AR5K_RAC_PISR
Definition: reg.h:366
#define AR5K_ISR_TXDESC
Definition: reg.h:294
#define AR5K_SISR3_QCBRURN
Definition: reg.h:356
#define AR5K_SISR1_QCU_TXEOL
Definition: reg.h:336
#define AR5K_ISR_RXDOPPLER
Definition: reg.h:312
#define AR5K_SISR2_DTIM_SYNC
Definition: reg.h:347
#define AR5K_SISR1_QCU_TXERR
Definition: reg.h:334
#define AR5K_ISR_QTRIG
Definition: reg.h:319
#define AR5K_RAC_SISR4
Definition: reg.h:371
#define AR5K_ISR_TXEOL
Definition: reg.h:297
#define AR5K_ISR_QCBRORN
Definition: reg.h:317
#define AR5K_ISR_SSERR
Definition: reg.h:310
#define AR5K_ISR_BCNMISC
Definition: reg.h:314
#define ENODEV
No such device.
Definition: errno.h:509
#define AR5K_ISR_TXURN
Definition: reg.h:298
#define AR5K_ISR_TXOK
Definition: reg.h:293
#define AR5K_ISR
Definition: reg.h:285
#define AR5K_RAC_SISR1
Definition: reg.h:368
#define AR5K_SISR2_QCU_TXURN
Definition: reg.h:340
#define AR5K_ISR_TXERR
Definition: reg.h:295
#define AR5K_ISR_DPERR
Definition: reg.h:311
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define AR5K_SISR4_QTRIG
Definition: reg.h:360
uint8_t ah
Definition: registers.h:85
#define AR5K_SISR2_BCN_TIMEOUT
Definition: reg.h:348
#define AR5K_SISR0_QCU_TXDESC
Definition: reg.h:330
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214
#define AR5K_RAC_SISR0
Definition: reg.h:367
#define AR5K_SISR3_QCBRORN
Definition: reg.h:354
#define AR5K_SISR2_SSERR
Definition: reg.h:343
#define AR5K_ISR_BNR
Definition: reg.h:307
#define AR5K_SISR2_DTIM
Definition: reg.h:350
#define AR5K_SISR0_QCU_TXOK
Definition: reg.h:328
uint32_t u32
Definition: stdint.h:23
#define AR5K_SISR2_MCABT
Definition: reg.h:342
if(natsemi->flags &NATSEMI_64BIT) return 1
#define AR5K_RAC_SISR2
Definition: reg.h:369

References ah, AR5K_AR5210, AR5K_INT_BCN_TIMEOUT, AR5K_INT_BNR, AR5K_INT_CAB_TIMEOUT, AR5K_INT_COMMON, AR5K_INT_DTIM, AR5K_INT_DTIM_SYNC, AR5K_INT_FATAL, AR5K_INT_NOCARD, AR5K_INT_QCBRORN, AR5K_INT_QCBRURN, AR5K_INT_QTRIG, AR5K_INT_RX_DOPPLER, AR5K_INT_TIM, AR5K_ISR, AR5K_ISR_BCNMISC, AR5K_ISR_BNR, AR5K_ISR_DPERR, AR5K_ISR_HIUERR, AR5K_ISR_MCABT, AR5K_ISR_QCBRORN, AR5K_ISR_QCBRURN, AR5K_ISR_QTRIG, AR5K_ISR_RXDOPPLER, AR5K_ISR_SSERR, AR5K_ISR_TIM, AR5K_ISR_TXDESC, AR5K_ISR_TXEOL, AR5K_ISR_TXERR, AR5K_ISR_TXOK, AR5K_ISR_TXURN, AR5K_RAC_PISR, AR5K_RAC_SISR0, AR5K_RAC_SISR1, AR5K_RAC_SISR2, AR5K_RAC_SISR3, AR5K_RAC_SISR4, AR5K_REG_MS, AR5K_SISR0_QCU_TXDESC, AR5K_SISR0_QCU_TXOK, AR5K_SISR1_QCU_TXEOL, AR5K_SISR1_QCU_TXERR, AR5K_SISR2_BCN_TIMEOUT, AR5K_SISR2_CAB_TIMEOUT, AR5K_SISR2_DPERR, AR5K_SISR2_DTIM, AR5K_SISR2_DTIM_SYNC, AR5K_SISR2_MCABT, AR5K_SISR2_QCU_TXURN, AR5K_SISR2_SSERR, AR5K_SISR2_TIM, AR5K_SISR3_QCBRORN, AR5K_SISR3_QCBRURN, AR5K_SISR4_QTRIG, ath5k_hw_reg_read(), data, ENODEV, and if().

Referenced by ath5k_poll().

◆ ath5k_hw_set_imr()

enum ath5k_int ath5k_hw_set_imr ( struct ath5k_hw ah,
enum ath5k_int  new_mask 
)

ath5k_hw_set_imr - Set interrupt mask

@ah: The &struct ath5k_hw @new_mask: The new interrupt mask to be set

Set the interrupt mask in hw to save interrupts. We do that by mapping ath5k_int bits to hw-specific bits to remove abstraction and writing Interrupt Mask Register.

Definition at line 548 of file ath5k_dma.c.

549 {
550  enum ath5k_int old_mask, int_mask;
551 
552  old_mask = ah->ah_imr;
553 
554  /*
555  * Disable card interrupts to prevent any race conditions
556  * (they will be re-enabled afterwards if AR5K_INT GLOBAL
557  * is set again on the new mask).
558  */
559  if (old_mask & AR5K_INT_GLOBAL) {
562  }
563 
564  /*
565  * Add additional, chipset-dependent interrupt mask flags
566  * and write them to the IMR (interrupt mask register).
567  */
568  int_mask = new_mask & AR5K_INT_COMMON;
569 
570  if (ah->ah_version != AR5K_AR5210) {
571  /* Preserve per queue TXURN interrupt mask */
574 
575  if (new_mask & AR5K_INT_FATAL) {
576  int_mask |= AR5K_IMR_HIUERR;
578  | AR5K_SIMR2_DPERR);
579  }
580 
581  /*Beacon Not Ready*/
582  if (new_mask & AR5K_INT_BNR)
583  int_mask |= AR5K_INT_BNR;
584 
585  if (new_mask & AR5K_INT_TIM)
586  int_mask |= AR5K_IMR_TIM;
587 
588  if (new_mask & AR5K_INT_TIM)
589  simr2 |= AR5K_SISR2_TIM;
590  if (new_mask & AR5K_INT_DTIM)
591  simr2 |= AR5K_SISR2_DTIM;
592  if (new_mask & AR5K_INT_DTIM_SYNC)
593  simr2 |= AR5K_SISR2_DTIM_SYNC;
594  if (new_mask & AR5K_INT_BCN_TIMEOUT)
595  simr2 |= AR5K_SISR2_BCN_TIMEOUT;
596  if (new_mask & AR5K_INT_CAB_TIMEOUT)
597  simr2 |= AR5K_SISR2_CAB_TIMEOUT;
598 
599  if (new_mask & AR5K_INT_RX_DOPPLER)
600  int_mask |= AR5K_IMR_RXDOPPLER;
601 
602  /* Note: Per queue interrupt masks
603  * are set via reset_tx_queue (qcu.c) */
604  ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR);
606 
607  } else {
608  if (new_mask & AR5K_INT_FATAL)
609  int_mask |= (AR5K_IMR_SSERR | AR5K_IMR_MCABT
611 
612  ath5k_hw_reg_write(ah, int_mask, AR5K_IMR);
613  }
614 
615  /* If RXNOFRM interrupt is masked disable it
616  * by setting AR5K_RXNOFRM to zero */
617  if (!(new_mask & AR5K_INT_RXNOFRM))
619 
620  /* Store new interrupt mask */
621  ah->ah_imr = new_mask;
622 
623  /* ..re-enable interrupts if AR5K_INT_GLOBAL is set */
624  if (new_mask & AR5K_INT_GLOBAL) {
625  ath5k_hw_reg_write(ah, ah->ah_ier, AR5K_IER);
627  }
628 
629  return old_mask;
630 }
#define AR5K_SISR2_TIM
Definition: reg.h:345
#define AR5K_SIMR2_MCABT
Definition: reg.h:433
#define AR5K_SISR2_CAB_TIMEOUT
Definition: reg.h:349
#define AR5K_IMR_SSERR
Definition: reg.h:404
#define AR5K_IMR_MCABT
Definition: reg.h:402
#define AR5K_IMR_TIM
Definition: reg.h:407
#define AR5K_SISR2_DTIM_SYNC
Definition: reg.h:347
#define AR5K_PIMR
Definition: reg.h:380
#define AR5K_SIMR2
Definition: reg.h:430
static void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
Definition: ath5k.h:1222
#define AR5K_SIMR2_SSERR
Definition: reg.h:434
#define AR5K_IMR_RXDOPPLER
Definition: reg.h:406
#define AR5K_IER_DISABLE
Definition: reg.h:91
#define AR5K_RXNOFRM
Definition: reg.h:229
#define AR5K_IMR
Definition: reg.h:379
uint8_t ah
Definition: registers.h:85
#define AR5K_IER
Definition: reg.h:90
#define AR5K_SISR2_BCN_TIMEOUT
Definition: reg.h:348
static u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
Definition: ath5k.h:1214
#define AR5K_IMR_HIUERR
Definition: reg.h:400
#define AR5K_IMR_DPERR
Definition: reg.h:405
#define AR5K_SISR2_DTIM
Definition: reg.h:350
#define AR5K_SIMR2_DPERR
Definition: reg.h:435
#define AR5K_SIMR2_QCU_TXURN
Definition: reg.h:431
ath5k_int
enum ath5k_int - Hardware interrupt masks helpers
Definition: ath5k.h:804
uint32_t u32
Definition: stdint.h:23

References ah, AR5K_AR5210, AR5K_IER, AR5K_IER_DISABLE, AR5K_IMR, AR5K_IMR_DPERR, AR5K_IMR_HIUERR, AR5K_IMR_MCABT, AR5K_IMR_RXDOPPLER, AR5K_IMR_SSERR, AR5K_IMR_TIM, AR5K_INT_BCN_TIMEOUT, AR5K_INT_BNR, AR5K_INT_CAB_TIMEOUT, AR5K_INT_COMMON, AR5K_INT_DTIM, AR5K_INT_DTIM_SYNC, AR5K_INT_FATAL, AR5K_INT_GLOBAL, AR5K_INT_RX_DOPPLER, AR5K_INT_RXNOFRM, AR5K_INT_TIM, AR5K_PIMR, AR5K_RXNOFRM, AR5K_SIMR2, AR5K_SIMR2_DPERR, AR5K_SIMR2_MCABT, AR5K_SIMR2_QCU_TXURN, AR5K_SIMR2_SSERR, AR5K_SISR2_BCN_TIMEOUT, AR5K_SISR2_CAB_TIMEOUT, AR5K_SISR2_DTIM, AR5K_SISR2_DTIM_SYNC, AR5K_SISR2_TIM, ath5k_hw_reg_read(), and ath5k_hw_reg_write().

Referenced by ath5k_hw_reset(), ath5k_hw_update_tx_triglevel(), ath5k_irq(), ath5k_reset(), and ath5k_stop_hw().