1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
From 269f19c848a2380db03a3f207cafb88e28d71c53 Mon Sep 17 00:00:00 2001
From: Gabor Juhos <juhosg@openwrt.org>
Date: Sun, 24 Mar 2013 19:26:28 +0100
Subject: [PATCH] rt2x00: rt2800lib: add channel configuration code for RT3883
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
drivers/net/wireless/rt2x00/rt2800lib.c | 72 +++++++++++++++++++++++++++++--
1 file changed, 69 insertions(+), 3 deletions(-)
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -3384,6 +3384,36 @@ static char rt2800_txpower_to_dev(struct
return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER);
}
+static void rt3883_bbp_adjust(struct rt2x00_dev *rt2x00dev,
+ struct rf_channel *rf)
+{
+ u8 bbp;
+
+ bbp = (rf->channel > 14) ? 0x48 : 0x38;
+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, bbp);
+
+ rt2800_bbp_write(rt2x00dev, 69, 0x12);
+
+ if (rf->channel <= 14) {
+ rt2800_bbp_write(rt2x00dev, 70, 0x0a);
+ } else {
+ /* Disable CCK packet detection */
+ rt2800_bbp_write(rt2x00dev, 70, 0x00);
+ }
+
+ rt2800_bbp_write(rt2x00dev, 73, 0x10);
+
+ if (rf->channel > 14) {
+ rt2800_bbp_write(rt2x00dev, 62, 0x1d);
+ rt2800_bbp_write(rt2x00dev, 63, 0x1d);
+ rt2800_bbp_write(rt2x00dev, 64, 0x1d);
+ } else {
+ rt2800_bbp_write(rt2x00dev, 62, 0x2d);
+ rt2800_bbp_write(rt2x00dev, 63, 0x2d);
+ rt2800_bbp_write(rt2x00dev, 64, 0x2d);
+ }
+}
+
static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
struct ieee80211_conf *conf,
struct rf_channel *rf,
@@ -3402,6 +3432,12 @@ static void rt2800_config_channel(struct
rt2800_txpower_to_dev(rt2x00dev, rf->channel,
info->default_power3);
+ switch (rt2x00dev->chip.rt) {
+ case RT3883:
+ rt3883_bbp_adjust(rt2x00dev, rf);
+ break;
+ }
+
switch (rt2x00dev->chip.rf) {
case RF2020:
case RF3020:
@@ -3483,6 +3519,15 @@ static void rt2800_config_channel(struct
rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
rt2800_bbp_write(rt2x00dev, 77, 0x98);
+ } else if (rt2x00_rt(rt2x00dev, RT3883)) {
+ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+
+ if (rt2x00dev->default_ant.rx_chain_num > 1)
+ rt2800_bbp_write(rt2x00dev, 86, 0x46);
+ else
+ rt2800_bbp_write(rt2x00dev, 86, 0);
} else {
rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
@@ -3495,6 +3540,7 @@ static void rt2800_config_channel(struct
!rt2x00_rt(rt2x00dev, RT5392)) {
if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) {
rt2800_bbp_write(rt2x00dev, 82, 0x62);
+ rt2800_bbp_write(rt2x00dev, 82, 0x62);
rt2800_bbp_write(rt2x00dev, 75, 0x46);
} else {
if (rt2x00_rt(rt2x00dev, RT3593))
@@ -3503,19 +3549,22 @@ static void rt2800_config_channel(struct
rt2800_bbp_write(rt2x00dev, 82, 0x84);
rt2800_bbp_write(rt2x00dev, 75, 0x50);
}
- if (rt2x00_rt(rt2x00dev, RT3593))
+ if (rt2x00_rt(rt2x00dev, RT3593) ||
+ rt2x00_rt(rt2x00dev, RT3883))
rt2800_bbp_write(rt2x00dev, 83, 0x8a);
}
} else {
if (rt2x00_rt(rt2x00dev, RT3572))
rt2800_bbp_write(rt2x00dev, 82, 0x94);
- else if (rt2x00_rt(rt2x00dev, RT3593))
+ else if (rt2x00_rt(rt2x00dev, RT3593) ||
+ rt2x00_rt(rt2x00dev, RT3883))
rt2800_bbp_write(rt2x00dev, 82, 0x82);
else
rt2800_bbp_write(rt2x00dev, 82, 0xf2);
- if (rt2x00_rt(rt2x00dev, RT3593))
+ if (rt2x00_rt(rt2x00dev, RT3593) ||
+ rt2x00_rt(rt2x00dev, RT3883))
rt2800_bbp_write(rt2x00dev, 83, 0x9a);
if (rt2x00_has_cap_external_lna_a(rt2x00dev))
@@ -3640,6 +3689,23 @@ static void rt2800_config_channel(struct
usleep_range(1000, 1500);
}
+ if (rt2x00_rt(rt2x00dev, RT3883)) {
+ if (!conf_is_ht40(conf))
+ rt2800_bbp_write(rt2x00dev, 105, 0x34);
+ else
+ rt2800_bbp_write(rt2x00dev, 105, 0x04);
+
+ /* AGC init */
+ if (rf->channel <= 14)
+ reg = 0x2e + rt2x00dev->lna_gain;
+ else
+ reg = 0x20 + ((rt2x00dev->lna_gain * 5) / 3);
+
+ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg);
+
+ usleep_range(1000, 1500);
+ }
+
if (rt2x00_rt(rt2x00dev, RT5592)) {
rt2800_bbp_write(rt2x00dev, 195, 141);
rt2800_bbp_write(rt2x00dev, 196, conf_is_ht40(conf) ? 0x10 : 0x1a);
|