diff options
author | Rajkumar Manoharan <rmanohar@qca.qualcomm.com> | 2012-06-11 02:49:32 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-06-13 14:35:53 -0400 |
commit | 3863495b86d8ee8e7e70a328de5b88d555d7305a (patch) | |
tree | 1d74ca3fbb7774bed9cee07c4162b1ef2e52459b | |
parent | 9dd9b0dc1de8031a31b3eaebc6a9c0ab60612026 (diff) |
ath9k_hw: check GPM HW write pointer before chip reset
Both "MAC Warm Reset" and "MCI Reset Rx" will reset GPM HW write_ptr.
We should check software cached write_ptr against HW write_ptr before
reset. Otherwise the pending DMA data will be lost.
Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_mci.c | 18 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_mci.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 3 |
3 files changed, 22 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 13907f63bdc0..cbeff9c4b5d8 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c | |||
@@ -893,6 +893,9 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, | |||
893 | udelay(100); | 893 | udelay(100); |
894 | } | 894 | } |
895 | 895 | ||
896 | /* Check pending GPM msg before MCI Reset Rx */ | ||
897 | ar9003_mci_state(ah, MCI_STATE_CHECK_GPM_OFFSET, NULL); | ||
898 | |||
896 | regval |= SM(1, AR_MCI_COMMAND2_RESET_RX); | 899 | regval |= SM(1, AR_MCI_COMMAND2_RESET_RX); |
897 | REG_WRITE(ah, AR_MCI_COMMAND2, regval); | 900 | REG_WRITE(ah, AR_MCI_COMMAND2, regval); |
898 | udelay(1); | 901 | udelay(1); |
@@ -1190,6 +1193,21 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type, u32 *p_data) | |||
1190 | value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); | 1193 | value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); |
1191 | mci->gpm_idx = value; | 1194 | mci->gpm_idx = value; |
1192 | break; | 1195 | break; |
1196 | case MCI_STATE_CHECK_GPM_OFFSET: | ||
1197 | /* | ||
1198 | * This should only be called before "MAC Warm Reset" or | ||
1199 | * "MCI Reset Rx". | ||
1200 | */ | ||
1201 | value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); | ||
1202 | if (mci->gpm_idx == value) | ||
1203 | break; | ||
1204 | ath_dbg(common, MCI, | ||
1205 | "GPM cached write pointer mismatch %d %d\n", | ||
1206 | mci->gpm_idx, value); | ||
1207 | mci->query_bt = true; | ||
1208 | mci->need_flush_btinfo = true; | ||
1209 | mci->gpm_idx = 0; | ||
1210 | break; | ||
1193 | case MCI_STATE_NEXT_GPM_OFFSET: | 1211 | case MCI_STATE_NEXT_GPM_OFFSET: |
1194 | case MCI_STATE_LAST_GPM_OFFSET: | 1212 | case MCI_STATE_LAST_GPM_OFFSET: |
1195 | /* | 1213 | /* |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index 2a8c764281ba..45624e1d3960 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h | |||
@@ -190,6 +190,7 @@ enum mci_bt_state { | |||
190 | enum mci_state_type { | 190 | enum mci_state_type { |
191 | MCI_STATE_ENABLE, | 191 | MCI_STATE_ENABLE, |
192 | MCI_STATE_INIT_GPM_OFFSET, | 192 | MCI_STATE_INIT_GPM_OFFSET, |
193 | MCI_STATE_CHECK_GPM_OFFSET, | ||
193 | MCI_STATE_NEXT_GPM_OFFSET, | 194 | MCI_STATE_NEXT_GPM_OFFSET, |
194 | MCI_STATE_LAST_GPM_OFFSET, | 195 | MCI_STATE_LAST_GPM_OFFSET, |
195 | MCI_STATE_BT, | 196 | MCI_STATE_BT, |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 6d893335f42b..8412128b842a 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -1348,6 +1348,9 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | |||
1348 | } | 1348 | } |
1349 | } | 1349 | } |
1350 | 1350 | ||
1351 | if (ath9k_hw_mci_is_enabled(ah)) | ||
1352 | ar9003_mci_state(ah, MCI_STATE_CHECK_GPM_OFFSET, NULL); | ||
1353 | |||
1351 | REG_WRITE(ah, AR_RTC_RC, rst_flags); | 1354 | REG_WRITE(ah, AR_RTC_RC, rst_flags); |
1352 | 1355 | ||
1353 | REGWRITE_BUFFER_FLUSH(ah); | 1356 | REGWRITE_BUFFER_FLUSH(ah); |