Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/ath/ath_hal/ar9002/ar9285_btcoex.c
39566 views
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
21
#include "opt_ah.h"
22
23
#include "ah.h"
24
#include "ah_internal.h"
25
#include "ah_devid.h"
26
#ifdef AH_DEBUG
27
#include "ah_desc.h" /* NB: for HAL_PHYERR* */
28
#endif
29
30
#include "ar5416/ar5416.h"
31
#include "ar5416/ar5416reg.h"
32
#include "ar5416/ar5416phy.h"
33
#include "ar5416/ar5416desc.h" /* AR5416_CONTTXMODE */
34
35
#include "ar9002/ar9285phy.h"
36
#include "ar9002/ar9285.h"
37
38
/*
39
* This is specific to Kite.
40
*
41
* Kiwi and others don't have antenna diversity like this.
42
*/
43
void
44
ar9285BTCoexAntennaDiversity(struct ath_hal *ah)
45
{
46
struct ath_hal_5416 *ahp = AH5416(ah);
47
u_int32_t regVal;
48
u_int8_t ant_div_control1, ant_div_control2;
49
50
HALDEBUG(ah, HAL_DEBUG_BT_COEX,
51
"%s: btCoexFlag: ALLOW=%d, ENABLE=%d\n",
52
__func__,
53
!! (ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ALLOW),
54
!! (ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ENABLE));
55
56
if ((ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ALLOW) ||
57
(AH5212(ah)->ah_diversity == AH_TRUE)) {
58
if ((ahp->ah_btCoexFlag & HAL_BT_COEX_FLAG_ANT_DIV_ENABLE) &&
59
(AH5212(ah)->ah_antControl == HAL_ANT_VARIABLE)) {
60
/* Enable antenna diversity */
61
ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_ENABLE;
62
ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_ENABLE;
63
64
/* Don't disable BT ant to allow BB to control SWCOM */
65
ahp->ah_btCoexMode2 &= (~(AR_BT_DISABLE_BT_ANT));
66
OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2);
67
68
/* Program the correct SWCOM table */
69
OS_REG_WRITE(ah, AR_PHY_SWITCH_COM,
70
HAL_BT_COEX_ANT_DIV_SWITCH_COM);
71
OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000);
72
} else if (AH5212(ah)->ah_antControl == HAL_ANT_FIXED_B) {
73
/* Disable antenna diversity. Use antenna B(LNA2) only. */
74
ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_FIXED_B;
75
ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_FIXED_B;
76
77
/* Disable BT ant to allow concurrent BT and WLAN receive */
78
ahp->ah_btCoexMode2 |= AR_BT_DISABLE_BT_ANT;
79
OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2);
80
81
/*
82
* Program SWCOM table to make sure RF switch always parks
83
* at WLAN side
84
*/
85
OS_REG_WRITE(ah, AR_PHY_SWITCH_COM,
86
HAL_BT_COEX_ANT_DIV_SWITCH_COM);
87
OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0x60000000, 0xf0000000);
88
} else {
89
/* Disable antenna diversity. Use antenna A(LNA1) only */
90
ant_div_control1 = HAL_BT_COEX_ANTDIV_CONTROL1_FIXED_A;
91
ant_div_control2 = HAL_BT_COEX_ANTDIV_CONTROL2_FIXED_A;
92
93
/* Disable BT ant to allow concurrent BT and WLAN receive */
94
ahp->ah_btCoexMode2 |= AR_BT_DISABLE_BT_ANT;
95
OS_REG_WRITE(ah, AR_BT_COEX_MODE2, ahp->ah_btCoexMode2);
96
97
/*
98
* Program SWCOM table to make sure RF switch always
99
* parks at BT side
100
*/
101
OS_REG_WRITE(ah, AR_PHY_SWITCH_COM, 0);
102
OS_REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0, 0, 0xf0000000);
103
}
104
105
regVal = OS_REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
106
regVal &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL));
107
/*
108
* Clear ant_fast_div_bias [14:9] since for Janus the main LNA is
109
* always LNA1.
110
*/
111
regVal &= (~(AR_PHY_9285_FAST_DIV_BIAS));
112
113
regVal |= SM(ant_div_control1, AR_PHY_9285_ANT_DIV_CTL);
114
regVal |= SM(ant_div_control2, AR_PHY_9285_ANT_DIV_ALT_LNACONF);
115
regVal |= SM((ant_div_control2 >> 2), AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
116
regVal |= SM((ant_div_control1 >> 1), AR_PHY_9285_ANT_DIV_ALT_GAINTB);
117
regVal |= SM((ant_div_control1 >> 2), AR_PHY_9285_ANT_DIV_MAIN_GAINTB);
118
OS_REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal);
119
120
regVal = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
121
regVal &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
122
regVal |= SM((ant_div_control1 >> 3),
123
AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
124
OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regVal);
125
}
126
}
127
128
void
129
ar9285BTCoexSetParameter(struct ath_hal *ah, u_int32_t type, u_int32_t value)
130
{
131
struct ath_hal_5416 *ahp = AH5416(ah);
132
133
switch (type) {
134
case HAL_BT_COEX_ANTENNA_DIVERSITY:
135
if (AR_SREV_KITE(ah)) {
136
ahp->ah_btCoexFlag |= HAL_BT_COEX_FLAG_ANT_DIV_ALLOW;
137
if (value)
138
ahp->ah_btCoexFlag |=
139
HAL_BT_COEX_FLAG_ANT_DIV_ENABLE;
140
else
141
ahp->ah_btCoexFlag &=
142
~HAL_BT_COEX_FLAG_ANT_DIV_ENABLE;
143
ar9285BTCoexAntennaDiversity(ah);
144
}
145
break;
146
default:
147
ar5416BTCoexSetParameter(ah, type, value);
148
break;
149
}
150
}
151
152