1b7d5e03cSMatthew Dillon /*
2b7d5e03cSMatthew Dillon  * Copyright (c) 2013 Qualcomm Atheros, Inc.
3b7d5e03cSMatthew Dillon  *
4b7d5e03cSMatthew Dillon  * Permission to use, copy, modify, and/or distribute this software for any
5b7d5e03cSMatthew Dillon  * purpose with or without fee is hereby granted, provided that the above
6b7d5e03cSMatthew Dillon  * copyright notice and this permission notice appear in all copies.
7b7d5e03cSMatthew Dillon  *
8b7d5e03cSMatthew Dillon  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9b7d5e03cSMatthew Dillon  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10b7d5e03cSMatthew Dillon  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11b7d5e03cSMatthew Dillon  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12b7d5e03cSMatthew Dillon  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13b7d5e03cSMatthew Dillon  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14b7d5e03cSMatthew Dillon  * PERFORMANCE OF THIS SOFTWARE.
15b7d5e03cSMatthew Dillon  */
16b7d5e03cSMatthew Dillon 
17b7d5e03cSMatthew Dillon #include "opt_ah.h"
18b7d5e03cSMatthew Dillon 
19b7d5e03cSMatthew Dillon #include "ah.h"
20b7d5e03cSMatthew Dillon #include "ah_desc.h"
21b7d5e03cSMatthew Dillon #include "ah_internal.h"
22b7d5e03cSMatthew Dillon 
23b7d5e03cSMatthew Dillon #include "ar9300/ar9300.h"
24b7d5e03cSMatthew Dillon #include "ar9300/ar9300reg.h"
25b7d5e03cSMatthew Dillon #include "ar9300/ar9300desc.h"
26b7d5e03cSMatthew Dillon 
27b7d5e03cSMatthew Dillon /*
28b7d5e03cSMatthew Dillon  * Get the RXDP.
29b7d5e03cSMatthew Dillon  */
30b7d5e03cSMatthew Dillon u_int32_t
ar9300_get_rx_dp(struct ath_hal * ath,HAL_RX_QUEUE qtype)31b7d5e03cSMatthew Dillon ar9300_get_rx_dp(struct ath_hal *ath, HAL_RX_QUEUE qtype)
32b7d5e03cSMatthew Dillon {
33b7d5e03cSMatthew Dillon     if (qtype == HAL_RX_QUEUE_HP) {
34b7d5e03cSMatthew Dillon         return OS_REG_READ(ath, AR_HP_RXDP);
35b7d5e03cSMatthew Dillon     } else {
36b7d5e03cSMatthew Dillon         return OS_REG_READ(ath, AR_LP_RXDP);
37b7d5e03cSMatthew Dillon     }
38b7d5e03cSMatthew Dillon }
39b7d5e03cSMatthew Dillon 
40b7d5e03cSMatthew Dillon /*
41b7d5e03cSMatthew Dillon  * Set the rx_dp.
42b7d5e03cSMatthew Dillon  */
43b7d5e03cSMatthew Dillon void
ar9300_set_rx_dp(struct ath_hal * ah,u_int32_t rxdp,HAL_RX_QUEUE qtype)44b7d5e03cSMatthew Dillon ar9300_set_rx_dp(struct ath_hal *ah, u_int32_t rxdp, HAL_RX_QUEUE qtype)
45b7d5e03cSMatthew Dillon {
46b7d5e03cSMatthew Dillon     HALASSERT((qtype == HAL_RX_QUEUE_HP) || (qtype == HAL_RX_QUEUE_LP));
47b7d5e03cSMatthew Dillon 
48b7d5e03cSMatthew Dillon     if (qtype == HAL_RX_QUEUE_HP) {
49b7d5e03cSMatthew Dillon         OS_REG_WRITE(ah, AR_HP_RXDP, rxdp);
50b7d5e03cSMatthew Dillon     } else {
51b7d5e03cSMatthew Dillon         OS_REG_WRITE(ah, AR_LP_RXDP, rxdp);
52b7d5e03cSMatthew Dillon     }
53b7d5e03cSMatthew Dillon }
54b7d5e03cSMatthew Dillon 
55b7d5e03cSMatthew Dillon /*
56b7d5e03cSMatthew Dillon  * Set Receive Enable bits.
57b7d5e03cSMatthew Dillon  */
58b7d5e03cSMatthew Dillon void
ar9300_enable_receive(struct ath_hal * ah)59b7d5e03cSMatthew Dillon ar9300_enable_receive(struct ath_hal *ah)
60b7d5e03cSMatthew Dillon {
61b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_CR, 0);
62b7d5e03cSMatthew Dillon }
63b7d5e03cSMatthew Dillon 
64b7d5e03cSMatthew Dillon /*
65b7d5e03cSMatthew Dillon  * Set the RX abort bit.
66b7d5e03cSMatthew Dillon  */
67b7d5e03cSMatthew Dillon HAL_BOOL
ar9300_set_rx_abort(struct ath_hal * ah,HAL_BOOL set)68b7d5e03cSMatthew Dillon ar9300_set_rx_abort(struct ath_hal *ah, HAL_BOOL set)
69b7d5e03cSMatthew Dillon {
70b7d5e03cSMatthew Dillon     if (set) {
71b7d5e03cSMatthew Dillon         /* Set the force_rx_abort bit */
72b7d5e03cSMatthew Dillon         OS_REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
73b7d5e03cSMatthew Dillon 
74b7d5e03cSMatthew Dillon         if ( AH9300(ah)->ah_reset_reason == HAL_RESET_BBPANIC ){
75b7d5e03cSMatthew Dillon             /* depending upon the BB panic status, rx state may not return to 0,
76b7d5e03cSMatthew Dillon              * so skipping the wait for BB panic reset */
77b7d5e03cSMatthew Dillon             OS_REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
78b7d5e03cSMatthew Dillon             return AH_FALSE;
79b7d5e03cSMatthew Dillon         } else {
80b7d5e03cSMatthew Dillon             HAL_BOOL okay;
81b7d5e03cSMatthew Dillon             okay = ath_hal_wait(
82b7d5e03cSMatthew Dillon                 ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0);
83b7d5e03cSMatthew Dillon             /* Wait for Rx state to return to 0 */
84b7d5e03cSMatthew Dillon             if (!okay) {
85b7d5e03cSMatthew Dillon                 /* abort: chip rx failed to go idle in 10 ms */
86b7d5e03cSMatthew Dillon                 OS_REG_CLR_BIT(ah, AR_DIAG_SW,
87b7d5e03cSMatthew Dillon                     (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
88b7d5e03cSMatthew Dillon 
89b7d5e03cSMatthew Dillon                 HALDEBUG(ah, HAL_DEBUG_RX,
90b7d5e03cSMatthew Dillon                     "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
91b7d5e03cSMatthew Dillon                     __func__, OS_REG_READ(ah, AR_OBS_BUS_1));
92b7d5e03cSMatthew Dillon 
93b7d5e03cSMatthew Dillon                 return AH_FALSE; /* failure */
94b7d5e03cSMatthew Dillon             }
95b7d5e03cSMatthew Dillon         }
96b7d5e03cSMatthew Dillon     } else {
97b7d5e03cSMatthew Dillon         OS_REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
98b7d5e03cSMatthew Dillon     }
99b7d5e03cSMatthew Dillon 
100b7d5e03cSMatthew Dillon     return AH_TRUE; /* success */
101b7d5e03cSMatthew Dillon }
102b7d5e03cSMatthew Dillon 
103b7d5e03cSMatthew Dillon /*
104b7d5e03cSMatthew Dillon  * Stop Receive at the DMA engine
105b7d5e03cSMatthew Dillon  */
106b7d5e03cSMatthew Dillon HAL_BOOL
ar9300_stop_dma_receive(struct ath_hal * ah,u_int timeout)107b7d5e03cSMatthew Dillon ar9300_stop_dma_receive(struct ath_hal *ah, u_int timeout)
108b7d5e03cSMatthew Dillon {
109b7d5e03cSMatthew Dillon     int wait;
110b7d5e03cSMatthew Dillon     HAL_BOOL status, okay;
111b7d5e03cSMatthew Dillon     u_int32_t org_value;
112b7d5e03cSMatthew Dillon 
113b7d5e03cSMatthew Dillon #define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
114b7d5e03cSMatthew Dillon #define AH_TIME_QUANTUM        100     /* usec */
115b7d5e03cSMatthew Dillon 
1164b8649cbSMatthew Dillon     OS_MARK(ah, AH_MARK_RX_CTL, AH_MARK_RX_CTL_DMA_STOP);
1174b8649cbSMatthew Dillon 
118b7d5e03cSMatthew Dillon     if (timeout == 0) {
119b7d5e03cSMatthew Dillon         timeout = AH_RX_STOP_DMA_TIMEOUT;
120b7d5e03cSMatthew Dillon     }
121b7d5e03cSMatthew Dillon 
122b7d5e03cSMatthew Dillon     org_value = OS_REG_READ(ah, AR_MACMISC);
123b7d5e03cSMatthew Dillon 
124b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_MACMISC,
125b7d5e03cSMatthew Dillon         ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
126b7d5e03cSMatthew Dillon          (AR_MACMISC_MISC_OBS_BUS_1 << AR_MACMISC_MISC_OBS_BUS_MSB_S)));
127b7d5e03cSMatthew Dillon 
128b7d5e03cSMatthew Dillon         okay = ath_hal_wait(
129b7d5e03cSMatthew Dillon             ah, AR_DMADBG_7, AR_DMADBG_RX_STATE, 0);
130b7d5e03cSMatthew Dillon     /* wait for Rx DMA state machine to become idle */
131b7d5e03cSMatthew Dillon         if (!okay) {
132b7d5e03cSMatthew Dillon             HALDEBUG(ah, HAL_DEBUG_RX,
133b7d5e03cSMatthew Dillon                 "reg AR_DMADBG_7 is not 0, instead 0x%08x\n",
134b7d5e03cSMatthew Dillon                 OS_REG_READ(ah, AR_DMADBG_7));
135b7d5e03cSMatthew Dillon         }
136b7d5e03cSMatthew Dillon 
137b7d5e03cSMatthew Dillon     /* Set receive disable bit */
138b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_CR, AR_CR_RXD);
139b7d5e03cSMatthew Dillon 
140b7d5e03cSMatthew Dillon     /* Wait for rx enable bit to go low */
141b7d5e03cSMatthew Dillon     for (wait = timeout / AH_TIME_QUANTUM; wait != 0; wait--) {
142b7d5e03cSMatthew Dillon         if ((OS_REG_READ(ah, AR_CR) & AR_CR_RXE) == 0) {
143b7d5e03cSMatthew Dillon             break;
144b7d5e03cSMatthew Dillon         }
145b7d5e03cSMatthew Dillon         OS_DELAY(AH_TIME_QUANTUM);
146b7d5e03cSMatthew Dillon     }
147b7d5e03cSMatthew Dillon 
148b7d5e03cSMatthew Dillon     if (wait == 0) {
149b7d5e03cSMatthew Dillon         HALDEBUG(ah, HAL_DEBUG_RX, "%s: dma failed to stop in %d ms\n"
150b7d5e03cSMatthew Dillon                 "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
151b7d5e03cSMatthew Dillon                 __func__,
152b7d5e03cSMatthew Dillon                 timeout / 1000,
153b7d5e03cSMatthew Dillon                 OS_REG_READ(ah, AR_CR),
154b7d5e03cSMatthew Dillon                 OS_REG_READ(ah, AR_DIAG_SW));
155b7d5e03cSMatthew Dillon         status = AH_FALSE;
156b7d5e03cSMatthew Dillon     } else {
157b7d5e03cSMatthew Dillon         status = AH_TRUE;
158b7d5e03cSMatthew Dillon     }
159b7d5e03cSMatthew Dillon 
160b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_MACMISC, org_value);
161b7d5e03cSMatthew Dillon 
1624b8649cbSMatthew Dillon     OS_MARK(ah, AH_MARK_RX_CTL,
1634b8649cbSMatthew Dillon         status ? AH_MARK_RX_CTL_DMA_STOP_OK : AH_MARK_RX_CTL_DMA_STOP_ERR);
1644b8649cbSMatthew Dillon 
165b7d5e03cSMatthew Dillon     return status;
166b7d5e03cSMatthew Dillon #undef AH_RX_STOP_DMA_TIMEOUT
167b7d5e03cSMatthew Dillon #undef AH_TIME_QUANTUM
168b7d5e03cSMatthew Dillon }
169b7d5e03cSMatthew Dillon 
170b7d5e03cSMatthew Dillon /*
171b7d5e03cSMatthew Dillon  * Start Transmit at the PCU engine (unpause receive)
172b7d5e03cSMatthew Dillon  */
173b7d5e03cSMatthew Dillon void
ar9300_start_pcu_receive(struct ath_hal * ah,HAL_BOOL is_scanning)174b7d5e03cSMatthew Dillon ar9300_start_pcu_receive(struct ath_hal *ah, HAL_BOOL is_scanning)
175b7d5e03cSMatthew Dillon {
176b7d5e03cSMatthew Dillon     ar9300_enable_mib_counters(ah);
177b7d5e03cSMatthew Dillon     ar9300_ani_reset(ah, is_scanning);
178b7d5e03cSMatthew Dillon     /* Clear RX_DIS and RX_ABORT after enabling phy errors in ani_reset */
179b7d5e03cSMatthew Dillon     OS_REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
180b7d5e03cSMatthew Dillon }
181b7d5e03cSMatthew Dillon 
182b7d5e03cSMatthew Dillon /*
183b7d5e03cSMatthew Dillon  * Stop Transmit at the PCU engine (pause receive)
184b7d5e03cSMatthew Dillon  */
185b7d5e03cSMatthew Dillon void
ar9300_stop_pcu_receive(struct ath_hal * ah)186b7d5e03cSMatthew Dillon ar9300_stop_pcu_receive(struct ath_hal *ah)
187b7d5e03cSMatthew Dillon {
188b7d5e03cSMatthew Dillon     OS_REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
189b7d5e03cSMatthew Dillon     ar9300_disable_mib_counters(ah);
190b7d5e03cSMatthew Dillon }
191b7d5e03cSMatthew Dillon 
192b7d5e03cSMatthew Dillon /*
193b7d5e03cSMatthew Dillon  * Set multicast filter 0 (lower 32-bits)
194b7d5e03cSMatthew Dillon  *               filter 1 (upper 32-bits)
195b7d5e03cSMatthew Dillon  */
196b7d5e03cSMatthew Dillon void
ar9300_set_multicast_filter(struct ath_hal * ah,u_int32_t filter0,u_int32_t filter1)197b7d5e03cSMatthew Dillon ar9300_set_multicast_filter(
198b7d5e03cSMatthew Dillon     struct ath_hal *ah,
199b7d5e03cSMatthew Dillon     u_int32_t filter0,
200b7d5e03cSMatthew Dillon     u_int32_t filter1)
201b7d5e03cSMatthew Dillon {
202b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_MCAST_FIL0, filter0);
203b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_MCAST_FIL1, filter1);
204b7d5e03cSMatthew Dillon }
205b7d5e03cSMatthew Dillon 
206b7d5e03cSMatthew Dillon /*
207b7d5e03cSMatthew Dillon  * Get the receive filter.
208b7d5e03cSMatthew Dillon  */
209b7d5e03cSMatthew Dillon u_int32_t
ar9300_get_rx_filter(struct ath_hal * ah)210b7d5e03cSMatthew Dillon ar9300_get_rx_filter(struct ath_hal *ah)
211b7d5e03cSMatthew Dillon {
212b7d5e03cSMatthew Dillon     u_int32_t bits = OS_REG_READ(ah, AR_RX_FILTER);
213b7d5e03cSMatthew Dillon     u_int32_t phybits = OS_REG_READ(ah, AR_PHY_ERR);
214b7d5e03cSMatthew Dillon     if (phybits & AR_PHY_ERR_RADAR) {
215b7d5e03cSMatthew Dillon         bits |= HAL_RX_FILTER_PHYRADAR;
216b7d5e03cSMatthew Dillon     }
217b7d5e03cSMatthew Dillon     if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING)) {
218b7d5e03cSMatthew Dillon         bits |= HAL_RX_FILTER_PHYERR;
219b7d5e03cSMatthew Dillon     }
220b7d5e03cSMatthew Dillon     return bits;
221b7d5e03cSMatthew Dillon }
222b7d5e03cSMatthew Dillon 
223b7d5e03cSMatthew Dillon /*
224b7d5e03cSMatthew Dillon  * Set the receive filter.
225b7d5e03cSMatthew Dillon  */
226b7d5e03cSMatthew Dillon void
ar9300_set_rx_filter(struct ath_hal * ah,u_int32_t bits)227b7d5e03cSMatthew Dillon ar9300_set_rx_filter(struct ath_hal *ah, u_int32_t bits)
228b7d5e03cSMatthew Dillon {
229b7d5e03cSMatthew Dillon     u_int32_t phybits;
230b7d5e03cSMatthew Dillon 
231*a20e5e51SMatthew Dillon     if (AR_SREV_SCORPION(ah) || AR_SREV_HONEYBEE(ah)) {
232b7d5e03cSMatthew Dillon         /* Enable Rx for 4 address frames */
233b7d5e03cSMatthew Dillon         bits |= AR_RX_4ADDRESS;
234b7d5e03cSMatthew Dillon     }
235b7d5e03cSMatthew Dillon     if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
236b7d5e03cSMatthew Dillon         /* HW fix for rx hang and corruption. */
237b7d5e03cSMatthew Dillon         bits |= AR_RX_CONTROL_WRAPPER;
238b7d5e03cSMatthew Dillon     }
239b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_RX_FILTER,
240b7d5e03cSMatthew Dillon         bits | AR_RX_UNCOM_BA_BAR | AR_RX_COMPR_BAR);
241b7d5e03cSMatthew Dillon     phybits = 0;
242b7d5e03cSMatthew Dillon     if (bits & HAL_RX_FILTER_PHYRADAR) {
243b7d5e03cSMatthew Dillon         phybits |= AR_PHY_ERR_RADAR;
244b7d5e03cSMatthew Dillon     }
245b7d5e03cSMatthew Dillon     if (bits & HAL_RX_FILTER_PHYERR) {
246b7d5e03cSMatthew Dillon         phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING;
247b7d5e03cSMatthew Dillon     }
248b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_PHY_ERR, phybits);
249b7d5e03cSMatthew Dillon     if (phybits) {
250b7d5e03cSMatthew Dillon         OS_REG_WRITE(ah, AR_RXCFG,
251b7d5e03cSMatthew Dillon             OS_REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
252b7d5e03cSMatthew Dillon     } else {
253b7d5e03cSMatthew Dillon         OS_REG_WRITE(ah, AR_RXCFG,
254b7d5e03cSMatthew Dillon             OS_REG_READ(ah, AR_RXCFG) &~ AR_RXCFG_ZLFDMA);
255b7d5e03cSMatthew Dillon     }
256b7d5e03cSMatthew Dillon }
257b7d5e03cSMatthew Dillon 
258b7d5e03cSMatthew Dillon /*
259b7d5e03cSMatthew Dillon  * Select to pass PLCP headr or EVM data.
260b7d5e03cSMatthew Dillon  */
261b7d5e03cSMatthew Dillon HAL_BOOL
ar9300_set_rx_sel_evm(struct ath_hal * ah,HAL_BOOL sel_evm,HAL_BOOL just_query)262b7d5e03cSMatthew Dillon ar9300_set_rx_sel_evm(struct ath_hal *ah, HAL_BOOL sel_evm, HAL_BOOL just_query)
263b7d5e03cSMatthew Dillon {
264b7d5e03cSMatthew Dillon     struct ath_hal_9300 *ahp = AH9300(ah);
265b7d5e03cSMatthew Dillon     HAL_BOOL old_value = ahp->ah_get_plcp_hdr == 0;
266b7d5e03cSMatthew Dillon 
267b7d5e03cSMatthew Dillon     if (just_query) {
268b7d5e03cSMatthew Dillon         return old_value;
269b7d5e03cSMatthew Dillon     }
270b7d5e03cSMatthew Dillon     if (sel_evm) {
271b7d5e03cSMatthew Dillon         OS_REG_SET_BIT(ah, AR_PCU_MISC, AR_PCU_SEL_EVM);
272b7d5e03cSMatthew Dillon     } else {
273b7d5e03cSMatthew Dillon         OS_REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_SEL_EVM);
274b7d5e03cSMatthew Dillon     }
275b7d5e03cSMatthew Dillon 
276b7d5e03cSMatthew Dillon     ahp->ah_get_plcp_hdr = !sel_evm;
277b7d5e03cSMatthew Dillon 
278b7d5e03cSMatthew Dillon     return old_value;
279b7d5e03cSMatthew Dillon }
280b7d5e03cSMatthew Dillon 
ar9300_promisc_mode(struct ath_hal * ah,HAL_BOOL enable)281b7d5e03cSMatthew Dillon void ar9300_promisc_mode(struct ath_hal *ah, HAL_BOOL enable)
282b7d5e03cSMatthew Dillon {
283b7d5e03cSMatthew Dillon     u_int32_t reg_val = 0;
284b7d5e03cSMatthew Dillon     reg_val =  OS_REG_READ(ah, AR_RX_FILTER);
285b7d5e03cSMatthew Dillon     if (enable){
286b7d5e03cSMatthew Dillon         reg_val |= AR_RX_PROM;
287b7d5e03cSMatthew Dillon     } else{ /*Disable promisc mode */
288b7d5e03cSMatthew Dillon         reg_val &= ~AR_RX_PROM;
289b7d5e03cSMatthew Dillon     }
290b7d5e03cSMatthew Dillon     OS_REG_WRITE(ah, AR_RX_FILTER, reg_val);
291b7d5e03cSMatthew Dillon }
292b7d5e03cSMatthew Dillon 
293b7d5e03cSMatthew Dillon void
ar9300_read_pktlog_reg(struct ath_hal * ah,u_int32_t * rxfilter_val,u_int32_t * rxcfg_val,u_int32_t * phy_err_mask_val,u_int32_t * mac_pcu_phy_err_regval)294b7d5e03cSMatthew Dillon ar9300_read_pktlog_reg(
295b7d5e03cSMatthew Dillon     struct ath_hal *ah,
296b7d5e03cSMatthew Dillon     u_int32_t *rxfilter_val,
297b7d5e03cSMatthew Dillon     u_int32_t *rxcfg_val,
298b7d5e03cSMatthew Dillon     u_int32_t *phy_err_mask_val,
299b7d5e03cSMatthew Dillon     u_int32_t *mac_pcu_phy_err_regval)
300b7d5e03cSMatthew Dillon {
301b7d5e03cSMatthew Dillon     *rxfilter_val = OS_REG_READ(ah, AR_RX_FILTER);
302b7d5e03cSMatthew Dillon     *rxcfg_val    = OS_REG_READ(ah, AR_RXCFG);
303b7d5e03cSMatthew Dillon     *phy_err_mask_val = OS_REG_READ(ah, AR_PHY_ERR);
304b7d5e03cSMatthew Dillon     *mac_pcu_phy_err_regval = OS_REG_READ(ah, 0x8338);
305b7d5e03cSMatthew Dillon     HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
306b7d5e03cSMatthew Dillon         "%s[%d] rxfilter_val 0x%08x , rxcfg_val 0x%08x, "
307b7d5e03cSMatthew Dillon         "phy_err_mask_val 0x%08x mac_pcu_phy_err_regval 0x%08x\n",
308b7d5e03cSMatthew Dillon         __func__, __LINE__,
309b7d5e03cSMatthew Dillon         *rxfilter_val, *rxcfg_val, *phy_err_mask_val, *mac_pcu_phy_err_regval);
310b7d5e03cSMatthew Dillon }
311b7d5e03cSMatthew Dillon 
312b7d5e03cSMatthew Dillon void
ar9300_write_pktlog_reg(struct ath_hal * ah,HAL_BOOL enable,u_int32_t rxfilter_val,u_int32_t rxcfg_val,u_int32_t phy_err_mask_val,u_int32_t mac_pcu_phy_err_reg_val)313b7d5e03cSMatthew Dillon ar9300_write_pktlog_reg(
314b7d5e03cSMatthew Dillon     struct ath_hal *ah,
315b7d5e03cSMatthew Dillon     HAL_BOOL enable,
316b7d5e03cSMatthew Dillon     u_int32_t rxfilter_val,
317b7d5e03cSMatthew Dillon     u_int32_t rxcfg_val,
318b7d5e03cSMatthew Dillon     u_int32_t phy_err_mask_val,
319b7d5e03cSMatthew Dillon     u_int32_t mac_pcu_phy_err_reg_val)
320b7d5e03cSMatthew Dillon {
321b7d5e03cSMatthew Dillon     if (AR_SREV_JUPITER(ah) || AR_SREV_APHRODITE(ah)) {
322b7d5e03cSMatthew Dillon         /* HW fix for rx hang and corruption. */
323b7d5e03cSMatthew Dillon         rxfilter_val |= AR_RX_CONTROL_WRAPPER;
324b7d5e03cSMatthew Dillon     }
325b7d5e03cSMatthew Dillon     if (enable) { /* Enable pktlog phyerr setting */
326b7d5e03cSMatthew Dillon         OS_REG_WRITE(ah, AR_RX_FILTER, 0xffff | AR_RX_COMPR_BAR | rxfilter_val);
327b7d5e03cSMatthew Dillon         OS_REG_WRITE(ah, AR_PHY_ERR, 0xFFFFFFFF);
328b7d5e03cSMatthew Dillon         OS_REG_WRITE(ah, AR_RXCFG, rxcfg_val | AR_RXCFG_ZLFDMA);
329b7d5e03cSMatthew Dillon         OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, mac_pcu_phy_err_reg_val | 0xFF);
330b7d5e03cSMatthew Dillon     } else { /* Disable phyerr and Restore regs */
331b7d5e03cSMatthew Dillon         OS_REG_WRITE(ah, AR_RX_FILTER, rxfilter_val);
332b7d5e03cSMatthew Dillon         OS_REG_WRITE(ah, AR_PHY_ERR, phy_err_mask_val);
333b7d5e03cSMatthew Dillon         OS_REG_WRITE(ah, AR_RXCFG, rxcfg_val);
334b7d5e03cSMatthew Dillon         OS_REG_WRITE(ah, AR_PHY_ERR_MASK_REG, mac_pcu_phy_err_reg_val);
335b7d5e03cSMatthew Dillon     }
336b7d5e03cSMatthew Dillon     HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
337b7d5e03cSMatthew Dillon         "%s[%d] ena %d rxfilter_val 0x%08x , rxcfg_val 0x%08x, "
338b7d5e03cSMatthew Dillon         "phy_err_mask_val 0x%08x mac_pcu_phy_err_regval 0x%08x\n",
339b7d5e03cSMatthew Dillon         __func__, __LINE__,
340b7d5e03cSMatthew Dillon         enable, rxfilter_val, rxcfg_val,
341b7d5e03cSMatthew Dillon         phy_err_mask_val, mac_pcu_phy_err_reg_val);
342b7d5e03cSMatthew Dillon }
343