Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d41174fa authored by Nick Kossifidis's avatar Nick Kossifidis Committed by John W. Linville
Browse files

ath5k: Add new function to stop rx/tx DMA



 * Add a new function to stop rx/tx dma and use in when reset starts

 Signed-off-by: default avatarNick Kossifidis <mickflemm@gmail.com>

Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 9320b5c4
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1180,8 +1180,9 @@ bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
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);
void ath5k_hw_update_mib_counters(struct ath5k_hw *ah);
/* Init function */
/* Init/Stop functions */
void ath5k_hw_dma_init(struct ath5k_hw *ah);
int ath5k_hw_dma_stop(struct ath5k_hw *ah);

/* EEPROM access functions */
int ath5k_eeprom_init(struct ath5k_hw *ah);
+49 −3
Original line number Diff line number Diff line
@@ -126,7 +126,7 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)

	/* Return if queue is declared inactive */
	if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
		return -EIO;
		return -EINVAL;

	if (ah->ah_version == AR5K_AR5210) {
		tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
@@ -174,7 +174,7 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
 *
 * 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.
 * -EINVAL if queue number is out of range or inactive.
 *
 */
int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
@@ -186,7 +186,7 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)

	/* Return if queue is declared inactive */
	if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
		return -EIO;
		return -EINVAL;

	if (ah->ah_version == AR5K_AR5210) {
		tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
@@ -733,3 +733,49 @@ void ath5k_hw_dma_init(struct ath5k_hw *ah)
		ath5k_hw_set_imr(ah, ah->ah_imr);

}

/**
 * ath5k_hw_dma_stop - stop DMA unit
 *
 * @ah: The &struct ath5k_hw
 *
 * Stop tx/rx DMA and interrupts. Returns
 * -EBUSY if tx or rx dma failed to stop.
 *
 * XXX: Sometimes DMA unit hangs and we have
 * stuck frames on tx queues, only a reset
 * can fix that.
 */
int ath5k_hw_dma_stop(struct ath5k_hw *ah)
{
	int i, qmax, err;
	err = 0;

	/* Disable interrupts */
	ath5k_hw_set_imr(ah, 0);

	/* Stop rx dma */
	err = ath5k_hw_stop_rx_dma(ah);
	if (err)
		return err;

	/* Clear any pending interrupts
	 * and disable tx dma */
	if (ah->ah_version != AR5K_AR5210) {
		ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
		qmax = AR5K_NUM_TX_QUEUES;
	} else {
		/* PISR/SISR Not available on 5210 */
		ath5k_hw_reg_read(ah, AR5K_ISR);
		qmax = AR5K_NUM_TX_QUEUES_NOQCU;
	}

	for (i = 0; i < qmax; i++) {
		err = ath5k_hw_stop_tx_dma(ah, i);
		/* -EINVAL -> queue inactive */
		if (err != -EINVAL)
			return err;
	}

	return err;
}
+8 −5
Original line number Diff line number Diff line
@@ -822,6 +822,14 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
	freq = 0;
	mode = 0;

	/*
	 * Stop DMA
	 *
	 * Note: If DMA didn't stop continue
	 * since only a reset will fix it.
	 */
	ath5k_hw_dma_stop(ah);

	/*
	 * Save some registers before a reset
	 */
@@ -1015,11 +1023,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
	 */
	ath5k_hw_pcu_init(ah, op_mode, mode);

	/* Clear any pending interrupts
	 * PISR/SISR Not available on 5210 */
	if (ah->ah_version != AR5K_AR5210)
		ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);

	/*
	 * Initialize PHY
	 */