Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/bwi/bwimac.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/bwimac.c,v 1.13 2008/02/15 11:15:38 sephe 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 <sys/linker.h>
57
#include <sys/firmware.h>
58
59
#include <net/if.h>
60
#include <net/if_var.h>
61
#include <net/if_dl.h>
62
#include <net/if_media.h>
63
#include <net/if_types.h>
64
#include <net/if_arp.h>
65
#include <net/ethernet.h>
66
#include <net/if_llc.h>
67
68
#include <net80211/ieee80211_var.h>
69
#include <net80211/ieee80211_radiotap.h>
70
#include <net80211/ieee80211_amrr.h>
71
#include <net80211/ieee80211_phy.h>
72
73
#include <machine/bus.h>
74
75
#include <dev/bwi/bitops.h>
76
#include <dev/bwi/if_bwireg.h>
77
#include <dev/bwi/if_bwivar.h>
78
#include <dev/bwi/bwimac.h>
79
#include <dev/bwi/bwirf.h>
80
#include <dev/bwi/bwiphy.h>
81
82
struct bwi_retry_lim {
83
uint16_t shretry;
84
uint16_t shretry_fb;
85
uint16_t lgretry;
86
uint16_t lgretry_fb;
87
};
88
89
static int bwi_mac_test(struct bwi_mac *);
90
static int bwi_mac_get_property(struct bwi_mac *);
91
92
static void bwi_mac_set_retry_lim(struct bwi_mac *,
93
const struct bwi_retry_lim *);
94
static void bwi_mac_set_ackrates(struct bwi_mac *,
95
const struct ieee80211_rate_table *rt,
96
const struct ieee80211_rateset *);
97
98
static int bwi_mac_gpio_init(struct bwi_mac *);
99
static int bwi_mac_gpio_fini(struct bwi_mac *);
100
static void bwi_mac_opmode_init(struct bwi_mac *);
101
static void bwi_mac_hostflags_init(struct bwi_mac *);
102
static void bwi_mac_bss_param_init(struct bwi_mac *);
103
104
static void bwi_mac_fw_free(struct bwi_mac *);
105
static int bwi_mac_fw_load(struct bwi_mac *);
106
static int bwi_mac_fw_init(struct bwi_mac *);
107
static int bwi_mac_fw_load_iv(struct bwi_mac *, const struct firmware *);
108
109
static void bwi_mac_setup_tpctl(struct bwi_mac *);
110
static void bwi_mac_adjust_tpctl(struct bwi_mac *, int, int);
111
112
static void bwi_mac_lock(struct bwi_mac *);
113
static void bwi_mac_unlock(struct bwi_mac *);
114
115
static const uint8_t bwi_sup_macrev[] = { 2, 4, 5, 6, 7, 9, 10 };
116
117
void
118
bwi_tmplt_write_4(struct bwi_mac *mac, uint32_t ofs, uint32_t val)
119
{
120
struct bwi_softc *sc = mac->mac_sc;
121
122
if (mac->mac_flags & BWI_MAC_F_BSWAP)
123
val = bswap32(val);
124
125
CSR_WRITE_4(sc, BWI_MAC_TMPLT_CTRL, ofs);
126
CSR_WRITE_4(sc, BWI_MAC_TMPLT_DATA, val);
127
}
128
129
void
130
bwi_hostflags_write(struct bwi_mac *mac, uint64_t flags)
131
{
132
uint64_t val;
133
134
val = flags & 0xffff;
135
MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO, val);
136
137
val = (flags >> 16) & 0xffff;
138
MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI, val);
139
140
/* HI has unclear meaning, so leave it as it is */
141
}
142
143
uint64_t
144
bwi_hostflags_read(struct bwi_mac *mac)
145
{
146
uint64_t flags, val;
147
148
/* HI has unclear meaning, so don't touch it */
149
flags = 0;
150
151
val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_MI);
152
flags |= val << 16;
153
154
val = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_HFLAGS_LO);
155
flags |= val;
156
157
return flags;
158
}
159
160
uint16_t
161
bwi_memobj_read_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0)
162
{
163
struct bwi_softc *sc = mac->mac_sc;
164
uint32_t data_reg;
165
int ofs;
166
167
data_reg = BWI_MOBJ_DATA;
168
ofs = ofs0 / 4;
169
170
if (ofs0 % 4 != 0)
171
data_reg = BWI_MOBJ_DATA_UNALIGN;
172
173
CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
174
return CSR_READ_2(sc, data_reg);
175
}
176
177
uint32_t
178
bwi_memobj_read_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0)
179
{
180
struct bwi_softc *sc = mac->mac_sc;
181
int ofs;
182
183
ofs = ofs0 / 4;
184
if (ofs0 % 4 != 0) {
185
uint32_t ret;
186
187
CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
188
ret = CSR_READ_2(sc, BWI_MOBJ_DATA_UNALIGN);
189
ret <<= 16;
190
191
CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
192
BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1));
193
ret |= CSR_READ_2(sc, BWI_MOBJ_DATA);
194
195
return ret;
196
} else {
197
CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
198
return CSR_READ_4(sc, BWI_MOBJ_DATA);
199
}
200
}
201
202
void
203
bwi_memobj_write_2(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0,
204
uint16_t v)
205
{
206
struct bwi_softc *sc = mac->mac_sc;
207
uint32_t data_reg;
208
int ofs;
209
210
data_reg = BWI_MOBJ_DATA;
211
ofs = ofs0 / 4;
212
213
if (ofs0 % 4 != 0)
214
data_reg = BWI_MOBJ_DATA_UNALIGN;
215
216
CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
217
CSR_WRITE_2(sc, data_reg, v);
218
}
219
220
void
221
bwi_memobj_write_4(struct bwi_mac *mac, uint16_t obj_id, uint16_t ofs0,
222
uint32_t v)
223
{
224
struct bwi_softc *sc = mac->mac_sc;
225
int ofs;
226
227
ofs = ofs0 / 4;
228
if (ofs0 % 4 != 0) {
229
CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
230
CSR_WRITE_2(sc, BWI_MOBJ_DATA_UNALIGN, v >> 16);
231
232
CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
233
BWI_MOBJ_CTRL_VAL(obj_id, ofs + 1));
234
CSR_WRITE_2(sc, BWI_MOBJ_DATA, v & 0xffff);
235
} else {
236
CSR_WRITE_4(sc, BWI_MOBJ_CTRL, BWI_MOBJ_CTRL_VAL(obj_id, ofs));
237
CSR_WRITE_4(sc, BWI_MOBJ_DATA, v);
238
}
239
}
240
241
int
242
bwi_mac_lateattach(struct bwi_mac *mac)
243
{
244
int error;
245
246
if (mac->mac_rev >= 5)
247
CSR_READ_4(mac->mac_sc, BWI_STATE_HI); /* dummy read */
248
249
bwi_mac_reset(mac, 1);
250
251
error = bwi_phy_attach(mac);
252
if (error)
253
return error;
254
255
error = bwi_rf_attach(mac);
256
if (error)
257
return error;
258
259
/* Link 11B/G PHY, unlink 11A PHY */
260
if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A)
261
bwi_mac_reset(mac, 0);
262
else
263
bwi_mac_reset(mac, 1);
264
265
error = bwi_mac_test(mac);
266
if (error)
267
return error;
268
269
error = bwi_mac_get_property(mac);
270
if (error)
271
return error;
272
273
error = bwi_rf_map_txpower(mac);
274
if (error)
275
return error;
276
277
bwi_rf_off(mac);
278
CSR_WRITE_2(mac->mac_sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC);
279
bwi_regwin_disable(mac->mac_sc, &mac->mac_regwin, 0);
280
281
return 0;
282
}
283
284
int
285
bwi_mac_init(struct bwi_mac *mac)
286
{
287
struct bwi_softc *sc = mac->mac_sc;
288
int error, i;
289
290
/* Clear MAC/PHY/RF states */
291
bwi_mac_setup_tpctl(mac);
292
bwi_rf_clear_state(&mac->mac_rf);
293
bwi_phy_clear_state(&mac->mac_phy);
294
295
/* Enable MAC and linked it to PHY */
296
if (!bwi_regwin_is_enabled(sc, &mac->mac_regwin))
297
bwi_mac_reset(mac, 1);
298
299
/* Initialize backplane */
300
error = bwi_bus_init(sc, mac);
301
if (error)
302
return error;
303
304
/* do timeout fixup */
305
if (sc->sc_bus_regwin.rw_rev <= 5 &&
306
sc->sc_bus_regwin.rw_type != BWI_REGWIN_T_BUSPCIE) {
307
CSR_SETBITS_4(sc, BWI_CONF_LO,
308
__SHIFTIN(BWI_CONF_LO_SERVTO, BWI_CONF_LO_SERVTO_MASK) |
309
__SHIFTIN(BWI_CONF_LO_REQTO, BWI_CONF_LO_REQTO_MASK));
310
}
311
312
/* Calibrate PHY */
313
error = bwi_phy_calibrate(mac);
314
if (error) {
315
device_printf(sc->sc_dev, "PHY calibrate failed\n");
316
return error;
317
}
318
319
/* Prepare to initialize firmware */
320
CSR_WRITE_4(sc, BWI_MAC_STATUS,
321
BWI_MAC_STATUS_UCODE_JUMP0 |
322
BWI_MAC_STATUS_IHREN);
323
324
/*
325
* Load and initialize firmwares
326
*/
327
error = bwi_mac_fw_load(mac);
328
if (error)
329
return error;
330
331
error = bwi_mac_gpio_init(mac);
332
if (error)
333
return error;
334
335
error = bwi_mac_fw_init(mac);
336
if (error)
337
return error;
338
339
/*
340
* Turn on RF
341
*/
342
bwi_rf_on(mac);
343
344
/* TODO: LED, hardware rf enabled is only related to LED setting */
345
346
/*
347
* Initialize PHY
348
*/
349
CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
350
bwi_phy_init(mac);
351
352
/* TODO: interference mitigation */
353
354
/*
355
* Setup antenna mode
356
*/
357
bwi_rf_set_ant_mode(mac, mac->mac_rf.rf_ant_mode);
358
359
/*
360
* Initialize operation mode (RX configuration)
361
*/
362
bwi_mac_opmode_init(mac);
363
364
/* set up Beacon interval */
365
if (mac->mac_rev < 3) {
366
CSR_WRITE_2(sc, 0x60e, 0);
367
CSR_WRITE_2(sc, 0x610, 0x8000);
368
CSR_WRITE_2(sc, 0x604, 0);
369
CSR_WRITE_2(sc, 0x606, 0x200);
370
} else {
371
CSR_WRITE_4(sc, 0x188, 0x80000000);
372
CSR_WRITE_4(sc, 0x18c, 0x2000000);
373
}
374
375
/*
376
* Initialize TX/RX interrupts' mask
377
*/
378
CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_TIMER1);
379
for (i = 0; i < BWI_TXRX_NRING; ++i) {
380
uint32_t intrs;
381
382
if (BWI_TXRX_IS_RX(i))
383
intrs = BWI_TXRX_RX_INTRS;
384
else
385
intrs = BWI_TXRX_TX_INTRS;
386
CSR_WRITE_4(sc, BWI_TXRX_INTR_MASK(i), intrs);
387
}
388
389
/* allow the MAC to control the PHY clock (dynamic on/off) */
390
CSR_SETBITS_4(sc, BWI_STATE_LO, 0x100000);
391
392
/* Setup MAC power up delay */
393
CSR_WRITE_2(sc, BWI_MAC_POWERUP_DELAY, sc->sc_pwron_delay);
394
395
/* Set MAC regwin revision */
396
MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_MACREV, mac->mac_rev);
397
398
/*
399
* Initialize host flags
400
*/
401
bwi_mac_hostflags_init(mac);
402
403
/*
404
* Initialize BSS parameters
405
*/
406
bwi_mac_bss_param_init(mac);
407
408
/*
409
* Initialize TX rings
410
*/
411
for (i = 0; i < BWI_TX_NRING; ++i) {
412
error = sc->sc_init_tx_ring(sc, i);
413
if (error) {
414
device_printf(sc->sc_dev,
415
"can't initialize %dth TX ring\n", i);
416
return error;
417
}
418
}
419
420
/*
421
* Initialize RX ring
422
*/
423
error = sc->sc_init_rx_ring(sc);
424
if (error) {
425
device_printf(sc->sc_dev, "can't initialize RX ring\n");
426
return error;
427
}
428
429
/*
430
* Initialize TX stats if the current MAC uses that
431
*/
432
if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) {
433
error = sc->sc_init_txstats(sc);
434
if (error) {
435
device_printf(sc->sc_dev,
436
"can't initialize TX stats ring\n");
437
return error;
438
}
439
}
440
441
/* update PRETBTT */
442
CSR_WRITE_2(sc, 0x612, 0x50); /* Force Pre-TBTT to 80? */
443
MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x416, 0x50);
444
MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x414, 0x1f4);
445
446
mac->mac_flags |= BWI_MAC_F_INITED;
447
return 0;
448
}
449
450
void
451
bwi_mac_reset(struct bwi_mac *mac, int link_phy)
452
{
453
struct bwi_softc *sc = mac->mac_sc;
454
uint32_t flags, state_lo, status;
455
456
flags = BWI_STATE_LO_FLAG_PHYRST | BWI_STATE_LO_FLAG_PHYCLKEN;
457
if (link_phy)
458
flags |= BWI_STATE_LO_FLAG_PHYLNK;
459
bwi_regwin_enable(sc, &mac->mac_regwin, flags);
460
DELAY(2000);
461
462
state_lo = CSR_READ_4(sc, BWI_STATE_LO);
463
state_lo |= BWI_STATE_LO_GATED_CLOCK;
464
state_lo &= ~__SHIFTIN(BWI_STATE_LO_FLAG_PHYRST,
465
BWI_STATE_LO_FLAGS_MASK);
466
CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
467
/* Flush pending bus write */
468
CSR_READ_4(sc, BWI_STATE_LO);
469
DELAY(1000);
470
471
state_lo &= ~BWI_STATE_LO_GATED_CLOCK;
472
CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
473
/* Flush pending bus write */
474
CSR_READ_4(sc, BWI_STATE_LO);
475
DELAY(1000);
476
477
CSR_WRITE_2(sc, BWI_BBP_ATTEN, 0);
478
479
status = CSR_READ_4(sc, BWI_MAC_STATUS);
480
status |= BWI_MAC_STATUS_IHREN;
481
if (link_phy)
482
status |= BWI_MAC_STATUS_PHYLNK;
483
else
484
status &= ~BWI_MAC_STATUS_PHYLNK;
485
CSR_WRITE_4(sc, BWI_MAC_STATUS, status);
486
487
if (link_phy) {
488
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH | BWI_DBG_INIT,
489
"%s\n", "PHY is linked");
490
mac->mac_phy.phy_flags |= BWI_PHY_F_LINKED;
491
} else {
492
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH | BWI_DBG_INIT,
493
"%s\n", "PHY is unlinked");
494
mac->mac_phy.phy_flags &= ~BWI_PHY_F_LINKED;
495
}
496
}
497
498
void
499
bwi_mac_set_tpctl_11bg(struct bwi_mac *mac, const struct bwi_tpctl *new_tpctl)
500
{
501
struct bwi_rf *rf = &mac->mac_rf;
502
struct bwi_tpctl *tpctl = &mac->mac_tpctl;
503
504
if (new_tpctl != NULL) {
505
KASSERT(new_tpctl->bbp_atten <= BWI_BBP_ATTEN_MAX,
506
("bbp_atten %d", new_tpctl->bbp_atten));
507
KASSERT(new_tpctl->rf_atten <=
508
(rf->rf_rev < 6 ? BWI_RF_ATTEN_MAX0
509
: BWI_RF_ATTEN_MAX1),
510
("rf_atten %d", new_tpctl->rf_atten));
511
KASSERT(new_tpctl->tp_ctrl1 <= BWI_TPCTL1_MAX,
512
("tp_ctrl1 %d", new_tpctl->tp_ctrl1));
513
514
tpctl->bbp_atten = new_tpctl->bbp_atten;
515
tpctl->rf_atten = new_tpctl->rf_atten;
516
tpctl->tp_ctrl1 = new_tpctl->tp_ctrl1;
517
}
518
519
/* Set BBP attenuation */
520
bwi_phy_set_bbp_atten(mac, tpctl->bbp_atten);
521
522
/* Set RF attenuation */
523
RF_WRITE(mac, BWI_RFR_ATTEN, tpctl->rf_atten);
524
MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_RF_ATTEN,
525
tpctl->rf_atten);
526
527
/* Set TX power */
528
if (rf->rf_type == BWI_RF_T_BCM2050) {
529
RF_FILT_SETBITS(mac, BWI_RFR_TXPWR, ~BWI_RFR_TXPWR1_MASK,
530
__SHIFTIN(tpctl->tp_ctrl1, BWI_RFR_TXPWR1_MASK));
531
}
532
533
/* Adjust RF Local Oscillator */
534
if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G)
535
bwi_rf_lo_adjust(mac, tpctl);
536
}
537
538
static int
539
bwi_mac_test(struct bwi_mac *mac)
540
{
541
struct bwi_softc *sc = mac->mac_sc;
542
uint32_t orig_val, val;
543
544
#define TEST_VAL1 0xaa5555aa
545
#define TEST_VAL2 0x55aaaa55
546
547
/* Save it for later restoring */
548
orig_val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
549
550
/* Test 1 */
551
MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL1);
552
val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
553
if (val != TEST_VAL1) {
554
device_printf(sc->sc_dev, "TEST1 failed\n");
555
return ENXIO;
556
}
557
558
/* Test 2 */
559
MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, TEST_VAL2);
560
val = MOBJ_READ_4(mac, BWI_COMM_MOBJ, 0);
561
if (val != TEST_VAL2) {
562
device_printf(sc->sc_dev, "TEST2 failed\n");
563
return ENXIO;
564
}
565
566
/* Restore to the original value */
567
MOBJ_WRITE_4(mac, BWI_COMM_MOBJ, 0, orig_val);
568
569
val = CSR_READ_4(sc, BWI_MAC_STATUS);
570
if ((val & ~BWI_MAC_STATUS_PHYLNK) != BWI_MAC_STATUS_IHREN) {
571
device_printf(sc->sc_dev, "%s failed, MAC status 0x%08x\n",
572
__func__, val);
573
return ENXIO;
574
}
575
576
val = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
577
if (val != 0) {
578
device_printf(sc->sc_dev, "%s failed, intr status %08x\n",
579
__func__, val);
580
return ENXIO;
581
}
582
583
#undef TEST_VAL2
584
#undef TEST_VAL1
585
586
return 0;
587
}
588
589
static void
590
bwi_mac_setup_tpctl(struct bwi_mac *mac)
591
{
592
struct bwi_softc *sc = mac->mac_sc;
593
struct bwi_rf *rf = &mac->mac_rf;
594
struct bwi_phy *phy = &mac->mac_phy;
595
struct bwi_tpctl *tpctl = &mac->mac_tpctl;
596
597
/* Calc BBP attenuation */
598
if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev < 6)
599
tpctl->bbp_atten = 0;
600
else
601
tpctl->bbp_atten = 2;
602
603
/* Calc TX power CTRL1?? */
604
tpctl->tp_ctrl1 = 0;
605
if (rf->rf_type == BWI_RF_T_BCM2050) {
606
if (rf->rf_rev == 1)
607
tpctl->tp_ctrl1 = 3;
608
else if (rf->rf_rev < 6)
609
tpctl->tp_ctrl1 = 2;
610
else if (rf->rf_rev == 8)
611
tpctl->tp_ctrl1 = 1;
612
}
613
614
/* Empty TX power CTRL2?? */
615
tpctl->tp_ctrl2 = 0xffff;
616
617
/*
618
* Calc RF attenuation
619
*/
620
if (phy->phy_mode == IEEE80211_MODE_11A) {
621
tpctl->rf_atten = 0x60;
622
goto back;
623
}
624
625
if (BWI_IS_BRCM_BCM4309G(sc) && sc->sc_pci_revid < 0x51) {
626
tpctl->rf_atten = sc->sc_pci_revid < 0x43 ? 2 : 3;
627
goto back;
628
}
629
630
tpctl->rf_atten = 5;
631
632
if (rf->rf_type != BWI_RF_T_BCM2050) {
633
if (rf->rf_type == BWI_RF_T_BCM2053 && rf->rf_rev == 1)
634
tpctl->rf_atten = 6;
635
goto back;
636
}
637
638
/*
639
* NB: If we reaches here and the card is BRCM_BCM4309G,
640
* then the card's PCI revision must >= 0x51
641
*/
642
643
/* BCM2050 RF */
644
switch (rf->rf_rev) {
645
case 1:
646
if (phy->phy_mode == IEEE80211_MODE_11G) {
647
if (BWI_IS_BRCM_BCM4309G(sc) || BWI_IS_BRCM_BU4306(sc))
648
tpctl->rf_atten = 3;
649
else
650
tpctl->rf_atten = 1;
651
} else {
652
if (BWI_IS_BRCM_BCM4309G(sc))
653
tpctl->rf_atten = 7;
654
else
655
tpctl->rf_atten = 6;
656
}
657
break;
658
case 2:
659
if (phy->phy_mode == IEEE80211_MODE_11G) {
660
/*
661
* NOTE: Order of following conditions is critical
662
*/
663
if (BWI_IS_BRCM_BCM4309G(sc))
664
tpctl->rf_atten = 3;
665
else if (BWI_IS_BRCM_BU4306(sc))
666
tpctl->rf_atten = 5;
667
else if (sc->sc_bbp_id == BWI_BBPID_BCM4320)
668
tpctl->rf_atten = 4;
669
else
670
tpctl->rf_atten = 3;
671
} else {
672
tpctl->rf_atten = 6;
673
}
674
break;
675
case 4:
676
case 5:
677
tpctl->rf_atten = 1;
678
break;
679
case 8:
680
tpctl->rf_atten = 0x1a;
681
break;
682
}
683
back:
684
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_TXPOWER,
685
"bbp atten: %u, rf atten: %u, ctrl1: %u, ctrl2: %u\n",
686
tpctl->bbp_atten, tpctl->rf_atten,
687
tpctl->tp_ctrl1, tpctl->tp_ctrl2);
688
}
689
690
void
691
bwi_mac_dummy_xmit(struct bwi_mac *mac)
692
{
693
#define PACKET_LEN 5
694
static const uint32_t packet_11a[PACKET_LEN] =
695
{ 0x000201cc, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
696
static const uint32_t packet_11bg[PACKET_LEN] =
697
{ 0x000b846e, 0x00d40000, 0x00000000, 0x01000000, 0x00000000 };
698
699
struct bwi_softc *sc = mac->mac_sc;
700
struct bwi_rf *rf = &mac->mac_rf;
701
const uint32_t *packet;
702
uint16_t val_50c;
703
int wait_max, i;
704
705
if (mac->mac_phy.phy_mode == IEEE80211_MODE_11A) {
706
wait_max = 30;
707
packet = packet_11a;
708
val_50c = 1;
709
} else {
710
wait_max = 250;
711
packet = packet_11bg;
712
val_50c = 0;
713
}
714
715
for (i = 0; i < PACKET_LEN; ++i)
716
TMPLT_WRITE_4(mac, i * 4, packet[i]);
717
718
CSR_READ_4(sc, BWI_MAC_STATUS); /* dummy read */
719
720
CSR_WRITE_2(sc, 0x568, 0);
721
CSR_WRITE_2(sc, 0x7c0, 0);
722
CSR_WRITE_2(sc, 0x50c, val_50c);
723
CSR_WRITE_2(sc, 0x508, 0);
724
CSR_WRITE_2(sc, 0x50a, 0);
725
CSR_WRITE_2(sc, 0x54c, 0);
726
CSR_WRITE_2(sc, 0x56a, 0x14);
727
CSR_WRITE_2(sc, 0x568, 0x826);
728
CSR_WRITE_2(sc, 0x500, 0);
729
CSR_WRITE_2(sc, 0x502, 0x30);
730
731
if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev <= 5)
732
RF_WRITE(mac, 0x51, 0x17);
733
734
for (i = 0; i < wait_max; ++i) {
735
if (CSR_READ_2(sc, 0x50e) & 0x80)
736
break;
737
DELAY(10);
738
}
739
for (i = 0; i < 10; ++i) {
740
if (CSR_READ_2(sc, 0x50e) & 0x400)
741
break;
742
DELAY(10);
743
}
744
for (i = 0; i < 10; ++i) {
745
if ((CSR_READ_2(sc, 0x690) & 0x100) == 0)
746
break;
747
DELAY(10);
748
}
749
750
if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev <= 5)
751
RF_WRITE(mac, 0x51, 0x37);
752
#undef PACKET_LEN
753
}
754
755
void
756
bwi_mac_init_tpctl_11bg(struct bwi_mac *mac)
757
{
758
struct bwi_softc *sc = mac->mac_sc;
759
struct bwi_phy *phy = &mac->mac_phy;
760
struct bwi_rf *rf = &mac->mac_rf;
761
struct bwi_tpctl tpctl_orig;
762
int restore_tpctl = 0;
763
764
KASSERT(phy->phy_mode != IEEE80211_MODE_11A,
765
("phy_mode %d", phy->phy_mode));
766
767
if (BWI_IS_BRCM_BU4306(sc))
768
return;
769
770
PHY_WRITE(mac, 0x28, 0x8018);
771
CSR_CLRBITS_2(sc, BWI_BBP_ATTEN, 0x20);
772
773
if (phy->phy_mode == IEEE80211_MODE_11G) {
774
if ((phy->phy_flags & BWI_PHY_F_LINKED) == 0)
775
return;
776
PHY_WRITE(mac, 0x47a, 0xc111);
777
}
778
if (mac->mac_flags & BWI_MAC_F_TPCTL_INITED)
779
return;
780
781
if (phy->phy_mode == IEEE80211_MODE_11B && phy->phy_rev >= 2 &&
782
rf->rf_type == BWI_RF_T_BCM2050) {
783
RF_SETBITS(mac, 0x76, 0x84);
784
} else {
785
struct bwi_tpctl tpctl;
786
787
/* Backup original TX power control variables */
788
bcopy(&mac->mac_tpctl, &tpctl_orig, sizeof(tpctl_orig));
789
restore_tpctl = 1;
790
791
bcopy(&mac->mac_tpctl, &tpctl, sizeof(tpctl));
792
tpctl.bbp_atten = 11;
793
tpctl.tp_ctrl1 = 0;
794
#ifdef notyet
795
if (rf->rf_rev >= 6 && rf->rf_rev <= 8)
796
tpctl.rf_atten = 31;
797
else
798
#endif
799
tpctl.rf_atten = 9;
800
801
bwi_mac_set_tpctl_11bg(mac, &tpctl);
802
}
803
804
bwi_mac_dummy_xmit(mac);
805
806
mac->mac_flags |= BWI_MAC_F_TPCTL_INITED;
807
rf->rf_base_tssi = PHY_READ(mac, 0x29);
808
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_TXPOWER,
809
"base tssi %d\n", rf->rf_base_tssi);
810
811
if (abs(rf->rf_base_tssi - rf->rf_idle_tssi) >= 20) {
812
device_printf(sc->sc_dev, "base tssi measure failed\n");
813
mac->mac_flags |= BWI_MAC_F_TPCTL_ERROR;
814
}
815
816
if (restore_tpctl)
817
bwi_mac_set_tpctl_11bg(mac, &tpctl_orig);
818
else
819
RF_CLRBITS(mac, 0x76, 0x84);
820
821
bwi_rf_clear_tssi(mac);
822
}
823
824
void
825
bwi_mac_detach(struct bwi_mac *mac)
826
{
827
bwi_mac_fw_free(mac);
828
}
829
830
static __inline int
831
bwi_fwimage_is_valid(struct bwi_softc *sc, const struct firmware *fw,
832
uint8_t fw_type)
833
{
834
const struct bwi_fwhdr *hdr;
835
836
if (fw->datasize < sizeof(*hdr)) {
837
device_printf(sc->sc_dev,
838
"invalid firmware (%s): invalid size %zu\n",
839
fw->name, fw->datasize);
840
return 0;
841
}
842
843
hdr = (const struct bwi_fwhdr *)fw->data;
844
845
if (fw_type != BWI_FW_T_IV) {
846
/*
847
* Don't verify IV's size, it has different meaning
848
*/
849
if (be32toh(hdr->fw_size) != fw->datasize - sizeof(*hdr)) {
850
device_printf(sc->sc_dev,
851
"invalid firmware (%s): size mismatch, "
852
"fw %u, real %zu\n", fw->name,
853
be32toh(hdr->fw_size), fw->datasize - sizeof(*hdr));
854
return 0;
855
}
856
}
857
858
if (hdr->fw_type != fw_type) {
859
device_printf(sc->sc_dev,
860
"invalid firmware (%s): type mismatch, "
861
"fw \'%c\', target \'%c\'\n", fw->name,
862
hdr->fw_type, fw_type);
863
return 0;
864
}
865
866
if (hdr->fw_gen != BWI_FW_GEN_1) {
867
device_printf(sc->sc_dev,
868
"invalid firmware (%s): wrong generation, "
869
"fw %d, target %d\n", fw->name, hdr->fw_gen, BWI_FW_GEN_1);
870
return 0;
871
}
872
return 1;
873
}
874
875
/*
876
* XXX Error cleanup
877
*/
878
int
879
bwi_mac_fw_alloc(struct bwi_mac *mac)
880
{
881
struct bwi_softc *sc = mac->mac_sc;
882
char fwname[64];
883
int idx;
884
885
/*
886
* Try getting the firmware stub so firmware
887
* module would be loaded automatically
888
*/
889
if (mac->mac_stub == NULL) {
890
snprintf(fwname, sizeof(fwname), BWI_FW_STUB_PATH,
891
sc->sc_fw_version);
892
mac->mac_stub = firmware_get(fwname);
893
if (mac->mac_stub == NULL)
894
goto no_firmware;
895
}
896
897
if (mac->mac_ucode == NULL) {
898
snprintf(fwname, sizeof(fwname), BWI_FW_UCODE_PATH,
899
sc->sc_fw_version,
900
mac->mac_rev >= 5 ? 5 : mac->mac_rev);
901
902
mac->mac_ucode = firmware_get(fwname);
903
if (mac->mac_ucode == NULL)
904
goto no_firmware;
905
if (!bwi_fwimage_is_valid(sc, mac->mac_ucode, BWI_FW_T_UCODE))
906
return EINVAL;
907
}
908
909
if (mac->mac_pcm == NULL) {
910
snprintf(fwname, sizeof(fwname), BWI_FW_PCM_PATH,
911
sc->sc_fw_version,
912
mac->mac_rev < 5 ? 4 : 5);
913
914
mac->mac_pcm = firmware_get(fwname);
915
if (mac->mac_pcm == NULL)
916
goto no_firmware;
917
if (!bwi_fwimage_is_valid(sc, mac->mac_pcm, BWI_FW_T_PCM))
918
return EINVAL;
919
}
920
921
if (mac->mac_iv == NULL) {
922
/* TODO: 11A */
923
if (mac->mac_rev == 2 || mac->mac_rev == 4) {
924
idx = 2;
925
} else if (mac->mac_rev >= 5 && mac->mac_rev <= 10) {
926
idx = 5;
927
} else {
928
device_printf(sc->sc_dev,
929
"no suitible IV for MAC rev %d\n", mac->mac_rev);
930
return ENODEV;
931
}
932
933
snprintf(fwname, sizeof(fwname), BWI_FW_IV_PATH,
934
sc->sc_fw_version, idx);
935
936
mac->mac_iv = firmware_get(fwname);
937
if (mac->mac_iv == NULL)
938
goto no_firmware;
939
if (!bwi_fwimage_is_valid(sc, mac->mac_iv, BWI_FW_T_IV))
940
return EINVAL;
941
}
942
943
if (mac->mac_iv_ext == NULL) {
944
/* TODO: 11A */
945
if (mac->mac_rev == 2 || mac->mac_rev == 4 ||
946
mac->mac_rev >= 11) {
947
/* No extended IV */
948
return (0);
949
} else if (mac->mac_rev >= 5 && mac->mac_rev <= 10) {
950
idx = 5;
951
} else {
952
device_printf(sc->sc_dev,
953
"no suitible ExtIV for MAC rev %d\n", mac->mac_rev);
954
return ENODEV;
955
}
956
957
snprintf(fwname, sizeof(fwname), BWI_FW_IV_EXT_PATH,
958
sc->sc_fw_version, idx);
959
960
mac->mac_iv_ext = firmware_get(fwname);
961
if (mac->mac_iv_ext == NULL)
962
goto no_firmware;
963
if (!bwi_fwimage_is_valid(sc, mac->mac_iv_ext, BWI_FW_T_IV))
964
return EINVAL;
965
}
966
return (0);
967
968
no_firmware:
969
device_printf(sc->sc_dev, "request firmware %s failed\n", fwname);
970
return (ENOENT);
971
}
972
973
static void
974
bwi_mac_fw_free(struct bwi_mac *mac)
975
{
976
if (mac->mac_ucode != NULL) {
977
firmware_put(mac->mac_ucode, FIRMWARE_UNLOAD);
978
mac->mac_ucode = NULL;
979
}
980
981
if (mac->mac_pcm != NULL) {
982
firmware_put(mac->mac_pcm, FIRMWARE_UNLOAD);
983
mac->mac_pcm = NULL;
984
}
985
986
if (mac->mac_iv != NULL) {
987
firmware_put(mac->mac_iv, FIRMWARE_UNLOAD);
988
mac->mac_iv = NULL;
989
}
990
991
if (mac->mac_iv_ext != NULL) {
992
firmware_put(mac->mac_iv_ext, FIRMWARE_UNLOAD);
993
mac->mac_iv_ext = NULL;
994
}
995
996
if (mac->mac_stub != NULL) {
997
firmware_put(mac->mac_stub, FIRMWARE_UNLOAD);
998
mac->mac_stub = NULL;
999
}
1000
}
1001
1002
static int
1003
bwi_mac_fw_load(struct bwi_mac *mac)
1004
{
1005
struct bwi_softc *sc = mac->mac_sc;
1006
const uint32_t *fw;
1007
uint16_t fw_rev;
1008
int fw_len, i;
1009
1010
/*
1011
* Load ucode image
1012
*/
1013
fw = (const uint32_t *)
1014
((const uint8_t *)mac->mac_ucode->data + BWI_FWHDR_SZ);
1015
fw_len = (mac->mac_ucode->datasize - BWI_FWHDR_SZ) / sizeof(uint32_t);
1016
1017
CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
1018
BWI_MOBJ_CTRL_VAL(
1019
BWI_FW_UCODE_MOBJ | BWI_WR_MOBJ_AUTOINC, 0));
1020
for (i = 0; i < fw_len; ++i) {
1021
CSR_WRITE_4(sc, BWI_MOBJ_DATA, be32toh(fw[i]));
1022
DELAY(10);
1023
}
1024
1025
/*
1026
* Load PCM image
1027
*/
1028
fw = (const uint32_t *)
1029
((const uint8_t *)mac->mac_pcm->data + BWI_FWHDR_SZ);
1030
fw_len = (mac->mac_pcm->datasize - BWI_FWHDR_SZ) / sizeof(uint32_t);
1031
1032
CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
1033
BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01ea));
1034
CSR_WRITE_4(sc, BWI_MOBJ_DATA, 0x4000);
1035
1036
CSR_WRITE_4(sc, BWI_MOBJ_CTRL,
1037
BWI_MOBJ_CTRL_VAL(BWI_FW_PCM_MOBJ, 0x01eb));
1038
for (i = 0; i < fw_len; ++i) {
1039
CSR_WRITE_4(sc, BWI_MOBJ_DATA, be32toh(fw[i]));
1040
DELAY(10);
1041
}
1042
1043
CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_ALL_INTRS);
1044
CSR_WRITE_4(sc, BWI_MAC_STATUS,
1045
BWI_MAC_STATUS_UCODE_START |
1046
BWI_MAC_STATUS_IHREN |
1047
BWI_MAC_STATUS_INFRA);
1048
1049
#define NRETRY 200
1050
1051
for (i = 0; i < NRETRY; ++i) {
1052
uint32_t intr_status;
1053
1054
intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
1055
if (intr_status == BWI_INTR_READY)
1056
break;
1057
DELAY(10);
1058
}
1059
if (i == NRETRY) {
1060
device_printf(sc->sc_dev,
1061
"firmware (ucode&pcm) loading timed out\n");
1062
return ETIMEDOUT;
1063
}
1064
1065
#undef NRETRY
1066
1067
CSR_READ_4(sc, BWI_MAC_INTR_STATUS); /* dummy read */
1068
1069
fw_rev = MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWREV);
1070
if (fw_rev > BWI_FW_VERSION3_REVMAX) {
1071
device_printf(sc->sc_dev,
1072
"firmware version 4 is not supported yet\n");
1073
return ENODEV;
1074
}
1075
1076
device_printf(sc->sc_dev,
1077
"firmware rev 0x%04x, patch level 0x%04x\n", fw_rev,
1078
MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_FWPATCHLV));
1079
return 0;
1080
}
1081
1082
static int
1083
bwi_mac_gpio_init(struct bwi_mac *mac)
1084
{
1085
struct bwi_softc *sc = mac->mac_sc;
1086
struct bwi_regwin *old, *gpio_rw;
1087
uint32_t filt, bits;
1088
int error;
1089
1090
CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_GPOSEL_MASK);
1091
/* TODO:LED */
1092
1093
CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0xf);
1094
1095
filt = 0x1f;
1096
bits = 0xf;
1097
if (sc->sc_bbp_id == BWI_BBPID_BCM4301) {
1098
filt |= 0x60;
1099
bits |= 0x60;
1100
}
1101
if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) {
1102
CSR_SETBITS_2(sc, BWI_MAC_GPIO_MASK, 0x200);
1103
filt |= 0x200;
1104
bits |= 0x200;
1105
}
1106
1107
gpio_rw = BWI_GPIO_REGWIN(sc);
1108
error = bwi_regwin_switch(sc, gpio_rw, &old);
1109
if (error)
1110
return error;
1111
1112
CSR_FILT_SETBITS_4(sc, BWI_GPIO_CTRL, filt, bits);
1113
1114
return bwi_regwin_switch(sc, old, NULL);
1115
}
1116
1117
static int
1118
bwi_mac_gpio_fini(struct bwi_mac *mac)
1119
{
1120
struct bwi_softc *sc = mac->mac_sc;
1121
struct bwi_regwin *old, *gpio_rw;
1122
int error;
1123
1124
gpio_rw = BWI_GPIO_REGWIN(sc);
1125
error = bwi_regwin_switch(sc, gpio_rw, &old);
1126
if (error)
1127
return error;
1128
1129
CSR_WRITE_4(sc, BWI_GPIO_CTRL, 0);
1130
1131
return bwi_regwin_switch(sc, old, NULL);
1132
}
1133
1134
static int
1135
bwi_mac_fw_load_iv(struct bwi_mac *mac, const struct firmware *fw)
1136
{
1137
struct bwi_softc *sc = mac->mac_sc;
1138
const struct bwi_fwhdr *hdr;
1139
const struct bwi_fw_iv *iv;
1140
int n, i, iv_img_size;
1141
1142
/* Get the number of IVs in the IV image */
1143
hdr = (const struct bwi_fwhdr *)fw->data;
1144
n = be32toh(hdr->fw_iv_cnt);
1145
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_INIT | BWI_DBG_FIRMWARE,
1146
"IV count %d\n", n);
1147
1148
/* Calculate the IV image size, for later sanity check */
1149
iv_img_size = fw->datasize - sizeof(*hdr);
1150
1151
/* Locate the first IV */
1152
iv = (const struct bwi_fw_iv *)
1153
((const uint8_t *)fw->data + sizeof(*hdr));
1154
1155
for (i = 0; i < n; ++i) {
1156
uint16_t iv_ofs, ofs;
1157
int sz = 0;
1158
1159
if (iv_img_size < sizeof(iv->iv_ofs)) {
1160
device_printf(sc->sc_dev, "invalid IV image, ofs\n");
1161
return EINVAL;
1162
}
1163
iv_img_size -= sizeof(iv->iv_ofs);
1164
sz += sizeof(iv->iv_ofs);
1165
1166
iv_ofs = be16toh(iv->iv_ofs);
1167
1168
ofs = __SHIFTOUT(iv_ofs, BWI_FW_IV_OFS_MASK);
1169
if (ofs >= 0x1000) {
1170
device_printf(sc->sc_dev, "invalid ofs (0x%04x) "
1171
"for %dth iv\n", ofs, i);
1172
return EINVAL;
1173
}
1174
1175
if (iv_ofs & BWI_FW_IV_IS_32BIT) {
1176
uint32_t val32;
1177
1178
if (iv_img_size < sizeof(iv->iv_val.val32)) {
1179
device_printf(sc->sc_dev,
1180
"invalid IV image, val32\n");
1181
return EINVAL;
1182
}
1183
iv_img_size -= sizeof(iv->iv_val.val32);
1184
sz += sizeof(iv->iv_val.val32);
1185
1186
val32 = be32toh(iv->iv_val.val32);
1187
CSR_WRITE_4(sc, ofs, val32);
1188
} else {
1189
uint16_t val16;
1190
1191
if (iv_img_size < sizeof(iv->iv_val.val16)) {
1192
device_printf(sc->sc_dev,
1193
"invalid IV image, val16\n");
1194
return EINVAL;
1195
}
1196
iv_img_size -= sizeof(iv->iv_val.val16);
1197
sz += sizeof(iv->iv_val.val16);
1198
1199
val16 = be16toh(iv->iv_val.val16);
1200
CSR_WRITE_2(sc, ofs, val16);
1201
}
1202
1203
iv = (const struct bwi_fw_iv *)((const uint8_t *)iv + sz);
1204
}
1205
1206
if (iv_img_size != 0) {
1207
device_printf(sc->sc_dev, "invalid IV image, size left %d\n",
1208
iv_img_size);
1209
return EINVAL;
1210
}
1211
return 0;
1212
}
1213
1214
static int
1215
bwi_mac_fw_init(struct bwi_mac *mac)
1216
{
1217
device_t dev = mac->mac_sc->sc_dev;
1218
int error;
1219
1220
error = bwi_mac_fw_load_iv(mac, mac->mac_iv);
1221
if (error) {
1222
device_printf(dev, "load IV failed\n");
1223
return error;
1224
}
1225
1226
if (mac->mac_iv_ext != NULL) {
1227
error = bwi_mac_fw_load_iv(mac, mac->mac_iv_ext);
1228
if (error)
1229
device_printf(dev, "load ExtIV failed\n");
1230
}
1231
return error;
1232
}
1233
1234
static void
1235
bwi_mac_opmode_init(struct bwi_mac *mac)
1236
{
1237
struct bwi_softc *sc = mac->mac_sc;
1238
struct ieee80211com *ic = &sc->sc_ic;
1239
uint32_t mac_status;
1240
uint16_t pre_tbtt;
1241
1242
CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA);
1243
CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_INFRA);
1244
1245
/* Set probe resp timeout to infinite */
1246
MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 0);
1247
1248
/*
1249
* TODO: factor out following part
1250
*/
1251
1252
mac_status = CSR_READ_4(sc, BWI_MAC_STATUS);
1253
mac_status &= ~(BWI_MAC_STATUS_OPMODE_HOSTAP |
1254
BWI_MAC_STATUS_PASS_CTL |
1255
BWI_MAC_STATUS_PASS_BCN |
1256
BWI_MAC_STATUS_PASS_BADPLCP |
1257
BWI_MAC_STATUS_PASS_BADFCS |
1258
BWI_MAC_STATUS_PROMISC);
1259
mac_status |= BWI_MAC_STATUS_INFRA;
1260
1261
/* Always turn on PROMISC on old hardware */
1262
if (mac->mac_rev < 5)
1263
mac_status |= BWI_MAC_STATUS_PROMISC;
1264
1265
switch (ic->ic_opmode) {
1266
case IEEE80211_M_IBSS:
1267
mac_status &= ~BWI_MAC_STATUS_INFRA;
1268
break;
1269
case IEEE80211_M_HOSTAP:
1270
mac_status |= BWI_MAC_STATUS_OPMODE_HOSTAP;
1271
break;
1272
case IEEE80211_M_MONITOR:
1273
#if 0
1274
/* Do you want data from your microwave oven? */
1275
mac_status |= BWI_MAC_STATUS_PASS_CTL |
1276
BWI_MAC_STATUS_PASS_BADPLCP |
1277
BWI_MAC_STATUS_PASS_BADFCS;
1278
#else
1279
mac_status |= BWI_MAC_STATUS_PASS_CTL;
1280
#endif
1281
/* Promisc? */
1282
break;
1283
default:
1284
break;
1285
}
1286
1287
if (ic->ic_promisc > 0)
1288
mac_status |= BWI_MAC_STATUS_PROMISC;
1289
1290
CSR_WRITE_4(sc, BWI_MAC_STATUS, mac_status);
1291
1292
if (ic->ic_opmode != IEEE80211_M_IBSS &&
1293
ic->ic_opmode != IEEE80211_M_HOSTAP) {
1294
if (sc->sc_bbp_id == BWI_BBPID_BCM4306 && sc->sc_bbp_rev == 3)
1295
pre_tbtt = 100;
1296
else
1297
pre_tbtt = 50;
1298
} else {
1299
pre_tbtt = 2;
1300
}
1301
CSR_WRITE_2(sc, BWI_MAC_PRE_TBTT, pre_tbtt);
1302
}
1303
1304
static void
1305
bwi_mac_hostflags_init(struct bwi_mac *mac)
1306
{
1307
struct bwi_softc *sc = mac->mac_sc;
1308
struct bwi_phy *phy = &mac->mac_phy;
1309
struct bwi_rf *rf = &mac->mac_rf;
1310
uint64_t host_flags;
1311
1312
if (phy->phy_mode == IEEE80211_MODE_11A)
1313
return;
1314
1315
host_flags = HFLAGS_READ(mac);
1316
host_flags |= BWI_HFLAG_SYM_WA;
1317
1318
if (phy->phy_mode == IEEE80211_MODE_11G) {
1319
if (phy->phy_rev == 1)
1320
host_flags |= BWI_HFLAG_GDC_WA;
1321
if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9)
1322
host_flags |= BWI_HFLAG_OFDM_PA;
1323
} else if (phy->phy_mode == IEEE80211_MODE_11B) {
1324
if (phy->phy_rev >= 2 && rf->rf_type == BWI_RF_T_BCM2050)
1325
host_flags &= ~BWI_HFLAG_GDC_WA;
1326
} else {
1327
panic("unknown PHY mode %u\n", phy->phy_mode);
1328
}
1329
1330
HFLAGS_WRITE(mac, host_flags);
1331
}
1332
1333
static void
1334
bwi_mac_bss_param_init(struct bwi_mac *mac)
1335
{
1336
struct bwi_softc *sc = mac->mac_sc;
1337
struct bwi_phy *phy = &mac->mac_phy;
1338
struct ieee80211com *ic = &sc->sc_ic;
1339
const struct ieee80211_rate_table *rt;
1340
struct bwi_retry_lim lim;
1341
uint16_t cw_min;
1342
1343
/*
1344
* Set short/long retry limits
1345
*/
1346
bzero(&lim, sizeof(lim));
1347
lim.shretry = BWI_SHRETRY;
1348
lim.shretry_fb = BWI_SHRETRY_FB;
1349
lim.lgretry = BWI_LGRETRY;
1350
lim.lgretry_fb = BWI_LGRETRY_FB;
1351
bwi_mac_set_retry_lim(mac, &lim);
1352
1353
/*
1354
* Implicitly prevent firmware from sending probe response
1355
* by setting its "probe response timeout" to 1us.
1356
*/
1357
MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_PROBE_RESP_TO, 1);
1358
1359
/*
1360
* XXX MAC level acknowledge and CW min/max should depend
1361
* on the char rateset of the IBSS/BSS to join.
1362
* XXX this is all wrong; should be done on channel change
1363
*/
1364
if (phy->phy_mode == IEEE80211_MODE_11B) {
1365
rt = ieee80211_get_ratetable(
1366
ieee80211_find_channel(ic, 2412, IEEE80211_CHAN_B));
1367
bwi_mac_set_ackrates(mac, rt,
1368
&ic->ic_sup_rates[IEEE80211_MODE_11B]);
1369
} else {
1370
rt = ieee80211_get_ratetable(
1371
ieee80211_find_channel(ic, 2412, IEEE80211_CHAN_G));
1372
bwi_mac_set_ackrates(mac, rt,
1373
&ic->ic_sup_rates[IEEE80211_MODE_11G]);
1374
}
1375
1376
/*
1377
* Set CW min
1378
*/
1379
if (phy->phy_mode == IEEE80211_MODE_11B)
1380
cw_min = IEEE80211_CW_MIN_0;
1381
else
1382
cw_min = IEEE80211_CW_MIN_1;
1383
MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMIN, cw_min);
1384
1385
/*
1386
* Set CW max
1387
*/
1388
MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_CWMAX,
1389
IEEE80211_CW_MAX);
1390
}
1391
1392
static void
1393
bwi_mac_set_retry_lim(struct bwi_mac *mac, const struct bwi_retry_lim *lim)
1394
{
1395
/* Short/Long retry limit */
1396
MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_SHRETRY,
1397
lim->shretry);
1398
MOBJ_WRITE_2(mac, BWI_80211_MOBJ, BWI_80211_MOBJ_LGRETRY,
1399
lim->lgretry);
1400
1401
/* Short/Long retry fallback limit */
1402
MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SHRETRY_FB,
1403
lim->shretry_fb);
1404
MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_LGRETEY_FB,
1405
lim->lgretry_fb);
1406
}
1407
1408
static void
1409
bwi_mac_set_ackrates(struct bwi_mac *mac, const struct ieee80211_rate_table *rt,
1410
const struct ieee80211_rateset *rs)
1411
{
1412
int i;
1413
1414
/* XXX not standard conforming */
1415
for (i = 0; i < rs->rs_nrates; ++i) {
1416
enum ieee80211_phytype modtype;
1417
uint16_t ofs;
1418
1419
modtype = ieee80211_rate2phytype(rt,
1420
rs->rs_rates[i] & IEEE80211_RATE_VAL);
1421
switch (modtype) {
1422
case IEEE80211_T_DS:
1423
ofs = 0x4c0;
1424
break;
1425
case IEEE80211_T_OFDM:
1426
ofs = 0x480;
1427
break;
1428
default:
1429
panic("unsupported modtype %u\n", modtype);
1430
}
1431
ofs += 2*(ieee80211_rate2plcp(
1432
rs->rs_rates[i] & IEEE80211_RATE_VAL,
1433
modtype) & 0xf);
1434
1435
MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, ofs + 0x20,
1436
MOBJ_READ_2(mac, BWI_COMM_MOBJ, ofs));
1437
}
1438
}
1439
1440
int
1441
bwi_mac_start(struct bwi_mac *mac)
1442
{
1443
struct bwi_softc *sc = mac->mac_sc;
1444
1445
CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE);
1446
CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, BWI_INTR_READY);
1447
1448
/* Flush pending bus writes */
1449
CSR_READ_4(sc, BWI_MAC_STATUS);
1450
CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
1451
1452
return bwi_mac_config_ps(mac);
1453
}
1454
1455
int
1456
bwi_mac_stop(struct bwi_mac *mac)
1457
{
1458
struct bwi_softc *sc = mac->mac_sc;
1459
int error, i;
1460
1461
error = bwi_mac_config_ps(mac);
1462
if (error)
1463
return error;
1464
1465
CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_ENABLE);
1466
1467
/* Flush pending bus write */
1468
CSR_READ_4(sc, BWI_MAC_STATUS);
1469
1470
#define NRETRY 10000
1471
for (i = 0; i < NRETRY; ++i) {
1472
if (CSR_READ_4(sc, BWI_MAC_INTR_STATUS) & BWI_INTR_READY)
1473
break;
1474
DELAY(1);
1475
}
1476
if (i == NRETRY) {
1477
device_printf(sc->sc_dev, "can't stop MAC\n");
1478
return ETIMEDOUT;
1479
}
1480
#undef NRETRY
1481
1482
return 0;
1483
}
1484
1485
int
1486
bwi_mac_config_ps(struct bwi_mac *mac)
1487
{
1488
struct bwi_softc *sc = mac->mac_sc;
1489
uint32_t status;
1490
1491
status = CSR_READ_4(sc, BWI_MAC_STATUS);
1492
1493
status &= ~BWI_MAC_STATUS_HW_PS;
1494
status |= BWI_MAC_STATUS_WAKEUP;
1495
CSR_WRITE_4(sc, BWI_MAC_STATUS, status);
1496
1497
/* Flush pending bus write */
1498
CSR_READ_4(sc, BWI_MAC_STATUS);
1499
1500
if (mac->mac_rev >= 5) {
1501
int i;
1502
1503
#define NRETRY 100
1504
for (i = 0; i < NRETRY; ++i) {
1505
if (MOBJ_READ_2(mac, BWI_COMM_MOBJ,
1506
BWI_COMM_MOBJ_UCODE_STATE) != BWI_UCODE_STATE_PS)
1507
break;
1508
DELAY(10);
1509
}
1510
if (i == NRETRY) {
1511
device_printf(sc->sc_dev, "config PS failed\n");
1512
return ETIMEDOUT;
1513
}
1514
#undef NRETRY
1515
}
1516
return 0;
1517
}
1518
1519
void
1520
bwi_mac_reset_hwkeys(struct bwi_mac *mac)
1521
{
1522
/* TODO: firmware crypto */
1523
MOBJ_READ_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_KEYTABLE_OFS);
1524
}
1525
1526
void
1527
bwi_mac_shutdown(struct bwi_mac *mac)
1528
{
1529
struct bwi_softc *sc = mac->mac_sc;
1530
int i;
1531
1532
if (mac->mac_flags & BWI_MAC_F_HAS_TXSTATS)
1533
sc->sc_free_txstats(sc);
1534
1535
sc->sc_free_rx_ring(sc);
1536
1537
for (i = 0; i < BWI_TX_NRING; ++i)
1538
sc->sc_free_tx_ring(sc, i);
1539
1540
bwi_rf_off(mac);
1541
1542
/* TODO:LED */
1543
1544
bwi_mac_gpio_fini(mac);
1545
1546
bwi_rf_off(mac); /* XXX again */
1547
CSR_WRITE_2(sc, BWI_BBP_ATTEN, BWI_BBP_ATTEN_MAGIC);
1548
bwi_regwin_disable(sc, &mac->mac_regwin, 0);
1549
1550
mac->mac_flags &= ~BWI_MAC_F_INITED;
1551
}
1552
1553
static int
1554
bwi_mac_get_property(struct bwi_mac *mac)
1555
{
1556
struct bwi_softc *sc = mac->mac_sc;
1557
enum bwi_bus_space old_bus_space;
1558
uint32_t val;
1559
1560
/*
1561
* Byte swap
1562
*/
1563
val = CSR_READ_4(sc, BWI_MAC_STATUS);
1564
if (val & BWI_MAC_STATUS_BSWAP) {
1565
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "%s\n",
1566
"need byte swap");
1567
mac->mac_flags |= BWI_MAC_F_BSWAP;
1568
}
1569
1570
/*
1571
* DMA address space
1572
*/
1573
old_bus_space = sc->sc_bus_space;
1574
1575
val = CSR_READ_4(sc, BWI_STATE_HI);
1576
if (__SHIFTOUT(val, BWI_STATE_HI_FLAGS_MASK) &
1577
BWI_STATE_HI_FLAG_64BIT) {
1578
/* 64bit address */
1579
sc->sc_bus_space = BWI_BUS_SPACE_64BIT;
1580
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "%s\n",
1581
"64bit bus space");
1582
} else {
1583
uint32_t txrx_reg = BWI_TXRX_CTRL_BASE + BWI_TX32_CTRL;
1584
1585
CSR_WRITE_4(sc, txrx_reg, BWI_TXRX32_CTRL_ADDRHI_MASK);
1586
if (CSR_READ_4(sc, txrx_reg) & BWI_TXRX32_CTRL_ADDRHI_MASK) {
1587
/* 32bit address */
1588
sc->sc_bus_space = BWI_BUS_SPACE_32BIT;
1589
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "%s\n",
1590
"32bit bus space");
1591
} else {
1592
/* 30bit address */
1593
sc->sc_bus_space = BWI_BUS_SPACE_30BIT;
1594
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "%s\n",
1595
"30bit bus space");
1596
}
1597
}
1598
1599
if (old_bus_space != 0 && old_bus_space != sc->sc_bus_space) {
1600
device_printf(sc->sc_dev, "MACs bus space mismatch!\n");
1601
return ENXIO;
1602
}
1603
return 0;
1604
}
1605
1606
void
1607
bwi_mac_updateslot(struct bwi_mac *mac, int shslot)
1608
{
1609
uint16_t slot_time;
1610
1611
if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B)
1612
return;
1613
1614
if (shslot)
1615
slot_time = IEEE80211_DUR_SHSLOT;
1616
else
1617
slot_time = IEEE80211_DUR_SLOT;
1618
1619
CSR_WRITE_2(mac->mac_sc, BWI_MAC_SLOTTIME,
1620
slot_time + BWI_MAC_SLOTTIME_ADJUST);
1621
MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, BWI_COMM_MOBJ_SLOTTIME, slot_time);
1622
}
1623
1624
int
1625
bwi_mac_attach(struct bwi_softc *sc, int id, uint8_t rev)
1626
{
1627
struct bwi_mac *mac;
1628
int i;
1629
1630
KASSERT(sc->sc_nmac <= BWI_MAC_MAX && sc->sc_nmac >= 0,
1631
("sc_nmac %d", sc->sc_nmac));
1632
1633
if (sc->sc_nmac == BWI_MAC_MAX) {
1634
device_printf(sc->sc_dev, "too many MACs\n");
1635
return 0;
1636
}
1637
1638
/*
1639
* More than one MAC is only supported by BCM4309
1640
*/
1641
if (sc->sc_nmac != 0 &&
1642
sc->sc_pci_did != PCI_PRODUCT_BROADCOM_BCM4309) {
1643
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "%s\n",
1644
"ignore second MAC");
1645
return 0;
1646
}
1647
1648
mac = &sc->sc_mac[sc->sc_nmac];
1649
1650
/* XXX will this happen? */
1651
if (BWI_REGWIN_EXIST(&mac->mac_regwin)) {
1652
device_printf(sc->sc_dev, "%dth MAC already attached\n",
1653
sc->sc_nmac);
1654
return 0;
1655
}
1656
1657
/*
1658
* Test whether the revision of this MAC is supported
1659
*/
1660
for (i = 0; i < nitems(bwi_sup_macrev); ++i) {
1661
if (bwi_sup_macrev[i] == rev)
1662
break;
1663
}
1664
if (i == nitems(bwi_sup_macrev)) {
1665
device_printf(sc->sc_dev, "MAC rev %u is "
1666
"not supported\n", rev);
1667
return ENXIO;
1668
}
1669
1670
BWI_CREATE_MAC(mac, sc, id, rev);
1671
sc->sc_nmac++;
1672
1673
if (mac->mac_rev < 5) {
1674
mac->mac_flags |= BWI_MAC_F_HAS_TXSTATS;
1675
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "%s\n",
1676
"has TX stats");
1677
} else {
1678
mac->mac_flags |= BWI_MAC_F_PHYE_RESET;
1679
}
1680
1681
device_printf(sc->sc_dev, "MAC: rev %u\n", rev);
1682
return 0;
1683
}
1684
1685
static __inline void
1686
bwi_mac_balance_atten(int *bbp_atten0, int *rf_atten0)
1687
{
1688
int bbp_atten, rf_atten, rf_atten_lim = -1;
1689
1690
bbp_atten = *bbp_atten0;
1691
rf_atten = *rf_atten0;
1692
1693
/*
1694
* RF attenuation affects TX power BWI_RF_ATTEN_FACTOR times
1695
* as much as BBP attenuation, so we try our best to keep RF
1696
* attenuation within range. BBP attenuation will be clamped
1697
* later if it is out of range during balancing.
1698
*
1699
* BWI_RF_ATTEN_MAX0 is used as RF attenuation upper limit.
1700
*/
1701
1702
/*
1703
* Use BBP attenuation to balance RF attenuation
1704
*/
1705
if (rf_atten < 0)
1706
rf_atten_lim = 0;
1707
else if (rf_atten > BWI_RF_ATTEN_MAX0)
1708
rf_atten_lim = BWI_RF_ATTEN_MAX0;
1709
1710
if (rf_atten_lim >= 0) {
1711
bbp_atten += (BWI_RF_ATTEN_FACTOR * (rf_atten - rf_atten_lim));
1712
rf_atten = rf_atten_lim;
1713
}
1714
1715
/*
1716
* If possible, use RF attenuation to balance BBP attenuation
1717
* NOTE: RF attenuation is still kept within range.
1718
*/
1719
while (rf_atten < BWI_RF_ATTEN_MAX0 && bbp_atten > BWI_BBP_ATTEN_MAX) {
1720
bbp_atten -= BWI_RF_ATTEN_FACTOR;
1721
++rf_atten;
1722
}
1723
while (rf_atten > 0 && bbp_atten < 0) {
1724
bbp_atten += BWI_RF_ATTEN_FACTOR;
1725
--rf_atten;
1726
}
1727
1728
/* RF attenuation MUST be within range */
1729
KASSERT(rf_atten >= 0 && rf_atten <= BWI_RF_ATTEN_MAX0,
1730
("rf_atten %d", rf_atten));
1731
1732
/*
1733
* Clamp BBP attenuation
1734
*/
1735
if (bbp_atten < 0)
1736
bbp_atten = 0;
1737
else if (bbp_atten > BWI_BBP_ATTEN_MAX)
1738
bbp_atten = BWI_BBP_ATTEN_MAX;
1739
1740
*rf_atten0 = rf_atten;
1741
*bbp_atten0 = bbp_atten;
1742
}
1743
1744
static void
1745
bwi_mac_adjust_tpctl(struct bwi_mac *mac, int rf_atten_adj, int bbp_atten_adj)
1746
{
1747
struct bwi_softc *sc = mac->mac_sc;
1748
struct bwi_rf *rf = &mac->mac_rf;
1749
struct bwi_tpctl tpctl;
1750
int bbp_atten, rf_atten, tp_ctrl1;
1751
1752
bcopy(&mac->mac_tpctl, &tpctl, sizeof(tpctl));
1753
1754
/* NOTE: Use signed value to do calulation */
1755
bbp_atten = tpctl.bbp_atten;
1756
rf_atten = tpctl.rf_atten;
1757
tp_ctrl1 = tpctl.tp_ctrl1;
1758
1759
bbp_atten += bbp_atten_adj;
1760
rf_atten += rf_atten_adj;
1761
1762
bwi_mac_balance_atten(&bbp_atten, &rf_atten);
1763
1764
if (rf->rf_type == BWI_RF_T_BCM2050 && rf->rf_rev == 2) {
1765
if (rf_atten <= 1) {
1766
if (tp_ctrl1 == 0) {
1767
tp_ctrl1 = 3;
1768
bbp_atten += 2;
1769
rf_atten += 2;
1770
} else if (sc->sc_card_flags & BWI_CARD_F_PA_GPIO9) {
1771
bbp_atten +=
1772
(BWI_RF_ATTEN_FACTOR * (rf_atten - 2));
1773
rf_atten = 2;
1774
}
1775
} else if (rf_atten > 4 && tp_ctrl1 != 0) {
1776
tp_ctrl1 = 0;
1777
if (bbp_atten < 3) {
1778
bbp_atten += 2;
1779
rf_atten -= 3;
1780
} else {
1781
bbp_atten -= 2;
1782
rf_atten -= 2;
1783
}
1784
}
1785
bwi_mac_balance_atten(&bbp_atten, &rf_atten);
1786
}
1787
1788
tpctl.bbp_atten = bbp_atten;
1789
tpctl.rf_atten = rf_atten;
1790
tpctl.tp_ctrl1 = tp_ctrl1;
1791
1792
bwi_mac_lock(mac);
1793
bwi_mac_set_tpctl_11bg(mac, &tpctl);
1794
bwi_mac_unlock(mac);
1795
}
1796
1797
/*
1798
* http://bcm-specs.sipsolutions.net/RecalculateTransmissionPower
1799
*/
1800
void
1801
bwi_mac_calibrate_txpower(struct bwi_mac *mac, enum bwi_txpwrcb_type type)
1802
{
1803
struct bwi_softc *sc = mac->mac_sc;
1804
struct bwi_rf *rf = &mac->mac_rf;
1805
int8_t tssi[4], tssi_avg, cur_txpwr;
1806
int error, i, ofdm_tssi;
1807
int txpwr_diff, rf_atten_adj, bbp_atten_adj;
1808
1809
if (!sc->sc_txpwr_calib)
1810
return;
1811
1812
if (mac->mac_flags & BWI_MAC_F_TPCTL_ERROR) {
1813
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "%s\n",
1814
"tpctl error happened, can't set txpower");
1815
return;
1816
}
1817
1818
if (BWI_IS_BRCM_BU4306(sc)) {
1819
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "%s\n",
1820
"BU4306, can't set txpower");
1821
return;
1822
}
1823
1824
/*
1825
* Save latest TSSI and reset the related memory objects
1826
*/
1827
ofdm_tssi = 0;
1828
error = bwi_rf_get_latest_tssi(mac, tssi, BWI_COMM_MOBJ_TSSI_DS);
1829
if (error) {
1830
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "%s\n",
1831
"no DS tssi");
1832
1833
if (mac->mac_phy.phy_mode == IEEE80211_MODE_11B) {
1834
if (type == BWI_TXPWR_FORCE) {
1835
rf_atten_adj = 0;
1836
bbp_atten_adj = 1;
1837
goto calib;
1838
} else {
1839
return;
1840
}
1841
}
1842
1843
error = bwi_rf_get_latest_tssi(mac, tssi,
1844
BWI_COMM_MOBJ_TSSI_OFDM);
1845
if (error) {
1846
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "%s\n",
1847
"no OFDM tssi");
1848
if (type == BWI_TXPWR_FORCE) {
1849
rf_atten_adj = 0;
1850
bbp_atten_adj = 1;
1851
goto calib;
1852
} else {
1853
return;
1854
}
1855
}
1856
1857
for (i = 0; i < 4; ++i) {
1858
tssi[i] += 0x20;
1859
tssi[i] &= 0x3f;
1860
}
1861
ofdm_tssi = 1;
1862
}
1863
bwi_rf_clear_tssi(mac);
1864
1865
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER,
1866
"tssi0 %d, tssi1 %d, tssi2 %d, tssi3 %d\n",
1867
tssi[0], tssi[1], tssi[2], tssi[3]);
1868
1869
/*
1870
* Calculate RF/BBP attenuation adjustment based on
1871
* the difference between desired TX power and sampled
1872
* TX power.
1873
*/
1874
/* +8 == "each incremented by 1/2" */
1875
tssi_avg = (tssi[0] + tssi[1] + tssi[2] + tssi[3] + 8) / 4;
1876
if (ofdm_tssi && (HFLAGS_READ(mac) & BWI_HFLAG_PWR_BOOST_DS))
1877
tssi_avg -= 13;
1878
1879
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "tssi avg %d\n", tssi_avg);
1880
1881
error = bwi_rf_tssi2dbm(mac, tssi_avg, &cur_txpwr);
1882
if (error)
1883
return;
1884
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "current txpower %d\n",
1885
cur_txpwr);
1886
1887
txpwr_diff = rf->rf_txpower_max - cur_txpwr; /* XXX ni_txpower */
1888
1889
rf_atten_adj = -howmany(txpwr_diff, 8);
1890
if (type == BWI_TXPWR_INIT) {
1891
/*
1892
* Move toward EEPROM max TX power as fast as we can
1893
*/
1894
bbp_atten_adj = -txpwr_diff;
1895
} else {
1896
bbp_atten_adj = -(txpwr_diff / 2);
1897
}
1898
bbp_atten_adj -= (BWI_RF_ATTEN_FACTOR * rf_atten_adj);
1899
1900
if (rf_atten_adj == 0 && bbp_atten_adj == 0) {
1901
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER, "%s\n",
1902
"no need to adjust RF/BBP attenuation");
1903
/* TODO: LO */
1904
return;
1905
}
1906
1907
calib:
1908
DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_TXPOWER,
1909
"rf atten adjust %d, bbp atten adjust %d\n",
1910
rf_atten_adj, bbp_atten_adj);
1911
bwi_mac_adjust_tpctl(mac, rf_atten_adj, bbp_atten_adj);
1912
/* TODO: LO */
1913
}
1914
1915
static void
1916
bwi_mac_lock(struct bwi_mac *mac)
1917
{
1918
struct bwi_softc *sc = mac->mac_sc;
1919
struct ieee80211com *ic = &sc->sc_ic;
1920
1921
KASSERT((mac->mac_flags & BWI_MAC_F_LOCKED) == 0,
1922
("mac_flags 0x%x", mac->mac_flags));
1923
1924
if (mac->mac_rev < 3)
1925
bwi_mac_stop(mac);
1926
else if (ic->ic_opmode != IEEE80211_M_HOSTAP)
1927
bwi_mac_config_ps(mac);
1928
1929
CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK);
1930
1931
/* Flush pending bus write */
1932
CSR_READ_4(sc, BWI_MAC_STATUS);
1933
DELAY(10);
1934
1935
mac->mac_flags |= BWI_MAC_F_LOCKED;
1936
}
1937
1938
static void
1939
bwi_mac_unlock(struct bwi_mac *mac)
1940
{
1941
struct bwi_softc *sc = mac->mac_sc;
1942
struct ieee80211com *ic = &sc->sc_ic;
1943
1944
KASSERT(mac->mac_flags & BWI_MAC_F_LOCKED,
1945
("mac_flags 0x%x", mac->mac_flags));
1946
1947
CSR_READ_2(sc, BWI_PHYINFO); /* dummy read */
1948
1949
CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_RFLOCK);
1950
1951
if (mac->mac_rev < 3)
1952
bwi_mac_start(mac);
1953
else if (ic->ic_opmode != IEEE80211_M_HOSTAP)
1954
bwi_mac_config_ps(mac);
1955
1956
mac->mac_flags &= ~BWI_MAC_F_LOCKED;
1957
}
1958
1959
void
1960
bwi_mac_set_promisc(struct bwi_mac *mac, int promisc)
1961
{
1962
struct bwi_softc *sc = mac->mac_sc;
1963
1964
if (mac->mac_rev < 5) /* Promisc is always on */
1965
return;
1966
1967
if (promisc)
1968
CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC);
1969
else
1970
CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PROMISC);
1971
}
1972
1973