]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/ath/ath_hal/ar9002/ar9285_btcoex.c
Update to 6.2-20200215
[FreeBSD/FreeBSD.git] / sys / dev / ath / ath_hal / ar9002 / ar9285_btcoex.c
1 /*-
2  * SPDX-License-Identifier: ISC
3  *
4  * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
5  * Copyright (c) 2002-2005 Atheros Communications, Inc.
6  * Copyright (c) 2008-2010, Atheros Communications Inc.
7  *
8  * Permission to use, copy, modify, and/or distribute this software for any
9  * purpose with or without fee is hereby granted, provided that the above
10  * copyright notice and this permission notice appear in all copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19  *
20  * $FreeBSD$
21  */
22
23 #include "opt_ah.h"
24
25 #include "ah.h"
26 #include "ah_internal.h"
27 #include "ah_devid.h"
28 #ifdef AH_DEBUG
29 #include "ah_desc.h"                /* NB: for HAL_PHYERR* */
30 #endif
31
32 #include "ar5416/ar5416.h"
33 #include "ar5416/ar5416reg.h"
34 #include "ar5416/ar5416phy.h"
35 #include "ar5416/ar5416desc.h" /* AR5416_CONTTXMODE */
36
37 #include "ar9002/ar9285phy.h"
38 #include "ar9002/ar9285.h"
39
40 /*
41  * This is specific to Kite.
42  *
43  * Kiwi and others don't have antenna diversity like this.
44  */
45 void
46 ar9285BTCoexAntennaDiversity(struct ath_hal *ah)
47 {
48         struct ath_hal_5416 *ahp = AH5416(ah);
49         u_int32_t regVal;
50         u_int8_t ant_div_control1, ant_div_control2;
51
52         HALDEBUG(ah, HAL_DEBUG_BT_COEX,
53             "%s: btCoexFlag: ALLOW=%d, ENABLE=%d\n",
54             __func__,
55             !! (ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ALLOW),
56             !! (ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ENABLE));
57
58         if ((ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ALLOW) ||
59             (AH5212(ah)->ah_diversity != HAL_ANT_VARIABLE)) {
60         if ((ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ENABLE) &&
61              (AH5212(ah)->ah_antControl == HAL_ANT_VARIABLE)) {
62                 /* Enable antenna diversity */
63                 ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_ENABLE;
64                 ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_ENABLE;
65
66                 /* Don't disable BT ant to allow BB to control SWCOM */
67                 ahp->ah_btCoexMode2 &= (~(AR_BT_DISABLE_BT_ANT));
68                 OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2);
69
70                 /* Program the correct SWCOM table */
71                 OS_REG_WRITE(ah, AR_PHY_SWITCH_COM,
72                     HAL_BT_COEX_ANT_DIV_SWITCH_COM);
73                 OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000);
74         } else if (AH5212(ah)->ah_antControl == HAL_ANT_FIXED_B) {
75                 /* Disable antenna diversity. Use antenna B(LNA2) only. */
76                 ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_FIXED_B;
77                 ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_FIXED_B;
78
79                 /* Disable BT ant to allow concurrent BT and WLAN receive */
80                 ahp->ah_btCoexMode2 |= AR_BT_DISABLE_BT_ANT;
81                 OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2);
82
83                 /*
84                  * Program SWCOM table to make sure RF switch always parks
85                  * at WLAN side
86                  */
87                 OS_REG_WRITE(ah, AR_PHY_SWITCH_COM,
88                     HAL_BT_COEX_ANT_DIV_SWITCH_COM);
89                 OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0x60000000, 0xf0000000);
90         } else {
91                 /* Disable antenna diversity. Use antenna A(LNA1) only */
92                 ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_FIXED_A;
93                 ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_FIXED_A;
94
95                 /* Disable BT ant to allow concurrent BT and WLAN receive */
96                 ahp->ah_btCoexMode2 |= AR_BT_DISABLE_BT_ANT;
97                 OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2);
98
99                 /*
100                  * Program SWCOM table to make sure RF switch always
101                  * parks at BT side
102                  */
103                 OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, 0);
104                 OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000);
105         }
106
107         regVal = OS_REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
108         regVal &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL));
109         /*
110          * Clear ant_fast_div_bias [14:9] since for Janus the main LNA is
111          * always LNA1.
112          */
113         regVal &= (~(AR_PHY_9285_FAST_DIV_BIAS));
114
115         regVal |= SM(ant_div_control1, AR_PHY_9285_ANT_DIV_CTL);
116         regVal |= SM(ant_div_control2, AR_PHY_9285_ANT_DIV_ALT_LNACONF);
117         regVal |= SM((ant_div_control2 >> 2), AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
118         regVal |= SM((ant_div_control1 >> 1), AR_PHY_9285_ANT_DIV_ALT_GAINTB);
119         regVal |= SM((ant_div_control1 >> 2), AR_PHY_9285_ANT_DIV_MAIN_GAINTB);
120         OS_REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal);
121
122         regVal = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
123         regVal &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
124         regVal |= SM((ant_div_control1 >> 3),
125             AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
126         OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regVal);
127     }
128 }
129
130 void
131 ar9285BTCoexSetParameter(struct ath_hal *ah, u_int32_t type, u_int32_t value)
132 {
133         struct ath_hal_5416 *ahp = AH5416(ah);
134
135         switch (type) {
136         case HAL_BT_COEX_ANTENNA_DIVERSITY:
137                 if (AR_SREV_KITE(ah)) {
138                         ahp->ah_btCoexFlag |= HAL_BT_COEX_FLAG_ANT_DIV_ALLOW;
139                         if (value)
140                                 ahp->ah_btCoexFlag |=
141                                     HAL_BT_COEX_FLAG_ANT_DIV_ENABLE;
142                         else
143                                 ahp->ah_btCoexFlag &=
144                                     ~HAL_BT_COEX_FLAG_ANT_DIV_ENABLE;
145                         ar9285BTCoexAntennaDiversity(ah);
146                 }
147                 break;
148         default:
149                 ar5416BTCoexSetParameter(ah, type, value);
150                 break;
151         }
152 }
153
154