Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/bwi/bwiphy.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/bwiphy.c,v 1.5 2008/01/15 09:01:13 sephe Exp $
37
*/
38
39
#include <sys/cdefs.h>
40
#include "opt_inet.h"
41
#include "opt_wlan.h"
42
43
#include <sys/param.h>
44
#include <sys/endian.h>
45
#include <sys/kernel.h>
46
#include <sys/bus.h>
47
#include <sys/malloc.h>
48
#include <sys/proc.h>
49
#include <sys/rman.h>
50
#include <sys/socket.h>
51
#include <sys/sockio.h>
52
#include <sys/sysctl.h>
53
#include <sys/systm.h>
54
55
#include <net/if.h>
56
#include <net/if_var.h>
57
#include <net/if_dl.h>
58
#include <net/if_media.h>
59
#include <net/if_types.h>
60
#include <net/if_arp.h>
61
#include <net/ethernet.h>
62
#include <net/if_llc.h>
63
64
#include <net80211/ieee80211_var.h>
65
#include <net80211/ieee80211_radiotap.h>
66
#include <net80211/ieee80211_amrr.h>
67
68
#include <machine/bus.h>
69
70
#include <dev/bwi/bitops.h>
71
#include <dev/bwi/if_bwireg.h>
72
#include <dev/bwi/if_bwivar.h>
73
#include <dev/bwi/bwimac.h>
74
#include <dev/bwi/bwirf.h>
75
#include <dev/bwi/bwiphy.h>
76
77
static void bwi_phy_init_11a(struct bwi_mac *);
78
static void bwi_phy_init_11g(struct bwi_mac *);
79
static void bwi_phy_init_11b_rev2(struct bwi_mac *);
80
static void bwi_phy_init_11b_rev4(struct bwi_mac *);
81
static void bwi_phy_init_11b_rev5(struct bwi_mac *);
82
static void bwi_phy_init_11b_rev6(struct bwi_mac *);
83
84
static void bwi_phy_config_11g(struct bwi_mac *);
85
static void bwi_phy_config_agc(struct bwi_mac *);
86
87
static void bwi_tbl_write_2(struct bwi_mac *mac, uint16_t, uint16_t);
88
static void bwi_tbl_write_4(struct bwi_mac *mac, uint16_t, uint32_t);
89
#define SUP_BPHY(num) { .rev = num, .init = bwi_phy_init_11b_rev##num }
90
91
static const struct {
92
uint8_t rev;
93
void (*init)(struct bwi_mac *);
94
} bwi_sup_bphy[] = {
95
SUP_BPHY(2),
96
SUP_BPHY(4),
97
SUP_BPHY(5),
98
SUP_BPHY(6)
99
};
100
101
#undef SUP_BPHY
102
103
#define BWI_PHYTBL_WRSSI 0x1000
104
#define BWI_PHYTBL_NOISE_SCALE 0x1400
105
#define BWI_PHYTBL_NOISE 0x1800
106
#define BWI_PHYTBL_ROTOR 0x2000
107
#define BWI_PHYTBL_DELAY 0x2400
108
#define BWI_PHYTBL_RSSI 0x4000
109
#define BWI_PHYTBL_SIGMA_SQ 0x5000
110
#define BWI_PHYTBL_WRSSI_REV1 0x5400
111
#define BWI_PHYTBL_FREQ 0x5800
112
113
static const uint16_t bwi_phy_freq_11g_rev1[] =
114
{ BWI_PHY_FREQ_11G_REV1 };
115
static const uint16_t bwi_phy_noise_11g_rev1[] =
116
{ BWI_PHY_NOISE_11G_REV1 };
117
static const uint16_t bwi_phy_noise_11g[] =
118
{ BWI_PHY_NOISE_11G };
119
static const uint32_t bwi_phy_rotor_11g_rev1[] =
120
{ BWI_PHY_ROTOR_11G_REV1 };
121
static const uint16_t bwi_phy_noise_scale_11g_rev2[] =
122
{ BWI_PHY_NOISE_SCALE_11G_REV2 };
123
static const uint16_t bwi_phy_noise_scale_11g_rev7[] =
124
{ BWI_PHY_NOISE_SCALE_11G_REV7 };
125
static const uint16_t bwi_phy_noise_scale_11g[] =
126
{ BWI_PHY_NOISE_SCALE_11G };
127
static const uint16_t bwi_phy_sigma_sq_11g_rev2[] =
128
{ BWI_PHY_SIGMA_SQ_11G_REV2 };
129
static const uint16_t bwi_phy_sigma_sq_11g_rev7[] =
130
{ BWI_PHY_SIGMA_SQ_11G_REV7 };
131
static const uint32_t bwi_phy_delay_11g_rev1[] =
132
{ BWI_PHY_DELAY_11G_REV1 };
133
134
void
135
bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data)
136
{
137
struct bwi_softc *sc = mac->mac_sc;
138
139
CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
140
CSR_WRITE_2(sc, BWI_PHY_DATA, data);
141
}
142
143
uint16_t
144
bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl)
145
{
146
struct bwi_softc *sc = mac->mac_sc;
147
148
CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl);
149
return CSR_READ_2(sc, BWI_PHY_DATA);
150
}
151
152
int
153
bwi_phy_attach(struct bwi_mac *mac)
154
{
155
struct bwi_softc *sc = mac->mac_sc;
156
struct bwi_phy *phy = &mac->mac_phy;
157
uint8_t phyrev, phytype, phyver;
158
uint16_t val;
159
int i;
160
161
/* Get PHY type/revision/version */
162
val = CSR_READ_2(sc, BWI_PHYINFO);
163
phyrev = __SHIFTOUT(val, BWI_PHYINFO_REV_MASK);
164
phytype = __SHIFTOUT(val, BWI_PHYINFO_TYPE_MASK);
165
phyver = __SHIFTOUT(val, BWI_PHYINFO_VER_MASK);
166
device_printf(sc->sc_dev, "PHY: type %d, rev %d, ver %d\n",
167
phytype, phyrev, phyver);
168
169
/*
170
* Verify whether the revision of the PHY type is supported
171
* Convert PHY type to ieee80211_phymode
172
*/
173
switch (phytype) {
174
case BWI_PHYINFO_TYPE_11A:
175
if (phyrev >= 4) {
176
device_printf(sc->sc_dev, "unsupported 11A PHY, "
177
"rev %u\n", phyrev);
178
return ENXIO;
179
}
180
phy->phy_init = bwi_phy_init_11a;
181
phy->phy_mode = IEEE80211_MODE_11A;
182
phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11A;
183
phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11A;
184
phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11A;
185
break;
186
case BWI_PHYINFO_TYPE_11B:
187
for (i = 0; i < nitems(bwi_sup_bphy); ++i) {
188
if (phyrev == bwi_sup_bphy[i].rev) {
189
phy->phy_init = bwi_sup_bphy[i].init;
190
break;
191
}
192
}
193
if (i == nitems(bwi_sup_bphy)) {
194
device_printf(sc->sc_dev, "unsupported 11B PHY, "
195
"rev %u\n", phyrev);
196
return ENXIO;
197
}
198
phy->phy_mode = IEEE80211_MODE_11B;
199
break;
200
case BWI_PHYINFO_TYPE_11G:
201
if (phyrev > 8) {
202
device_printf(sc->sc_dev, "unsupported 11G PHY, "
203
"rev %u\n", phyrev);
204
return ENXIO;
205
}
206
phy->phy_init = bwi_phy_init_11g;
207
phy->phy_mode = IEEE80211_MODE_11G;
208
phy->phy_tbl_ctrl = BWI_PHYR_TBL_CTRL_11G;
209
phy->phy_tbl_data_lo = BWI_PHYR_TBL_DATA_LO_11G;
210
phy->phy_tbl_data_hi = BWI_PHYR_TBL_DATA_HI_11G;
211
break;
212
default:
213
device_printf(sc->sc_dev, "unsupported PHY type %d\n",
214
phytype);
215
return ENXIO;
216
}
217
phy->phy_rev = phyrev;
218
phy->phy_version = phyver;
219
return 0;
220
}
221
222
void
223
bwi_phy_set_bbp_atten(struct bwi_mac *mac, uint16_t bbp_atten)
224
{
225
struct bwi_phy *phy = &mac->mac_phy;
226
uint16_t mask = __BITS(3, 0);
227
228
if (phy->phy_version == 0) {
229
CSR_FILT_SETBITS_2(mac->mac_sc, BWI_BBP_ATTEN, ~mask,
230
__SHIFTIN(bbp_atten, mask));
231
} else {
232
if (phy->phy_version > 1)
233
mask <<= 2;
234
else
235
mask <<= 3;
236
PHY_FILT_SETBITS(mac, BWI_PHYR_BBP_ATTEN, ~mask,
237
__SHIFTIN(bbp_atten, mask));
238
}
239
}
240
241
int
242
bwi_phy_calibrate(struct bwi_mac *mac)
243
{
244
struct bwi_phy *phy = &mac->mac_phy;
245
246
/* Dummy read */
247
CSR_READ_4(mac->mac_sc, BWI_MAC_STATUS);
248
249
/* Don't re-init */
250
if (phy->phy_flags & BWI_PHY_F_CALIBRATED)
251
return 0;
252
253
if (phy->phy_mode == IEEE80211_MODE_11G && phy->phy_rev == 1) {
254
bwi_mac_reset(mac, 0);
255
bwi_phy_init_11g(mac);
256
bwi_mac_reset(mac, 1);
257
}
258
259
phy->phy_flags |= BWI_PHY_F_CALIBRATED;
260
return 0;
261
}
262
263
static void
264
bwi_tbl_write_2(struct bwi_mac *mac, uint16_t ofs, uint16_t data)
265
{
266
struct bwi_phy *phy = &mac->mac_phy;
267
268
KASSERT(phy->phy_tbl_ctrl != 0 && phy->phy_tbl_data_lo != 0,
269
("phy_tbl_ctrl %d phy_tbl_data_lo %d",
270
phy->phy_tbl_ctrl, phy->phy_tbl_data_lo));
271
PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
272
PHY_WRITE(mac, phy->phy_tbl_data_lo, data);
273
}
274
275
static void
276
bwi_tbl_write_4(struct bwi_mac *mac, uint16_t ofs, uint32_t data)
277
{
278
struct bwi_phy *phy = &mac->mac_phy;
279
280
KASSERT(phy->phy_tbl_data_lo != 0 && phy->phy_tbl_data_hi != 0 &&
281
phy->phy_tbl_ctrl != 0,
282
("phy_tbl_data_lo %d phy_tbl_data_hi %d phy_tbl_ctrl %d",
283
phy->phy_tbl_data_lo, phy->phy_tbl_data_hi, phy->phy_tbl_ctrl));
284
285
PHY_WRITE(mac, phy->phy_tbl_ctrl, ofs);
286
PHY_WRITE(mac, phy->phy_tbl_data_hi, data >> 16);
287
PHY_WRITE(mac, phy->phy_tbl_data_lo, data & 0xffff);
288
}
289
290
void
291
bwi_nrssi_write(struct bwi_mac *mac, uint16_t ofs, int16_t data)
292
{
293
PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
294
PHY_WRITE(mac, BWI_PHYR_NRSSI_DATA, (uint16_t)data);
295
}
296
297
int16_t
298
bwi_nrssi_read(struct bwi_mac *mac, uint16_t ofs)
299
{
300
PHY_WRITE(mac, BWI_PHYR_NRSSI_CTRL, ofs);
301
return (int16_t)PHY_READ(mac, BWI_PHYR_NRSSI_DATA);
302
}
303
304
static void
305
bwi_phy_init_11a(struct bwi_mac *mac)
306
{
307
/* TODO:11A */
308
}
309
310
static void
311
bwi_phy_init_11g(struct bwi_mac *mac)
312
{
313
struct bwi_softc *sc = mac->mac_sc;
314
struct bwi_phy *phy = &mac->mac_phy;
315
struct bwi_rf *rf = &mac->mac_rf;
316
const struct bwi_tpctl *tpctl = &mac->mac_tpctl;
317
318
if (phy->phy_rev == 1)
319
bwi_phy_init_11b_rev5(mac);
320
else
321
bwi_phy_init_11b_rev6(mac);
322
323
if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED))
324
bwi_phy_config_11g(mac);
325
326
if (phy->phy_rev >= 2) {
327
PHY_WRITE(mac, 0x814, 0);
328
PHY_WRITE(mac, 0x815, 0);
329
330
if (phy->phy_rev == 2) {
331
PHY_WRITE(mac, 0x811, 0);
332
PHY_WRITE(mac, 0x15, 0xc0);
333
} else if (phy->phy_rev > 5) {
334
PHY_WRITE(mac, 0x811, 0x400);
335
PHY_WRITE(mac, 0x15, 0xc0);
336
}
337
}
338
339
if (phy->phy_rev >= 2 || (phy->phy_flags & BWI_PHY_F_LINKED)) {
340
uint16_t val;
341
342
val = PHY_READ(mac, 0x400) & 0xff;
343
if (val == 3 || val == 5) {
344
PHY_WRITE(mac, 0x4c2, 0x1816);
345
PHY_WRITE(mac, 0x4c3, 0x8006);
346
if (val == 5) {
347
PHY_FILT_SETBITS(mac, 0x4cc,
348
0xff, 0x1f00);
349
}
350
}
351
}
352
353
if ((phy->phy_rev <= 2 && (phy->phy_flags & BWI_PHY_F_LINKED)) ||
354
phy->phy_rev >= 2)
355
PHY_WRITE(mac, 0x47e, 0x78);
356
357
if (rf->rf_rev == 8) {
358
PHY_SETBITS(mac, 0x801, 0x80);
359
PHY_SETBITS(mac, 0x43e, 0x4);
360
}
361
362
if (phy->phy_rev >= 2 && (phy->phy_flags & BWI_PHY_F_LINKED))
363
bwi_rf_get_gains(mac);
364
365
if (rf->rf_rev != 8)
366
bwi_rf_init(mac);
367
368
if (tpctl->tp_ctrl2 == 0xffff) {
369
bwi_rf_lo_update(mac);
370
} else {
371
if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 8) {
372
RF_WRITE(mac, 0x52,
373
(tpctl->tp_ctrl1 << 4) | tpctl->tp_ctrl2);
374
} else {
375
RF_FILT_SETBITS(mac, 0x52, 0xfff0, tpctl->tp_ctrl2);
376
}
377
378
if (phy->phy_rev >= 6) {
379
PHY_FILT_SETBITS(mac, 0x36, 0xfff,
380
tpctl->tp_ctrl2 << 12);
381
}
382
383
if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
384
PHY_WRITE(mac, 0x2e, 0x8075);
385
else
386
PHY_WRITE(mac, 0x2e, 0x807f);
387
388
if (phy->phy_rev < 2)
389
PHY_WRITE(mac, 0x2f, 0x101);
390
else
391
PHY_WRITE(mac, 0x2f, 0x202);
392
}
393
394
if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
395
bwi_rf_lo_adjust(mac, tpctl);
396
PHY_WRITE(mac, 0x80f, 0x8078);
397
}
398
399
if ((sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) == 0) {
400
bwi_rf_init_hw_nrssi_table(mac, 0xffff /* XXX */);
401
bwi_rf_set_nrssi_thr(mac);
402
} else if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
403
if (rf->rf_nrssi[0] == BWI_INVALID_NRSSI) {
404
KASSERT(rf->rf_nrssi[1] == BWI_INVALID_NRSSI,
405
("rf_nrssi[1] %d", rf->rf_nrssi[1]));
406
bwi_rf_calc_nrssi_slope(mac);
407
} else {
408
KASSERT(rf->rf_nrssi[1] != BWI_INVALID_NRSSI,
409
("rf_nrssi[1] %d", rf->rf_nrssi[1]));
410
bwi_rf_set_nrssi_thr(mac);
411
}
412
}
413
414
if (rf->rf_rev == 8)
415
PHY_WRITE(mac, 0x805, 0x3230);
416
417
bwi_mac_init_tpctl_11bg(mac);
418
419
if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_pkg == 2) {
420
PHY_CLRBITS(mac, 0x429, 0x4000);
421
PHY_CLRBITS(mac, 0x4c3, 0x8000);
422
}
423
}
424
425
static void
426
bwi_phy_init_11b_rev2(struct bwi_mac *mac)
427
{
428
/* TODO:11B */
429
device_printf(mac->mac_sc->sc_dev,
430
"%s is not implemented yet\n", __func__);
431
}
432
433
static void
434
bwi_phy_init_11b_rev4(struct bwi_mac *mac)
435
{
436
struct bwi_softc *sc = mac->mac_sc;
437
struct bwi_rf *rf = &mac->mac_rf;
438
uint16_t val, ofs;
439
u_int chan;
440
441
CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
442
443
PHY_WRITE(mac, 0x20, 0x301c);
444
PHY_WRITE(mac, 0x26, 0);
445
PHY_WRITE(mac, 0x30, 0xc6);
446
PHY_WRITE(mac, 0x88, 0x3e00);
447
448
for (ofs = 0, val = 0x3c3d; ofs < 30; ++ofs, val -= 0x202)
449
PHY_WRITE(mac, 0x89 + ofs, val);
450
451
CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
452
453
chan = rf->rf_curchan;
454
if (chan == IEEE80211_CHAN_ANY)
455
chan = 6; /* Force to channel 6 */
456
bwi_rf_set_chan(mac, chan, 0);
457
458
if (rf->rf_type != BWI_RF_T_BCM2050) {
459
RF_WRITE(mac, 0x75, 0x80);
460
RF_WRITE(mac, 0x79, 0x81);
461
}
462
463
RF_WRITE(mac, 0x50, 0x20);
464
RF_WRITE(mac, 0x50, 0x23);
465
466
if (rf->rf_type == BWI_RF_T_BCM2050) {
467
RF_WRITE(mac, 0x50, 0x20);
468
RF_WRITE(mac, 0x5a, 0x70);
469
RF_WRITE(mac, 0x5b, 0x7b);
470
RF_WRITE(mac, 0x5c, 0xb0);
471
RF_WRITE(mac, 0x7a, 0xf);
472
PHY_WRITE(mac, 0x38, 0x677);
473
bwi_rf_init_bcm2050(mac);
474
}
475
476
PHY_WRITE(mac, 0x14, 0x80);
477
PHY_WRITE(mac, 0x32, 0xca);
478
if (rf->rf_type == BWI_RF_T_BCM2050)
479
PHY_WRITE(mac, 0x32, 0xe0);
480
PHY_WRITE(mac, 0x35, 0x7c2);
481
482
bwi_rf_lo_update(mac);
483
484
PHY_WRITE(mac, 0x26, 0xcc00);
485
if (rf->rf_type == BWI_RF_T_BCM2050)
486
PHY_WRITE(mac, 0x26, 0xce00);
487
488
CSR_WRITE_2(sc, BWI_RF_CHAN_EX, 0x1100);
489
490
PHY_WRITE(mac, 0x2a, 0x88a3);
491
if (rf->rf_type == BWI_RF_T_BCM2050)
492
PHY_WRITE(mac, 0x2a, 0x88c2);
493
494
bwi_mac_set_tpctl_11bg(mac, NULL);
495
if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
496
bwi_rf_calc_nrssi_slope(mac);
497
bwi_rf_set_nrssi_thr(mac);
498
}
499
bwi_mac_init_tpctl_11bg(mac);
500
}
501
502
static void
503
bwi_phy_init_11b_rev5(struct bwi_mac *mac)
504
{
505
struct bwi_softc *sc = mac->mac_sc;
506
struct bwi_rf *rf = &mac->mac_rf;
507
struct bwi_phy *phy = &mac->mac_phy;
508
u_int orig_chan;
509
510
if (phy->phy_version == 1)
511
RF_SETBITS(mac, 0x7a, 0x50);
512
513
if (sc->sc_pci_subvid != PCI_VENDOR_BROADCOM &&
514
sc->sc_pci_subdid != BWI_PCI_SUBDEVICE_BU4306) {
515
uint16_t ofs, val;
516
517
val = 0x2120;
518
for (ofs = 0xa8; ofs < 0xc7; ++ofs) {
519
PHY_WRITE(mac, ofs, val);
520
val += 0x202;
521
}
522
}
523
524
PHY_FILT_SETBITS(mac, 0x35, 0xf0ff, 0x700);
525
526
if (rf->rf_type == BWI_RF_T_BCM2050)
527
PHY_WRITE(mac, 0x38, 0x667);
528
529
if ((phy->phy_flags & BWI_PHY_F_LINKED) || phy->phy_rev >= 2) {
530
if (rf->rf_type == BWI_RF_T_BCM2050) {
531
RF_SETBITS(mac, 0x7a, 0x20);
532
RF_SETBITS(mac, 0x51, 0x4);
533
}
534
535
CSR_WRITE_2(sc, BWI_RF_ANTDIV, 0);
536
537
PHY_SETBITS(mac, 0x802, 0x100);
538
PHY_SETBITS(mac, 0x42b, 0x2000);
539
PHY_WRITE(mac, 0x1c, 0x186a);
540
541
PHY_FILT_SETBITS(mac, 0x13, 0xff, 0x1900);
542
PHY_FILT_SETBITS(mac, 0x35, 0xffc0, 0x64);
543
PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0xa);
544
}
545
546
/* TODO: bad_frame_preempt? */
547
548
if (phy->phy_version == 1) {
549
PHY_WRITE(mac, 0x26, 0xce00);
550
PHY_WRITE(mac, 0x21, 0x3763);
551
PHY_WRITE(mac, 0x22, 0x1bc3);
552
PHY_WRITE(mac, 0x23, 0x6f9);
553
PHY_WRITE(mac, 0x24, 0x37e);
554
} else {
555
PHY_WRITE(mac, 0x26, 0xcc00);
556
}
557
PHY_WRITE(mac, 0x30, 0xc6);
558
559
CSR_WRITE_2(sc, BWI_BPHY_CTRL, BWI_BPHY_CTRL_INIT);
560
561
if (phy->phy_version == 1)
562
PHY_WRITE(mac, 0x20, 0x3e1c);
563
else
564
PHY_WRITE(mac, 0x20, 0x301c);
565
566
if (phy->phy_version == 0)
567
CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL1);
568
569
/* Force to channel 7 */
570
orig_chan = rf->rf_curchan;
571
bwi_rf_set_chan(mac, 7, 0);
572
573
if (rf->rf_type != BWI_RF_T_BCM2050) {
574
RF_WRITE(mac, 0x75, 0x80);
575
RF_WRITE(mac, 0x79, 0x81);
576
}
577
578
RF_WRITE(mac, 0x50, 0x20);
579
RF_WRITE(mac, 0x50, 0x23);
580
581
if (rf->rf_type == BWI_RF_T_BCM2050) {
582
RF_WRITE(mac, 0x50, 0x20);
583
RF_WRITE(mac, 0x5a, 0x70);
584
}
585
586
RF_WRITE(mac, 0x5b, 0x7b);
587
RF_WRITE(mac, 0x5c, 0xb0);
588
RF_SETBITS(mac, 0x7a, 0x7);
589
590
bwi_rf_set_chan(mac, orig_chan, 0);
591
592
PHY_WRITE(mac, 0x14, 0x80);
593
PHY_WRITE(mac, 0x32, 0xca);
594
PHY_WRITE(mac, 0x2a, 0x88a3);
595
596
bwi_mac_set_tpctl_11bg(mac, NULL);
597
598
if (rf->rf_type == BWI_RF_T_BCM2050)
599
RF_WRITE(mac, 0x5d, 0xd);
600
601
CSR_FILT_SETBITS_2(sc, BWI_PHY_MAGIC_REG1, 0xffc0, 0x4);
602
}
603
604
static void
605
bwi_phy_init_11b_rev6(struct bwi_mac *mac)
606
{
607
struct bwi_softc *sc = mac->mac_sc;
608
struct bwi_rf *rf = &mac->mac_rf;
609
struct bwi_phy *phy = &mac->mac_phy;
610
uint16_t val, ofs;
611
u_int orig_chan;
612
613
PHY_WRITE(mac, 0x3e, 0x817a);
614
RF_SETBITS(mac, 0x7a, 0x58);
615
616
if (rf->rf_rev == 4 || rf->rf_rev == 5) {
617
RF_WRITE(mac, 0x51, 0x37);
618
RF_WRITE(mac, 0x52, 0x70);
619
RF_WRITE(mac, 0x53, 0xb3);
620
RF_WRITE(mac, 0x54, 0x9b);
621
RF_WRITE(mac, 0x5a, 0x88);
622
RF_WRITE(mac, 0x5b, 0x88);
623
RF_WRITE(mac, 0x5d, 0x88);
624
RF_WRITE(mac, 0x5e, 0x88);
625
RF_WRITE(mac, 0x7d, 0x88);
626
HFLAGS_SETBITS(mac, BWI_HFLAG_MAGIC1);
627
} else if (rf->rf_rev == 8) {
628
RF_WRITE(mac, 0x51, 0);
629
RF_WRITE(mac, 0x52, 0x40);
630
RF_WRITE(mac, 0x53, 0xb7);
631
RF_WRITE(mac, 0x54, 0x98);
632
RF_WRITE(mac, 0x5a, 0x88);
633
RF_WRITE(mac, 0x5b, 0x6b);
634
RF_WRITE(mac, 0x5c, 0xf);
635
if (sc->sc_card_flags & BWI_CARD_F_ALT_IQ) {
636
RF_WRITE(mac, 0x5d, 0xfa);
637
RF_WRITE(mac, 0x5e, 0xd8);
638
} else {
639
RF_WRITE(mac, 0x5d, 0xf5);
640
RF_WRITE(mac, 0x5e, 0xb8);
641
}
642
RF_WRITE(mac, 0x73, 0x3);
643
RF_WRITE(mac, 0x7d, 0xa8);
644
RF_WRITE(mac, 0x7c, 0x1);
645
RF_WRITE(mac, 0x7e, 0x8);
646
}
647
648
val = 0x1e1f;
649
for (ofs = 0x88; ofs < 0x98; ++ofs) {
650
PHY_WRITE(mac, ofs, val);
651
val -= 0x202;
652
}
653
654
val = 0x3e3f;
655
for (ofs = 0x98; ofs < 0xa8; ++ofs) {
656
PHY_WRITE(mac, ofs, val);
657
val -= 0x202;
658
}
659
660
val = 0x2120;
661
for (ofs = 0xa8; ofs < 0xc8; ++ofs) {
662
PHY_WRITE(mac, ofs, (val & 0x3f3f));
663
val += 0x202;
664
665
/* XXX: delay 10 us to avoid PCI parity errors with BCM4318 */
666
DELAY(10);
667
}
668
669
if (phy->phy_mode == IEEE80211_MODE_11G) {
670
RF_SETBITS(mac, 0x7a, 0x20);
671
RF_SETBITS(mac, 0x51, 0x4);
672
PHY_SETBITS(mac, 0x802, 0x100);
673
PHY_SETBITS(mac, 0x42b, 0x2000);
674
PHY_WRITE(mac, 0x5b, 0);
675
PHY_WRITE(mac, 0x5c, 0);
676
}
677
678
/* Force to channel 7 */
679
orig_chan = rf->rf_curchan;
680
if (orig_chan >= 8)
681
bwi_rf_set_chan(mac, 1, 0);
682
else
683
bwi_rf_set_chan(mac, 13, 0);
684
685
RF_WRITE(mac, 0x50, 0x20);
686
RF_WRITE(mac, 0x50, 0x23);
687
688
DELAY(40);
689
690
if (rf->rf_rev < 6 || rf->rf_rev == 8) {
691
RF_SETBITS(mac, 0x7c, 0x2);
692
RF_WRITE(mac, 0x50, 0x20);
693
}
694
if (rf->rf_rev <= 2) {
695
RF_WRITE(mac, 0x7c, 0x20);
696
RF_WRITE(mac, 0x5a, 0x70);
697
RF_WRITE(mac, 0x5b, 0x7b);
698
RF_WRITE(mac, 0x5c, 0xb0);
699
}
700
701
RF_FILT_SETBITS(mac, 0x7a, 0xf8, 0x7);
702
703
bwi_rf_set_chan(mac, orig_chan, 0);
704
705
PHY_WRITE(mac, 0x14, 0x200);
706
if (rf->rf_rev >= 6)
707
PHY_WRITE(mac, 0x2a, 0x88c2);
708
else
709
PHY_WRITE(mac, 0x2a, 0x8ac0);
710
PHY_WRITE(mac, 0x38, 0x668);
711
712
bwi_mac_set_tpctl_11bg(mac, NULL);
713
714
if (rf->rf_rev <= 5) {
715
PHY_FILT_SETBITS(mac, 0x5d, 0xff80, 0x3);
716
if (rf->rf_rev <= 2)
717
RF_WRITE(mac, 0x5d, 0xd);
718
}
719
720
if (phy->phy_version == 4) {
721
CSR_WRITE_2(sc, BWI_PHY_MAGIC_REG1, BWI_PHY_MAGIC_REG1_VAL2);
722
PHY_CLRBITS(mac, 0x61, 0xf000);
723
} else {
724
PHY_FILT_SETBITS(mac, 0x2, 0xffc0, 0x4);
725
}
726
727
if (phy->phy_mode == IEEE80211_MODE_11B) {
728
CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC2);
729
PHY_WRITE(mac, 0x16, 0x410);
730
PHY_WRITE(mac, 0x17, 0x820);
731
PHY_WRITE(mac, 0x62, 0x7);
732
733
bwi_rf_init_bcm2050(mac);
734
bwi_rf_lo_update(mac);
735
if (sc->sc_card_flags & BWI_CARD_F_SW_NRSSI) {
736
bwi_rf_calc_nrssi_slope(mac);
737
bwi_rf_set_nrssi_thr(mac);
738
}
739
bwi_mac_init_tpctl_11bg(mac);
740
} else {
741
CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
742
}
743
}
744
745
static void
746
bwi_phy_config_11g(struct bwi_mac *mac)
747
{
748
struct bwi_softc *sc = mac->mac_sc;
749
struct bwi_phy *phy = &mac->mac_phy;
750
const uint16_t *tbl;
751
uint16_t wrd_ofs1, wrd_ofs2;
752
int i, n;
753
754
if (phy->phy_rev == 1) {
755
PHY_WRITE(mac, 0x406, 0x4f19);
756
PHY_FILT_SETBITS(mac, 0x429, 0xfc3f, 0x340);
757
PHY_WRITE(mac, 0x42c, 0x5a);
758
PHY_WRITE(mac, 0x427, 0x1a);
759
760
/* Fill frequency table */
761
for (i = 0; i < nitems(bwi_phy_freq_11g_rev1); ++i) {
762
bwi_tbl_write_2(mac, BWI_PHYTBL_FREQ + i,
763
bwi_phy_freq_11g_rev1[i]);
764
}
765
766
/* Fill noise table */
767
for (i = 0; i < nitems(bwi_phy_noise_11g_rev1); ++i) {
768
bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
769
bwi_phy_noise_11g_rev1[i]);
770
}
771
772
/* Fill rotor table */
773
for (i = 0; i < nitems(bwi_phy_rotor_11g_rev1); ++i) {
774
/* NB: data length is 4 bytes */
775
bwi_tbl_write_4(mac, BWI_PHYTBL_ROTOR + i,
776
bwi_phy_rotor_11g_rev1[i]);
777
}
778
} else {
779
bwi_nrssi_write(mac, 0xba98, (int16_t)0x7654); /* XXX */
780
781
if (phy->phy_rev == 2) {
782
PHY_WRITE(mac, 0x4c0, 0x1861);
783
PHY_WRITE(mac, 0x4c1, 0x271);
784
} else if (phy->phy_rev > 2) {
785
PHY_WRITE(mac, 0x4c0, 0x98);
786
PHY_WRITE(mac, 0x4c1, 0x70);
787
PHY_WRITE(mac, 0x4c9, 0x80);
788
}
789
PHY_SETBITS(mac, 0x42b, 0x800);
790
791
/* Fill RSSI table */
792
for (i = 0; i < 64; ++i)
793
bwi_tbl_write_2(mac, BWI_PHYTBL_RSSI + i, i);
794
795
/* Fill noise table */
796
for (i = 0; i < nitems(bwi_phy_noise_11g); ++i) {
797
bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE + i,
798
bwi_phy_noise_11g[i]);
799
}
800
}
801
802
/*
803
* Fill noise scale table
804
*/
805
if (phy->phy_rev <= 2) {
806
tbl = bwi_phy_noise_scale_11g_rev2;
807
n = nitems(bwi_phy_noise_scale_11g_rev2);
808
} else if (phy->phy_rev >= 7 && (PHY_READ(mac, 0x449) & 0x200)) {
809
tbl = bwi_phy_noise_scale_11g_rev7;
810
n = nitems(bwi_phy_noise_scale_11g_rev7);
811
} else {
812
tbl = bwi_phy_noise_scale_11g;
813
n = nitems(bwi_phy_noise_scale_11g);
814
}
815
for (i = 0; i < n; ++i)
816
bwi_tbl_write_2(mac, BWI_PHYTBL_NOISE_SCALE + i, tbl[i]);
817
818
/*
819
* Fill sigma square table
820
*/
821
if (phy->phy_rev == 2) {
822
tbl = bwi_phy_sigma_sq_11g_rev2;
823
n = nitems(bwi_phy_sigma_sq_11g_rev2);
824
} else if (phy->phy_rev > 2 && phy->phy_rev <= 8) {
825
tbl = bwi_phy_sigma_sq_11g_rev7;
826
n = nitems(bwi_phy_sigma_sq_11g_rev7);
827
} else {
828
tbl = NULL;
829
n = 0;
830
}
831
for (i = 0; i < n; ++i)
832
bwi_tbl_write_2(mac, BWI_PHYTBL_SIGMA_SQ + i, tbl[i]);
833
834
if (phy->phy_rev == 1) {
835
/* Fill delay table */
836
for (i = 0; i < nitems(bwi_phy_delay_11g_rev1); ++i) {
837
bwi_tbl_write_4(mac, BWI_PHYTBL_DELAY + i,
838
bwi_phy_delay_11g_rev1[i]);
839
}
840
841
/* Fill WRSSI (Wide-Band RSSI) table */
842
for (i = 4; i < 20; ++i)
843
bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI_REV1 + i, 0x20);
844
845
bwi_phy_config_agc(mac);
846
847
wrd_ofs1 = 0x5001;
848
wrd_ofs2 = 0x5002;
849
} else {
850
/* Fill WRSSI (Wide-Band RSSI) table */
851
for (i = 0; i < 0x20; ++i)
852
bwi_tbl_write_2(mac, BWI_PHYTBL_WRSSI + i, 0x820);
853
854
bwi_phy_config_agc(mac);
855
856
PHY_READ(mac, 0x400); /* Dummy read */
857
PHY_WRITE(mac, 0x403, 0x1000);
858
bwi_tbl_write_2(mac, 0x3c02, 0xf);
859
bwi_tbl_write_2(mac, 0x3c03, 0x14);
860
861
wrd_ofs1 = 0x401;
862
wrd_ofs2 = 0x402;
863
}
864
865
if (!(BWI_IS_BRCM_BU4306(sc) && sc->sc_pci_revid == 0x17)) {
866
bwi_tbl_write_2(mac, wrd_ofs1, 0x2);
867
bwi_tbl_write_2(mac, wrd_ofs2, 0x1);
868
}
869
870
/* phy->phy_flags & BWI_PHY_F_LINKED ? */
871
if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
872
PHY_WRITE(mac, 0x46e, 0x3cf);
873
}
874
875
/*
876
* Configure Automatic Gain Controller
877
*/
878
static void
879
bwi_phy_config_agc(struct bwi_mac *mac)
880
{
881
struct bwi_phy *phy = &mac->mac_phy;
882
uint16_t ofs;
883
884
ofs = phy->phy_rev == 1 ? 0x4c00 : 0;
885
886
bwi_tbl_write_2(mac, ofs, 0xfe);
887
bwi_tbl_write_2(mac, ofs + 1, 0xd);
888
bwi_tbl_write_2(mac, ofs + 2, 0x13);
889
bwi_tbl_write_2(mac, ofs + 3, 0x19);
890
891
if (phy->phy_rev == 1) {
892
bwi_tbl_write_2(mac, 0x1800, 0x2710);
893
bwi_tbl_write_2(mac, 0x1801, 0x9b83);
894
bwi_tbl_write_2(mac, 0x1802, 0x9b83);
895
bwi_tbl_write_2(mac, 0x1803, 0xf8d);
896
PHY_WRITE(mac, 0x455, 0x4);
897
}
898
899
PHY_FILT_SETBITS(mac, 0x4a5, 0xff, 0x5700);
900
PHY_FILT_SETBITS(mac, 0x41a, 0xff80, 0xf);
901
PHY_FILT_SETBITS(mac, 0x41a, 0xc07f, 0x2b80);
902
PHY_FILT_SETBITS(mac, 0x48c, 0xf0ff, 0x300);
903
904
RF_SETBITS(mac, 0x7a, 0x8);
905
906
PHY_FILT_SETBITS(mac, 0x4a0, 0xfff0, 0x8);
907
PHY_FILT_SETBITS(mac, 0x4a1, 0xf0ff, 0x600);
908
PHY_FILT_SETBITS(mac, 0x4a2, 0xf0ff, 0x700);
909
PHY_FILT_SETBITS(mac, 0x4a0, 0xf0ff, 0x100);
910
911
if (phy->phy_rev == 1)
912
PHY_FILT_SETBITS(mac, 0x4a2, 0xfff0, 0x7);
913
914
PHY_FILT_SETBITS(mac, 0x488, 0xff00, 0x1c);
915
PHY_FILT_SETBITS(mac, 0x488, 0xc0ff, 0x200);
916
PHY_FILT_SETBITS(mac, 0x496, 0xff00, 0x1c);
917
PHY_FILT_SETBITS(mac, 0x489, 0xff00, 0x20);
918
PHY_FILT_SETBITS(mac, 0x489, 0xc0ff, 0x200);
919
PHY_FILT_SETBITS(mac, 0x482, 0xff00, 0x2e);
920
PHY_FILT_SETBITS(mac, 0x496, 0xff, 0x1a00);
921
PHY_FILT_SETBITS(mac, 0x481, 0xff00, 0x28);
922
PHY_FILT_SETBITS(mac, 0x481, 0xff, 0x2c00);
923
924
if (phy->phy_rev == 1) {
925
PHY_WRITE(mac, 0x430, 0x92b);
926
PHY_FILT_SETBITS(mac, 0x41b, 0xffe1, 0x2);
927
} else {
928
PHY_CLRBITS(mac, 0x41b, 0x1e);
929
PHY_WRITE(mac, 0x41f, 0x287a);
930
PHY_FILT_SETBITS(mac, 0x420, 0xfff0, 0x4);
931
932
if (phy->phy_rev >= 6) {
933
PHY_WRITE(mac, 0x422, 0x287a);
934
PHY_FILT_SETBITS(mac, 0x420, 0xfff, 0x3000);
935
}
936
}
937
938
PHY_FILT_SETBITS(mac, 0x4a8, 0x8080, 0x7874);
939
PHY_WRITE(mac, 0x48e, 0x1c00);
940
941
if (phy->phy_rev == 1) {
942
PHY_FILT_SETBITS(mac, 0x4ab, 0xf0ff, 0x600);
943
PHY_WRITE(mac, 0x48b, 0x5e);
944
PHY_FILT_SETBITS(mac, 0x48c, 0xff00, 0x1e);
945
PHY_WRITE(mac, 0x48d, 0x2);
946
}
947
948
bwi_tbl_write_2(mac, ofs + 0x800, 0);
949
bwi_tbl_write_2(mac, ofs + 0x801, 7);
950
bwi_tbl_write_2(mac, ofs + 0x802, 16);
951
bwi_tbl_write_2(mac, ofs + 0x803, 28);
952
953
if (phy->phy_rev >= 6) {
954
PHY_CLRBITS(mac, 0x426, 0x3);
955
PHY_CLRBITS(mac, 0x426, 0x1000);
956
}
957
}
958
959
void
960
bwi_set_gains(struct bwi_mac *mac, const struct bwi_gains *gains)
961
{
962
struct bwi_phy *phy = &mac->mac_phy;
963
uint16_t tbl_gain_ofs1, tbl_gain_ofs2, tbl_gain;
964
int i;
965
966
if (phy->phy_rev <= 1) {
967
tbl_gain_ofs1 = 0x5000;
968
tbl_gain_ofs2 = tbl_gain_ofs1 + 16;
969
} else {
970
tbl_gain_ofs1 = 0x400;
971
tbl_gain_ofs2 = tbl_gain_ofs1 + 8;
972
}
973
974
for (i = 0; i < 4; ++i) {
975
if (gains != NULL) {
976
tbl_gain = gains->tbl_gain1;
977
} else {
978
/* Bit swap */
979
tbl_gain = (i & 0x1) << 1;
980
tbl_gain |= (i & 0x2) >> 1;
981
}
982
bwi_tbl_write_2(mac, tbl_gain_ofs1 + i, tbl_gain);
983
}
984
985
for (i = 0; i < 16; ++i) {
986
if (gains != NULL)
987
tbl_gain = gains->tbl_gain2;
988
else
989
tbl_gain = i;
990
bwi_tbl_write_2(mac, tbl_gain_ofs2 + i, tbl_gain);
991
}
992
993
if (gains == NULL || (gains != NULL && gains->phy_gain != -1)) {
994
uint16_t phy_gain1, phy_gain2;
995
996
if (gains != NULL) {
997
phy_gain1 =
998
((uint16_t)gains->phy_gain << 14) |
999
((uint16_t)gains->phy_gain << 6);
1000
phy_gain2 = phy_gain1;
1001
} else {
1002
phy_gain1 = 0x4040;
1003
phy_gain2 = 0x4000;
1004
}
1005
PHY_FILT_SETBITS(mac, 0x4a0, 0xbfbf, phy_gain1);
1006
PHY_FILT_SETBITS(mac, 0x4a1, 0xbfbf, phy_gain1);
1007
PHY_FILT_SETBITS(mac, 0x4a2, 0xbfbf, phy_gain2);
1008
}
1009
bwi_mac_dummy_xmit(mac);
1010
}
1011
1012
void
1013
bwi_phy_clear_state(struct bwi_phy *phy)
1014
{
1015
phy->phy_flags &= ~BWI_CLEAR_PHY_FLAGS;
1016
}
1017
1018