Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/bwi/bwirf.c
39507 views
1
/*-
2
* SPDX-License-Identifier: BSD-3-Clause
3
*
4
* Copyright (c) 2007 The DragonFly Project. All rights reserved.
5
*
6
* This code is derived from software contributed to The DragonFly Project
7
* by Sepherosa Ziehau <[email protected]>
8
*
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted provided that the following conditions
11
* are met:
12
*
13
* 1. Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in
17
* the documentation and/or other materials provided with the
18
* distribution.
19
* 3. Neither the name of The DragonFly Project nor the names of its
20
* contributors may be used to endorse or promote products derived
21
* from this software without specific, prior written permission.
22
*
23
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28
* INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
29
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
31
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34
* SUCH DAMAGE.
35
*
36
* $DragonFly: src/sys/dev/netif/bwi/bwirf.c,v 1.9 2008/08/21 12:19:33 swildner Exp $
37
*/
38
39
#include <sys/cdefs.h>
40
#include "opt_inet.h"
41
#include "opt_bwi.h"
42
#include "opt_wlan.h"
43
44
#include <sys/param.h>
45
#include <sys/endian.h>
46
#include <sys/kernel.h>
47
#include <sys/bus.h>
48
#include <sys/malloc.h>
49
#include <sys/proc.h>
50
#include <sys/rman.h>
51
#include <sys/socket.h>
52
#include <sys/sockio.h>
53
#include <sys/sysctl.h>
54
#include <sys/systm.h>
55
56
#include <net/if.h>
57
#include <net/if_var.h>
58
#include <net/if_dl.h>
59
#include <net/if_media.h>
60
#include <net/if_types.h>
61
#include <net/if_arp.h>
62
#include <net/ethernet.h>
63
#include <net/if_llc.h>
64
65
#include <net80211/ieee80211_var.h>
66
#include <net80211/ieee80211_radiotap.h>
67
#include <net80211/ieee80211_amrr.h>
68
69
#include <machine/bus.h>
70
71
#include <dev/bwi/bitops.h>
72
#include <dev/bwi/if_bwireg.h>
73
#include <dev/bwi/if_bwivar.h>
74
#include <dev/bwi/bwimac.h>
75
#include <dev/bwi/bwirf.h>
76
#include <dev/bwi/bwiphy.h>
77
78
#define RF_LO_WRITE(mac, lo) bwi_rf_lo_write((mac), (lo))
79
80
#define BWI_RF_2GHZ_CHAN(chan) \
81
(ieee80211_ieee2mhz((chan), IEEE80211_CHAN_2GHZ) - 2400)
82
83
#define BWI_DEFAULT_IDLE_TSSI 52
84
85
struct rf_saveregs {
86
uint16_t phy_01;
87
uint16_t phy_03;
88
uint16_t phy_0a;
89
uint16_t phy_15;
90
uint16_t phy_2a;
91
uint16_t phy_30;
92
uint16_t phy_35;
93
uint16_t phy_60;
94
uint16_t phy_429;
95
uint16_t phy_802;
96
uint16_t phy_811;
97
uint16_t phy_812;
98
uint16_t phy_814;
99
uint16_t phy_815;
100
101
uint16_t rf_43;
102
uint16_t rf_52;
103
uint16_t rf_7a;
104
};
105
106
#define SAVE_RF_REG(mac, regs, n) (regs)->rf_##n = RF_READ((mac), 0x##n)
107
#define RESTORE_RF_REG(mac, regs, n) RF_WRITE((mac), 0x##n, (regs)->rf_##n)
108
109
#define SAVE_PHY_REG(mac, regs, n) (regs)->phy_##n = PHY_READ((mac), 0x##n)
110
#define RESTORE_PHY_REG(mac, regs, n) PHY_WRITE((mac), 0x##n, (regs)->phy_##n)
111
112
static int bwi_rf_calc_txpower(int8_t *, uint8_t, const int16_t[]);
113
static void bwi_rf_work_around(struct bwi_mac *, u_int);
114
static int bwi_rf_gain_max_reached(struct bwi_mac *, int);
115
static uint16_t bwi_rf_calibval(struct bwi_mac *);
116
static uint16_t bwi_rf_get_tp_ctrl2(struct bwi_mac *);
117
118
static void bwi_rf_lo_update_11b(struct bwi_mac *);
119
static uint16_t bwi_rf_lo_measure_11b(struct bwi_mac *);
120
121
static void bwi_rf_lo_update_11g(struct bwi_mac *);
122
static uint32_t bwi_rf_lo_devi_measure(struct bwi_mac *, uint16_t);
123
static void bwi_rf_lo_measure_11g(struct bwi_mac *,
124
const struct bwi_rf_lo *, struct bwi_rf_lo *, uint8_t);
125
static uint8_t _bwi_rf_lo_update_11g(struct bwi_mac *, uint16_t);
126
static void bwi_rf_lo_write(struct bwi_mac *, const struct bwi_rf_lo *);
127
128
static void bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *);
129
static void bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *);
130
static void bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *);
131
static void bwi_rf_set_nrssi_thr_11b(struct bwi_mac *);
132
static void bwi_rf_set_nrssi_thr_11g(struct bwi_mac *);
133
134
static void bwi_rf_init_sw_nrssi_table(struct bwi_mac *);
135
136
static int bwi_rf_calc_rssi_bcm2050(struct bwi_mac *,
137
const struct bwi_rxbuf_hdr *);
138
static int bwi_rf_calc_rssi_bcm2053(struct bwi_mac *,
139
const struct bwi_rxbuf_hdr *);
140
static int bwi_rf_calc_rssi_bcm2060(struct bwi_mac *,
141
const struct bwi_rxbuf_hdr *);
142
static int bwi_rf_calc_noise_bcm2050(struct bwi_mac *);
143
static int bwi_rf_calc_noise_bcm2053(struct bwi_mac *);
144
static int bwi_rf_calc_noise_bcm2060(struct bwi_mac *);
145
146
static void bwi_rf_on_11a(struct bwi_mac *);
147
static void bwi_rf_on_11bg(struct bwi_mac *);
148
149
static void bwi_rf_off_11a(struct bwi_mac *);
150
static void bwi_rf_off_11bg(struct bwi_mac *);
151
static void bwi_rf_off_11g_rev5(struct bwi_mac *);
152
153
static const int8_t bwi_txpower_map_11b[BWI_TSSI_MAX] =
154
{ BWI_TXPOWER_MAP_11B };
155
static const int8_t bwi_txpower_map_11g[BWI_TSSI_MAX] =
156
{ BWI_TXPOWER_MAP_11G };
157
158
static __inline int16_t
159
bwi_nrssi_11g(struct bwi_mac *mac)
160
{
161
int16_t val;
162
163
#define NRSSI_11G_MASK __BITS(13, 8)
164
165
val = (int16_t)__SHIFTOUT(PHY_READ(mac, 0x47f), NRSSI_11G_MASK);
166
if (val >= 32)
167
val -= 64;
168
return val;
169
170
#undef NRSSI_11G_MASK
171
}
172
173
static __inline struct bwi_rf_lo *
174
bwi_get_rf_lo(struct bwi_mac *mac, uint16_t rf_atten, uint16_t bbp_atten)
175
{
176
int n;
177
178
n = rf_atten + (14 * (bbp_atten / 2));
179
KASSERT(n < BWI_RFLO_MAX, ("n %d", n));
180
181
return &mac->mac_rf.rf_lo[n];
182
}
183
184
static __inline int
185
bwi_rf_lo_isused(struct bwi_mac *mac, const struct bwi_rf_lo *lo)
186
{
187
struct bwi_rf *rf = &mac->mac_rf;
188
int idx;
189
190
idx = lo - rf->rf_lo;
191
KASSERT(idx >= 0 && idx < BWI_RFLO_MAX, ("idx %d", idx));
192
193
return isset(rf->rf_lo_used, idx);
194
}
195
196
void
197
bwi_rf_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
198
{
199
struct bwi_softc *sc = mac->mac_sc;
200
201
CSR_WRITE_2(sc, BWI_RF_CTRL, ctrl);
202
CSR_WRITE_2(sc, BWI_RF_DATA_LO, data);
203
}
204
205
uint16_t
206
bwi_rf_read(struct bwi_mac *mac, uint16_t ctrl)
207
{
208
struct bwi_rf *rf = &mac->mac_rf;
209
struct bwi_softc *sc = mac->mac_sc;
210
211
ctrl |= rf->rf_ctrl_rd;
212
if (rf->rf_ctrl_adj) {
213
/* XXX */
214
if (ctrl < 0x70)
215
ctrl += 0x80;
216
else if (ctrl < 0x80)
217
ctrl += 0x70;
218
}
219
220
CSR_WRITE_2(sc, BWI_RF_CTRL, ctrl);
221
return CSR_READ_2(sc, BWI_RF_DATA_LO);
222
}
223
224
int
225
bwi_rf_attach(struct bwi_mac *mac)
226
{
227
struct bwi_softc *sc = mac->mac_sc;
228
struct bwi_phy *phy = &mac->mac_phy;
229
struct bwi_rf *rf = &mac->mac_rf;
230
uint16_t type, manu;
231
uint8_t rev;
232
233
/*
234
* Get RF manufacture/type/revision
235
*/
236
if (sc->sc_bbp_id == BWI_BBPID_BCM4317) {
237
/*
238
* Fake a BCM2050 RF
239
*/
240
manu = BWI_RF_MANUFACT_BCM;
241
type = BWI_RF_T_BCM2050;
242
if (sc->sc_bbp_rev == 0)
243
rev = 3;
244
else if (sc->sc_bbp_rev == 1)
245
rev = 4;
246
else
247
rev = 5;
248
} else {
249
uint32_t val;
250
251
CSR_WRITE_2(sc, BWI_RF_CTRL, BWI_RF_CTRL_RFINFO);
252
val = CSR_READ_2(sc, BWI_RF_DATA_HI);
253
val <<= 16;
254
255
CSR_WRITE_2(sc, BWI_RF_CTRL, BWI_RF_CTRL_RFINFO);
256
val |= CSR_READ_2(sc, BWI_RF_DATA_LO);
257
258
manu = __SHIFTOUT(val, BWI_RFINFO_MANUFACT_MASK);
259
type = __SHIFTOUT(val, BWI_RFINFO_TYPE_MASK);
260
rev = __SHIFTOUT(val, BWI_RFINFO_REV_MASK);
261
}
262
device_printf(sc->sc_dev, "RF: manu 0x%03x, type 0x%04x, rev %u\n",
263
manu, type, rev);
264
265
/*
266
* Verify whether the RF is supported
267
*/
268
rf->rf_ctrl_rd = 0;
269
rf->rf_ctrl_adj = 0;
270
switch (phy->phy_mode) {
271
case IEEE80211_MODE_11A:
272
if (manu != BWI_RF_MANUFACT_BCM ||
273
type != BWI_RF_T_BCM2060 ||
274
rev != 1) {
275
device_printf(sc->sc_dev, "only BCM2060 rev 1 RF "
276
"is supported for 11A PHY\n");
277
return ENXIO;
278
}
279
rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11A;
280
rf->rf_on = bwi_rf_on_11a;
281
rf->rf_off = bwi_rf_off_11a;
282
rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2060;
283
rf->rf_calc_noise = bwi_rf_calc_noise_bcm2060;
284
break;
285
case IEEE80211_MODE_11B:
286
if (type == BWI_RF_T_BCM2050) {
287
rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11BG;
288
rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2050;
289
rf->rf_calc_noise = bwi_rf_calc_noise_bcm2050;
290
} else if (type == BWI_RF_T_BCM2053) {
291
rf->rf_ctrl_adj = 1;
292
rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2053;
293
rf->rf_calc_noise = bwi_rf_calc_noise_bcm2053;
294
} else {
295
device_printf(sc->sc_dev, "only BCM2050/BCM2053 RF "
296
"is supported for 11B PHY\n");
297
return ENXIO;
298
}
299
rf->rf_on = bwi_rf_on_11bg;
300
rf->rf_off = bwi_rf_off_11bg;
301
rf->rf_calc_nrssi_slope = bwi_rf_calc_nrssi_slope_11b;
302
rf->rf_set_nrssi_thr = bwi_rf_set_nrssi_thr_11b;
303
if (phy->phy_rev == 6)
304
rf->rf_lo_update = bwi_rf_lo_update_11g;
305
else
306
rf->rf_lo_update = bwi_rf_lo_update_11b;
307
break;
308
case IEEE80211_MODE_11G:
309
if (type != BWI_RF_T_BCM2050) {
310
device_printf(sc->sc_dev, "only BCM2050 RF "
311
"is supported for 11G PHY\n");
312
return ENXIO;
313
}
314
rf->rf_ctrl_rd = BWI_RF_CTRL_RD_11BG;
315
rf->rf_on = bwi_rf_on_11bg;
316
if (mac->mac_rev >= 5)
317
rf->rf_off = bwi_rf_off_11g_rev5;
318
else
319
rf->rf_off = bwi_rf_off_11bg;
320
rf->rf_calc_nrssi_slope = bwi_rf_calc_nrssi_slope_11g;
321
rf->rf_set_nrssi_thr = bwi_rf_set_nrssi_thr_11g;
322
rf->rf_calc_rssi = bwi_rf_calc_rssi_bcm2050;
323
rf->rf_calc_noise = bwi_rf_calc_noise_bcm2050;
324
rf->rf_lo_update = bwi_rf_lo_update_11g;
325
break;
326
default:
327
device_printf(sc->sc_dev, "unsupported PHY mode\n");
328
return ENXIO;
329
}
330
331
rf->rf_type = type;
332
rf->rf_rev = rev;
333
rf->rf_manu = manu;
334
rf->rf_curchan = IEEE80211_CHAN_ANY;
335
rf->rf_ant_mode = BWI_ANT_MODE_AUTO;
336
return 0;
337
}
338
339
void
340
bwi_rf_set_chan(struct bwi_mac *mac, u_int chan, int work_around)
341
{
342
struct bwi_softc *sc = mac->mac_sc;
343
344
if (chan == IEEE80211_CHAN_ANY)
345
return;
346
347
MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_CHAN, chan);
348
349
/* TODO: 11A */
350
351
if (work_around)
352
bwi_rf_work_around(mac, chan);
353
354
CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan));
355
356
if (chan == 14) {
357
if (sc->sc_locale == BWI_SPROM_LOCALE_JAPAN)
358
HFLAGS_CLRBITS(mac, BWI_HFLAG_NOT_JAPAN);
359
else
360
HFLAGS_SETBITS(mac, BWI_HFLAG_NOT_JAPAN);
361
CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, (1 << 11)); /* XXX */
362
} else {
363
CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0x840); /* XXX */
364
}
365
DELAY(8000); /* DELAY(2000); */
366
367
mac->mac_rf.rf_curchan = chan;
368
}
369
370
void
371
bwi_rf_get_gains(struct bwi_mac *mac)
372
{
373
#define SAVE_PHY_MAX 15
374
#define SAVE_RF_MAX 3
375
376
static const uint16_t save_rf_regs[SAVE_RF_MAX] =
377
{ 0x52, 0x43, 0x7a };
378
static const uint16_t save_phy_regs[SAVE_PHY_MAX] = {
379
0x0429, 0x0001, 0x0811, 0x0812,
380
0x0814, 0x0815, 0x005a, 0x0059,
381
0x0058, 0x000a, 0x0003, 0x080f,
382
0x0810, 0x002b, 0x0015
383
};
384
385
struct bwi_softc *sc = mac->mac_sc;
386
struct bwi_phy *phy = &mac->mac_phy;
387
struct bwi_rf *rf = &mac->mac_rf;
388
uint16_t save_phy[SAVE_PHY_MAX];
389
uint16_t save_rf[SAVE_RF_MAX];
390
uint16_t trsw;
391
int i, j, loop1_max, loop1, loop2;
392
393
/*
394
* Save PHY/RF registers for later restoration
395
*/
396
for (i = 0; i < SAVE_PHY_MAX; ++i)
397
save_phy[i] = PHY_READ(mac, save_phy_regs[i]);
398
PHY_READ(mac, 0x2d); /* dummy read */
399
400
for (i = 0; i < SAVE_RF_MAX; ++i)
401
save_rf[i] = RF_READ(mac, save_rf_regs[i]);
402
403
PHY_CLRBITS(mac, 0x429, 0xc000);
404
PHY_SETBITS(mac, 0x1, 0x8000);
405
406
PHY_SETBITS(mac, 0x811, 0x2);
407
PHY_CLRBITS(mac, 0x812, 0x2);
408
PHY_SETBITS(mac, 0x811, 0x1);
409
PHY_CLRBITS(mac, 0x812, 0x1);
410
411
PHY_SETBITS(mac, 0x814, 0x1);
412
PHY_CLRBITS(mac, 0x815, 0x1);
413
PHY_SETBITS(mac, 0x814, 0x2);
414
PHY_CLRBITS(mac, 0x815, 0x2);
415
416
PHY_SETBITS(mac, 0x811, 0xc);
417
PHY_SETBITS(mac, 0x812, 0xc);
418
PHY_SETBITS(mac, 0x811, 0x30);
419
PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10);
420
421
PHY_WRITE(mac, 0x5a, 0x780);
422
PHY_WRITE(mac, 0x59, 0xc810);
423
PHY_WRITE(mac, 0x58, 0xd);
424
PHY_SETBITS(mac, 0xa, 0x2000);
425
426
PHY_SETBITS(mac, 0x814, 0x4);
427
PHY_CLRBITS(mac, 0x815, 0x4);
428
429
PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
430
431
if (rf->rf_rev == 8) {
432
loop1_max = 15;
433
RF_WRITE(mac, 0x43, loop1_max);
434
} else {
435
loop1_max = 9;
436
RF_WRITE(mac, 0x52, 0x0);
437
RF_FILT_SETBITS(mac, 0x43, 0xfff0, loop1_max);
438
}
439
440
bwi_phy_set_bbp_atten(mac, 11);
441
442
if (phy->phy_rev >= 3)
443
PHY_WRITE(mac, 0x80f, 0xc020);
444
else
445
PHY_WRITE(mac, 0x80f, 0x8020);
446
PHY_WRITE(mac, 0x810, 0);
447
448
PHY_FILT_SETBITS(mac, 0x2b, 0xffc0, 0x1);
449
PHY_FILT_SETBITS(mac, 0x2b, 0xc0ff, 0x800);
450
PHY_SETBITS(mac, 0x811, 0x100);
451
PHY_CLRBITS(mac, 0x812, 0x3000);
452
453
if ((sc->sc_card_flags & BWI_CARD_F_EXT_LNA) &&
454
phy->phy_rev >= 7) {
455
PHY_SETBITS(mac, 0x811, 0x800);
456
PHY_SETBITS(mac, 0x812, 0x8000);
457
}
458
RF_CLRBITS(mac, 0x7a, 0xff08);
459
460
/*
461
* Find out 'loop1/loop2', which will be used to calculate
462
* max loopback gain later
463
*/
464
j = 0;
465
for (i = 0; i < loop1_max; ++i) {
466
for (j = 0; j < 16; ++j) {
467
RF_WRITE(mac, 0x43, i);
468
469
if (bwi_rf_gain_max_reached(mac, j))
470
goto loop1_exit;
471
}
472
}
473
loop1_exit:
474
loop1 = i;
475
loop2 = j;
476
477
/*
478
* Find out 'trsw', which will be used to calculate
479
* TRSW(TX/RX switch) RX gain later
480
*/
481
if (loop2 >= 8) {
482
PHY_SETBITS(mac, 0x812, 0x30);
483
trsw = 0x1b;
484
for (i = loop2 - 8; i < 16; ++i) {
485
trsw -= 3;
486
if (bwi_rf_gain_max_reached(mac, i))
487
break;
488
}
489
} else {
490
trsw = 0x18;
491
}
492
493
/*
494
* Restore saved PHY/RF registers
495
*/
496
/* First 4 saved PHY registers need special processing */
497
for (i = 4; i < SAVE_PHY_MAX; ++i)
498
PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
499
500
bwi_phy_set_bbp_atten(mac, mac->mac_tpctl.bbp_atten);
501
502
for (i = 0; i < SAVE_RF_MAX; ++i)
503
RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
504
505
PHY_WRITE(mac, save_phy_regs[2], save_phy[2] | 0x3);
506
DELAY(10);
507
PHY_WRITE(mac, save_phy_regs[2], save_phy[2]);
508
PHY_WRITE(mac, save_phy_regs[3], save_phy[3]);
509
PHY_WRITE(mac, save_phy_regs[0], save_phy[0]);
510
PHY_WRITE(mac, save_phy_regs[1], save_phy[1]);
511
512
/*
513
* Calculate gains
514
*/
515
rf->rf_lo_gain = (loop2 * 6) - (loop1 * 4) - 11;
516
rf->rf_rx_gain = trsw * 2;
517
DPRINTF(mac->mac_sc, BWI_DBG_RF | BWI_DBG_INIT,
518
"lo gain: %u, rx gain: %u\n",
519
rf->rf_lo_gain, rf->rf_rx_gain);
520
521
#undef SAVE_RF_MAX
522
#undef SAVE_PHY_MAX
523
}
524
525
void
526
bwi_rf_init(struct bwi_mac *mac)
527
{
528
struct bwi_rf *rf = &mac->mac_rf;
529
530
if (rf->rf_type == BWI_RF_T_BCM2060) {
531
/* TODO: 11A */
532
} else {
533
if (rf->rf_flags & BWI_RF_F_INITED)
534
RF_WRITE(mac, 0x78, rf->rf_calib);
535
else
536
bwi_rf_init_bcm2050(mac);
537
}
538
}
539
540
static void
541
bwi_rf_off_11a(struct bwi_mac *mac)
542
{
543
RF_WRITE(mac, 0x4, 0xff);
544
RF_WRITE(mac, 0x5, 0xfb);
545
546
PHY_SETBITS(mac, 0x10, 0x8);
547
PHY_SETBITS(mac, 0x11, 0x8);
548
549
PHY_WRITE(mac, 0x15, 0xaa00);
550
}
551
552
static void
553
bwi_rf_off_11bg(struct bwi_mac *mac)
554
{
555
PHY_WRITE(mac, 0x15, 0xaa00);
556
}
557
558
static void
559
bwi_rf_off_11g_rev5(struct bwi_mac *mac)
560
{
561
PHY_SETBITS(mac, 0x811, 0x8c);
562
PHY_CLRBITS(mac, 0x812, 0x8c);
563
}
564
565
static void
566
bwi_rf_work_around(struct bwi_mac *mac, u_int chan)
567
{
568
struct bwi_softc *sc = mac->mac_sc;
569
struct bwi_rf *rf = &mac->mac_rf;
570
571
if (chan == IEEE80211_CHAN_ANY) {
572
device_printf(sc->sc_dev, "%s invalid channel!!\n", __func__);
573
return;
574
}
575
576
if (rf->rf_type != BWI_RF_T_BCM2050 || rf->rf_rev >= 6)
577
return;
578
579
if (chan <= 10)
580
CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan + 4));
581
else
582
CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(1));
583
DELAY(1000);
584
CSR_WRITE_2(sc, BWI_RF_CHAN, BWI_RF_2GHZ_CHAN(chan));
585
}
586
587
static __inline struct bwi_rf_lo *
588
bwi_rf_lo_find(struct bwi_mac *mac, const struct bwi_tpctl *tpctl)
589
{
590
uint16_t rf_atten, bbp_atten;
591
int remap_rf_atten;
592
593
remap_rf_atten = 1;
594
if (tpctl == NULL) {
595
bbp_atten = 2;
596
rf_atten = 3;
597
} else {
598
if (tpctl->tp_ctrl1 == 3)
599
remap_rf_atten = 0;
600
601
bbp_atten = tpctl->bbp_atten;
602
rf_atten = tpctl->rf_atten;
603
604
if (bbp_atten > 6)
605
bbp_atten = 6;
606
}
607
608
if (remap_rf_atten) {
609
#define MAP_MAX 10
610
static const uint16_t map[MAP_MAX] =
611
{ 11, 10, 11, 12, 13, 12, 13, 12, 13, 12 };
612
613
#if 0
614
KASSERT(rf_atten < MAP_MAX, ("rf_atten %d", rf_atten));
615
rf_atten = map[rf_atten];
616
#else
617
if (rf_atten >= MAP_MAX) {
618
rf_atten = 0; /* XXX */
619
} else {
620
rf_atten = map[rf_atten];
621
}
622
#endif
623
#undef MAP_MAX
624
}
625
626
return bwi_get_rf_lo(mac, rf_atten, bbp_atten);
627
}
628
629
void
630
bwi_rf_lo_adjust(struct bwi_mac *mac, const struct bwi_tpctl *tpctl)
631
{
632
const struct bwi_rf_lo *lo;
633
634
lo = bwi_rf_lo_find(mac, tpctl);
635
RF_LO_WRITE(mac, lo);
636
}
637
638
static void
639
bwi_rf_lo_write(struct bwi_mac *mac, const struct bwi_rf_lo *lo)
640
{
641
uint16_t val;
642
643
val = (uint8_t)lo->ctrl_lo;
644
val |= ((uint8_t)lo->ctrl_hi) << 8;
645
646
PHY_WRITE(mac, BWI_PHYR_RF_LO, val);
647
}
648
649
static int
650
bwi_rf_gain_max_reached(struct bwi_mac *mac, int idx)
651
{
652
PHY_FILT_SETBITS(mac, 0x812, 0xf0ff, idx << 8);
653
PHY_FILT_SETBITS(mac, 0x15, 0xfff, 0xa000);
654
PHY_SETBITS(mac, 0x15, 0xf000);
655
656
DELAY(20);
657
658
return (PHY_READ(mac, 0x2d) >= 0xdfc);
659
}
660
661
/* XXX use bitmap array */
662
static __inline uint16_t
663
bitswap4(uint16_t val)
664
{
665
uint16_t ret;
666
667
ret = (val & 0x8) >> 3;
668
ret |= (val & 0x4) >> 1;
669
ret |= (val & 0x2) << 1;
670
ret |= (val & 0x1) << 3;
671
return ret;
672
}
673
674
static __inline uint16_t
675
bwi_phy812_value(struct bwi_mac *mac, uint16_t lpd)
676
{
677
struct bwi_softc *sc = mac->mac_sc;
678
struct bwi_phy *phy = &mac->mac_phy;
679
struct bwi_rf *rf = &mac->mac_rf;
680
uint16_t lo_gain, ext_lna, loop;
681
682
if ((phy->phy_flags & BWI_PHY_F_LINKED) == 0)
683
return 0;
684
685
lo_gain = rf->rf_lo_gain;
686
if (rf->rf_rev == 8)
687
lo_gain += 0x3e;
688
else
689
lo_gain += 0x26;
690
691
if (lo_gain >= 0x46) {
692
lo_gain -= 0x46;
693
ext_lna = 0x3000;
694
} else if (lo_gain >= 0x3a) {
695
lo_gain -= 0x3a;
696
ext_lna = 0x1000;
697
} else if (lo_gain >= 0x2e) {
698
lo_gain -= 0x2e;
699
ext_lna = 0x2000;
700
} else {
701
lo_gain -= 0x10;
702
ext_lna = 0;
703
}
704
705
for (loop = 0; loop < 16; ++loop) {
706
lo_gain -= (6 * loop);
707
if (lo_gain < 6)
708
break;
709
}
710
711
if (phy->phy_rev >= 7 && (sc->sc_card_flags & BWI_CARD_F_EXT_LNA)) {
712
if (ext_lna)
713
ext_lna |= 0x8000;
714
ext_lna |= (loop << 8);
715
switch (lpd) {
716
case 0x011:
717
return 0x8f92;
718
case 0x001:
719
return (0x8092 | ext_lna);
720
case 0x101:
721
return (0x2092 | ext_lna);
722
case 0x100:
723
return (0x2093 | ext_lna);
724
default:
725
panic("unsupported lpd\n");
726
}
727
} else {
728
ext_lna |= (loop << 8);
729
switch (lpd) {
730
case 0x011:
731
return 0xf92;
732
case 0x001:
733
case 0x101:
734
return (0x92 | ext_lna);
735
case 0x100:
736
return (0x93 | ext_lna);
737
default:
738
panic("unsupported lpd\n");
739
}
740
}
741
742
panic("never reached\n");
743
return 0;
744
}
745
746
void
747
bwi_rf_init_bcm2050(struct bwi_mac *mac)
748
{
749
#define SAVE_RF_MAX 3
750
#define SAVE_PHY_COMM_MAX 4
751
#define SAVE_PHY_11G_MAX 6
752
753
static const uint16_t save_rf_regs[SAVE_RF_MAX] =
754
{ 0x0043, 0x0051, 0x0052 };
755
static const uint16_t save_phy_regs_comm[SAVE_PHY_COMM_MAX] =
756
{ 0x0015, 0x005a, 0x0059, 0x0058 };
757
static const uint16_t save_phy_regs_11g[SAVE_PHY_11G_MAX] =
758
{ 0x0811, 0x0812, 0x0814, 0x0815, 0x0429, 0x0802 };
759
760
uint16_t save_rf[SAVE_RF_MAX];
761
uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
762
uint16_t save_phy_11g[SAVE_PHY_11G_MAX];
763
uint16_t phyr_35, phyr_30 = 0, rfr_78, phyr_80f = 0, phyr_810 = 0;
764
uint16_t bphy_ctrl = 0, bbp_atten, rf_chan_ex;
765
uint16_t phy812_val;
766
uint16_t calib;
767
uint32_t test_lim, test;
768
struct bwi_softc *sc = mac->mac_sc;
769
struct bwi_phy *phy = &mac->mac_phy;
770
struct bwi_rf *rf = &mac->mac_rf;
771
int i;
772
773
/*
774
* Save registers for later restoring
775
*/
776
for (i = 0; i < SAVE_RF_MAX; ++i)
777
save_rf[i] = RF_READ(mac, save_rf_regs[i]);
778
for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
779
save_phy_comm[i] = PHY_READ(mac, save_phy_regs_comm[i]);
780
781
if (phy->phy_mode == IEEE80211_MODE_11B) {
782
phyr_30 = PHY_READ(mac, 0x30);
783
bphy_ctrl = CSR_READ_2(sc, BWI_BPHY_CTRL);
784
785
PHY_WRITE(mac, 0x30, 0xff);
786
CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x3f3f);
787
} else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
788
for (i = 0; i < SAVE_PHY_11G_MAX; ++i) {
789
save_phy_11g[i] =
790
PHY_READ(mac, save_phy_regs_11g[i]);
791
}
792
793
PHY_SETBITS(mac, 0x814, 0x3);
794
PHY_CLRBITS(mac, 0x815, 0x3);
795
PHY_CLRBITS(mac, 0x429, 0x8000);
796
PHY_CLRBITS(mac, 0x802, 0x3);
797
798
phyr_80f = PHY_READ(mac, 0x80f);
799
phyr_810 = PHY_READ(mac, 0x810);
800
801
if (phy->phy_rev >= 3)
802
PHY_WRITE(mac, 0x80f, 0xc020);
803
else
804
PHY_WRITE(mac, 0x80f, 0x8020);
805
PHY_WRITE(mac, 0x810, 0);
806
807
phy812_val = bwi_phy812_value(mac, 0x011);
808
PHY_WRITE(mac, 0x812, phy812_val);
809
if (phy->phy_rev < 7 ||
810
(sc->sc_card_flags & BWI_CARD_F_EXT_LNA) == 0)
811
PHY_WRITE(mac, 0x811, 0x1b3);
812
else
813
PHY_WRITE(mac, 0x811, 0x9b3);
814
}
815
CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
816
817
phyr_35 = PHY_READ(mac, 0x35);
818
PHY_CLRBITS(mac, 0x35, 0x80);
819
820
bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
821
rf_chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
822
823
if (phy->phy_version == 0) {
824
CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122);
825
} else {
826
if (phy->phy_version >= 2)
827
PHY_FILT_SETBITS(mac, 0x3, 0xffbf, 0x40);
828
CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000);
829
}
830
831
calib = bwi_rf_calibval(mac);
832
833
if (phy->phy_mode == IEEE80211_MODE_11B)
834
RF_WRITE(mac, 0x78, 0x26);
835
836
if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
837
phy812_val = bwi_phy812_value(mac, 0x011);
838
PHY_WRITE(mac, 0x812, phy812_val);
839
}
840
841
PHY_WRITE(mac, 0x15, 0xbfaf);
842
PHY_WRITE(mac, 0x2b, 0x1403);
843
844
if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
845
phy812_val = bwi_phy812_value(mac, 0x001);
846
PHY_WRITE(mac, 0x812, phy812_val);
847
}
848
849
PHY_WRITE(mac, 0x15, 0xbfa0);
850
851
RF_SETBITS(mac, 0x51, 0x4);
852
if (rf->rf_rev == 8) {
853
RF_WRITE(mac, 0x43, 0x1f);
854
} else {
855
RF_WRITE(mac, 0x52, 0);
856
RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9);
857
}
858
859
test_lim = 0;
860
PHY_WRITE(mac, 0x58, 0);
861
for (i = 0; i < 16; ++i) {
862
PHY_WRITE(mac, 0x5a, 0x480);
863
PHY_WRITE(mac, 0x59, 0xc810);
864
865
PHY_WRITE(mac, 0x58, 0xd);
866
if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
867
phy812_val = bwi_phy812_value(mac, 0x101);
868
PHY_WRITE(mac, 0x812, phy812_val);
869
}
870
PHY_WRITE(mac, 0x15, 0xafb0);
871
DELAY(10);
872
873
if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
874
phy812_val = bwi_phy812_value(mac, 0x101);
875
PHY_WRITE(mac, 0x812, phy812_val);
876
}
877
PHY_WRITE(mac, 0x15, 0xefb0);
878
DELAY(10);
879
880
if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
881
phy812_val = bwi_phy812_value(mac, 0x100);
882
PHY_WRITE(mac, 0x812, phy812_val);
883
}
884
PHY_WRITE(mac, 0x15, 0xfff0);
885
DELAY(20);
886
887
test_lim += PHY_READ(mac, 0x2d);
888
889
PHY_WRITE(mac, 0x58, 0);
890
if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
891
phy812_val = bwi_phy812_value(mac, 0x101);
892
PHY_WRITE(mac, 0x812, phy812_val);
893
}
894
PHY_WRITE(mac, 0x15, 0xafb0);
895
}
896
++test_lim;
897
test_lim >>= 9;
898
899
DELAY(10);
900
901
test = 0;
902
PHY_WRITE(mac, 0x58, 0);
903
for (i = 0; i < 16; ++i) {
904
int j;
905
906
rfr_78 = (bitswap4(i) << 1) | 0x20;
907
RF_WRITE(mac, 0x78, rfr_78);
908
DELAY(10);
909
910
/* NB: This block is slight different than the above one */
911
for (j = 0; j < 16; ++j) {
912
PHY_WRITE(mac, 0x5a, 0xd80);
913
PHY_WRITE(mac, 0x59, 0xc810);
914
915
PHY_WRITE(mac, 0x58, 0xd);
916
if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
917
phy->phy_rev >= 2) {
918
phy812_val = bwi_phy812_value(mac, 0x101);
919
PHY_WRITE(mac, 0x812, phy812_val);
920
}
921
PHY_WRITE(mac, 0x15, 0xafb0);
922
DELAY(10);
923
924
if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
925
phy->phy_rev >= 2) {
926
phy812_val = bwi_phy812_value(mac, 0x101);
927
PHY_WRITE(mac, 0x812, phy812_val);
928
}
929
PHY_WRITE(mac, 0x15, 0xefb0);
930
DELAY(10);
931
932
if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
933
phy->phy_rev >= 2) {
934
phy812_val = bwi_phy812_value(mac, 0x100);
935
PHY_WRITE(mac, 0x812, phy812_val);
936
}
937
PHY_WRITE(mac, 0x15, 0xfff0);
938
DELAY(10);
939
940
test += PHY_READ(mac, 0x2d);
941
942
PHY_WRITE(mac, 0x58, 0);
943
if ((phy->phy_flags & BWI_PHY_F_LINKED) ||
944
phy->phy_rev >= 2) {
945
phy812_val = bwi_phy812_value(mac, 0x101);
946
PHY_WRITE(mac, 0x812, phy812_val);
947
}
948
PHY_WRITE(mac, 0x15, 0xafb0);
949
}
950
951
++test;
952
test >>= 8;
953
954
if (test > test_lim)
955
break;
956
}
957
if (i > 15)
958
rf->rf_calib = rfr_78;
959
else
960
rf->rf_calib = calib;
961
if (rf->rf_calib != 0xffff) {
962
DPRINTF(sc, BWI_DBG_RF | BWI_DBG_INIT,
963
"RF calibration value: 0x%04x\n", rf->rf_calib);
964
rf->rf_flags |= BWI_RF_F_INITED;
965
}
966
967
/*
968
* Restore trashes registers
969
*/
970
PHY_WRITE(mac, save_phy_regs_comm[0], save_phy_comm[0]);
971
972
for (i = 0; i < SAVE_RF_MAX; ++i) {
973
int pos = (i + 1) % SAVE_RF_MAX;
974
975
RF_WRITE(mac, save_rf_regs[pos], save_rf[pos]);
976
}
977
for (i = 1; i < SAVE_PHY_COMM_MAX; ++i)
978
PHY_WRITE(mac, save_phy_regs_comm[i], save_phy_comm[i]);
979
980
CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten);
981
if (phy->phy_version != 0)
982
CSR_WRITE_2(sc, BWI_RF_CHAN_EX, rf_chan_ex);
983
984
PHY_WRITE(mac, 0x35, phyr_35);
985
bwi_rf_work_around(mac, rf->rf_curchan);
986
987
if (phy->phy_mode == IEEE80211_MODE_11B) {
988
PHY_WRITE(mac, 0x30, phyr_30);
989
CSR_WRITE_2(sc, BWI_BPHY_CTRL, bphy_ctrl);
990
} else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
991
/* XXX Spec only says when PHY is linked (gmode) */
992
CSR_CLRBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
993
994
for (i = 0; i < SAVE_PHY_11G_MAX; ++i) {
995
PHY_WRITE(mac, save_phy_regs_11g[i],
996
save_phy_11g[i]);
997
}
998
999
PHY_WRITE(mac, 0x80f, phyr_80f);
1000
PHY_WRITE(mac, 0x810, phyr_810);
1001
}
1002
1003
#undef SAVE_PHY_11G_MAX
1004
#undef SAVE_PHY_COMM_MAX
1005
#undef SAVE_RF_MAX
1006
}
1007
1008
static uint16_t
1009
bwi_rf_calibval(struct bwi_mac *mac)
1010
{
1011
/* http://bcm-specs.sipsolutions.net/RCCTable */
1012
static const uint16_t rf_calibvals[] = {
1013
0x2, 0x3, 0x1, 0xf, 0x6, 0x7, 0x5, 0xf,
1014
0xa, 0xb, 0x9, 0xf, 0xe, 0xf, 0xd, 0xf
1015
};
1016
uint16_t val, calib;
1017
int idx;
1018
1019
val = RF_READ(mac, BWI_RFR_BBP_ATTEN);
1020
idx = __SHIFTOUT(val, BWI_RFR_BBP_ATTEN_CALIB_IDX);
1021
KASSERT(idx < (int)nitems(rf_calibvals), ("idx %d", idx));
1022
1023
calib = rf_calibvals[idx] << 1;
1024
if (val & BWI_RFR_BBP_ATTEN_CALIB_BIT)
1025
calib |= 0x1;
1026
calib |= 0x20;
1027
1028
return calib;
1029
}
1030
1031
static __inline int32_t
1032
_bwi_adjust_devide(int32_t num, int32_t den)
1033
{
1034
if (num < 0)
1035
return (num / den);
1036
else
1037
return (num + den / 2) / den;
1038
}
1039
1040
/*
1041
* http://bcm-specs.sipsolutions.net/TSSI_to_DBM_Table
1042
* "calculating table entries"
1043
*/
1044
static int
1045
bwi_rf_calc_txpower(int8_t *txpwr, uint8_t idx, const int16_t pa_params[])
1046
{
1047
int32_t m1, m2, f, dbm;
1048
int i;
1049
1050
m1 = _bwi_adjust_devide(16 * pa_params[0] + idx * pa_params[1], 32);
1051
m2 = imax(_bwi_adjust_devide(32768 + idx * pa_params[2], 256), 1);
1052
1053
#define ITER_MAX 16
1054
1055
f = 256;
1056
for (i = 0; i < ITER_MAX; ++i) {
1057
int32_t q, d;
1058
1059
q = _bwi_adjust_devide(
1060
f * 4096 - _bwi_adjust_devide(m2 * f, 16) * f, 2048);
1061
d = abs(q - f);
1062
f = q;
1063
1064
if (d < 2)
1065
break;
1066
}
1067
if (i == ITER_MAX)
1068
return EINVAL;
1069
1070
#undef ITER_MAX
1071
1072
dbm = _bwi_adjust_devide(m1 * f, 8192);
1073
if (dbm < -127)
1074
dbm = -127;
1075
else if (dbm > 128)
1076
dbm = 128;
1077
1078
*txpwr = dbm;
1079
return 0;
1080
}
1081
1082
int
1083
bwi_rf_map_txpower(struct bwi_mac *mac)
1084
{
1085
struct bwi_softc *sc = mac->mac_sc;
1086
struct bwi_rf *rf = &mac->mac_rf;
1087
struct bwi_phy *phy = &mac->mac_phy;
1088
uint16_t sprom_ofs, val, mask;
1089
int16_t pa_params[3];
1090
int error = 0, i, ant_gain, reg_txpower_max;
1091
1092
/*
1093
* Find out max TX power
1094
*/
1095
val = bwi_read_sprom(sc, BWI_SPROM_MAX_TXPWR);
1096
if (phy->phy_mode == IEEE80211_MODE_11A) {
1097
rf->rf_txpower_max = __SHIFTOUT(val,
1098
BWI_SPROM_MAX_TXPWR_MASK_11A);
1099
} else {
1100
rf->rf_txpower_max = __SHIFTOUT(val,
1101
BWI_SPROM_MAX_TXPWR_MASK_11BG);
1102
1103
if ((sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) &&
1104
phy->phy_mode == IEEE80211_MODE_11G)
1105
rf->rf_txpower_max -= 3;
1106
}
1107
if (rf->rf_txpower_max <= 0) {
1108
device_printf(sc->sc_dev, "invalid max txpower in sprom\n");
1109
rf->rf_txpower_max = 74;
1110
}
1111
DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
1112
"max txpower from sprom: %d dBm\n", rf->rf_txpower_max);
1113
1114
/*
1115
* Find out region/domain max TX power, which is adjusted
1116
* by antenna gain and 1.5 dBm fluctuation as mentioned
1117
* in v3 spec.
1118
*/
1119
val = bwi_read_sprom(sc, BWI_SPROM_ANT_GAIN);
1120
if (phy->phy_mode == IEEE80211_MODE_11A)
1121
ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11A);
1122
else
1123
ant_gain = __SHIFTOUT(val, BWI_SPROM_ANT_GAIN_MASK_11BG);
1124
if (ant_gain == 0xff) {
1125
device_printf(sc->sc_dev, "invalid antenna gain in sprom\n");
1126
ant_gain = 2;
1127
}
1128
ant_gain *= 4;
1129
DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
1130
"ant gain %d dBm\n", ant_gain);
1131
1132
reg_txpower_max = 90 - ant_gain - 6; /* XXX magic number */
1133
DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
1134
"region/domain max txpower %d dBm\n", reg_txpower_max);
1135
1136
/*
1137
* Force max TX power within region/domain TX power limit
1138
*/
1139
if (rf->rf_txpower_max > reg_txpower_max)
1140
rf->rf_txpower_max = reg_txpower_max;
1141
DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
1142
"max txpower %d dBm\n", rf->rf_txpower_max);
1143
1144
/*
1145
* Create TSSI to TX power mapping
1146
*/
1147
1148
if (sc->sc_bbp_id == BWI_BBPID_BCM4301 &&
1149
rf->rf_type != BWI_RF_T_BCM2050) {
1150
rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI;
1151
bcopy(bwi_txpower_map_11b, rf->rf_txpower_map0,
1152
sizeof(rf->rf_txpower_map0));
1153
goto back;
1154
}
1155
1156
#define IS_VALID_PA_PARAM(p) ((p) != 0 && (p) != -1)
1157
1158
/*
1159
* Extract PA parameters
1160
*/
1161
if (phy->phy_mode == IEEE80211_MODE_11A)
1162
sprom_ofs = BWI_SPROM_PA_PARAM_11A;
1163
else
1164
sprom_ofs = BWI_SPROM_PA_PARAM_11BG;
1165
for (i = 0; i < nitems(pa_params); ++i)
1166
pa_params[i] = (int16_t)bwi_read_sprom(sc, sprom_ofs + (i * 2));
1167
1168
for (i = 0; i < nitems(pa_params); ++i) {
1169
/*
1170
* If one of the PA parameters from SPROM is not valid,
1171
* fall back to the default values, if there are any.
1172
*/
1173
if (!IS_VALID_PA_PARAM(pa_params[i])) {
1174
const int8_t *txpower_map;
1175
1176
if (phy->phy_mode == IEEE80211_MODE_11A) {
1177
device_printf(sc->sc_dev,
1178
"no tssi2dbm table for 11a PHY\n");
1179
return ENXIO;
1180
}
1181
1182
if (phy->phy_mode == IEEE80211_MODE_11G) {
1183
DPRINTF(sc,
1184
BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
1185
"%s\n", "use default 11g TSSI map");
1186
txpower_map = bwi_txpower_map_11g;
1187
} else {
1188
DPRINTF(sc,
1189
BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
1190
"%s\n", "use default 11b TSSI map");
1191
txpower_map = bwi_txpower_map_11b;
1192
}
1193
1194
rf->rf_idle_tssi0 = BWI_DEFAULT_IDLE_TSSI;
1195
bcopy(txpower_map, rf->rf_txpower_map0,
1196
sizeof(rf->rf_txpower_map0));
1197
goto back;
1198
}
1199
}
1200
1201
/*
1202
* All of the PA parameters from SPROM are valid.
1203
*/
1204
1205
/*
1206
* Extract idle TSSI from SPROM.
1207
*/
1208
val = bwi_read_sprom(sc, BWI_SPROM_IDLE_TSSI);
1209
DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
1210
"sprom idle tssi: 0x%04x\n", val);
1211
1212
if (phy->phy_mode == IEEE80211_MODE_11A)
1213
mask = BWI_SPROM_IDLE_TSSI_MASK_11A;
1214
else
1215
mask = BWI_SPROM_IDLE_TSSI_MASK_11BG;
1216
1217
rf->rf_idle_tssi0 = (int)__SHIFTOUT(val, mask);
1218
if (!IS_VALID_PA_PARAM(rf->rf_idle_tssi0))
1219
rf->rf_idle_tssi0 = 62;
1220
1221
#undef IS_VALID_PA_PARAM
1222
1223
/*
1224
* Calculate TX power map, which is indexed by TSSI
1225
*/
1226
DPRINTF(sc, BWI_DBG_RF | BWI_DBG_ATTACH | BWI_DBG_TXPOWER,
1227
"%s\n", "TSSI-TX power map:");
1228
for (i = 0; i < BWI_TSSI_MAX; ++i) {
1229
error = bwi_rf_calc_txpower(&rf->rf_txpower_map0[i], i,
1230
pa_params);
1231
if (error) {
1232
device_printf(sc->sc_dev,
1233
"bwi_rf_calc_txpower failed\n");
1234
break;
1235
}
1236
1237
#ifdef BWI_DEBUG
1238
if (i != 0 && i % 8 == 0) {
1239
_DPRINTF(sc,
1240
BWI_DBG_RF | BWI_DBG_ATTACH | BWI_DBG_TXPOWER,
1241
"%s\n", "");
1242
}
1243
#endif
1244
_DPRINTF(sc, BWI_DBG_RF | BWI_DBG_ATTACH | BWI_DBG_TXPOWER,
1245
"%d ", rf->rf_txpower_map0[i]);
1246
}
1247
_DPRINTF(sc, BWI_DBG_RF | BWI_DBG_ATTACH | BWI_DBG_TXPOWER,
1248
"%s\n", "");
1249
back:
1250
DPRINTF(sc, BWI_DBG_RF | BWI_DBG_TXPOWER | BWI_DBG_ATTACH,
1251
"idle tssi0: %d\n", rf->rf_idle_tssi0);
1252
return error;
1253
}
1254
1255
static void
1256
bwi_rf_lo_update_11g(struct bwi_mac *mac)
1257
{
1258
struct bwi_softc *sc = mac->mac_sc;
1259
struct bwi_rf *rf = &mac->mac_rf;
1260
struct bwi_phy *phy = &mac->mac_phy;
1261
struct bwi_tpctl *tpctl = &mac->mac_tpctl;
1262
struct rf_saveregs regs;
1263
uint16_t ant_div, chan_ex;
1264
uint8_t devi_ctrl;
1265
u_int orig_chan;
1266
1267
/*
1268
* Save RF/PHY registers for later restoration
1269
*/
1270
orig_chan = rf->rf_curchan;
1271
bzero(&regs, sizeof(regs));
1272
1273
if (phy->phy_flags & BWI_PHY_F_LINKED) {
1274
SAVE_PHY_REG(mac, &regs, 429);
1275
SAVE_PHY_REG(mac, &regs, 802);
1276
1277
PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff);
1278
PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc);
1279
}
1280
1281
ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
1282
CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div | 0x8000);
1283
chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
1284
1285
SAVE_PHY_REG(mac, &regs, 15);
1286
SAVE_PHY_REG(mac, &regs, 2a);
1287
SAVE_PHY_REG(mac, &regs, 35);
1288
SAVE_PHY_REG(mac, &regs, 60);
1289
SAVE_RF_REG(mac, &regs, 43);
1290
SAVE_RF_REG(mac, &regs, 7a);
1291
SAVE_RF_REG(mac, &regs, 52);
1292
if (phy->phy_flags & BWI_PHY_F_LINKED) {
1293
SAVE_PHY_REG(mac, &regs, 811);
1294
SAVE_PHY_REG(mac, &regs, 812);
1295
SAVE_PHY_REG(mac, &regs, 814);
1296
SAVE_PHY_REG(mac, &regs, 815);
1297
}
1298
1299
/* Force to channel 6 */
1300
bwi_rf_set_chan(mac, 6, 0);
1301
1302
if (phy->phy_flags & BWI_PHY_F_LINKED) {
1303
PHY_WRITE(mac, 0x429, regs.phy_429 & 0x7fff);
1304
PHY_WRITE(mac, 0x802, regs.phy_802 & 0xfffc);
1305
bwi_mac_dummy_xmit(mac);
1306
}
1307
RF_WRITE(mac, 0x43, 0x6);
1308
1309
bwi_phy_set_bbp_atten(mac, 2);
1310
1311
CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0);
1312
1313
PHY_WRITE(mac, 0x2e, 0x7f);
1314
PHY_WRITE(mac, 0x80f, 0x78);
1315
PHY_WRITE(mac, 0x35, regs.phy_35 & 0xff7f);
1316
RF_WRITE(mac, 0x7a, regs.rf_7a & 0xfff0);
1317
PHY_WRITE(mac, 0x2b, 0x203);
1318
PHY_WRITE(mac, 0x2a, 0x8a3);
1319
1320
if (phy->phy_flags & BWI_PHY_F_LINKED) {
1321
PHY_WRITE(mac, 0x814, regs.phy_814 | 0x3);
1322
PHY_WRITE(mac, 0x815, regs.phy_815 & 0xfffc);
1323
PHY_WRITE(mac, 0x811, 0x1b3);
1324
PHY_WRITE(mac, 0x812, 0xb2);
1325
}
1326
1327
if ((sc->sc_flags & BWI_F_RUNNING) == 0)
1328
tpctl->tp_ctrl2 = bwi_rf_get_tp_ctrl2(mac);
1329
PHY_WRITE(mac, 0x80f, 0x8078);
1330
1331
/*
1332
* Measure all RF LO
1333
*/
1334
devi_ctrl = _bwi_rf_lo_update_11g(mac, regs.rf_7a);
1335
1336
/*
1337
* Restore saved RF/PHY registers
1338
*/
1339
if (phy->phy_flags & BWI_PHY_F_LINKED) {
1340
PHY_WRITE(mac, 0x15, 0xe300);
1341
PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa0);
1342
DELAY(5);
1343
PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa2);
1344
DELAY(2);
1345
PHY_WRITE(mac, 0x812, (devi_ctrl << 8) | 0xa3);
1346
} else {
1347
PHY_WRITE(mac, 0x15, devi_ctrl | 0xefa0);
1348
}
1349
1350
if ((sc->sc_flags & BWI_F_RUNNING) == 0)
1351
tpctl = NULL;
1352
bwi_rf_lo_adjust(mac, tpctl);
1353
1354
PHY_WRITE(mac, 0x2e, 0x807f);
1355
if (phy->phy_flags & BWI_PHY_F_LINKED)
1356
PHY_WRITE(mac, 0x2f, 0x202);
1357
else
1358
PHY_WRITE(mac, 0x2f, 0x101);
1359
1360
CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
1361
1362
RESTORE_PHY_REG(mac, &regs, 15);
1363
RESTORE_PHY_REG(mac, &regs, 2a);
1364
RESTORE_PHY_REG(mac, &regs, 35);
1365
RESTORE_PHY_REG(mac, &regs, 60);
1366
1367
RESTORE_RF_REG(mac, &regs, 43);
1368
RESTORE_RF_REG(mac, &regs, 7a);
1369
1370
regs.rf_52 &= 0xf0;
1371
regs.rf_52 |= (RF_READ(mac, 0x52) & 0xf);
1372
RF_WRITE(mac, 0x52, regs.rf_52);
1373
1374
CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
1375
1376
if (phy->phy_flags & BWI_PHY_F_LINKED) {
1377
RESTORE_PHY_REG(mac, &regs, 811);
1378
RESTORE_PHY_REG(mac, &regs, 812);
1379
RESTORE_PHY_REG(mac, &regs, 814);
1380
RESTORE_PHY_REG(mac, &regs, 815);
1381
RESTORE_PHY_REG(mac, &regs, 429);
1382
RESTORE_PHY_REG(mac, &regs, 802);
1383
}
1384
1385
bwi_rf_set_chan(mac, orig_chan, 1);
1386
}
1387
1388
static uint32_t
1389
bwi_rf_lo_devi_measure(struct bwi_mac *mac, uint16_t ctrl)
1390
{
1391
struct bwi_phy *phy = &mac->mac_phy;
1392
uint32_t devi = 0;
1393
int i;
1394
1395
if (phy->phy_flags & BWI_PHY_F_LINKED)
1396
ctrl <<= 8;
1397
1398
for (i = 0; i < 8; ++i) {
1399
if (phy->phy_flags & BWI_PHY_F_LINKED) {
1400
PHY_WRITE(mac, 0x15, 0xe300);
1401
PHY_WRITE(mac, 0x812, ctrl | 0xb0);
1402
DELAY(5);
1403
PHY_WRITE(mac, 0x812, ctrl | 0xb2);
1404
DELAY(2);
1405
PHY_WRITE(mac, 0x812, ctrl | 0xb3);
1406
DELAY(4);
1407
PHY_WRITE(mac, 0x15, 0xf300);
1408
} else {
1409
PHY_WRITE(mac, 0x15, ctrl | 0xefa0);
1410
DELAY(2);
1411
PHY_WRITE(mac, 0x15, ctrl | 0xefe0);
1412
DELAY(4);
1413
PHY_WRITE(mac, 0x15, ctrl | 0xffe0);
1414
}
1415
DELAY(8);
1416
devi += PHY_READ(mac, 0x2d);
1417
}
1418
return devi;
1419
}
1420
1421
static uint16_t
1422
bwi_rf_get_tp_ctrl2(struct bwi_mac *mac)
1423
{
1424
uint32_t devi_min;
1425
uint16_t tp_ctrl2 = 0;
1426
int i;
1427
1428
RF_WRITE(mac, 0x52, 0);
1429
DELAY(10);
1430
devi_min = bwi_rf_lo_devi_measure(mac, 0);
1431
1432
for (i = 0; i < 16; ++i) {
1433
uint32_t devi;
1434
1435
RF_WRITE(mac, 0x52, i);
1436
DELAY(10);
1437
devi = bwi_rf_lo_devi_measure(mac, 0);
1438
1439
if (devi < devi_min) {
1440
devi_min = devi;
1441
tp_ctrl2 = i;
1442
}
1443
}
1444
return tp_ctrl2;
1445
}
1446
1447
static uint8_t
1448
_bwi_rf_lo_update_11g(struct bwi_mac *mac, uint16_t orig_rf7a)
1449
{
1450
#define RF_ATTEN_LISTSZ 14
1451
#define BBP_ATTEN_MAX 4 /* half */
1452
1453
static const int rf_atten_list[RF_ATTEN_LISTSZ] =
1454
{ 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 1, 2, 3, 4 };
1455
static const int rf_atten_init_list[RF_ATTEN_LISTSZ] =
1456
{ 0, 3, 1, 5, 7, 3, 2, 0, 4, 6, -1, -1, -1, -1 };
1457
static const int rf_lo_measure_order[RF_ATTEN_LISTSZ] =
1458
{ 3, 1, 5, 7, 9, 2, 0, 4, 6, 8, 10, 11, 12, 13 };
1459
1460
struct bwi_softc *sc = mac->mac_sc;
1461
struct bwi_rf_lo lo_save, *lo;
1462
uint8_t devi_ctrl = 0;
1463
int idx, adj_rf7a = 0;
1464
1465
bzero(&lo_save, sizeof(lo_save));
1466
for (idx = 0; idx < RF_ATTEN_LISTSZ; ++idx) {
1467
int init_rf_atten = rf_atten_init_list[idx];
1468
int rf_atten = rf_atten_list[idx];
1469
int bbp_atten;
1470
1471
for (bbp_atten = 0; bbp_atten < BBP_ATTEN_MAX; ++bbp_atten) {
1472
uint16_t tp_ctrl2, rf7a;
1473
1474
if ((sc->sc_flags & BWI_F_RUNNING) == 0) {
1475
if (idx == 0) {
1476
bzero(&lo_save, sizeof(lo_save));
1477
} else if (init_rf_atten < 0) {
1478
lo = bwi_get_rf_lo(mac,
1479
rf_atten, 2 * bbp_atten);
1480
bcopy(lo, &lo_save, sizeof(lo_save));
1481
} else {
1482
lo = bwi_get_rf_lo(mac,
1483
init_rf_atten, 0);
1484
bcopy(lo, &lo_save, sizeof(lo_save));
1485
}
1486
1487
devi_ctrl = 0;
1488
adj_rf7a = 0;
1489
1490
/*
1491
* XXX
1492
* Linux driver overflows 'val'
1493
*/
1494
if (init_rf_atten >= 0) {
1495
int val;
1496
1497
val = rf_atten * 2 + bbp_atten;
1498
if (val > 14) {
1499
adj_rf7a = 1;
1500
if (val > 17)
1501
devi_ctrl = 1;
1502
if (val > 19)
1503
devi_ctrl = 2;
1504
}
1505
}
1506
} else {
1507
lo = bwi_get_rf_lo(mac,
1508
rf_atten, 2 * bbp_atten);
1509
if (!bwi_rf_lo_isused(mac, lo))
1510
continue;
1511
bcopy(lo, &lo_save, sizeof(lo_save));
1512
1513
devi_ctrl = 3;
1514
adj_rf7a = 0;
1515
}
1516
1517
RF_WRITE(mac, BWI_RFR_ATTEN, rf_atten);
1518
1519
tp_ctrl2 = mac->mac_tpctl.tp_ctrl2;
1520
if (init_rf_atten < 0)
1521
tp_ctrl2 |= (3 << 4);
1522
RF_WRITE(mac, BWI_RFR_TXPWR, tp_ctrl2);
1523
1524
DELAY(10);
1525
1526
bwi_phy_set_bbp_atten(mac, bbp_atten * 2);
1527
1528
rf7a = orig_rf7a & 0xfff0;
1529
if (adj_rf7a)
1530
rf7a |= 0x8;
1531
RF_WRITE(mac, 0x7a, rf7a);
1532
1533
lo = bwi_get_rf_lo(mac,
1534
rf_lo_measure_order[idx], bbp_atten * 2);
1535
bwi_rf_lo_measure_11g(mac, &lo_save, lo, devi_ctrl);
1536
}
1537
}
1538
return devi_ctrl;
1539
1540
#undef RF_ATTEN_LISTSZ
1541
#undef BBP_ATTEN_MAX
1542
}
1543
1544
static void
1545
bwi_rf_lo_measure_11g(struct bwi_mac *mac, const struct bwi_rf_lo *src_lo,
1546
struct bwi_rf_lo *dst_lo, uint8_t devi_ctrl)
1547
{
1548
#define LO_ADJUST_MIN 1
1549
#define LO_ADJUST_MAX 8
1550
#define LO_ADJUST(hi, lo) { .ctrl_hi = hi, .ctrl_lo = lo }
1551
static const struct bwi_rf_lo rf_lo_adjust[LO_ADJUST_MAX] = {
1552
LO_ADJUST(1, 1),
1553
LO_ADJUST(1, 0),
1554
LO_ADJUST(1, -1),
1555
LO_ADJUST(0, -1),
1556
LO_ADJUST(-1, -1),
1557
LO_ADJUST(-1, 0),
1558
LO_ADJUST(-1, 1),
1559
LO_ADJUST(0, 1)
1560
};
1561
#undef LO_ADJUST
1562
1563
struct bwi_rf_lo lo_min;
1564
uint32_t devi_min;
1565
int found, loop_count, adjust_state;
1566
1567
bcopy(src_lo, &lo_min, sizeof(lo_min));
1568
RF_LO_WRITE(mac, &lo_min);
1569
devi_min = bwi_rf_lo_devi_measure(mac, devi_ctrl);
1570
1571
loop_count = 12; /* XXX */
1572
adjust_state = 0;
1573
do {
1574
struct bwi_rf_lo lo_base;
1575
int i, fin;
1576
1577
found = 0;
1578
if (adjust_state == 0) {
1579
i = LO_ADJUST_MIN;
1580
fin = LO_ADJUST_MAX;
1581
} else if (adjust_state % 2 == 0) {
1582
i = adjust_state - 1;
1583
fin = adjust_state + 1;
1584
} else {
1585
i = adjust_state - 2;
1586
fin = adjust_state + 2;
1587
}
1588
1589
if (i < LO_ADJUST_MIN)
1590
i += LO_ADJUST_MAX;
1591
KASSERT(i <= LO_ADJUST_MAX && i >= LO_ADJUST_MIN, ("i %d", i));
1592
1593
if (fin > LO_ADJUST_MAX)
1594
fin -= LO_ADJUST_MAX;
1595
KASSERT(fin <= LO_ADJUST_MAX && fin >= LO_ADJUST_MIN,
1596
("fin %d", fin));
1597
1598
bcopy(&lo_min, &lo_base, sizeof(lo_base));
1599
for (;;) {
1600
struct bwi_rf_lo lo;
1601
1602
lo.ctrl_hi = lo_base.ctrl_hi +
1603
rf_lo_adjust[i - 1].ctrl_hi;
1604
lo.ctrl_lo = lo_base.ctrl_lo +
1605
rf_lo_adjust[i - 1].ctrl_lo;
1606
1607
if (abs(lo.ctrl_lo) < 9 && abs(lo.ctrl_hi) < 9) {
1608
uint32_t devi;
1609
1610
RF_LO_WRITE(mac, &lo);
1611
devi = bwi_rf_lo_devi_measure(mac, devi_ctrl);
1612
if (devi < devi_min) {
1613
devi_min = devi;
1614
adjust_state = i;
1615
found = 1;
1616
bcopy(&lo, &lo_min, sizeof(lo_min));
1617
}
1618
}
1619
if (i == fin)
1620
break;
1621
if (i == LO_ADJUST_MAX)
1622
i = LO_ADJUST_MIN;
1623
else
1624
++i;
1625
}
1626
} while (loop_count-- && found);
1627
1628
bcopy(&lo_min, dst_lo, sizeof(*dst_lo));
1629
1630
#undef LO_ADJUST_MIN
1631
#undef LO_ADJUST_MAX
1632
}
1633
1634
static void
1635
bwi_rf_calc_nrssi_slope_11b(struct bwi_mac *mac)
1636
{
1637
#define SAVE_RF_MAX 3
1638
#define SAVE_PHY_MAX 8
1639
1640
static const uint16_t save_rf_regs[SAVE_RF_MAX] =
1641
{ 0x7a, 0x52, 0x43 };
1642
static const uint16_t save_phy_regs[SAVE_PHY_MAX] =
1643
{ 0x30, 0x26, 0x15, 0x2a, 0x20, 0x5a, 0x59, 0x58 };
1644
1645
struct bwi_softc *sc = mac->mac_sc;
1646
struct bwi_rf *rf = &mac->mac_rf;
1647
struct bwi_phy *phy = &mac->mac_phy;
1648
uint16_t save_rf[SAVE_RF_MAX];
1649
uint16_t save_phy[SAVE_PHY_MAX];
1650
uint16_t ant_div, chan_ex;
1651
int16_t nrssi[2];
1652
int i;
1653
1654
/*
1655
* Save RF/PHY registers for later restoration
1656
*/
1657
for (i = 0; i < SAVE_RF_MAX; ++i)
1658
save_rf[i] = RF_READ(mac, save_rf_regs[i]);
1659
for (i = 0; i < SAVE_PHY_MAX; ++i)
1660
save_phy[i] = PHY_READ(mac, save_phy_regs[i]);
1661
1662
ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
1663
CSR_READ_2(sc, BWI_BBP_ATTEN);
1664
chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
1665
1666
/*
1667
* Calculate nrssi0
1668
*/
1669
if (phy->phy_rev >= 5)
1670
RF_CLRBITS(mac, 0x7a, 0xff80);
1671
else
1672
RF_CLRBITS(mac, 0x7a, 0xfff0);
1673
PHY_WRITE(mac, 0x30, 0xff);
1674
1675
CSR_WRITE_2(sc, BWI_BPHY_CTRL, 0x7f7f);
1676
1677
PHY_WRITE(mac, 0x26, 0);
1678
PHY_SETBITS(mac, 0x15, 0x20);
1679
PHY_WRITE(mac, 0x2a, 0x8a3);
1680
RF_SETBITS(mac, 0x7a, 0x80);
1681
1682
nrssi[0] = (int16_t)PHY_READ(mac, 0x27);
1683
1684
/*
1685
* Calculate nrssi1
1686
*/
1687
RF_CLRBITS(mac, 0x7a, 0xff80);
1688
if (phy->phy_version >= 2)
1689
CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x40);
1690
else if (phy->phy_version == 0)
1691
CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0x122);
1692
else
1693
CSR_CLRBITS_2(sc, BWI_RF_CHAN_EX, 0xdfff);
1694
1695
PHY_WRITE(mac, 0x20, 0x3f3f);
1696
PHY_WRITE(mac, 0x15, 0xf330);
1697
1698
RF_WRITE(mac, 0x5a, 0x60);
1699
RF_CLRBITS(mac, 0x43, 0xff0f);
1700
1701
PHY_WRITE(mac, 0x5a, 0x480);
1702
PHY_WRITE(mac, 0x59, 0x810);
1703
PHY_WRITE(mac, 0x58, 0xd);
1704
1705
DELAY(20);
1706
1707
nrssi[1] = (int16_t)PHY_READ(mac, 0x27);
1708
1709
/*
1710
* Restore saved RF/PHY registers
1711
*/
1712
PHY_WRITE(mac, save_phy_regs[0], save_phy[0]);
1713
RF_WRITE(mac, save_rf_regs[0], save_rf[0]);
1714
1715
CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
1716
1717
for (i = 1; i < 4; ++i)
1718
PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
1719
1720
bwi_rf_work_around(mac, rf->rf_curchan);
1721
1722
if (phy->phy_version != 0)
1723
CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
1724
1725
for (; i < SAVE_PHY_MAX; ++i)
1726
PHY_WRITE(mac, save_phy_regs[i], save_phy[i]);
1727
1728
for (i = 1; i < SAVE_RF_MAX; ++i)
1729
RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
1730
1731
/*
1732
* Install calculated narrow RSSI values
1733
*/
1734
if (nrssi[0] == nrssi[1])
1735
rf->rf_nrssi_slope = 0x10000;
1736
else
1737
rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]);
1738
if (nrssi[0] <= -4) {
1739
rf->rf_nrssi[0] = nrssi[0];
1740
rf->rf_nrssi[1] = nrssi[1];
1741
}
1742
1743
#undef SAVE_RF_MAX
1744
#undef SAVE_PHY_MAX
1745
}
1746
1747
static void
1748
bwi_rf_set_nrssi_ofs_11g(struct bwi_mac *mac)
1749
{
1750
#define SAVE_RF_MAX 2
1751
#define SAVE_PHY_COMM_MAX 10
1752
#define SAVE_PHY6_MAX 8
1753
1754
static const uint16_t save_rf_regs[SAVE_RF_MAX] =
1755
{ 0x7a, 0x43 };
1756
static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] = {
1757
0x0001, 0x0811, 0x0812, 0x0814,
1758
0x0815, 0x005a, 0x0059, 0x0058,
1759
0x000a, 0x0003
1760
};
1761
static const uint16_t save_phy6_regs[SAVE_PHY6_MAX] = {
1762
0x002e, 0x002f, 0x080f, 0x0810,
1763
0x0801, 0x0060, 0x0014, 0x0478
1764
};
1765
1766
struct bwi_phy *phy = &mac->mac_phy;
1767
uint16_t save_rf[SAVE_RF_MAX];
1768
uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
1769
uint16_t save_phy6[SAVE_PHY6_MAX];
1770
uint16_t rf7b = 0xffff;
1771
int16_t nrssi;
1772
int i, phy6_idx = 0;
1773
1774
for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
1775
save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]);
1776
for (i = 0; i < SAVE_RF_MAX; ++i)
1777
save_rf[i] = RF_READ(mac, save_rf_regs[i]);
1778
1779
PHY_CLRBITS(mac, 0x429, 0x8000);
1780
PHY_FILT_SETBITS(mac, 0x1, 0x3fff, 0x4000);
1781
PHY_SETBITS(mac, 0x811, 0xc);
1782
PHY_FILT_SETBITS(mac, 0x812, 0xfff3, 0x4);
1783
PHY_CLRBITS(mac, 0x802, 0x3);
1784
1785
if (phy->phy_rev >= 6) {
1786
for (i = 0; i < SAVE_PHY6_MAX; ++i)
1787
save_phy6[i] = PHY_READ(mac, save_phy6_regs[i]);
1788
1789
PHY_WRITE(mac, 0x2e, 0);
1790
PHY_WRITE(mac, 0x2f, 0);
1791
PHY_WRITE(mac, 0x80f, 0);
1792
PHY_WRITE(mac, 0x810, 0);
1793
PHY_SETBITS(mac, 0x478, 0x100);
1794
PHY_SETBITS(mac, 0x801, 0x40);
1795
PHY_SETBITS(mac, 0x60, 0x40);
1796
PHY_SETBITS(mac, 0x14, 0x200);
1797
}
1798
1799
RF_SETBITS(mac, 0x7a, 0x70);
1800
RF_SETBITS(mac, 0x7a, 0x80);
1801
1802
DELAY(30);
1803
1804
nrssi = bwi_nrssi_11g(mac);
1805
if (nrssi == 31) {
1806
for (i = 7; i >= 4; --i) {
1807
RF_WRITE(mac, 0x7b, i);
1808
DELAY(20);
1809
nrssi = bwi_nrssi_11g(mac);
1810
if (nrssi < 31 && rf7b == 0xffff)
1811
rf7b = i;
1812
}
1813
if (rf7b == 0xffff)
1814
rf7b = 4;
1815
} else {
1816
struct bwi_gains gains;
1817
1818
RF_CLRBITS(mac, 0x7a, 0xff80);
1819
1820
PHY_SETBITS(mac, 0x814, 0x1);
1821
PHY_CLRBITS(mac, 0x815, 0x1);
1822
PHY_SETBITS(mac, 0x811, 0xc);
1823
PHY_SETBITS(mac, 0x812, 0xc);
1824
PHY_SETBITS(mac, 0x811, 0x30);
1825
PHY_SETBITS(mac, 0x812, 0x30);
1826
PHY_WRITE(mac, 0x5a, 0x480);
1827
PHY_WRITE(mac, 0x59, 0x810);
1828
PHY_WRITE(mac, 0x58, 0xd);
1829
if (phy->phy_version == 0)
1830
PHY_WRITE(mac, 0x3, 0x122);
1831
else
1832
PHY_SETBITS(mac, 0xa, 0x2000);
1833
PHY_SETBITS(mac, 0x814, 0x4);
1834
PHY_CLRBITS(mac, 0x815, 0x4);
1835
PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
1836
RF_SETBITS(mac, 0x7a, 0xf);
1837
1838
bzero(&gains, sizeof(gains));
1839
gains.tbl_gain1 = 3;
1840
gains.tbl_gain2 = 0;
1841
gains.phy_gain = 1;
1842
bwi_set_gains(mac, &gains);
1843
1844
RF_FILT_SETBITS(mac, 0x43, 0xf0, 0xf);
1845
DELAY(30);
1846
1847
nrssi = bwi_nrssi_11g(mac);
1848
if (nrssi == -32) {
1849
for (i = 0; i < 4; ++i) {
1850
RF_WRITE(mac, 0x7b, i);
1851
DELAY(20);
1852
nrssi = bwi_nrssi_11g(mac);
1853
if (nrssi > -31 && rf7b == 0xffff)
1854
rf7b = i;
1855
}
1856
if (rf7b == 0xffff)
1857
rf7b = 3;
1858
} else {
1859
rf7b = 0;
1860
}
1861
}
1862
RF_WRITE(mac, 0x7b, rf7b);
1863
1864
/*
1865
* Restore saved RF/PHY registers
1866
*/
1867
if (phy->phy_rev >= 6) {
1868
for (phy6_idx = 0; phy6_idx < 4; ++phy6_idx) {
1869
PHY_WRITE(mac, save_phy6_regs[phy6_idx],
1870
save_phy6[phy6_idx]);
1871
}
1872
}
1873
1874
/* Saved PHY registers 0, 1, 2 are handled later */
1875
for (i = 3; i < SAVE_PHY_COMM_MAX; ++i)
1876
PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
1877
1878
for (i = SAVE_RF_MAX - 1; i >= 0; --i)
1879
RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
1880
1881
PHY_SETBITS(mac, 0x802, 0x3);
1882
PHY_SETBITS(mac, 0x429, 0x8000);
1883
1884
bwi_set_gains(mac, NULL);
1885
1886
if (phy->phy_rev >= 6) {
1887
for (; phy6_idx < SAVE_PHY6_MAX; ++phy6_idx) {
1888
PHY_WRITE(mac, save_phy6_regs[phy6_idx],
1889
save_phy6[phy6_idx]);
1890
}
1891
}
1892
1893
PHY_WRITE(mac, save_phy_comm_regs[0], save_phy_comm[0]);
1894
PHY_WRITE(mac, save_phy_comm_regs[2], save_phy_comm[2]);
1895
PHY_WRITE(mac, save_phy_comm_regs[1], save_phy_comm[1]);
1896
1897
#undef SAVE_RF_MAX
1898
#undef SAVE_PHY_COMM_MAX
1899
#undef SAVE_PHY6_MAX
1900
}
1901
1902
static void
1903
bwi_rf_calc_nrssi_slope_11g(struct bwi_mac *mac)
1904
{
1905
#define SAVE_RF_MAX 3
1906
#define SAVE_PHY_COMM_MAX 4
1907
#define SAVE_PHY3_MAX 8
1908
1909
static const uint16_t save_rf_regs[SAVE_RF_MAX] =
1910
{ 0x7a, 0x52, 0x43 };
1911
static const uint16_t save_phy_comm_regs[SAVE_PHY_COMM_MAX] =
1912
{ 0x15, 0x5a, 0x59, 0x58 };
1913
static const uint16_t save_phy3_regs[SAVE_PHY3_MAX] = {
1914
0x002e, 0x002f, 0x080f, 0x0810,
1915
0x0801, 0x0060, 0x0014, 0x0478
1916
};
1917
1918
struct bwi_softc *sc = mac->mac_sc;
1919
struct bwi_phy *phy = &mac->mac_phy;
1920
struct bwi_rf *rf = &mac->mac_rf;
1921
uint16_t save_rf[SAVE_RF_MAX];
1922
uint16_t save_phy_comm[SAVE_PHY_COMM_MAX];
1923
uint16_t save_phy3[SAVE_PHY3_MAX];
1924
uint16_t ant_div, bbp_atten, chan_ex;
1925
struct bwi_gains gains;
1926
int16_t nrssi[2];
1927
int i, phy3_idx = 0;
1928
1929
if (rf->rf_rev >= 9)
1930
return;
1931
else if (rf->rf_rev == 8)
1932
bwi_rf_set_nrssi_ofs_11g(mac);
1933
1934
PHY_CLRBITS(mac, 0x429, 0x8000);
1935
PHY_CLRBITS(mac, 0x802, 0x3);
1936
1937
/*
1938
* Save RF/PHY registers for later restoration
1939
*/
1940
ant_div = CSR_READ_2(sc, BWI_RF_ANTDIV);
1941
CSR_SETBITS_2(sc, BWI_RF_ANTDIV, 0x8000);
1942
1943
for (i = 0; i < SAVE_RF_MAX; ++i)
1944
save_rf[i] = RF_READ(mac, save_rf_regs[i]);
1945
for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
1946
save_phy_comm[i] = PHY_READ(mac, save_phy_comm_regs[i]);
1947
1948
bbp_atten = CSR_READ_2(sc, BWI_BBP_ATTEN);
1949
chan_ex = CSR_READ_2(sc, BWI_RF_CHAN_EX);
1950
1951
if (phy->phy_rev >= 3) {
1952
for (i = 0; i < SAVE_PHY3_MAX; ++i)
1953
save_phy3[i] = PHY_READ(mac, save_phy3_regs[i]);
1954
1955
PHY_WRITE(mac, 0x2e, 0);
1956
PHY_WRITE(mac, 0x810, 0);
1957
1958
if (phy->phy_rev == 4 || phy->phy_rev == 6 ||
1959
phy->phy_rev == 7) {
1960
PHY_SETBITS(mac, 0x478, 0x100);
1961
PHY_SETBITS(mac, 0x810, 0x40);
1962
} else if (phy->phy_rev == 3 || phy->phy_rev == 5) {
1963
PHY_CLRBITS(mac, 0x810, 0x40);
1964
}
1965
1966
PHY_SETBITS(mac, 0x60, 0x40);
1967
PHY_SETBITS(mac, 0x14, 0x200);
1968
}
1969
1970
/*
1971
* Calculate nrssi0
1972
*/
1973
RF_SETBITS(mac, 0x7a, 0x70);
1974
1975
bzero(&gains, sizeof(gains));
1976
gains.tbl_gain1 = 0;
1977
gains.tbl_gain2 = 8;
1978
gains.phy_gain = 0;
1979
bwi_set_gains(mac, &gains);
1980
1981
RF_CLRBITS(mac, 0x7a, 0xff08);
1982
if (phy->phy_rev >= 2) {
1983
PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x30);
1984
PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x10);
1985
}
1986
1987
RF_SETBITS(mac, 0x7a, 0x80);
1988
DELAY(20);
1989
nrssi[0] = bwi_nrssi_11g(mac);
1990
1991
/*
1992
* Calculate nrssi1
1993
*/
1994
RF_CLRBITS(mac, 0x7a, 0xff80);
1995
if (phy->phy_version >= 2)
1996
PHY_FILT_SETBITS(mac, 0x3, 0xff9f, 0x40);
1997
CSR_SETBITS_2(sc, BWI_RF_CHAN_EX, 0x2000);
1998
1999
RF_SETBITS(mac, 0x7a, 0xf);
2000
PHY_WRITE(mac, 0x15, 0xf330);
2001
if (phy->phy_rev >= 2) {
2002
PHY_FILT_SETBITS(mac, 0x812, 0xffcf, 0x20);
2003
PHY_FILT_SETBITS(mac, 0x811, 0xffcf, 0x20);
2004
}
2005
2006
bzero(&gains, sizeof(gains));
2007
gains.tbl_gain1 = 3;
2008
gains.tbl_gain2 = 0;
2009
gains.phy_gain = 1;
2010
bwi_set_gains(mac, &gains);
2011
2012
if (rf->rf_rev == 8) {
2013
RF_WRITE(mac, 0x43, 0x1f);
2014
} else {
2015
RF_FILT_SETBITS(mac, 0x52, 0xff0f, 0x60);
2016
RF_FILT_SETBITS(mac, 0x43, 0xfff0, 0x9);
2017
}
2018
PHY_WRITE(mac, 0x5a, 0x480);
2019
PHY_WRITE(mac, 0x59, 0x810);
2020
PHY_WRITE(mac, 0x58, 0xd);
2021
DELAY(20);
2022
2023
nrssi[1] = bwi_nrssi_11g(mac);
2024
2025
/*
2026
* Install calculated narrow RSSI values
2027
*/
2028
if (nrssi[1] == nrssi[0])
2029
rf->rf_nrssi_slope = 0x10000;
2030
else
2031
rf->rf_nrssi_slope = 0x400000 / (nrssi[0] - nrssi[1]);
2032
if (nrssi[0] >= -4) {
2033
rf->rf_nrssi[0] = nrssi[1];
2034
rf->rf_nrssi[1] = nrssi[0];
2035
}
2036
2037
/*
2038
* Restore saved RF/PHY registers
2039
*/
2040
if (phy->phy_rev >= 3) {
2041
for (phy3_idx = 0; phy3_idx < 4; ++phy3_idx) {
2042
PHY_WRITE(mac, save_phy3_regs[phy3_idx],
2043
save_phy3[phy3_idx]);
2044
}
2045
}
2046
if (phy->phy_rev >= 2) {
2047
PHY_CLRBITS(mac, 0x812, 0x30);
2048
PHY_CLRBITS(mac, 0x811, 0x30);
2049
}
2050
2051
for (i = 0; i < SAVE_RF_MAX; ++i)
2052
RF_WRITE(mac, save_rf_regs[i], save_rf[i]);
2053
2054
CSR_WRITE_2(sc, BWI_RF_ANTDIV, ant_div);
2055
CSR_WRITE_2(sc, BWI_BBP_ATTEN, bbp_atten);
2056
CSR_WRITE_2(sc, BWI_RF_CHAN_EX, chan_ex);
2057
2058
for (i = 0; i < SAVE_PHY_COMM_MAX; ++i)
2059
PHY_WRITE(mac, save_phy_comm_regs[i], save_phy_comm[i]);
2060
2061
bwi_rf_work_around(mac, rf->rf_curchan);
2062
PHY_SETBITS(mac, 0x802, 0x3);
2063
bwi_set_gains(mac, NULL);
2064
PHY_SETBITS(mac, 0x429, 0x8000);
2065
2066
if (phy->phy_rev >= 3) {
2067
for (; phy3_idx < SAVE_PHY3_MAX; ++phy3_idx) {
2068
PHY_WRITE(mac, save_phy3_regs[phy3_idx],
2069
save_phy3[phy3_idx]);
2070
}
2071
}
2072
2073
bwi_rf_init_sw_nrssi_table(mac);
2074
bwi_rf_set_nrssi_thr_11g(mac);
2075
2076
#undef SAVE_RF_MAX
2077
#undef SAVE_PHY_COMM_MAX
2078
#undef SAVE_PHY3_MAX
2079
}
2080
2081
static void
2082
bwi_rf_init_sw_nrssi_table(struct bwi_mac *mac)
2083
{
2084
struct bwi_rf *rf = &mac->mac_rf;
2085
int d, i;
2086
2087
d = 0x1f - rf->rf_nrssi[0];
2088
for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) {
2089
int val;
2090
2091
val = (((i - d) * rf->rf_nrssi_slope) / 0x10000) + 0x3a;
2092
if (val < 0)
2093
val = 0;
2094
else if (val > 0x3f)
2095
val = 0x3f;
2096
2097
rf->rf_nrssi_table[i] = val;
2098
}
2099
}
2100
2101
void
2102
bwi_rf_init_hw_nrssi_table(struct bwi_mac *mac, uint16_t adjust)
2103
{
2104
int i;
2105
2106
for (i = 0; i < BWI_NRSSI_TBLSZ; ++i) {
2107
int16_t val;
2108
2109
val = bwi_nrssi_read(mac, i);
2110
2111
val -= adjust;
2112
if (val < -32)
2113
val = -32;
2114
else if (val > 31)
2115
val = 31;
2116
2117
bwi_nrssi_write(mac, i, val);
2118
}
2119
}
2120
2121
static void
2122
bwi_rf_set_nrssi_thr_11b(struct bwi_mac *mac)
2123
{
2124
struct bwi_rf *rf = &mac->mac_rf;
2125
int32_t thr;
2126
2127
if (rf->rf_type != BWI_RF_T_BCM2050 ||
2128
(mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0)
2129
return;
2130
2131
/*
2132
* Calculate nrssi threshold
2133
*/
2134
if (rf->rf_rev >= 6) {
2135
thr = (rf->rf_nrssi[1] - rf->rf_nrssi[0]) * 32;
2136
thr += 20 * (rf->rf_nrssi[0] + 1);
2137
thr /= 40;
2138
} else {
2139
thr = rf->rf_nrssi[1] - 5;
2140
}
2141
if (thr < 0)
2142
thr = 0;
2143
else if (thr > 0x3e)
2144
thr = 0x3e;
2145
2146
PHY_READ(mac, BWI_PHYR_NRSSI_THR_11B); /* dummy read */
2147
PHY_WRITE(mac, BWI_PHYR_NRSSI_THR_11B, (((uint16_t)thr) << 8) | 0x1c);
2148
2149
if (rf->rf_rev >= 6) {
2150
PHY_WRITE(mac, 0x87, 0xe0d);
2151
PHY_WRITE(mac, 0x86, 0xc0b);
2152
PHY_WRITE(mac, 0x85, 0xa09);
2153
PHY_WRITE(mac, 0x84, 0x808);
2154
PHY_WRITE(mac, 0x83, 0x808);
2155
PHY_WRITE(mac, 0x82, 0x604);
2156
PHY_WRITE(mac, 0x81, 0x302);
2157
PHY_WRITE(mac, 0x80, 0x100);
2158
}
2159
}
2160
2161
static __inline int32_t
2162
_nrssi_threshold(const struct bwi_rf *rf, int32_t val)
2163
{
2164
val *= (rf->rf_nrssi[1] - rf->rf_nrssi[0]);
2165
val += (rf->rf_nrssi[0] << 6);
2166
if (val < 32)
2167
val += 31;
2168
else
2169
val += 32;
2170
val >>= 6;
2171
if (val < -31)
2172
val = -31;
2173
else if (val > 31)
2174
val = 31;
2175
return val;
2176
}
2177
2178
static void
2179
bwi_rf_set_nrssi_thr_11g(struct bwi_mac *mac)
2180
{
2181
int32_t thr1, thr2;
2182
uint16_t thr;
2183
2184
/*
2185
* Find the two nrssi thresholds
2186
*/
2187
if ((mac->mac_phy.phy_flags & BWI_PHY_F_LINKED) == 0 ||
2188
(mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) {
2189
int16_t nrssi;
2190
2191
nrssi = bwi_nrssi_read(mac, 0x20);
2192
if (nrssi >= 32)
2193
nrssi -= 64;
2194
2195
if (nrssi < 3) {
2196
thr1 = 0x2b;
2197
thr2 = 0x27;
2198
} else {
2199
thr1 = 0x2d;
2200
thr2 = 0x2b;
2201
}
2202
} else {
2203
/* TODO Interfere mode */
2204
thr1 = _nrssi_threshold(&mac->mac_rf, 0x11);
2205
thr2 = _nrssi_threshold(&mac->mac_rf, 0xe);
2206
}
2207
2208
#define NRSSI_THR1_MASK __BITS(5, 0)
2209
#define NRSSI_THR2_MASK __BITS(11, 6)
2210
2211
thr = __SHIFTIN((uint32_t)thr1, NRSSI_THR1_MASK) |
2212
__SHIFTIN((uint32_t)thr2, NRSSI_THR2_MASK);
2213
PHY_FILT_SETBITS(mac, BWI_PHYR_NRSSI_THR_11G, 0xf000, thr);
2214
2215
#undef NRSSI_THR1_MASK
2216
#undef NRSSI_THR2_MASK
2217
}
2218
2219
void
2220
bwi_rf_clear_tssi(struct bwi_mac *mac)
2221
{
2222
/* XXX use function pointer */
2223
if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) {
2224
/* TODO:11A */
2225
} else {
2226
uint16_t val;
2227
int i;
2228
2229
val = __SHIFTIN(BWI_INVALID_TSSI, BWI_LO_TSSI_MASK) |
2230
__SHIFTIN(BWI_INVALID_TSSI, BWI_HI_TSSI_MASK);
2231
2232
for (i = 0; i < 2; ++i) {
2233
MOBJ_WRITE_2(mac, BWI_COMM_MOBJ,
2234
BWI_COMM_MOBJ_TSSI_DS + (i * 2), val);
2235
}
2236
2237
for (i = 0; i < 2; ++i) {
2238
MOBJ_WRITE_2(mac, BWI_COMM_MOBJ,
2239
BWI_COMM_MOBJ_TSSI_OFDM + (i * 2), val);
2240
}
2241
}
2242
}
2243
2244
void
2245
bwi_rf_clear_state(struct bwi_rf *rf)
2246
{
2247
int i;
2248
2249
rf->rf_flags &= ~BWI_RF_CLEAR_FLAGS;
2250
bzero(rf->rf_lo, sizeof(rf->rf_lo));
2251
bzero(rf->rf_lo_used, sizeof(rf->rf_lo_used));
2252
2253
rf->rf_nrssi_slope = 0;
2254
rf->rf_nrssi[0] = BWI_INVALID_NRSSI;
2255
rf->rf_nrssi[1] = BWI_INVALID_NRSSI;
2256
2257
for (i = 0; i < BWI_NRSSI_TBLSZ; ++i)
2258
rf->rf_nrssi_table[i] = i;
2259
2260
rf->rf_lo_gain = 0;
2261
rf->rf_rx_gain = 0;
2262
2263
bcopy(rf->rf_txpower_map0, rf->rf_txpower_map,
2264
sizeof(rf->rf_txpower_map));
2265
rf->rf_idle_tssi = rf->rf_idle_tssi0;
2266
}
2267
2268
static void
2269
bwi_rf_on_11a(struct bwi_mac *mac)
2270
{
2271
/* TODO:11A */
2272
}
2273
2274
static void
2275
bwi_rf_on_11bg(struct bwi_mac *mac)
2276
{
2277
struct bwi_phy *phy = &mac->mac_phy;
2278
2279
PHY_WRITE(mac, 0x15, 0x8000);
2280
PHY_WRITE(mac, 0x15, 0xcc00);
2281
if (phy->phy_flags & BWI_PHY_F_LINKED)
2282
PHY_WRITE(mac, 0x15, 0xc0);
2283
else
2284
PHY_WRITE(mac, 0x15, 0);
2285
2286
bwi_rf_set_chan(mac, 6 /* XXX */, 1);
2287
}
2288
2289
void
2290
bwi_rf_set_ant_mode(struct bwi_mac *mac, int ant_mode)
2291
{
2292
struct bwi_softc *sc = mac->mac_sc;
2293
struct bwi_phy *phy = &mac->mac_phy;
2294
uint16_t val;
2295
2296
KASSERT(ant_mode == BWI_ANT_MODE_0 ||
2297
ant_mode == BWI_ANT_MODE_1 ||
2298
ant_mode == BWI_ANT_MODE_AUTO, ("ant_mode %d", ant_mode));
2299
2300
HFLAGS_CLRBITS(mac, BWI_HFLAG_AUTO_ANTDIV);
2301
2302
if (phy->phy_mode == IEEE80211_MODE_11B) {
2303
/* NOTE: v4/v3 conflicts, take v3 */
2304
if (mac->mac_rev == 2)
2305
val = BWI_ANT_MODE_AUTO;
2306
else
2307
val = ant_mode;
2308
val <<= 7;
2309
PHY_FILT_SETBITS(mac, 0x3e2, 0xfe7f, val);
2310
} else { /* 11a/g */
2311
/* XXX reg/value naming */
2312
val = ant_mode << 7;
2313
PHY_FILT_SETBITS(mac, 0x401, 0x7e7f, val);
2314
2315
if (ant_mode == BWI_ANT_MODE_AUTO)
2316
PHY_CLRBITS(mac, 0x42b, 0x100);
2317
2318
if (phy->phy_mode == IEEE80211_MODE_11A) {
2319
/* TODO:11A */
2320
} else { /* 11g */
2321
if (ant_mode == BWI_ANT_MODE_AUTO)
2322
PHY_SETBITS(mac, 0x48c, 0x2000);
2323
else
2324
PHY_CLRBITS(mac, 0x48c, 0x2000);
2325
2326
if (phy->phy_rev >= 2) {
2327
PHY_SETBITS(mac, 0x461, 0x10);
2328
PHY_FILT_SETBITS(mac, 0x4ad, 0xff00, 0x15);
2329
if (phy->phy_rev == 2) {
2330
PHY_WRITE(mac, 0x427, 0x8);
2331
} else {
2332
PHY_FILT_SETBITS(mac, 0x427,
2333
0xff00, 0x8);
2334
}
2335
2336
if (phy->phy_rev >= 6)
2337
PHY_WRITE(mac, 0x49b, 0xdc);
2338
}
2339
}
2340
}
2341
2342
/* XXX v4 set AUTO_ANTDIV unconditionally */
2343
if (ant_mode == BWI_ANT_MODE_AUTO)
2344
HFLAGS_SETBITS(mac, BWI_HFLAG_AUTO_ANTDIV);
2345
2346
val = ant_mode << 8;
2347
MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_BEACON,
2348
0xfc3f, val);
2349
MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_ACK,
2350
0xfc3f, val);
2351
MOBJ_FILT_SETBITS_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_TX_PROBE_RESP,
2352
0xfc3f, val);
2353
2354
/* XXX what's these */
2355
if (phy->phy_mode == IEEE80211_MODE_11B)
2356
CSR_SETBITS_2(sc, 0x5e, 0x4);
2357
2358
CSR_WRITE_4(sc, 0x100, 0x1000000);
2359
if (mac->mac_rev < 5)
2360
CSR_WRITE_4(sc, 0x10c, 0x1000000);
2361
2362
mac->mac_rf.rf_ant_mode = ant_mode;
2363
}
2364
2365
int
2366
bwi_rf_get_latest_tssi(struct bwi_mac *mac, int8_t tssi[], uint16_t ofs)
2367
{
2368
int i;
2369
2370
for (i = 0; i < 4; ) {
2371
uint16_t val;
2372
2373
val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs + i);
2374
tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_LO_TSSI_MASK);
2375
tssi[i++] = (int8_t)__SHIFTOUT(val, BWI_HI_TSSI_MASK);
2376
}
2377
2378
for (i = 0; i < 4; ++i) {
2379
if (tssi[i] == BWI_INVALID_TSSI)
2380
return EINVAL;
2381
}
2382
return 0;
2383
}
2384
2385
int
2386
bwi_rf_tssi2dbm(struct bwi_mac *mac, int8_t tssi, int8_t *txpwr)
2387
{
2388
struct bwi_rf *rf = &mac->mac_rf;
2389
int pwr_idx;
2390
2391
pwr_idx = rf->rf_idle_tssi + (int)tssi - rf->rf_base_tssi;
2392
#if 0
2393
if (pwr_idx < 0 || pwr_idx >= BWI_TSSI_MAX)
2394
return EINVAL;
2395
#else
2396
if (pwr_idx < 0)
2397
pwr_idx = 0;
2398
else if (pwr_idx >= BWI_TSSI_MAX)
2399
pwr_idx = BWI_TSSI_MAX - 1;
2400
#endif
2401
2402
*txpwr = rf->rf_txpower_map[pwr_idx];
2403
return 0;
2404
}
2405
2406
static int
2407
bwi_rf_calc_rssi_bcm2050(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
2408
{
2409
uint16_t flags1, flags3;
2410
int rssi, lna_gain;
2411
2412
rssi = hdr->rxh_rssi;
2413
flags1 = le16toh(hdr->rxh_flags1);
2414
flags3 = le16toh(hdr->rxh_flags3);
2415
2416
if (flags1 & BWI_RXH_F1_OFDM) {
2417
if (rssi > 127)
2418
rssi -= 256;
2419
if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
2420
rssi += 17;
2421
else
2422
rssi -= 4;
2423
return rssi;
2424
}
2425
2426
if (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
2427
struct bwi_rf *rf = &mac->mac_rf;
2428
2429
if (rssi >= BWI_NRSSI_TBLSZ)
2430
rssi = BWI_NRSSI_TBLSZ - 1;
2431
2432
rssi = ((31 - (int)rf->rf_nrssi_table[rssi]) * -131) / 128;
2433
rssi -= 67;
2434
} else {
2435
rssi = ((31 - rssi) * -149) / 128;
2436
rssi -= 68;
2437
}
2438
2439
if (mac->mac_phy.phy_mode != IEEE80211_MODE_11G)
2440
return rssi;
2441
2442
if (flags3 & BWI_RXH_F3_BCM2050_RSSI)
2443
rssi += 20;
2444
2445
lna_gain = __SHIFTOUT(le16toh(hdr->rxh_phyinfo),
2446
BWI_RXH_PHYINFO_LNAGAIN);
2447
DPRINTF(mac->mac_sc, BWI_DBG_RF | BWI_DBG_RX,
2448
"lna_gain %d, phyinfo 0x%04x\n",
2449
lna_gain, le16toh(hdr->rxh_phyinfo));
2450
switch (lna_gain) {
2451
case 0:
2452
rssi += 27;
2453
break;
2454
case 1:
2455
rssi += 6;
2456
break;
2457
case 2:
2458
rssi += 12;
2459
break;
2460
case 3:
2461
/*
2462
* XXX
2463
* According to v3 spec, we should do _nothing_ here,
2464
* but it seems that the result RSSI will be too low
2465
* (relative to what ath(4) says). Raise it a little
2466
* bit.
2467
*/
2468
rssi += 5;
2469
break;
2470
default:
2471
panic("impossible lna gain %d", lna_gain);
2472
}
2473
return rssi;
2474
}
2475
2476
static int
2477
bwi_rf_calc_rssi_bcm2053(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
2478
{
2479
uint16_t flags1;
2480
int rssi;
2481
2482
rssi = (((int)hdr->rxh_rssi - 11) * 103) / 64;
2483
2484
flags1 = le16toh(hdr->rxh_flags1);
2485
if (flags1 & BWI_RXH_F1_BCM2053_RSSI)
2486
rssi -= 109;
2487
else
2488
rssi -= 83;
2489
return rssi;
2490
}
2491
2492
static int
2493
bwi_rf_calc_rssi_bcm2060(struct bwi_mac *mac, const struct bwi_rxbuf_hdr *hdr)
2494
{
2495
int rssi;
2496
2497
rssi = hdr->rxh_rssi;
2498
if (rssi > 127)
2499
rssi -= 256;
2500
return rssi;
2501
}
2502
2503
static int
2504
bwi_rf_calc_noise_bcm2050(struct bwi_mac *mac)
2505
{
2506
uint16_t val;
2507
int noise;
2508
2509
val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_RF_NOISE);
2510
noise = (int)val; /* XXX check bounds? */
2511
2512
if (mac->mac_sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
2513
struct bwi_rf *rf = &mac->mac_rf;
2514
2515
if (noise >= BWI_NRSSI_TBLSZ)
2516
noise = BWI_NRSSI_TBLSZ - 1;
2517
2518
noise = ((31 - (int)rf->rf_nrssi_table[noise]) * -131) / 128;
2519
noise -= 67;
2520
} else {
2521
noise = ((31 - noise) * -149) / 128;
2522
noise -= 68;
2523
}
2524
return noise;
2525
}
2526
2527
static int
2528
bwi_rf_calc_noise_bcm2053(struct bwi_mac *mac)
2529
{
2530
uint16_t val;
2531
int noise;
2532
2533
val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_RF_NOISE);
2534
noise = (int)val; /* XXX check bounds? */
2535
2536
noise = ((noise - 11) * 103) / 64;
2537
noise -= 109;
2538
return noise;
2539
}
2540
2541
static int
2542
bwi_rf_calc_noise_bcm2060(struct bwi_mac *mac)
2543
{
2544
/* XXX Dont know how to calc */
2545
return (BWI_NOISE_FLOOR);
2546
}
2547
2548
static uint16_t
2549
bwi_rf_lo_measure_11b(struct bwi_mac *mac)
2550
{
2551
uint16_t val;
2552
int i;
2553
2554
val = 0;
2555
for (i = 0; i < 10; ++i) {
2556
PHY_WRITE(mac, 0x15, 0xafa0);
2557
DELAY(1);
2558
PHY_WRITE(mac, 0x15, 0xefa0);
2559
DELAY(10);
2560
PHY_WRITE(mac, 0x15, 0xffa0);
2561
DELAY(40);
2562
2563
val += PHY_READ(mac, 0x2c);
2564
}
2565
return val;
2566
}
2567
2568
static void
2569
bwi_rf_lo_update_11b(struct bwi_mac *mac)
2570
{
2571
struct bwi_softc *sc = mac->mac_sc;
2572
struct bwi_rf *rf = &mac->mac_rf;
2573
struct rf_saveregs regs;
2574
uint16_t rf_val, phy_val, min_val, val;
2575
uint16_t rf52, bphy_ctrl;
2576
int i;
2577
2578
DPRINTF(sc, BWI_DBG_RF | BWI_DBG_INIT, "%s enter\n", __func__);
2579
2580
bzero(&regs, sizeof(regs));
2581
bphy_ctrl = 0;
2582
2583
/*
2584
* Save RF/PHY registers for later restoration
2585
*/
2586
SAVE_PHY_REG(mac, &regs, 15);
2587
rf52 = RF_READ(mac, 0x52) & 0xfff0;
2588
if (rf->rf_type == BWI_RF_T_BCM2050) {
2589
SAVE_PHY_REG(mac, &regs, 0a);
2590
SAVE_PHY_REG(mac, &regs, 2a);
2591
SAVE_PHY_REG(mac, &regs, 35);
2592
SAVE_PHY_REG(mac, &regs, 03);
2593
SAVE_PHY_REG(mac, &regs, 01);
2594
SAVE_PHY_REG(mac, &regs, 30);
2595
2596
SAVE_RF_REG(mac, &regs, 43);
2597
SAVE_RF_REG(mac, &regs, 7a);
2598
2599
bphy_ctrl = CSR_READ_2(sc, BWI_BPHY_CTRL);
2600
2601
SAVE_RF_REG(mac, &regs, 52);
2602
regs.rf_52 &= 0xf0;
2603
2604
PHY_WRITE(mac, 0x30, 0xff);
2605
CSR_WRITE_2(sc, BWI_PHY_CTRL, 0x3f3f);
2606
PHY_WRITE(mac, 0x35, regs.phy_35 & 0xff7f);
2607
RF_WRITE(mac, 0x7a, regs.rf_7a & 0xfff0);
2608
}
2609
2610
PHY_WRITE(mac, 0x15, 0xb000);
2611
2612
if (rf->rf_type == BWI_RF_T_BCM2050) {
2613
PHY_WRITE(mac, 0x2b, 0x203);
2614
PHY_WRITE(mac, 0x2a, 0x8a3);
2615
} else {
2616
PHY_WRITE(mac, 0x2b, 0x1402);
2617
}
2618
2619
/*
2620
* Setup RF signal
2621
*/
2622
rf_val = 0;
2623
min_val = UINT16_MAX;
2624
2625
for (i = 0; i < 4; ++i) {
2626
RF_WRITE(mac, 0x52, rf52 | i);
2627
bwi_rf_lo_measure_11b(mac); /* Ignore return value */
2628
}
2629
for (i = 0; i < 10; ++i) {
2630
RF_WRITE(mac, 0x52, rf52 | i);
2631
2632
val = bwi_rf_lo_measure_11b(mac) / 10;
2633
if (val < min_val) {
2634
min_val = val;
2635
rf_val = i;
2636
}
2637
}
2638
RF_WRITE(mac, 0x52, rf52 | rf_val);
2639
2640
/*
2641
* Setup PHY signal
2642
*/
2643
phy_val = 0;
2644
min_val = UINT16_MAX;
2645
2646
for (i = -4; i < 5; i += 2) {
2647
int j;
2648
2649
for (j = -4; j < 5; j += 2) {
2650
uint16_t phy2f;
2651
2652
phy2f = (0x100 * i) + j;
2653
if (j < 0)
2654
phy2f += 0x100;
2655
PHY_WRITE(mac, 0x2f, phy2f);
2656
2657
val = bwi_rf_lo_measure_11b(mac) / 10;
2658
if (val < min_val) {
2659
min_val = val;
2660
phy_val = phy2f;
2661
}
2662
}
2663
}
2664
PHY_WRITE(mac, 0x2f, phy_val + 0x101);
2665
2666
/*
2667
* Restore saved RF/PHY registers
2668
*/
2669
if (rf->rf_type == BWI_RF_T_BCM2050) {
2670
RESTORE_PHY_REG(mac, &regs, 0a);
2671
RESTORE_PHY_REG(mac, &regs, 2a);
2672
RESTORE_PHY_REG(mac, &regs, 35);
2673
RESTORE_PHY_REG(mac, &regs, 03);
2674
RESTORE_PHY_REG(mac, &regs, 01);
2675
RESTORE_PHY_REG(mac, &regs, 30);
2676
2677
RESTORE_RF_REG(mac, &regs, 43);
2678
RESTORE_RF_REG(mac, &regs, 7a);
2679
2680
RF_FILT_SETBITS(mac, 0x52, 0xf, regs.rf_52);
2681
2682
CSR_WRITE_2(sc, BWI_BPHY_CTRL, bphy_ctrl);
2683
}
2684
RESTORE_PHY_REG(mac, &regs, 15);
2685
2686
bwi_rf_work_around(mac, rf->rf_curchan);
2687
}
2688
2689