Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/bwi/if_bwi.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/if_bwi.c,v 1.19 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
#include <sys/taskqueue.h>
56
57
#include <net/if.h>
58
#include <net/if_var.h>
59
#include <net/if_dl.h>
60
#include <net/if_media.h>
61
#include <net/if_types.h>
62
#include <net/if_arp.h>
63
#include <net/ethernet.h>
64
#include <net/if_llc.h>
65
66
#include <net80211/ieee80211_var.h>
67
#include <net80211/ieee80211_radiotap.h>
68
#include <net80211/ieee80211_regdomain.h>
69
#include <net80211/ieee80211_phy.h>
70
#include <net80211/ieee80211_ratectl.h>
71
72
#include <net/bpf.h>
73
74
#ifdef INET
75
#include <netinet/in.h>
76
#include <netinet/if_ether.h>
77
#endif
78
79
#include <machine/bus.h>
80
81
#include <dev/pci/pcivar.h>
82
#include <dev/pci/pcireg.h>
83
84
#include <dev/bwi/bitops.h>
85
#include <dev/bwi/if_bwireg.h>
86
#include <dev/bwi/if_bwivar.h>
87
#include <dev/bwi/bwimac.h>
88
#include <dev/bwi/bwirf.h>
89
90
struct bwi_clock_freq {
91
u_int clkfreq_min;
92
u_int clkfreq_max;
93
};
94
95
struct bwi_myaddr_bssid {
96
uint8_t myaddr[IEEE80211_ADDR_LEN];
97
uint8_t bssid[IEEE80211_ADDR_LEN];
98
} __packed;
99
100
static struct ieee80211vap *bwi_vap_create(struct ieee80211com *,
101
const char [IFNAMSIZ], int, enum ieee80211_opmode, int,
102
const uint8_t [IEEE80211_ADDR_LEN],
103
const uint8_t [IEEE80211_ADDR_LEN]);
104
static void bwi_vap_delete(struct ieee80211vap *);
105
static void bwi_init(struct bwi_softc *);
106
static void bwi_parent(struct ieee80211com *);
107
static int bwi_transmit(struct ieee80211com *, struct mbuf *);
108
static void bwi_start_locked(struct bwi_softc *);
109
static int bwi_raw_xmit(struct ieee80211_node *, struct mbuf *,
110
const struct ieee80211_bpf_params *);
111
static void bwi_watchdog(void *);
112
static void bwi_scan_start(struct ieee80211com *);
113
static void bwi_getradiocaps(struct ieee80211com *, int, int *,
114
struct ieee80211_channel[]);
115
static void bwi_set_channel(struct ieee80211com *);
116
static void bwi_scan_end(struct ieee80211com *);
117
static int bwi_newstate(struct ieee80211vap *, enum ieee80211_state, int);
118
static void bwi_updateslot(struct ieee80211com *);
119
120
static void bwi_calibrate(void *);
121
122
static int bwi_calc_rssi(struct bwi_softc *, const struct bwi_rxbuf_hdr *);
123
static int bwi_calc_noise(struct bwi_softc *);
124
static __inline uint8_t bwi_plcp2rate(uint32_t, enum ieee80211_phytype);
125
static void bwi_rx_radiotap(struct bwi_softc *, struct mbuf *,
126
struct bwi_rxbuf_hdr *, const void *, int, int, int);
127
128
static void bwi_restart(void *, int);
129
static void bwi_init_statechg(struct bwi_softc *, int);
130
static void bwi_stop(struct bwi_softc *, int);
131
static void bwi_stop_locked(struct bwi_softc *, int);
132
static int bwi_newbuf(struct bwi_softc *, int, int);
133
static int bwi_encap(struct bwi_softc *, int, struct mbuf *,
134
struct ieee80211_node *);
135
static int bwi_encap_raw(struct bwi_softc *, int, struct mbuf *,
136
struct ieee80211_node *,
137
const struct ieee80211_bpf_params *);
138
139
static void bwi_init_rxdesc_ring32(struct bwi_softc *, uint32_t,
140
bus_addr_t, int, int);
141
static void bwi_reset_rx_ring32(struct bwi_softc *, uint32_t);
142
143
static int bwi_init_tx_ring32(struct bwi_softc *, int);
144
static int bwi_init_rx_ring32(struct bwi_softc *);
145
static int bwi_init_txstats32(struct bwi_softc *);
146
static void bwi_free_tx_ring32(struct bwi_softc *, int);
147
static void bwi_free_rx_ring32(struct bwi_softc *);
148
static void bwi_free_txstats32(struct bwi_softc *);
149
static void bwi_setup_rx_desc32(struct bwi_softc *, int, bus_addr_t, int);
150
static void bwi_setup_tx_desc32(struct bwi_softc *, struct bwi_ring_data *,
151
int, bus_addr_t, int);
152
static int bwi_rxeof32(struct bwi_softc *);
153
static void bwi_start_tx32(struct bwi_softc *, uint32_t, int);
154
static void bwi_txeof_status32(struct bwi_softc *);
155
156
static int bwi_init_tx_ring64(struct bwi_softc *, int);
157
static int bwi_init_rx_ring64(struct bwi_softc *);
158
static int bwi_init_txstats64(struct bwi_softc *);
159
static void bwi_free_tx_ring64(struct bwi_softc *, int);
160
static void bwi_free_rx_ring64(struct bwi_softc *);
161
static void bwi_free_txstats64(struct bwi_softc *);
162
static void bwi_setup_rx_desc64(struct bwi_softc *, int, bus_addr_t, int);
163
static void bwi_setup_tx_desc64(struct bwi_softc *, struct bwi_ring_data *,
164
int, bus_addr_t, int);
165
static int bwi_rxeof64(struct bwi_softc *);
166
static void bwi_start_tx64(struct bwi_softc *, uint32_t, int);
167
static void bwi_txeof_status64(struct bwi_softc *);
168
169
static int bwi_rxeof(struct bwi_softc *, int);
170
static void _bwi_txeof(struct bwi_softc *, uint16_t, int, int);
171
static void bwi_txeof(struct bwi_softc *);
172
static void bwi_txeof_status(struct bwi_softc *, int);
173
static void bwi_enable_intrs(struct bwi_softc *, uint32_t);
174
static void bwi_disable_intrs(struct bwi_softc *, uint32_t);
175
176
static int bwi_dma_alloc(struct bwi_softc *);
177
static void bwi_dma_free(struct bwi_softc *);
178
static int bwi_dma_ring_alloc(struct bwi_softc *, bus_dma_tag_t,
179
struct bwi_ring_data *, bus_size_t,
180
uint32_t);
181
static int bwi_dma_mbuf_create(struct bwi_softc *);
182
static void bwi_dma_mbuf_destroy(struct bwi_softc *, int, int);
183
static int bwi_dma_txstats_alloc(struct bwi_softc *, uint32_t, bus_size_t);
184
static void bwi_dma_txstats_free(struct bwi_softc *);
185
static void bwi_dma_ring_addr(void *, bus_dma_segment_t *, int, int);
186
static void bwi_dma_buf_addr(void *, bus_dma_segment_t *, int,
187
bus_size_t, int);
188
189
static void bwi_power_on(struct bwi_softc *, int);
190
static int bwi_power_off(struct bwi_softc *, int);
191
static int bwi_set_clock_mode(struct bwi_softc *, enum bwi_clock_mode);
192
static int bwi_set_clock_delay(struct bwi_softc *);
193
static void bwi_get_clock_freq(struct bwi_softc *, struct bwi_clock_freq *);
194
static int bwi_get_pwron_delay(struct bwi_softc *sc);
195
static void bwi_set_addr_filter(struct bwi_softc *, uint16_t,
196
const uint8_t *);
197
static void bwi_set_bssid(struct bwi_softc *, const uint8_t *);
198
199
static void bwi_get_card_flags(struct bwi_softc *);
200
static void bwi_get_eaddr(struct bwi_softc *, uint16_t, uint8_t *);
201
202
static int bwi_bus_attach(struct bwi_softc *);
203
static int bwi_bbp_attach(struct bwi_softc *);
204
static int bwi_bbp_power_on(struct bwi_softc *, enum bwi_clock_mode);
205
static void bwi_bbp_power_off(struct bwi_softc *);
206
207
static const char *bwi_regwin_name(const struct bwi_regwin *);
208
static uint32_t bwi_regwin_disable_bits(struct bwi_softc *);
209
static void bwi_regwin_info(struct bwi_softc *, uint16_t *, uint8_t *);
210
static int bwi_regwin_select(struct bwi_softc *, int);
211
212
static void bwi_led_attach(struct bwi_softc *);
213
static void bwi_led_newstate(struct bwi_softc *, enum ieee80211_state);
214
static void bwi_led_event(struct bwi_softc *, int);
215
static void bwi_led_blink_start(struct bwi_softc *, int, int);
216
static void bwi_led_blink_next(void *);
217
static void bwi_led_blink_end(void *);
218
219
static const struct {
220
uint16_t did_min;
221
uint16_t did_max;
222
uint16_t bbp_id;
223
} bwi_bbpid_map[] = {
224
{ 0x4301, 0x4301, 0x4301 },
225
{ 0x4305, 0x4307, 0x4307 },
226
{ 0x4402, 0x4403, 0x4402 },
227
{ 0x4610, 0x4615, 0x4610 },
228
{ 0x4710, 0x4715, 0x4710 },
229
{ 0x4720, 0x4725, 0x4309 }
230
};
231
232
static const struct {
233
uint16_t bbp_id;
234
int nregwin;
235
} bwi_regwin_count[] = {
236
{ 0x4301, 5 },
237
{ 0x4306, 6 },
238
{ 0x4307, 5 },
239
{ 0x4310, 8 },
240
{ 0x4401, 3 },
241
{ 0x4402, 3 },
242
{ 0x4610, 9 },
243
{ 0x4704, 9 },
244
{ 0x4710, 9 },
245
{ 0x5365, 7 }
246
};
247
248
#define CLKSRC(src) \
249
[BWI_CLKSRC_ ## src] = { \
250
.freq_min = BWI_CLKSRC_ ##src## _FMIN, \
251
.freq_max = BWI_CLKSRC_ ##src## _FMAX \
252
}
253
254
static const struct {
255
u_int freq_min;
256
u_int freq_max;
257
} bwi_clkfreq[BWI_CLKSRC_MAX] = {
258
CLKSRC(LP_OSC),
259
CLKSRC(CS_OSC),
260
CLKSRC(PCI)
261
};
262
263
#undef CLKSRC
264
265
#define VENDOR_LED_ACT(vendor) \
266
{ \
267
.vid = PCI_VENDOR_##vendor, \
268
.led_act = { BWI_VENDOR_LED_ACT_##vendor } \
269
}
270
271
static const struct {
272
#define PCI_VENDOR_COMPAQ 0x0e11
273
#define PCI_VENDOR_LINKSYS 0x1737
274
uint16_t vid;
275
uint8_t led_act[BWI_LED_MAX];
276
} bwi_vendor_led_act[] = {
277
VENDOR_LED_ACT(COMPAQ),
278
VENDOR_LED_ACT(LINKSYS)
279
#undef PCI_VENDOR_LINKSYS
280
#undef PCI_VENDOR_COMPAQ
281
};
282
283
static const uint8_t bwi_default_led_act[BWI_LED_MAX] =
284
{ BWI_VENDOR_LED_ACT_DEFAULT };
285
286
#undef VENDOR_LED_ACT
287
288
static const struct {
289
int on_dur;
290
int off_dur;
291
} bwi_led_duration[109] = {
292
[0] = { 400, 100 },
293
[2] = { 150, 75 },
294
[4] = { 90, 45 },
295
[11] = { 66, 34 },
296
[12] = { 53, 26 },
297
[18] = { 42, 21 },
298
[22] = { 35, 17 },
299
[24] = { 32, 16 },
300
[36] = { 21, 10 },
301
[48] = { 16, 8 },
302
[72] = { 11, 5 },
303
[96] = { 9, 4 },
304
[108] = { 7, 3 }
305
};
306
307
#ifdef BWI_DEBUG
308
#ifdef BWI_DEBUG_VERBOSE
309
static uint32_t bwi_debug = BWI_DBG_ATTACH | BWI_DBG_INIT | BWI_DBG_TXPOWER;
310
#else
311
static uint32_t bwi_debug;
312
#endif
313
TUNABLE_INT("hw.bwi.debug", (int *)&bwi_debug);
314
#endif /* BWI_DEBUG */
315
316
static const uint8_t bwi_zero_addr[IEEE80211_ADDR_LEN];
317
318
uint16_t
319
bwi_read_sprom(struct bwi_softc *sc, uint16_t ofs)
320
{
321
return CSR_READ_2(sc, ofs + BWI_SPROM_START);
322
}
323
324
static __inline void
325
bwi_setup_desc32(struct bwi_softc *sc, struct bwi_desc32 *desc_array,
326
int ndesc, int desc_idx, bus_addr_t paddr, int buf_len,
327
int tx)
328
{
329
struct bwi_desc32 *desc = &desc_array[desc_idx];
330
uint32_t ctrl, addr, addr_hi, addr_lo;
331
332
addr_lo = __SHIFTOUT(paddr, BWI_DESC32_A_ADDR_MASK);
333
addr_hi = __SHIFTOUT(paddr, BWI_DESC32_A_FUNC_MASK);
334
335
addr = __SHIFTIN(addr_lo, BWI_DESC32_A_ADDR_MASK) |
336
__SHIFTIN(BWI_DESC32_A_FUNC_TXRX, BWI_DESC32_A_FUNC_MASK);
337
338
ctrl = __SHIFTIN(buf_len, BWI_DESC32_C_BUFLEN_MASK) |
339
__SHIFTIN(addr_hi, BWI_DESC32_C_ADDRHI_MASK);
340
if (desc_idx == ndesc - 1)
341
ctrl |= BWI_DESC32_C_EOR;
342
if (tx) {
343
/* XXX */
344
ctrl |= BWI_DESC32_C_FRAME_START |
345
BWI_DESC32_C_FRAME_END |
346
BWI_DESC32_C_INTR;
347
}
348
349
desc->addr = htole32(addr);
350
desc->ctrl = htole32(ctrl);
351
}
352
353
int
354
bwi_attach(struct bwi_softc *sc)
355
{
356
struct ieee80211com *ic = &sc->sc_ic;
357
device_t dev = sc->sc_dev;
358
struct bwi_mac *mac;
359
struct bwi_phy *phy;
360
int i, error;
361
362
BWI_LOCK_INIT(sc);
363
364
/*
365
* Initialize taskq and various tasks
366
*/
367
sc->sc_tq = taskqueue_create("bwi_taskq", M_NOWAIT | M_ZERO,
368
taskqueue_thread_enqueue, &sc->sc_tq);
369
taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq",
370
device_get_nameunit(dev));
371
TASK_INIT(&sc->sc_restart_task, 0, bwi_restart, sc);
372
callout_init_mtx(&sc->sc_calib_ch, &sc->sc_mtx, 0);
373
mbufq_init(&sc->sc_snd, ifqmaxlen);
374
375
/*
376
* Initialize sysctl variables
377
*/
378
sc->sc_fw_version = BWI_FW_VERSION3;
379
sc->sc_led_idle = (2350 * hz) / 1000;
380
sc->sc_led_ticks = ticks - sc->sc_led_idle;
381
sc->sc_led_blink = 1;
382
sc->sc_txpwr_calib = 1;
383
#ifdef BWI_DEBUG
384
sc->sc_debug = bwi_debug;
385
#endif
386
bwi_power_on(sc, 1);
387
388
error = bwi_bbp_attach(sc);
389
if (error)
390
goto fail;
391
392
error = bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST);
393
if (error)
394
goto fail;
395
396
if (BWI_REGWIN_EXIST(&sc->sc_com_regwin)) {
397
error = bwi_set_clock_delay(sc);
398
if (error)
399
goto fail;
400
401
error = bwi_set_clock_mode(sc, BWI_CLOCK_MODE_FAST);
402
if (error)
403
goto fail;
404
405
error = bwi_get_pwron_delay(sc);
406
if (error)
407
goto fail;
408
}
409
410
error = bwi_bus_attach(sc);
411
if (error)
412
goto fail;
413
414
bwi_get_card_flags(sc);
415
416
bwi_led_attach(sc);
417
418
for (i = 0; i < sc->sc_nmac; ++i) {
419
struct bwi_regwin *old;
420
421
mac = &sc->sc_mac[i];
422
error = bwi_regwin_switch(sc, &mac->mac_regwin, &old);
423
if (error)
424
goto fail;
425
426
error = bwi_mac_lateattach(mac);
427
if (error)
428
goto fail;
429
430
error = bwi_regwin_switch(sc, old, NULL);
431
if (error)
432
goto fail;
433
}
434
435
/*
436
* XXX First MAC is known to exist
437
* TODO2
438
*/
439
mac = &sc->sc_mac[0];
440
phy = &mac->mac_phy;
441
442
bwi_bbp_power_off(sc);
443
444
error = bwi_dma_alloc(sc);
445
if (error)
446
goto fail;
447
448
error = bwi_mac_fw_alloc(mac);
449
if (error)
450
goto fail;
451
452
callout_init_mtx(&sc->sc_watchdog_timer, &sc->sc_mtx, 0);
453
454
/*
455
* Setup ratesets, phytype, channels and get MAC address
456
*/
457
if (phy->phy_mode == IEEE80211_MODE_11B ||
458
phy->phy_mode == IEEE80211_MODE_11G) {
459
if (phy->phy_mode == IEEE80211_MODE_11B) {
460
ic->ic_phytype = IEEE80211_T_DS;
461
} else {
462
ic->ic_phytype = IEEE80211_T_OFDM;
463
}
464
465
bwi_get_eaddr(sc, BWI_SPROM_11BG_EADDR, ic->ic_macaddr);
466
if (IEEE80211_IS_MULTICAST(ic->ic_macaddr)) {
467
bwi_get_eaddr(sc, BWI_SPROM_11A_EADDR, ic->ic_macaddr);
468
if (IEEE80211_IS_MULTICAST(ic->ic_macaddr)) {
469
device_printf(dev,
470
"invalid MAC address: %6D\n",
471
ic->ic_macaddr, ":");
472
}
473
}
474
} else if (phy->phy_mode == IEEE80211_MODE_11A) {
475
/* TODO:11A */
476
error = ENXIO;
477
goto fail;
478
} else {
479
panic("unknown phymode %d\n", phy->phy_mode);
480
}
481
482
/* Get locale */
483
sc->sc_locale = __SHIFTOUT(bwi_read_sprom(sc, BWI_SPROM_CARD_INFO),
484
BWI_SPROM_CARD_INFO_LOCALE);
485
DPRINTF(sc, BWI_DBG_ATTACH, "locale: %d\n", sc->sc_locale);
486
/* XXX use locale */
487
488
ic->ic_softc = sc;
489
490
bwi_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans,
491
ic->ic_channels);
492
493
ic->ic_name = device_get_nameunit(dev);
494
ic->ic_caps = IEEE80211_C_STA |
495
IEEE80211_C_SHSLOT |
496
IEEE80211_C_SHPREAMBLE |
497
IEEE80211_C_WPA |
498
IEEE80211_C_BGSCAN |
499
IEEE80211_C_MONITOR;
500
ic->ic_opmode = IEEE80211_M_STA;
501
502
ic->ic_flags_ext |= IEEE80211_FEXT_SEQNO_OFFLOAD;
503
504
ieee80211_ifattach(ic);
505
506
ic->ic_headroom = sizeof(struct bwi_txbuf_hdr);
507
508
/* override default methods */
509
ic->ic_vap_create = bwi_vap_create;
510
ic->ic_vap_delete = bwi_vap_delete;
511
ic->ic_raw_xmit = bwi_raw_xmit;
512
ic->ic_updateslot = bwi_updateslot;
513
ic->ic_scan_start = bwi_scan_start;
514
ic->ic_scan_end = bwi_scan_end;
515
ic->ic_getradiocaps = bwi_getradiocaps;
516
ic->ic_set_channel = bwi_set_channel;
517
ic->ic_transmit = bwi_transmit;
518
ic->ic_parent = bwi_parent;
519
520
sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan);
521
522
ieee80211_radiotap_attach(ic,
523
&sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th),
524
BWI_TX_RADIOTAP_PRESENT,
525
&sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th),
526
BWI_RX_RADIOTAP_PRESENT);
527
528
/*
529
* Add sysctl nodes
530
*/
531
SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
532
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
533
"fw_version", CTLFLAG_RD, &sc->sc_fw_version, 0,
534
"Firmware version");
535
SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
536
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
537
"led_idle", CTLFLAG_RW, &sc->sc_led_idle, 0,
538
"# ticks before LED enters idle state");
539
SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
540
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
541
"led_blink", CTLFLAG_RW, &sc->sc_led_blink, 0,
542
"Allow LED to blink");
543
SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
544
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
545
"txpwr_calib", CTLFLAG_RW, &sc->sc_txpwr_calib, 0,
546
"Enable software TX power calibration");
547
#ifdef BWI_DEBUG
548
SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
549
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
550
"debug", CTLFLAG_RW, &sc->sc_debug, 0, "Debug flags");
551
#endif
552
if (bootverbose)
553
ieee80211_announce(ic);
554
555
return (0);
556
fail:
557
BWI_LOCK_DESTROY(sc);
558
return (error);
559
}
560
561
int
562
bwi_detach(struct bwi_softc *sc)
563
{
564
struct ieee80211com *ic = &sc->sc_ic;
565
int i;
566
567
bwi_stop(sc, 1);
568
callout_drain(&sc->sc_led_blink_ch);
569
callout_drain(&sc->sc_calib_ch);
570
callout_drain(&sc->sc_watchdog_timer);
571
ieee80211_ifdetach(ic);
572
573
for (i = 0; i < sc->sc_nmac; ++i)
574
bwi_mac_detach(&sc->sc_mac[i]);
575
bwi_dma_free(sc);
576
taskqueue_free(sc->sc_tq);
577
mbufq_drain(&sc->sc_snd);
578
579
BWI_LOCK_DESTROY(sc);
580
581
return (0);
582
}
583
584
static struct ieee80211vap *
585
bwi_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ], int unit,
586
enum ieee80211_opmode opmode, int flags,
587
const uint8_t bssid[IEEE80211_ADDR_LEN],
588
const uint8_t mac[IEEE80211_ADDR_LEN])
589
{
590
struct bwi_vap *bvp;
591
struct ieee80211vap *vap;
592
593
if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */
594
return NULL;
595
bvp = malloc(sizeof(struct bwi_vap), M_80211_VAP, M_WAITOK | M_ZERO);
596
vap = &bvp->bv_vap;
597
/* enable s/w bmiss handling for sta mode */
598
ieee80211_vap_setup(ic, vap, name, unit, opmode,
599
flags | IEEE80211_CLONE_NOBEACONS, bssid);
600
601
/* override default methods */
602
bvp->bv_newstate = vap->iv_newstate;
603
vap->iv_newstate = bwi_newstate;
604
#if 0
605
vap->iv_update_beacon = bwi_beacon_update;
606
#endif
607
ieee80211_ratectl_init(vap);
608
609
/* complete setup */
610
ieee80211_vap_attach(vap, ieee80211_media_change,
611
ieee80211_media_status, mac);
612
ic->ic_opmode = opmode;
613
return vap;
614
}
615
616
static void
617
bwi_vap_delete(struct ieee80211vap *vap)
618
{
619
struct bwi_vap *bvp = BWI_VAP(vap);
620
621
ieee80211_ratectl_deinit(vap);
622
ieee80211_vap_detach(vap);
623
free(bvp, M_80211_VAP);
624
}
625
626
void
627
bwi_suspend(struct bwi_softc *sc)
628
{
629
bwi_stop(sc, 1);
630
}
631
632
void
633
bwi_resume(struct bwi_softc *sc)
634
{
635
636
if (sc->sc_ic.ic_nrunning > 0)
637
bwi_init(sc);
638
}
639
640
int
641
bwi_shutdown(struct bwi_softc *sc)
642
{
643
bwi_stop(sc, 1);
644
return 0;
645
}
646
647
static void
648
bwi_power_on(struct bwi_softc *sc, int with_pll)
649
{
650
uint32_t gpio_in, gpio_out, gpio_en;
651
uint16_t status;
652
653
gpio_in = pci_read_config(sc->sc_dev, BWI_PCIR_GPIO_IN, 4);
654
if (gpio_in & BWI_PCIM_GPIO_PWR_ON)
655
goto back;
656
657
gpio_out = pci_read_config(sc->sc_dev, BWI_PCIR_GPIO_OUT, 4);
658
gpio_en = pci_read_config(sc->sc_dev, BWI_PCIR_GPIO_ENABLE, 4);
659
660
gpio_out |= BWI_PCIM_GPIO_PWR_ON;
661
gpio_en |= BWI_PCIM_GPIO_PWR_ON;
662
if (with_pll) {
663
/* Turn off PLL first */
664
gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF;
665
gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF;
666
}
667
668
pci_write_config(sc->sc_dev, BWI_PCIR_GPIO_OUT, gpio_out, 4);
669
pci_write_config(sc->sc_dev, BWI_PCIR_GPIO_ENABLE, gpio_en, 4);
670
DELAY(1000);
671
672
if (with_pll) {
673
/* Turn on PLL */
674
gpio_out &= ~BWI_PCIM_GPIO_PLL_PWR_OFF;
675
pci_write_config(sc->sc_dev, BWI_PCIR_GPIO_OUT, gpio_out, 4);
676
DELAY(5000);
677
}
678
679
back:
680
/* Clear "Signaled Target Abort" */
681
status = pci_read_config(sc->sc_dev, PCIR_STATUS, 2);
682
status &= ~PCIM_STATUS_STABORT;
683
pci_write_config(sc->sc_dev, PCIR_STATUS, status, 2);
684
}
685
686
static int
687
bwi_power_off(struct bwi_softc *sc, int with_pll)
688
{
689
uint32_t gpio_out, gpio_en;
690
691
pci_read_config(sc->sc_dev, BWI_PCIR_GPIO_IN, 4); /* dummy read */
692
gpio_out = pci_read_config(sc->sc_dev, BWI_PCIR_GPIO_OUT, 4);
693
gpio_en = pci_read_config(sc->sc_dev, BWI_PCIR_GPIO_ENABLE, 4);
694
695
gpio_out &= ~BWI_PCIM_GPIO_PWR_ON;
696
gpio_en |= BWI_PCIM_GPIO_PWR_ON;
697
if (with_pll) {
698
gpio_out |= BWI_PCIM_GPIO_PLL_PWR_OFF;
699
gpio_en |= BWI_PCIM_GPIO_PLL_PWR_OFF;
700
}
701
702
pci_write_config(sc->sc_dev, BWI_PCIR_GPIO_OUT, gpio_out, 4);
703
pci_write_config(sc->sc_dev, BWI_PCIR_GPIO_ENABLE, gpio_en, 4);
704
return 0;
705
}
706
707
int
708
bwi_regwin_switch(struct bwi_softc *sc, struct bwi_regwin *rw,
709
struct bwi_regwin **old_rw)
710
{
711
int error;
712
713
if (old_rw != NULL)
714
*old_rw = NULL;
715
716
if (!BWI_REGWIN_EXIST(rw))
717
return EINVAL;
718
719
if (sc->sc_cur_regwin != rw) {
720
error = bwi_regwin_select(sc, rw->rw_id);
721
if (error) {
722
device_printf(sc->sc_dev, "can't select regwin %d\n",
723
rw->rw_id);
724
return error;
725
}
726
}
727
728
if (old_rw != NULL)
729
*old_rw = sc->sc_cur_regwin;
730
sc->sc_cur_regwin = rw;
731
return 0;
732
}
733
734
static int
735
bwi_regwin_select(struct bwi_softc *sc, int id)
736
{
737
uint32_t win = BWI_PCIM_REGWIN(id);
738
int i;
739
740
#define RETRY_MAX 50
741
for (i = 0; i < RETRY_MAX; ++i) {
742
pci_write_config(sc->sc_dev, BWI_PCIR_SEL_REGWIN, win, 4);
743
if (pci_read_config(sc->sc_dev, BWI_PCIR_SEL_REGWIN, 4) == win)
744
return 0;
745
DELAY(10);
746
}
747
#undef RETRY_MAX
748
749
return ENXIO;
750
}
751
752
static void
753
bwi_regwin_info(struct bwi_softc *sc, uint16_t *type, uint8_t *rev)
754
{
755
uint32_t val;
756
757
val = CSR_READ_4(sc, BWI_ID_HI);
758
*type = BWI_ID_HI_REGWIN_TYPE(val);
759
*rev = BWI_ID_HI_REGWIN_REV(val);
760
761
DPRINTF(sc, BWI_DBG_ATTACH, "regwin: type 0x%03x, rev %d, "
762
"vendor 0x%04x\n", *type, *rev,
763
__SHIFTOUT(val, BWI_ID_HI_REGWIN_VENDOR_MASK));
764
}
765
766
static int
767
bwi_bbp_attach(struct bwi_softc *sc)
768
{
769
uint16_t bbp_id, rw_type;
770
uint8_t rw_rev;
771
uint32_t info;
772
int error, nregwin, i;
773
774
/*
775
* Get 0th regwin information
776
* NOTE: 0th regwin should exist
777
*/
778
error = bwi_regwin_select(sc, 0);
779
if (error) {
780
device_printf(sc->sc_dev, "can't select regwin 0\n");
781
return error;
782
}
783
bwi_regwin_info(sc, &rw_type, &rw_rev);
784
785
/*
786
* Find out BBP id
787
*/
788
bbp_id = 0;
789
info = 0;
790
if (rw_type == BWI_REGWIN_T_COM) {
791
info = CSR_READ_4(sc, BWI_INFO);
792
bbp_id = __SHIFTOUT(info, BWI_INFO_BBPID_MASK);
793
794
BWI_CREATE_REGWIN(&sc->sc_com_regwin, 0, rw_type, rw_rev);
795
796
sc->sc_cap = CSR_READ_4(sc, BWI_CAPABILITY);
797
} else {
798
for (i = 0; i < nitems(bwi_bbpid_map); ++i) {
799
if (sc->sc_pci_did >= bwi_bbpid_map[i].did_min &&
800
sc->sc_pci_did <= bwi_bbpid_map[i].did_max) {
801
bbp_id = bwi_bbpid_map[i].bbp_id;
802
break;
803
}
804
}
805
if (bbp_id == 0) {
806
device_printf(sc->sc_dev, "no BBP id for device id "
807
"0x%04x\n", sc->sc_pci_did);
808
return ENXIO;
809
}
810
811
info = __SHIFTIN(sc->sc_pci_revid, BWI_INFO_BBPREV_MASK) |
812
__SHIFTIN(0, BWI_INFO_BBPPKG_MASK);
813
}
814
815
/*
816
* Find out number of regwins
817
*/
818
nregwin = 0;
819
if (rw_type == BWI_REGWIN_T_COM && rw_rev >= 4) {
820
nregwin = __SHIFTOUT(info, BWI_INFO_NREGWIN_MASK);
821
} else {
822
for (i = 0; i < nitems(bwi_regwin_count); ++i) {
823
if (bwi_regwin_count[i].bbp_id == bbp_id) {
824
nregwin = bwi_regwin_count[i].nregwin;
825
break;
826
}
827
}
828
if (nregwin == 0) {
829
device_printf(sc->sc_dev, "no number of win for "
830
"BBP id 0x%04x\n", bbp_id);
831
return ENXIO;
832
}
833
}
834
835
/* Record BBP id/rev for later using */
836
sc->sc_bbp_id = bbp_id;
837
sc->sc_bbp_rev = __SHIFTOUT(info, BWI_INFO_BBPREV_MASK);
838
sc->sc_bbp_pkg = __SHIFTOUT(info, BWI_INFO_BBPPKG_MASK);
839
device_printf(sc->sc_dev, "BBP: id 0x%04x, rev 0x%x, pkg %d\n",
840
sc->sc_bbp_id, sc->sc_bbp_rev, sc->sc_bbp_pkg);
841
842
DPRINTF(sc, BWI_DBG_ATTACH, "nregwin %d, cap 0x%08x\n",
843
nregwin, sc->sc_cap);
844
845
/*
846
* Create rest of the regwins
847
*/
848
849
/* Don't re-create common regwin, if it is already created */
850
i = BWI_REGWIN_EXIST(&sc->sc_com_regwin) ? 1 : 0;
851
852
for (; i < nregwin; ++i) {
853
/*
854
* Get regwin information
855
*/
856
error = bwi_regwin_select(sc, i);
857
if (error) {
858
device_printf(sc->sc_dev,
859
"can't select regwin %d\n", i);
860
return error;
861
}
862
bwi_regwin_info(sc, &rw_type, &rw_rev);
863
864
/*
865
* Try attach:
866
* 1) Bus (PCI/PCIE) regwin
867
* 2) MAC regwin
868
* Ignore rest types of regwin
869
*/
870
if (rw_type == BWI_REGWIN_T_BUSPCI ||
871
rw_type == BWI_REGWIN_T_BUSPCIE) {
872
if (BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) {
873
device_printf(sc->sc_dev,
874
"bus regwin already exists\n");
875
} else {
876
BWI_CREATE_REGWIN(&sc->sc_bus_regwin, i,
877
rw_type, rw_rev);
878
}
879
} else if (rw_type == BWI_REGWIN_T_MAC) {
880
/* XXX ignore return value */
881
bwi_mac_attach(sc, i, rw_rev);
882
}
883
}
884
885
/* At least one MAC shold exist */
886
if (!BWI_REGWIN_EXIST(&sc->sc_mac[0].mac_regwin)) {
887
device_printf(sc->sc_dev, "no MAC was found\n");
888
return ENXIO;
889
}
890
KASSERT(sc->sc_nmac > 0, ("no mac's"));
891
892
/* Bus regwin must exist */
893
if (!BWI_REGWIN_EXIST(&sc->sc_bus_regwin)) {
894
device_printf(sc->sc_dev, "no bus regwin was found\n");
895
return ENXIO;
896
}
897
898
/* Start with first MAC */
899
error = bwi_regwin_switch(sc, &sc->sc_mac[0].mac_regwin, NULL);
900
if (error)
901
return error;
902
903
return 0;
904
}
905
906
int
907
bwi_bus_init(struct bwi_softc *sc, struct bwi_mac *mac)
908
{
909
struct bwi_regwin *old, *bus;
910
uint32_t val;
911
int error;
912
913
bus = &sc->sc_bus_regwin;
914
KASSERT(sc->sc_cur_regwin == &mac->mac_regwin, ("not cur regwin"));
915
916
/*
917
* Tell bus to generate requested interrupts
918
*/
919
if (bus->rw_rev < 6 && bus->rw_type == BWI_REGWIN_T_BUSPCI) {
920
/*
921
* NOTE: Read BWI_FLAGS from MAC regwin
922
*/
923
val = CSR_READ_4(sc, BWI_FLAGS);
924
925
error = bwi_regwin_switch(sc, bus, &old);
926
if (error)
927
return error;
928
929
CSR_SETBITS_4(sc, BWI_INTRVEC, (val & BWI_FLAGS_INTR_MASK));
930
} else {
931
uint32_t mac_mask;
932
933
mac_mask = 1 << mac->mac_id;
934
935
error = bwi_regwin_switch(sc, bus, &old);
936
if (error)
937
return error;
938
939
val = pci_read_config(sc->sc_dev, BWI_PCIR_INTCTL, 4);
940
val |= mac_mask << 8;
941
pci_write_config(sc->sc_dev, BWI_PCIR_INTCTL, val, 4);
942
}
943
944
if (sc->sc_flags & BWI_F_BUS_INITED)
945
goto back;
946
947
if (bus->rw_type == BWI_REGWIN_T_BUSPCI) {
948
/*
949
* Enable prefetch and burst
950
*/
951
CSR_SETBITS_4(sc, BWI_BUS_CONFIG,
952
BWI_BUS_CONFIG_PREFETCH | BWI_BUS_CONFIG_BURST);
953
954
if (bus->rw_rev < 5) {
955
struct bwi_regwin *com = &sc->sc_com_regwin;
956
957
/*
958
* Configure timeouts for bus operation
959
*/
960
961
/*
962
* Set service timeout and request timeout
963
*/
964
CSR_SETBITS_4(sc, BWI_CONF_LO,
965
__SHIFTIN(BWI_CONF_LO_SERVTO, BWI_CONF_LO_SERVTO_MASK) |
966
__SHIFTIN(BWI_CONF_LO_REQTO, BWI_CONF_LO_REQTO_MASK));
967
968
/*
969
* If there is common regwin, we switch to that regwin
970
* and switch back to bus regwin once we have done.
971
*/
972
if (BWI_REGWIN_EXIST(com)) {
973
error = bwi_regwin_switch(sc, com, NULL);
974
if (error)
975
return error;
976
}
977
978
/* Let bus know what we have changed */
979
CSR_WRITE_4(sc, BWI_BUS_ADDR, BWI_BUS_ADDR_MAGIC);
980
CSR_READ_4(sc, BWI_BUS_ADDR); /* Flush */
981
CSR_WRITE_4(sc, BWI_BUS_DATA, 0);
982
CSR_READ_4(sc, BWI_BUS_DATA); /* Flush */
983
984
if (BWI_REGWIN_EXIST(com)) {
985
error = bwi_regwin_switch(sc, bus, NULL);
986
if (error)
987
return error;
988
}
989
} else if (bus->rw_rev >= 11) {
990
/*
991
* Enable memory read multiple
992
*/
993
CSR_SETBITS_4(sc, BWI_BUS_CONFIG, BWI_BUS_CONFIG_MRM);
994
}
995
} else {
996
/* TODO:PCIE */
997
}
998
999
sc->sc_flags |= BWI_F_BUS_INITED;
1000
back:
1001
return bwi_regwin_switch(sc, old, NULL);
1002
}
1003
1004
static void
1005
bwi_get_card_flags(struct bwi_softc *sc)
1006
{
1007
#define PCI_VENDOR_APPLE 0x106b
1008
#define PCI_VENDOR_DELL 0x1028
1009
sc->sc_card_flags = bwi_read_sprom(sc, BWI_SPROM_CARD_FLAGS);
1010
if (sc->sc_card_flags == 0xffff)
1011
sc->sc_card_flags = 0;
1012
1013
if (sc->sc_pci_subvid == PCI_VENDOR_DELL &&
1014
sc->sc_bbp_id == BWI_BBPID_BCM4301 &&
1015
sc->sc_pci_revid == 0x74)
1016
sc->sc_card_flags |= BWI_CARD_F_BT_COEXIST;
1017
1018
if (sc->sc_pci_subvid == PCI_VENDOR_APPLE &&
1019
sc->sc_pci_subdid == 0x4e && /* XXX */
1020
sc->sc_pci_revid > 0x40)
1021
sc->sc_card_flags |= BWI_CARD_F_PA_GPIO9;
1022
1023
DPRINTF(sc, BWI_DBG_ATTACH, "card flags 0x%04x\n", sc->sc_card_flags);
1024
#undef PCI_VENDOR_DELL
1025
#undef PCI_VENDOR_APPLE
1026
}
1027
1028
static void
1029
bwi_get_eaddr(struct bwi_softc *sc, uint16_t eaddr_ofs, uint8_t *eaddr)
1030
{
1031
int i;
1032
1033
for (i = 0; i < 3; ++i) {
1034
*((uint16_t *)eaddr + i) =
1035
htobe16(bwi_read_sprom(sc, eaddr_ofs + 2 * i));
1036
}
1037
}
1038
1039
static void
1040
bwi_get_clock_freq(struct bwi_softc *sc, struct bwi_clock_freq *freq)
1041
{
1042
struct bwi_regwin *com;
1043
uint32_t val;
1044
u_int div;
1045
int src;
1046
1047
bzero(freq, sizeof(*freq));
1048
com = &sc->sc_com_regwin;
1049
1050
KASSERT(BWI_REGWIN_EXIST(com), ("regwin does not exist"));
1051
KASSERT(sc->sc_cur_regwin == com, ("wrong regwin"));
1052
KASSERT(sc->sc_cap & BWI_CAP_CLKMODE, ("wrong clock mode"));
1053
1054
/*
1055
* Calculate clock frequency
1056
*/
1057
src = -1;
1058
div = 0;
1059
if (com->rw_rev < 6) {
1060
val = pci_read_config(sc->sc_dev, BWI_PCIR_GPIO_OUT, 4);
1061
if (val & BWI_PCIM_GPIO_OUT_CLKSRC) {
1062
src = BWI_CLKSRC_PCI;
1063
div = 64;
1064
} else {
1065
src = BWI_CLKSRC_CS_OSC;
1066
div = 32;
1067
}
1068
} else if (com->rw_rev < 10) {
1069
val = CSR_READ_4(sc, BWI_CLOCK_CTRL);
1070
1071
src = __SHIFTOUT(val, BWI_CLOCK_CTRL_CLKSRC);
1072
if (src == BWI_CLKSRC_LP_OSC) {
1073
div = 1;
1074
} else {
1075
div = (__SHIFTOUT(val, BWI_CLOCK_CTRL_FDIV) + 1) << 2;
1076
1077
/* Unknown source */
1078
if (src >= BWI_CLKSRC_MAX)
1079
src = BWI_CLKSRC_CS_OSC;
1080
}
1081
} else {
1082
val = CSR_READ_4(sc, BWI_CLOCK_INFO);
1083
1084
src = BWI_CLKSRC_CS_OSC;
1085
div = (__SHIFTOUT(val, BWI_CLOCK_INFO_FDIV) + 1) << 2;
1086
}
1087
1088
KASSERT(src >= 0 && src < BWI_CLKSRC_MAX, ("bad src %d", src));
1089
KASSERT(div != 0, ("div zero"));
1090
1091
DPRINTF(sc, BWI_DBG_ATTACH, "clksrc %s\n",
1092
src == BWI_CLKSRC_PCI ? "PCI" :
1093
(src == BWI_CLKSRC_LP_OSC ? "LP_OSC" : "CS_OSC"));
1094
1095
freq->clkfreq_min = bwi_clkfreq[src].freq_min / div;
1096
freq->clkfreq_max = bwi_clkfreq[src].freq_max / div;
1097
1098
DPRINTF(sc, BWI_DBG_ATTACH, "clkfreq min %u, max %u\n",
1099
freq->clkfreq_min, freq->clkfreq_max);
1100
}
1101
1102
static int
1103
bwi_set_clock_mode(struct bwi_softc *sc, enum bwi_clock_mode clk_mode)
1104
{
1105
struct bwi_regwin *old, *com;
1106
uint32_t clk_ctrl, clk_src;
1107
int error, pwr_off = 0;
1108
1109
com = &sc->sc_com_regwin;
1110
if (!BWI_REGWIN_EXIST(com))
1111
return 0;
1112
1113
if (com->rw_rev >= 10 || com->rw_rev < 6)
1114
return 0;
1115
1116
/*
1117
* For common regwin whose rev is [6, 10), the chip
1118
* must be capable to change clock mode.
1119
*/
1120
if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0)
1121
return 0;
1122
1123
error = bwi_regwin_switch(sc, com, &old);
1124
if (error)
1125
return error;
1126
1127
if (clk_mode == BWI_CLOCK_MODE_FAST)
1128
bwi_power_on(sc, 0); /* Don't turn on PLL */
1129
1130
clk_ctrl = CSR_READ_4(sc, BWI_CLOCK_CTRL);
1131
clk_src = __SHIFTOUT(clk_ctrl, BWI_CLOCK_CTRL_CLKSRC);
1132
1133
switch (clk_mode) {
1134
case BWI_CLOCK_MODE_FAST:
1135
clk_ctrl &= ~BWI_CLOCK_CTRL_SLOW;
1136
clk_ctrl |= BWI_CLOCK_CTRL_IGNPLL;
1137
break;
1138
case BWI_CLOCK_MODE_SLOW:
1139
clk_ctrl |= BWI_CLOCK_CTRL_SLOW;
1140
break;
1141
case BWI_CLOCK_MODE_DYN:
1142
clk_ctrl &= ~(BWI_CLOCK_CTRL_SLOW |
1143
BWI_CLOCK_CTRL_IGNPLL |
1144
BWI_CLOCK_CTRL_NODYN);
1145
if (clk_src != BWI_CLKSRC_CS_OSC) {
1146
clk_ctrl |= BWI_CLOCK_CTRL_NODYN;
1147
pwr_off = 1;
1148
}
1149
break;
1150
}
1151
CSR_WRITE_4(sc, BWI_CLOCK_CTRL, clk_ctrl);
1152
1153
if (pwr_off)
1154
bwi_power_off(sc, 0); /* Leave PLL as it is */
1155
1156
return bwi_regwin_switch(sc, old, NULL);
1157
}
1158
1159
static int
1160
bwi_set_clock_delay(struct bwi_softc *sc)
1161
{
1162
struct bwi_regwin *old, *com;
1163
int error;
1164
1165
com = &sc->sc_com_regwin;
1166
if (!BWI_REGWIN_EXIST(com))
1167
return 0;
1168
1169
error = bwi_regwin_switch(sc, com, &old);
1170
if (error)
1171
return error;
1172
1173
if (sc->sc_bbp_id == BWI_BBPID_BCM4321) {
1174
if (sc->sc_bbp_rev == 0)
1175
CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC0);
1176
else if (sc->sc_bbp_rev == 1)
1177
CSR_WRITE_4(sc, BWI_CONTROL, BWI_CONTROL_MAGIC1);
1178
}
1179
1180
if (sc->sc_cap & BWI_CAP_CLKMODE) {
1181
if (com->rw_rev >= 10) {
1182
CSR_FILT_SETBITS_4(sc, BWI_CLOCK_INFO, 0xffff, 0x40000);
1183
} else {
1184
struct bwi_clock_freq freq;
1185
1186
bwi_get_clock_freq(sc, &freq);
1187
CSR_WRITE_4(sc, BWI_PLL_ON_DELAY,
1188
howmany(freq.clkfreq_max * 150, 1000000));
1189
CSR_WRITE_4(sc, BWI_FREQ_SEL_DELAY,
1190
howmany(freq.clkfreq_max * 15, 1000000));
1191
}
1192
}
1193
1194
return bwi_regwin_switch(sc, old, NULL);
1195
}
1196
1197
static void
1198
bwi_init(struct bwi_softc *sc)
1199
{
1200
struct ieee80211com *ic = &sc->sc_ic;
1201
1202
BWI_LOCK(sc);
1203
bwi_init_statechg(sc, 1);
1204
BWI_UNLOCK(sc);
1205
1206
if (sc->sc_flags & BWI_F_RUNNING)
1207
ieee80211_start_all(ic); /* start all vap's */
1208
}
1209
1210
static void
1211
bwi_init_statechg(struct bwi_softc *sc, int statechg)
1212
{
1213
struct bwi_mac *mac;
1214
int error;
1215
1216
BWI_ASSERT_LOCKED(sc);
1217
1218
bwi_stop_locked(sc, statechg);
1219
1220
bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST);
1221
1222
/* TODO: 2 MAC */
1223
1224
mac = &sc->sc_mac[0];
1225
error = bwi_regwin_switch(sc, &mac->mac_regwin, NULL);
1226
if (error) {
1227
device_printf(sc->sc_dev, "%s: error %d on regwin switch\n",
1228
__func__, error);
1229
goto bad;
1230
}
1231
error = bwi_mac_init(mac);
1232
if (error) {
1233
device_printf(sc->sc_dev, "%s: error %d on MAC init\n",
1234
__func__, error);
1235
goto bad;
1236
}
1237
1238
bwi_bbp_power_on(sc, BWI_CLOCK_MODE_DYN);
1239
1240
bwi_set_bssid(sc, bwi_zero_addr); /* Clear BSSID */
1241
bwi_set_addr_filter(sc, BWI_ADDR_FILTER_MYADDR, sc->sc_ic.ic_macaddr);
1242
1243
bwi_mac_reset_hwkeys(mac);
1244
1245
if ((mac->mac_flags & BWI_MAC_F_HAS_TXSTATS) == 0) {
1246
int i;
1247
1248
#define NRETRY 1000
1249
/*
1250
* Drain any possible pending TX status
1251
*/
1252
for (i = 0; i < NRETRY; ++i) {
1253
if ((CSR_READ_4(sc, BWI_TXSTATUS0) &
1254
BWI_TXSTATUS0_VALID) == 0)
1255
break;
1256
CSR_READ_4(sc, BWI_TXSTATUS1);
1257
}
1258
if (i == NRETRY)
1259
device_printf(sc->sc_dev,
1260
"%s: can't drain TX status\n", __func__);
1261
#undef NRETRY
1262
}
1263
1264
if (mac->mac_phy.phy_mode == IEEE80211_MODE_11G)
1265
bwi_mac_updateslot(mac, 1);
1266
1267
/* Start MAC */
1268
error = bwi_mac_start(mac);
1269
if (error) {
1270
device_printf(sc->sc_dev, "%s: error %d starting MAC\n",
1271
__func__, error);
1272
goto bad;
1273
}
1274
1275
/* Clear stop flag before enabling interrupt */
1276
sc->sc_flags &= ~BWI_F_STOP;
1277
sc->sc_flags |= BWI_F_RUNNING;
1278
callout_reset(&sc->sc_watchdog_timer, hz, bwi_watchdog, sc);
1279
1280
/* Enable intrs */
1281
bwi_enable_intrs(sc, BWI_INIT_INTRS);
1282
return;
1283
bad:
1284
bwi_stop_locked(sc, 1);
1285
}
1286
1287
static void
1288
bwi_parent(struct ieee80211com *ic)
1289
{
1290
struct bwi_softc *sc = ic->ic_softc;
1291
int startall = 0;
1292
1293
BWI_LOCK(sc);
1294
if (ic->ic_nrunning > 0) {
1295
struct bwi_mac *mac;
1296
int promisc = -1;
1297
1298
KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
1299
("current regwin type %d",
1300
sc->sc_cur_regwin->rw_type));
1301
mac = (struct bwi_mac *)sc->sc_cur_regwin;
1302
1303
if (ic->ic_promisc > 0 && (sc->sc_flags & BWI_F_PROMISC) == 0) {
1304
promisc = 1;
1305
sc->sc_flags |= BWI_F_PROMISC;
1306
} else if (ic->ic_promisc == 0 &&
1307
(sc->sc_flags & BWI_F_PROMISC) != 0) {
1308
promisc = 0;
1309
sc->sc_flags &= ~BWI_F_PROMISC;
1310
}
1311
1312
if (promisc >= 0)
1313
bwi_mac_set_promisc(mac, promisc);
1314
}
1315
if (ic->ic_nrunning > 0) {
1316
if ((sc->sc_flags & BWI_F_RUNNING) == 0) {
1317
bwi_init_statechg(sc, 1);
1318
startall = 1;
1319
}
1320
} else if (sc->sc_flags & BWI_F_RUNNING)
1321
bwi_stop_locked(sc, 1);
1322
BWI_UNLOCK(sc);
1323
if (startall)
1324
ieee80211_start_all(ic);
1325
}
1326
1327
static int
1328
bwi_transmit(struct ieee80211com *ic, struct mbuf *m)
1329
{
1330
struct bwi_softc *sc = ic->ic_softc;
1331
int error;
1332
1333
BWI_LOCK(sc);
1334
if ((sc->sc_flags & BWI_F_RUNNING) == 0) {
1335
BWI_UNLOCK(sc);
1336
return (ENXIO);
1337
}
1338
error = mbufq_enqueue(&sc->sc_snd, m);
1339
if (error) {
1340
BWI_UNLOCK(sc);
1341
return (error);
1342
}
1343
bwi_start_locked(sc);
1344
BWI_UNLOCK(sc);
1345
return (0);
1346
}
1347
1348
static void
1349
bwi_start_locked(struct bwi_softc *sc)
1350
{
1351
struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
1352
struct ieee80211_frame *wh;
1353
struct ieee80211_node *ni;
1354
struct mbuf *m;
1355
int trans, idx;
1356
1357
BWI_ASSERT_LOCKED(sc);
1358
1359
trans = 0;
1360
idx = tbd->tbd_idx;
1361
1362
while (tbd->tbd_buf[idx].tb_mbuf == NULL &&
1363
tbd->tbd_used + BWI_TX_NSPRDESC < BWI_TX_NDESC &&
1364
(m = mbufq_dequeue(&sc->sc_snd)) != NULL) {
1365
ni = (struct ieee80211_node *) m->m_pkthdr.rcvif;
1366
wh = mtod(m, struct ieee80211_frame *);
1367
ieee80211_output_seqno_assign(ni, -1, m);
1368
if ((wh->i_fc[1] & IEEE80211_FC1_PROTECTED) != 0 &&
1369
ieee80211_crypto_encap(ni, m) == NULL) {
1370
if_inc_counter(ni->ni_vap->iv_ifp,
1371
IFCOUNTER_OERRORS, 1);
1372
ieee80211_free_node(ni);
1373
m_freem(m);
1374
continue;
1375
}
1376
if (bwi_encap(sc, idx, m, ni) != 0) {
1377
/* 'm' is freed in bwi_encap() if we reach here */
1378
if (ni != NULL) {
1379
if_inc_counter(ni->ni_vap->iv_ifp,
1380
IFCOUNTER_OERRORS, 1);
1381
ieee80211_free_node(ni);
1382
} else
1383
counter_u64_add(sc->sc_ic.ic_oerrors, 1);
1384
continue;
1385
}
1386
trans = 1;
1387
tbd->tbd_used++;
1388
idx = (idx + 1) % BWI_TX_NDESC;
1389
}
1390
1391
tbd->tbd_idx = idx;
1392
if (trans)
1393
sc->sc_tx_timer = 5;
1394
}
1395
1396
static int
1397
bwi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
1398
const struct ieee80211_bpf_params *params)
1399
{
1400
struct ieee80211com *ic = ni->ni_ic;
1401
struct bwi_softc *sc = ic->ic_softc;
1402
/* XXX wme? */
1403
struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
1404
int idx, error;
1405
1406
if ((sc->sc_flags & BWI_F_RUNNING) == 0) {
1407
m_freem(m);
1408
return ENETDOWN;
1409
}
1410
1411
BWI_LOCK(sc);
1412
idx = tbd->tbd_idx;
1413
KASSERT(tbd->tbd_buf[idx].tb_mbuf == NULL, ("slot %d not empty", idx));
1414
if (params == NULL) {
1415
/*
1416
* Legacy path; interpret frame contents to decide
1417
* precisely how to send the frame.
1418
*/
1419
error = bwi_encap(sc, idx, m, ni);
1420
} else {
1421
/*
1422
* Caller supplied explicit parameters to use in
1423
* sending the frame.
1424
*/
1425
error = bwi_encap_raw(sc, idx, m, ni, params);
1426
}
1427
if (error == 0) {
1428
tbd->tbd_used++;
1429
tbd->tbd_idx = (idx + 1) % BWI_TX_NDESC;
1430
sc->sc_tx_timer = 5;
1431
}
1432
BWI_UNLOCK(sc);
1433
return error;
1434
}
1435
1436
static void
1437
bwi_watchdog(void *arg)
1438
{
1439
struct bwi_softc *sc;
1440
1441
sc = arg;
1442
BWI_ASSERT_LOCKED(sc);
1443
if (sc->sc_tx_timer != 0 && --sc->sc_tx_timer == 0) {
1444
device_printf(sc->sc_dev, "watchdog timeout\n");
1445
counter_u64_add(sc->sc_ic.ic_oerrors, 1);
1446
taskqueue_enqueue(sc->sc_tq, &sc->sc_restart_task);
1447
}
1448
callout_reset(&sc->sc_watchdog_timer, hz, bwi_watchdog, sc);
1449
}
1450
1451
static void
1452
bwi_stop(struct bwi_softc *sc, int statechg)
1453
{
1454
BWI_LOCK(sc);
1455
bwi_stop_locked(sc, statechg);
1456
BWI_UNLOCK(sc);
1457
}
1458
1459
static void
1460
bwi_stop_locked(struct bwi_softc *sc, int statechg)
1461
{
1462
struct bwi_mac *mac;
1463
int i, error, pwr_off = 0;
1464
1465
BWI_ASSERT_LOCKED(sc);
1466
1467
callout_stop(&sc->sc_calib_ch);
1468
callout_stop(&sc->sc_led_blink_ch);
1469
sc->sc_led_blinking = 0;
1470
sc->sc_flags |= BWI_F_STOP;
1471
1472
if (sc->sc_flags & BWI_F_RUNNING) {
1473
KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
1474
("current regwin type %d", sc->sc_cur_regwin->rw_type));
1475
mac = (struct bwi_mac *)sc->sc_cur_regwin;
1476
1477
bwi_disable_intrs(sc, BWI_ALL_INTRS);
1478
CSR_READ_4(sc, BWI_MAC_INTR_MASK);
1479
bwi_mac_stop(mac);
1480
}
1481
1482
for (i = 0; i < sc->sc_nmac; ++i) {
1483
struct bwi_regwin *old_rw;
1484
1485
mac = &sc->sc_mac[i];
1486
if ((mac->mac_flags & BWI_MAC_F_INITED) == 0)
1487
continue;
1488
1489
error = bwi_regwin_switch(sc, &mac->mac_regwin, &old_rw);
1490
if (error)
1491
continue;
1492
1493
bwi_mac_shutdown(mac);
1494
pwr_off = 1;
1495
1496
bwi_regwin_switch(sc, old_rw, NULL);
1497
}
1498
1499
if (pwr_off)
1500
bwi_bbp_power_off(sc);
1501
1502
sc->sc_tx_timer = 0;
1503
callout_stop(&sc->sc_watchdog_timer);
1504
sc->sc_flags &= ~BWI_F_RUNNING;
1505
}
1506
1507
void
1508
bwi_intr(void *xsc)
1509
{
1510
struct bwi_softc *sc = xsc;
1511
struct bwi_mac *mac;
1512
uint32_t intr_status;
1513
uint32_t txrx_intr_status[BWI_TXRX_NRING];
1514
int i, txrx_error, tx = 0, rx_data = -1;
1515
1516
BWI_LOCK(sc);
1517
1518
if ((sc->sc_flags & BWI_F_RUNNING) == 0 ||
1519
(sc->sc_flags & BWI_F_STOP)) {
1520
BWI_UNLOCK(sc);
1521
return;
1522
}
1523
/*
1524
* Get interrupt status
1525
*/
1526
intr_status = CSR_READ_4(sc, BWI_MAC_INTR_STATUS);
1527
if (intr_status == 0xffffffff) { /* Not for us */
1528
BWI_UNLOCK(sc);
1529
return;
1530
}
1531
1532
DPRINTF(sc, BWI_DBG_INTR, "intr status 0x%08x\n", intr_status);
1533
1534
intr_status &= CSR_READ_4(sc, BWI_MAC_INTR_MASK);
1535
if (intr_status == 0) { /* Nothing is interesting */
1536
BWI_UNLOCK(sc);
1537
return;
1538
}
1539
1540
KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
1541
("current regwin type %d", sc->sc_cur_regwin->rw_type));
1542
mac = (struct bwi_mac *)sc->sc_cur_regwin;
1543
1544
txrx_error = 0;
1545
DPRINTF(sc, BWI_DBG_INTR, "%s\n", "TX/RX intr");
1546
for (i = 0; i < BWI_TXRX_NRING; ++i) {
1547
uint32_t mask;
1548
1549
if (BWI_TXRX_IS_RX(i))
1550
mask = BWI_TXRX_RX_INTRS;
1551
else
1552
mask = BWI_TXRX_TX_INTRS;
1553
1554
txrx_intr_status[i] =
1555
CSR_READ_4(sc, BWI_TXRX_INTR_STATUS(i)) & mask;
1556
1557
_DPRINTF(sc, BWI_DBG_INTR, ", %d 0x%08x",
1558
i, txrx_intr_status[i]);
1559
1560
if (txrx_intr_status[i] & BWI_TXRX_INTR_ERROR) {
1561
device_printf(sc->sc_dev,
1562
"%s: intr fatal TX/RX (%d) error 0x%08x\n",
1563
__func__, i, txrx_intr_status[i]);
1564
txrx_error = 1;
1565
}
1566
}
1567
_DPRINTF(sc, BWI_DBG_INTR, "%s\n", "");
1568
1569
/*
1570
* Acknowledge interrupt
1571
*/
1572
CSR_WRITE_4(sc, BWI_MAC_INTR_STATUS, intr_status);
1573
1574
for (i = 0; i < BWI_TXRX_NRING; ++i)
1575
CSR_WRITE_4(sc, BWI_TXRX_INTR_STATUS(i), txrx_intr_status[i]);
1576
1577
/* Disable all interrupts */
1578
bwi_disable_intrs(sc, BWI_ALL_INTRS);
1579
1580
/*
1581
* http://bcm-specs.sipsolutions.net/Interrupts
1582
* Says for this bit (0x800):
1583
* "Fatal Error
1584
*
1585
* We got this one while testing things when by accident the
1586
* template ram wasn't set to big endian when it should have
1587
* been after writing the initial values. It keeps on being
1588
* triggered, the only way to stop it seems to shut down the
1589
* chip."
1590
*
1591
* Suggesting that we should never get it and if we do we're not
1592
* feeding TX packets into the MAC correctly if we do... Apparently,
1593
* it is valid only on mac version 5 and higher, but I couldn't
1594
* find a reference for that... Since I see them from time to time
1595
* on my card, this suggests an error in the tx path still...
1596
*/
1597
if (intr_status & BWI_INTR_PHY_TXERR) {
1598
if (mac->mac_flags & BWI_MAC_F_PHYE_RESET) {
1599
device_printf(sc->sc_dev, "%s: intr PHY TX error\n",
1600
__func__);
1601
taskqueue_enqueue(sc->sc_tq, &sc->sc_restart_task);
1602
BWI_UNLOCK(sc);
1603
return;
1604
}
1605
}
1606
1607
if (txrx_error) {
1608
/* TODO: reset device */
1609
}
1610
1611
if (intr_status & BWI_INTR_TBTT)
1612
bwi_mac_config_ps(mac);
1613
1614
if (intr_status & BWI_INTR_EO_ATIM)
1615
device_printf(sc->sc_dev, "EO_ATIM\n");
1616
1617
if (intr_status & BWI_INTR_PMQ) {
1618
for (;;) {
1619
if ((CSR_READ_4(sc, BWI_MAC_PS_STATUS) & 0x8) == 0)
1620
break;
1621
}
1622
CSR_WRITE_2(sc, BWI_MAC_PS_STATUS, 0x2);
1623
}
1624
1625
if (intr_status & BWI_INTR_NOISE)
1626
device_printf(sc->sc_dev, "intr noise\n");
1627
1628
if (txrx_intr_status[0] & BWI_TXRX_INTR_RX) {
1629
rx_data = sc->sc_rxeof(sc);
1630
if (sc->sc_flags & BWI_F_STOP) {
1631
BWI_UNLOCK(sc);
1632
return;
1633
}
1634
}
1635
1636
if (txrx_intr_status[3] & BWI_TXRX_INTR_RX) {
1637
sc->sc_txeof_status(sc);
1638
tx = 1;
1639
}
1640
1641
if (intr_status & BWI_INTR_TX_DONE) {
1642
bwi_txeof(sc);
1643
tx = 1;
1644
}
1645
1646
/* Re-enable interrupts */
1647
bwi_enable_intrs(sc, BWI_INIT_INTRS);
1648
1649
if (sc->sc_blink_led != NULL && sc->sc_led_blink) {
1650
int evt = BWI_LED_EVENT_NONE;
1651
1652
if (tx && rx_data > 0) {
1653
if (sc->sc_rx_rate > sc->sc_tx_rate)
1654
evt = BWI_LED_EVENT_RX;
1655
else
1656
evt = BWI_LED_EVENT_TX;
1657
} else if (tx) {
1658
evt = BWI_LED_EVENT_TX;
1659
} else if (rx_data > 0) {
1660
evt = BWI_LED_EVENT_RX;
1661
} else if (rx_data == 0) {
1662
evt = BWI_LED_EVENT_POLL;
1663
}
1664
1665
if (evt != BWI_LED_EVENT_NONE)
1666
bwi_led_event(sc, evt);
1667
}
1668
1669
BWI_UNLOCK(sc);
1670
}
1671
1672
static void
1673
bwi_scan_start(struct ieee80211com *ic)
1674
{
1675
struct bwi_softc *sc = ic->ic_softc;
1676
1677
BWI_LOCK(sc);
1678
/* Enable MAC beacon promiscuity */
1679
CSR_SETBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PASS_BCN);
1680
BWI_UNLOCK(sc);
1681
}
1682
1683
static void
1684
bwi_getradiocaps(struct ieee80211com *ic,
1685
int maxchans, int *nchans, struct ieee80211_channel chans[])
1686
{
1687
struct bwi_softc *sc = ic->ic_softc;
1688
struct bwi_mac *mac;
1689
struct bwi_phy *phy;
1690
uint8_t bands[IEEE80211_MODE_BYTES];
1691
1692
/*
1693
* XXX First MAC is known to exist
1694
* TODO2
1695
*/
1696
mac = &sc->sc_mac[0];
1697
phy = &mac->mac_phy;
1698
1699
memset(bands, 0, sizeof(bands));
1700
switch (phy->phy_mode) {
1701
case IEEE80211_MODE_11G:
1702
setbit(bands, IEEE80211_MODE_11G);
1703
/* FALLTHROUGH */
1704
case IEEE80211_MODE_11B:
1705
setbit(bands, IEEE80211_MODE_11B);
1706
break;
1707
case IEEE80211_MODE_11A:
1708
/* TODO:11A */
1709
setbit(bands, IEEE80211_MODE_11A);
1710
device_printf(sc->sc_dev, "no 11a support\n");
1711
return;
1712
default:
1713
panic("unknown phymode %d\n", phy->phy_mode);
1714
}
1715
1716
ieee80211_add_channels_default_2ghz(chans, maxchans, nchans, bands, 0);
1717
}
1718
1719
static void
1720
bwi_set_channel(struct ieee80211com *ic)
1721
{
1722
struct bwi_softc *sc = ic->ic_softc;
1723
struct ieee80211_channel *c = ic->ic_curchan;
1724
struct bwi_mac *mac;
1725
1726
BWI_LOCK(sc);
1727
KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
1728
("current regwin type %d", sc->sc_cur_regwin->rw_type));
1729
mac = (struct bwi_mac *)sc->sc_cur_regwin;
1730
bwi_rf_set_chan(mac, ieee80211_chan2ieee(ic, c), 0);
1731
1732
sc->sc_rates = ieee80211_get_ratetable(c);
1733
BWI_UNLOCK(sc);
1734
}
1735
1736
static void
1737
bwi_scan_end(struct ieee80211com *ic)
1738
{
1739
struct bwi_softc *sc = ic->ic_softc;
1740
1741
BWI_LOCK(sc);
1742
CSR_CLRBITS_4(sc, BWI_MAC_STATUS, BWI_MAC_STATUS_PASS_BCN);
1743
BWI_UNLOCK(sc);
1744
}
1745
1746
static int
1747
bwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
1748
{
1749
struct bwi_vap *bvp = BWI_VAP(vap);
1750
struct ieee80211com *ic= vap->iv_ic;
1751
struct bwi_softc *sc = ic->ic_softc;
1752
enum ieee80211_state ostate = vap->iv_state;
1753
struct bwi_mac *mac;
1754
int error;
1755
1756
BWI_LOCK(sc);
1757
1758
callout_stop(&sc->sc_calib_ch);
1759
1760
if (nstate == IEEE80211_S_INIT)
1761
sc->sc_txpwrcb_type = BWI_TXPWR_INIT;
1762
1763
bwi_led_newstate(sc, nstate);
1764
1765
error = bvp->bv_newstate(vap, nstate, arg);
1766
if (error != 0)
1767
goto back;
1768
1769
/*
1770
* Clear the BSSID when we stop a STA
1771
*/
1772
if (vap->iv_opmode == IEEE80211_M_STA) {
1773
if (ostate == IEEE80211_S_RUN && nstate != IEEE80211_S_RUN) {
1774
/*
1775
* Clear out the BSSID. If we reassociate to
1776
* the same AP, this will reinialize things
1777
* correctly...
1778
*/
1779
if (ic->ic_opmode == IEEE80211_M_STA &&
1780
!(sc->sc_flags & BWI_F_STOP))
1781
bwi_set_bssid(sc, bwi_zero_addr);
1782
}
1783
}
1784
1785
if (vap->iv_opmode == IEEE80211_M_MONITOR) {
1786
/* Nothing to do */
1787
} else if (nstate == IEEE80211_S_RUN) {
1788
bwi_set_bssid(sc, vap->iv_bss->ni_bssid);
1789
1790
KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
1791
("current regwin type %d", sc->sc_cur_regwin->rw_type));
1792
mac = (struct bwi_mac *)sc->sc_cur_regwin;
1793
1794
/* Initial TX power calibration */
1795
bwi_mac_calibrate_txpower(mac, BWI_TXPWR_INIT);
1796
#ifdef notyet
1797
sc->sc_txpwrcb_type = BWI_TXPWR_FORCE;
1798
#else
1799
sc->sc_txpwrcb_type = BWI_TXPWR_CALIB;
1800
#endif
1801
1802
callout_reset(&sc->sc_calib_ch, hz, bwi_calibrate, sc);
1803
}
1804
back:
1805
BWI_UNLOCK(sc);
1806
1807
return error;
1808
}
1809
1810
static int
1811
bwi_dma_alloc(struct bwi_softc *sc)
1812
{
1813
int error, i, has_txstats;
1814
bus_addr_t lowaddr = 0;
1815
bus_size_t tx_ring_sz, rx_ring_sz, desc_sz = 0;
1816
uint32_t txrx_ctrl_step = 0;
1817
1818
has_txstats = 0;
1819
for (i = 0; i < sc->sc_nmac; ++i) {
1820
if (sc->sc_mac[i].mac_flags & BWI_MAC_F_HAS_TXSTATS) {
1821
has_txstats = 1;
1822
break;
1823
}
1824
}
1825
1826
switch (sc->sc_bus_space) {
1827
case BWI_BUS_SPACE_30BIT:
1828
case BWI_BUS_SPACE_32BIT:
1829
if (sc->sc_bus_space == BWI_BUS_SPACE_30BIT)
1830
lowaddr = BWI_BUS_SPACE_MAXADDR;
1831
else
1832
lowaddr = BUS_SPACE_MAXADDR_32BIT;
1833
desc_sz = sizeof(struct bwi_desc32);
1834
txrx_ctrl_step = 0x20;
1835
1836
sc->sc_init_tx_ring = bwi_init_tx_ring32;
1837
sc->sc_free_tx_ring = bwi_free_tx_ring32;
1838
sc->sc_init_rx_ring = bwi_init_rx_ring32;
1839
sc->sc_free_rx_ring = bwi_free_rx_ring32;
1840
sc->sc_setup_rxdesc = bwi_setup_rx_desc32;
1841
sc->sc_setup_txdesc = bwi_setup_tx_desc32;
1842
sc->sc_rxeof = bwi_rxeof32;
1843
sc->sc_start_tx = bwi_start_tx32;
1844
if (has_txstats) {
1845
sc->sc_init_txstats = bwi_init_txstats32;
1846
sc->sc_free_txstats = bwi_free_txstats32;
1847
sc->sc_txeof_status = bwi_txeof_status32;
1848
}
1849
break;
1850
1851
case BWI_BUS_SPACE_64BIT:
1852
lowaddr = BUS_SPACE_MAXADDR; /* XXX */
1853
desc_sz = sizeof(struct bwi_desc64);
1854
txrx_ctrl_step = 0x40;
1855
1856
sc->sc_init_tx_ring = bwi_init_tx_ring64;
1857
sc->sc_free_tx_ring = bwi_free_tx_ring64;
1858
sc->sc_init_rx_ring = bwi_init_rx_ring64;
1859
sc->sc_free_rx_ring = bwi_free_rx_ring64;
1860
sc->sc_setup_rxdesc = bwi_setup_rx_desc64;
1861
sc->sc_setup_txdesc = bwi_setup_tx_desc64;
1862
sc->sc_rxeof = bwi_rxeof64;
1863
sc->sc_start_tx = bwi_start_tx64;
1864
if (has_txstats) {
1865
sc->sc_init_txstats = bwi_init_txstats64;
1866
sc->sc_free_txstats = bwi_free_txstats64;
1867
sc->sc_txeof_status = bwi_txeof_status64;
1868
}
1869
break;
1870
}
1871
1872
KASSERT(lowaddr != 0, ("lowaddr zero"));
1873
KASSERT(desc_sz != 0, ("desc_sz zero"));
1874
KASSERT(txrx_ctrl_step != 0, ("txrx_ctrl_step zero"));
1875
1876
tx_ring_sz = roundup(desc_sz * BWI_TX_NDESC, BWI_RING_ALIGN);
1877
rx_ring_sz = roundup(desc_sz * BWI_RX_NDESC, BWI_RING_ALIGN);
1878
1879
/*
1880
* Create top level DMA tag
1881
*/
1882
error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), /* parent */
1883
BWI_ALIGN, 0, /* alignment, bounds */
1884
lowaddr, /* lowaddr */
1885
BUS_SPACE_MAXADDR, /* highaddr */
1886
NULL, NULL, /* filter, filterarg */
1887
BUS_SPACE_MAXSIZE, /* maxsize */
1888
BUS_SPACE_UNRESTRICTED, /* nsegments */
1889
BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
1890
0, /* flags */
1891
NULL, NULL, /* lockfunc, lockarg */
1892
&sc->sc_parent_dtag);
1893
if (error) {
1894
device_printf(sc->sc_dev, "can't create parent DMA tag\n");
1895
return error;
1896
}
1897
1898
#define TXRX_CTRL(idx) (BWI_TXRX_CTRL_BASE + (idx) * txrx_ctrl_step)
1899
1900
/*
1901
* Create TX ring DMA stuffs
1902
*/
1903
error = bus_dma_tag_create(sc->sc_parent_dtag,
1904
BWI_RING_ALIGN, 0,
1905
BUS_SPACE_MAXADDR,
1906
BUS_SPACE_MAXADDR,
1907
NULL, NULL,
1908
tx_ring_sz,
1909
1,
1910
tx_ring_sz,
1911
0,
1912
NULL, NULL,
1913
&sc->sc_txring_dtag);
1914
if (error) {
1915
device_printf(sc->sc_dev, "can't create TX ring DMA tag\n");
1916
return error;
1917
}
1918
1919
for (i = 0; i < BWI_TX_NRING; ++i) {
1920
error = bwi_dma_ring_alloc(sc, sc->sc_txring_dtag,
1921
&sc->sc_tx_rdata[i], tx_ring_sz,
1922
TXRX_CTRL(i));
1923
if (error) {
1924
device_printf(sc->sc_dev, "%dth TX ring "
1925
"DMA alloc failed\n", i);
1926
return error;
1927
}
1928
}
1929
1930
/*
1931
* Create RX ring DMA stuffs
1932
*/
1933
error = bus_dma_tag_create(sc->sc_parent_dtag,
1934
BWI_RING_ALIGN, 0,
1935
BUS_SPACE_MAXADDR,
1936
BUS_SPACE_MAXADDR,
1937
NULL, NULL,
1938
rx_ring_sz,
1939
1,
1940
rx_ring_sz,
1941
0,
1942
NULL, NULL,
1943
&sc->sc_rxring_dtag);
1944
if (error) {
1945
device_printf(sc->sc_dev, "can't create RX ring DMA tag\n");
1946
return error;
1947
}
1948
1949
error = bwi_dma_ring_alloc(sc, sc->sc_rxring_dtag, &sc->sc_rx_rdata,
1950
rx_ring_sz, TXRX_CTRL(0));
1951
if (error) {
1952
device_printf(sc->sc_dev, "RX ring DMA alloc failed\n");
1953
return error;
1954
}
1955
1956
if (has_txstats) {
1957
error = bwi_dma_txstats_alloc(sc, TXRX_CTRL(3), desc_sz);
1958
if (error) {
1959
device_printf(sc->sc_dev,
1960
"TX stats DMA alloc failed\n");
1961
return error;
1962
}
1963
}
1964
1965
#undef TXRX_CTRL
1966
1967
return bwi_dma_mbuf_create(sc);
1968
}
1969
1970
static void
1971
bwi_dma_free(struct bwi_softc *sc)
1972
{
1973
if (sc->sc_txring_dtag != NULL) {
1974
int i;
1975
1976
for (i = 0; i < BWI_TX_NRING; ++i) {
1977
struct bwi_ring_data *rd = &sc->sc_tx_rdata[i];
1978
1979
if (rd->rdata_desc != NULL) {
1980
bus_dmamap_unload(sc->sc_txring_dtag,
1981
rd->rdata_dmap);
1982
bus_dmamem_free(sc->sc_txring_dtag,
1983
rd->rdata_desc,
1984
rd->rdata_dmap);
1985
}
1986
}
1987
bus_dma_tag_destroy(sc->sc_txring_dtag);
1988
}
1989
1990
if (sc->sc_rxring_dtag != NULL) {
1991
struct bwi_ring_data *rd = &sc->sc_rx_rdata;
1992
1993
if (rd->rdata_desc != NULL) {
1994
bus_dmamap_unload(sc->sc_rxring_dtag, rd->rdata_dmap);
1995
bus_dmamem_free(sc->sc_rxring_dtag, rd->rdata_desc,
1996
rd->rdata_dmap);
1997
}
1998
bus_dma_tag_destroy(sc->sc_rxring_dtag);
1999
}
2000
2001
bwi_dma_txstats_free(sc);
2002
bwi_dma_mbuf_destroy(sc, BWI_TX_NRING, 1);
2003
2004
if (sc->sc_parent_dtag != NULL)
2005
bus_dma_tag_destroy(sc->sc_parent_dtag);
2006
}
2007
2008
static int
2009
bwi_dma_ring_alloc(struct bwi_softc *sc, bus_dma_tag_t dtag,
2010
struct bwi_ring_data *rd, bus_size_t size,
2011
uint32_t txrx_ctrl)
2012
{
2013
int error;
2014
2015
error = bus_dmamem_alloc(dtag, &rd->rdata_desc,
2016
BUS_DMA_WAITOK | BUS_DMA_ZERO,
2017
&rd->rdata_dmap);
2018
if (error) {
2019
device_printf(sc->sc_dev, "can't allocate DMA mem\n");
2020
return error;
2021
}
2022
2023
error = bus_dmamap_load(dtag, rd->rdata_dmap, rd->rdata_desc, size,
2024
bwi_dma_ring_addr, &rd->rdata_paddr,
2025
BUS_DMA_NOWAIT);
2026
if (error) {
2027
device_printf(sc->sc_dev, "can't load DMA mem\n");
2028
bus_dmamem_free(dtag, rd->rdata_desc, rd->rdata_dmap);
2029
rd->rdata_desc = NULL;
2030
return error;
2031
}
2032
2033
rd->rdata_txrx_ctrl = txrx_ctrl;
2034
return 0;
2035
}
2036
2037
static int
2038
bwi_dma_txstats_alloc(struct bwi_softc *sc, uint32_t ctrl_base,
2039
bus_size_t desc_sz)
2040
{
2041
struct bwi_txstats_data *st;
2042
bus_size_t dma_size;
2043
int error;
2044
2045
st = malloc(sizeof(*st), M_DEVBUF, M_NOWAIT | M_ZERO);
2046
if (st == NULL) {
2047
device_printf(sc->sc_dev, "can't allocate txstats data\n");
2048
return ENOMEM;
2049
}
2050
sc->sc_txstats = st;
2051
2052
/*
2053
* Create TX stats descriptor DMA stuffs
2054
*/
2055
dma_size = roundup(desc_sz * BWI_TXSTATS_NDESC, BWI_RING_ALIGN);
2056
2057
error = bus_dma_tag_create(sc->sc_parent_dtag,
2058
BWI_RING_ALIGN,
2059
0,
2060
BUS_SPACE_MAXADDR,
2061
BUS_SPACE_MAXADDR,
2062
NULL, NULL,
2063
dma_size,
2064
1,
2065
dma_size,
2066
0,
2067
NULL, NULL,
2068
&st->stats_ring_dtag);
2069
if (error) {
2070
device_printf(sc->sc_dev, "can't create txstats ring "
2071
"DMA tag\n");
2072
return error;
2073
}
2074
2075
error = bus_dmamem_alloc(st->stats_ring_dtag, &st->stats_ring,
2076
BUS_DMA_WAITOK | BUS_DMA_ZERO,
2077
&st->stats_ring_dmap);
2078
if (error) {
2079
device_printf(sc->sc_dev, "can't allocate txstats ring "
2080
"DMA mem\n");
2081
bus_dma_tag_destroy(st->stats_ring_dtag);
2082
st->stats_ring_dtag = NULL;
2083
return error;
2084
}
2085
2086
error = bus_dmamap_load(st->stats_ring_dtag, st->stats_ring_dmap,
2087
st->stats_ring, dma_size,
2088
bwi_dma_ring_addr, &st->stats_ring_paddr,
2089
BUS_DMA_NOWAIT);
2090
if (error) {
2091
device_printf(sc->sc_dev, "can't load txstats ring DMA mem\n");
2092
bus_dmamem_free(st->stats_ring_dtag, st->stats_ring,
2093
st->stats_ring_dmap);
2094
bus_dma_tag_destroy(st->stats_ring_dtag);
2095
st->stats_ring_dtag = NULL;
2096
return error;
2097
}
2098
2099
/*
2100
* Create TX stats DMA stuffs
2101
*/
2102
dma_size = roundup(sizeof(struct bwi_txstats) * BWI_TXSTATS_NDESC,
2103
BWI_ALIGN);
2104
2105
error = bus_dma_tag_create(sc->sc_parent_dtag,
2106
BWI_ALIGN,
2107
0,
2108
BUS_SPACE_MAXADDR,
2109
BUS_SPACE_MAXADDR,
2110
NULL, NULL,
2111
dma_size,
2112
1,
2113
dma_size,
2114
0,
2115
NULL, NULL,
2116
&st->stats_dtag);
2117
if (error) {
2118
device_printf(sc->sc_dev, "can't create txstats DMA tag\n");
2119
return error;
2120
}
2121
2122
error = bus_dmamem_alloc(st->stats_dtag, (void **)&st->stats,
2123
BUS_DMA_WAITOK | BUS_DMA_ZERO,
2124
&st->stats_dmap);
2125
if (error) {
2126
device_printf(sc->sc_dev, "can't allocate txstats DMA mem\n");
2127
bus_dma_tag_destroy(st->stats_dtag);
2128
st->stats_dtag = NULL;
2129
return error;
2130
}
2131
2132
error = bus_dmamap_load(st->stats_dtag, st->stats_dmap, st->stats,
2133
dma_size, bwi_dma_ring_addr, &st->stats_paddr,
2134
BUS_DMA_NOWAIT);
2135
if (error) {
2136
device_printf(sc->sc_dev, "can't load txstats DMA mem\n");
2137
bus_dmamem_free(st->stats_dtag, st->stats, st->stats_dmap);
2138
bus_dma_tag_destroy(st->stats_dtag);
2139
st->stats_dtag = NULL;
2140
return error;
2141
}
2142
2143
st->stats_ctrl_base = ctrl_base;
2144
return 0;
2145
}
2146
2147
static void
2148
bwi_dma_txstats_free(struct bwi_softc *sc)
2149
{
2150
struct bwi_txstats_data *st;
2151
2152
if (sc->sc_txstats == NULL)
2153
return;
2154
st = sc->sc_txstats;
2155
2156
if (st->stats_ring_dtag != NULL) {
2157
bus_dmamap_unload(st->stats_ring_dtag, st->stats_ring_dmap);
2158
bus_dmamem_free(st->stats_ring_dtag, st->stats_ring,
2159
st->stats_ring_dmap);
2160
bus_dma_tag_destroy(st->stats_ring_dtag);
2161
}
2162
2163
if (st->stats_dtag != NULL) {
2164
bus_dmamap_unload(st->stats_dtag, st->stats_dmap);
2165
bus_dmamem_free(st->stats_dtag, st->stats, st->stats_dmap);
2166
bus_dma_tag_destroy(st->stats_dtag);
2167
}
2168
2169
free(st, M_DEVBUF);
2170
}
2171
2172
static void
2173
bwi_dma_ring_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error)
2174
{
2175
KASSERT(nseg == 1, ("too many segments\n"));
2176
*((bus_addr_t *)arg) = seg->ds_addr;
2177
}
2178
2179
static int
2180
bwi_dma_mbuf_create(struct bwi_softc *sc)
2181
{
2182
struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
2183
int i, j, k, ntx, error;
2184
2185
/*
2186
* Create TX/RX mbuf DMA tag
2187
*/
2188
error = bus_dma_tag_create(sc->sc_parent_dtag,
2189
1,
2190
0,
2191
BUS_SPACE_MAXADDR,
2192
BUS_SPACE_MAXADDR,
2193
NULL, NULL,
2194
MCLBYTES,
2195
1,
2196
MCLBYTES,
2197
BUS_DMA_ALLOCNOW,
2198
NULL, NULL,
2199
&sc->sc_buf_dtag);
2200
if (error) {
2201
device_printf(sc->sc_dev, "can't create mbuf DMA tag\n");
2202
return error;
2203
}
2204
2205
ntx = 0;
2206
2207
/*
2208
* Create TX mbuf DMA map
2209
*/
2210
for (i = 0; i < BWI_TX_NRING; ++i) {
2211
struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
2212
2213
for (j = 0; j < BWI_TX_NDESC; ++j) {
2214
error = bus_dmamap_create(sc->sc_buf_dtag, 0,
2215
&tbd->tbd_buf[j].tb_dmap);
2216
if (error) {
2217
device_printf(sc->sc_dev, "can't create "
2218
"%dth tbd, %dth DMA map\n", i, j);
2219
2220
ntx = i;
2221
for (k = 0; k < j; ++k) {
2222
bus_dmamap_destroy(sc->sc_buf_dtag,
2223
tbd->tbd_buf[k].tb_dmap);
2224
}
2225
goto fail;
2226
}
2227
}
2228
}
2229
ntx = BWI_TX_NRING;
2230
2231
/*
2232
* Create RX mbuf DMA map and a spare DMA map
2233
*/
2234
error = bus_dmamap_create(sc->sc_buf_dtag, 0,
2235
&rbd->rbd_tmp_dmap);
2236
if (error) {
2237
device_printf(sc->sc_dev,
2238
"can't create spare RX buf DMA map\n");
2239
goto fail;
2240
}
2241
2242
for (j = 0; j < BWI_RX_NDESC; ++j) {
2243
error = bus_dmamap_create(sc->sc_buf_dtag, 0,
2244
&rbd->rbd_buf[j].rb_dmap);
2245
if (error) {
2246
device_printf(sc->sc_dev, "can't create %dth "
2247
"RX buf DMA map\n", j);
2248
2249
for (k = 0; k < j; ++k) {
2250
bus_dmamap_destroy(sc->sc_buf_dtag,
2251
rbd->rbd_buf[j].rb_dmap);
2252
}
2253
bus_dmamap_destroy(sc->sc_buf_dtag,
2254
rbd->rbd_tmp_dmap);
2255
goto fail;
2256
}
2257
}
2258
2259
return 0;
2260
fail:
2261
bwi_dma_mbuf_destroy(sc, ntx, 0);
2262
return error;
2263
}
2264
2265
static void
2266
bwi_dma_mbuf_destroy(struct bwi_softc *sc, int ntx, int nrx)
2267
{
2268
int i, j;
2269
2270
if (sc->sc_buf_dtag == NULL)
2271
return;
2272
2273
for (i = 0; i < ntx; ++i) {
2274
struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[i];
2275
2276
for (j = 0; j < BWI_TX_NDESC; ++j) {
2277
struct bwi_txbuf *tb = &tbd->tbd_buf[j];
2278
2279
if (tb->tb_mbuf != NULL) {
2280
bus_dmamap_unload(sc->sc_buf_dtag,
2281
tb->tb_dmap);
2282
m_freem(tb->tb_mbuf);
2283
}
2284
if (tb->tb_ni != NULL)
2285
ieee80211_free_node(tb->tb_ni);
2286
bus_dmamap_destroy(sc->sc_buf_dtag, tb->tb_dmap);
2287
}
2288
}
2289
2290
if (nrx) {
2291
struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
2292
2293
bus_dmamap_destroy(sc->sc_buf_dtag, rbd->rbd_tmp_dmap);
2294
for (j = 0; j < BWI_RX_NDESC; ++j) {
2295
struct bwi_rxbuf *rb = &rbd->rbd_buf[j];
2296
2297
if (rb->rb_mbuf != NULL) {
2298
bus_dmamap_unload(sc->sc_buf_dtag,
2299
rb->rb_dmap);
2300
m_freem(rb->rb_mbuf);
2301
}
2302
bus_dmamap_destroy(sc->sc_buf_dtag, rb->rb_dmap);
2303
}
2304
}
2305
2306
bus_dma_tag_destroy(sc->sc_buf_dtag);
2307
sc->sc_buf_dtag = NULL;
2308
}
2309
2310
static void
2311
bwi_enable_intrs(struct bwi_softc *sc, uint32_t enable_intrs)
2312
{
2313
CSR_SETBITS_4(sc, BWI_MAC_INTR_MASK, enable_intrs);
2314
}
2315
2316
static void
2317
bwi_disable_intrs(struct bwi_softc *sc, uint32_t disable_intrs)
2318
{
2319
CSR_CLRBITS_4(sc, BWI_MAC_INTR_MASK, disable_intrs);
2320
}
2321
2322
static int
2323
bwi_init_tx_ring32(struct bwi_softc *sc, int ring_idx)
2324
{
2325
struct bwi_ring_data *rd;
2326
struct bwi_txbuf_data *tbd;
2327
uint32_t val, addr_hi, addr_lo;
2328
2329
KASSERT(ring_idx < BWI_TX_NRING, ("ring_idx %d", ring_idx));
2330
rd = &sc->sc_tx_rdata[ring_idx];
2331
tbd = &sc->sc_tx_bdata[ring_idx];
2332
2333
tbd->tbd_idx = 0;
2334
tbd->tbd_used = 0;
2335
2336
bzero(rd->rdata_desc, sizeof(struct bwi_desc32) * BWI_TX_NDESC);
2337
bus_dmamap_sync(sc->sc_txring_dtag, rd->rdata_dmap,
2338
BUS_DMASYNC_PREWRITE);
2339
2340
addr_lo = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_ADDR_MASK);
2341
addr_hi = __SHIFTOUT(rd->rdata_paddr, BWI_TXRX32_RINGINFO_FUNC_MASK);
2342
2343
val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) |
2344
__SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX,
2345
BWI_TXRX32_RINGINFO_FUNC_MASK);
2346
CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, val);
2347
2348
val = __SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) |
2349
BWI_TXRX32_CTRL_ENABLE;
2350
CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, val);
2351
2352
return 0;
2353
}
2354
2355
static void
2356
bwi_init_rxdesc_ring32(struct bwi_softc *sc, uint32_t ctrl_base,
2357
bus_addr_t paddr, int hdr_size, int ndesc)
2358
{
2359
uint32_t val, addr_hi, addr_lo;
2360
2361
addr_lo = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_ADDR_MASK);
2362
addr_hi = __SHIFTOUT(paddr, BWI_TXRX32_RINGINFO_FUNC_MASK);
2363
2364
val = __SHIFTIN(addr_lo, BWI_TXRX32_RINGINFO_ADDR_MASK) |
2365
__SHIFTIN(BWI_TXRX32_RINGINFO_FUNC_TXRX,
2366
BWI_TXRX32_RINGINFO_FUNC_MASK);
2367
CSR_WRITE_4(sc, ctrl_base + BWI_RX32_RINGINFO, val);
2368
2369
val = __SHIFTIN(hdr_size, BWI_RX32_CTRL_HDRSZ_MASK) |
2370
__SHIFTIN(addr_hi, BWI_TXRX32_CTRL_ADDRHI_MASK) |
2371
BWI_TXRX32_CTRL_ENABLE;
2372
CSR_WRITE_4(sc, ctrl_base + BWI_RX32_CTRL, val);
2373
2374
CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX,
2375
(ndesc - 1) * sizeof(struct bwi_desc32));
2376
}
2377
2378
static int
2379
bwi_init_rx_ring32(struct bwi_softc *sc)
2380
{
2381
struct bwi_ring_data *rd = &sc->sc_rx_rdata;
2382
int i, error;
2383
2384
sc->sc_rx_bdata.rbd_idx = 0;
2385
2386
for (i = 0; i < BWI_RX_NDESC; ++i) {
2387
error = bwi_newbuf(sc, i, 1);
2388
if (error) {
2389
device_printf(sc->sc_dev,
2390
"can't allocate %dth RX buffer\n", i);
2391
return error;
2392
}
2393
}
2394
bus_dmamap_sync(sc->sc_rxring_dtag, rd->rdata_dmap,
2395
BUS_DMASYNC_PREWRITE);
2396
2397
bwi_init_rxdesc_ring32(sc, rd->rdata_txrx_ctrl, rd->rdata_paddr,
2398
sizeof(struct bwi_rxbuf_hdr), BWI_RX_NDESC);
2399
return 0;
2400
}
2401
2402
static int
2403
bwi_init_txstats32(struct bwi_softc *sc)
2404
{
2405
struct bwi_txstats_data *st = sc->sc_txstats;
2406
bus_addr_t stats_paddr;
2407
int i;
2408
2409
bzero(st->stats, BWI_TXSTATS_NDESC * sizeof(struct bwi_txstats));
2410
bus_dmamap_sync(st->stats_dtag, st->stats_dmap, BUS_DMASYNC_PREWRITE);
2411
2412
st->stats_idx = 0;
2413
2414
stats_paddr = st->stats_paddr;
2415
for (i = 0; i < BWI_TXSTATS_NDESC; ++i) {
2416
bwi_setup_desc32(sc, st->stats_ring, BWI_TXSTATS_NDESC, i,
2417
stats_paddr, sizeof(struct bwi_txstats), 0);
2418
stats_paddr += sizeof(struct bwi_txstats);
2419
}
2420
bus_dmamap_sync(st->stats_ring_dtag, st->stats_ring_dmap,
2421
BUS_DMASYNC_PREWRITE);
2422
2423
bwi_init_rxdesc_ring32(sc, st->stats_ctrl_base,
2424
st->stats_ring_paddr, 0, BWI_TXSTATS_NDESC);
2425
return 0;
2426
}
2427
2428
static void
2429
bwi_setup_rx_desc32(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr,
2430
int buf_len)
2431
{
2432
struct bwi_ring_data *rd = &sc->sc_rx_rdata;
2433
2434
KASSERT(buf_idx < BWI_RX_NDESC, ("buf_idx %d", buf_idx));
2435
bwi_setup_desc32(sc, rd->rdata_desc, BWI_RX_NDESC, buf_idx,
2436
paddr, buf_len, 0);
2437
}
2438
2439
static void
2440
bwi_setup_tx_desc32(struct bwi_softc *sc, struct bwi_ring_data *rd,
2441
int buf_idx, bus_addr_t paddr, int buf_len)
2442
{
2443
KASSERT(buf_idx < BWI_TX_NDESC, ("buf_idx %d", buf_idx));
2444
bwi_setup_desc32(sc, rd->rdata_desc, BWI_TX_NDESC, buf_idx,
2445
paddr, buf_len, 1);
2446
}
2447
2448
static int
2449
bwi_init_tx_ring64(struct bwi_softc *sc, int ring_idx)
2450
{
2451
/* TODO:64 */
2452
return EOPNOTSUPP;
2453
}
2454
2455
static int
2456
bwi_init_rx_ring64(struct bwi_softc *sc)
2457
{
2458
/* TODO:64 */
2459
return EOPNOTSUPP;
2460
}
2461
2462
static int
2463
bwi_init_txstats64(struct bwi_softc *sc)
2464
{
2465
/* TODO:64 */
2466
return EOPNOTSUPP;
2467
}
2468
2469
static void
2470
bwi_setup_rx_desc64(struct bwi_softc *sc, int buf_idx, bus_addr_t paddr,
2471
int buf_len)
2472
{
2473
/* TODO:64 */
2474
}
2475
2476
static void
2477
bwi_setup_tx_desc64(struct bwi_softc *sc, struct bwi_ring_data *rd,
2478
int buf_idx, bus_addr_t paddr, int buf_len)
2479
{
2480
/* TODO:64 */
2481
}
2482
2483
static void
2484
bwi_dma_buf_addr(void *arg, bus_dma_segment_t *seg, int nseg,
2485
bus_size_t mapsz __unused, int error)
2486
{
2487
if (!error) {
2488
KASSERT(nseg == 1, ("too many segments(%d)\n", nseg));
2489
*((bus_addr_t *)arg) = seg->ds_addr;
2490
}
2491
}
2492
2493
static int
2494
bwi_newbuf(struct bwi_softc *sc, int buf_idx, int init)
2495
{
2496
struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
2497
struct bwi_rxbuf *rxbuf = &rbd->rbd_buf[buf_idx];
2498
struct bwi_rxbuf_hdr *hdr;
2499
bus_dmamap_t map;
2500
bus_addr_t paddr;
2501
struct mbuf *m;
2502
int error;
2503
2504
KASSERT(buf_idx < BWI_RX_NDESC, ("buf_idx %d", buf_idx));
2505
2506
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
2507
if (m == NULL) {
2508
error = ENOBUFS;
2509
2510
/*
2511
* If the NIC is up and running, we need to:
2512
* - Clear RX buffer's header.
2513
* - Restore RX descriptor settings.
2514
*/
2515
if (init)
2516
return error;
2517
else
2518
goto back;
2519
}
2520
m->m_len = m->m_pkthdr.len = MCLBYTES;
2521
2522
/*
2523
* Try to load RX buf into temporary DMA map
2524
*/
2525
error = bus_dmamap_load_mbuf(sc->sc_buf_dtag, rbd->rbd_tmp_dmap, m,
2526
bwi_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
2527
if (error) {
2528
m_freem(m);
2529
2530
/*
2531
* See the comment above
2532
*/
2533
if (init)
2534
return error;
2535
else
2536
goto back;
2537
}
2538
2539
if (!init)
2540
bus_dmamap_unload(sc->sc_buf_dtag, rxbuf->rb_dmap);
2541
rxbuf->rb_mbuf = m;
2542
rxbuf->rb_paddr = paddr;
2543
2544
/*
2545
* Swap RX buf's DMA map with the loaded temporary one
2546
*/
2547
map = rxbuf->rb_dmap;
2548
rxbuf->rb_dmap = rbd->rbd_tmp_dmap;
2549
rbd->rbd_tmp_dmap = map;
2550
2551
back:
2552
/*
2553
* Clear RX buf header
2554
*/
2555
hdr = mtod(rxbuf->rb_mbuf, struct bwi_rxbuf_hdr *);
2556
bzero(hdr, sizeof(*hdr));
2557
bus_dmamap_sync(sc->sc_buf_dtag, rxbuf->rb_dmap, BUS_DMASYNC_PREWRITE);
2558
2559
/*
2560
* Setup RX buf descriptor
2561
*/
2562
sc->sc_setup_rxdesc(sc, buf_idx, rxbuf->rb_paddr,
2563
rxbuf->rb_mbuf->m_len - sizeof(*hdr));
2564
return error;
2565
}
2566
2567
static void
2568
bwi_set_addr_filter(struct bwi_softc *sc, uint16_t addr_ofs,
2569
const uint8_t *addr)
2570
{
2571
int i;
2572
2573
CSR_WRITE_2(sc, BWI_ADDR_FILTER_CTRL,
2574
BWI_ADDR_FILTER_CTRL_SET | addr_ofs);
2575
2576
for (i = 0; i < (IEEE80211_ADDR_LEN / 2); ++i) {
2577
uint16_t addr_val;
2578
2579
addr_val = (uint16_t)addr[i * 2] |
2580
(((uint16_t)addr[(i * 2) + 1]) << 8);
2581
CSR_WRITE_2(sc, BWI_ADDR_FILTER_DATA, addr_val);
2582
}
2583
}
2584
2585
static int
2586
bwi_rxeof(struct bwi_softc *sc, int end_idx)
2587
{
2588
struct bwi_ring_data *rd = &sc->sc_rx_rdata;
2589
struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
2590
struct ieee80211com *ic = &sc->sc_ic;
2591
int idx, rx_data = 0;
2592
2593
idx = rbd->rbd_idx;
2594
while (idx != end_idx) {
2595
struct bwi_rxbuf *rb = &rbd->rbd_buf[idx];
2596
struct bwi_rxbuf_hdr *hdr;
2597
struct ieee80211_frame_min *wh;
2598
struct ieee80211_node *ni;
2599
struct mbuf *m;
2600
uint32_t plcp;
2601
uint16_t flags2;
2602
int buflen, wh_ofs, hdr_extra, rssi, noise, type, rate;
2603
2604
m = rb->rb_mbuf;
2605
bus_dmamap_sync(sc->sc_buf_dtag, rb->rb_dmap,
2606
BUS_DMASYNC_POSTREAD);
2607
2608
if (bwi_newbuf(sc, idx, 0)) {
2609
counter_u64_add(ic->ic_ierrors, 1);
2610
goto next;
2611
}
2612
2613
hdr = mtod(m, struct bwi_rxbuf_hdr *);
2614
flags2 = le16toh(hdr->rxh_flags2);
2615
2616
hdr_extra = 0;
2617
if (flags2 & BWI_RXH_F2_TYPE2FRAME)
2618
hdr_extra = 2;
2619
wh_ofs = hdr_extra + 6; /* XXX magic number */
2620
2621
buflen = le16toh(hdr->rxh_buflen);
2622
if (buflen < BWI_FRAME_MIN_LEN(wh_ofs)) {
2623
device_printf(sc->sc_dev,
2624
"%s: zero length data, hdr_extra %d\n",
2625
__func__, hdr_extra);
2626
counter_u64_add(ic->ic_ierrors, 1);
2627
m_freem(m);
2628
goto next;
2629
}
2630
2631
bcopy((uint8_t *)(hdr + 1) + hdr_extra, &plcp, sizeof(plcp));
2632
rssi = bwi_calc_rssi(sc, hdr);
2633
noise = bwi_calc_noise(sc);
2634
2635
m->m_len = m->m_pkthdr.len = buflen + sizeof(*hdr);
2636
m_adj(m, sizeof(*hdr) + wh_ofs);
2637
2638
if (htole16(hdr->rxh_flags1) & BWI_RXH_F1_OFDM)
2639
rate = bwi_plcp2rate(plcp, IEEE80211_T_OFDM);
2640
else
2641
rate = bwi_plcp2rate(plcp, IEEE80211_T_CCK);
2642
2643
/* RX radio tap */
2644
if (ieee80211_radiotap_active(ic))
2645
bwi_rx_radiotap(sc, m, hdr, &plcp, rate, rssi, noise);
2646
2647
m_adj(m, -IEEE80211_CRC_LEN);
2648
2649
BWI_UNLOCK(sc);
2650
2651
wh = mtod(m, struct ieee80211_frame_min *);
2652
ni = ieee80211_find_rxnode(ic, wh);
2653
if (ni != NULL) {
2654
type = ieee80211_input(ni, m, rssi - noise, noise);
2655
ieee80211_free_node(ni);
2656
} else
2657
type = ieee80211_input_all(ic, m, rssi - noise, noise);
2658
if (type == IEEE80211_FC0_TYPE_DATA) {
2659
rx_data = 1;
2660
sc->sc_rx_rate = rate;
2661
}
2662
2663
BWI_LOCK(sc);
2664
next:
2665
idx = (idx + 1) % BWI_RX_NDESC;
2666
2667
if (sc->sc_flags & BWI_F_STOP) {
2668
/*
2669
* Take the fast lane, don't do
2670
* any damage to softc
2671
*/
2672
return -1;
2673
}
2674
}
2675
2676
rbd->rbd_idx = idx;
2677
bus_dmamap_sync(sc->sc_rxring_dtag, rd->rdata_dmap,
2678
BUS_DMASYNC_PREWRITE);
2679
2680
return rx_data;
2681
}
2682
2683
static int
2684
bwi_rxeof32(struct bwi_softc *sc)
2685
{
2686
uint32_t val, rx_ctrl;
2687
int end_idx, rx_data;
2688
2689
rx_ctrl = sc->sc_rx_rdata.rdata_txrx_ctrl;
2690
2691
val = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS);
2692
end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) /
2693
sizeof(struct bwi_desc32);
2694
2695
rx_data = bwi_rxeof(sc, end_idx);
2696
if (rx_data >= 0) {
2697
CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_INDEX,
2698
end_idx * sizeof(struct bwi_desc32));
2699
}
2700
return rx_data;
2701
}
2702
2703
static int
2704
bwi_rxeof64(struct bwi_softc *sc)
2705
{
2706
/* TODO:64 */
2707
return 0;
2708
}
2709
2710
static void
2711
bwi_reset_rx_ring32(struct bwi_softc *sc, uint32_t rx_ctrl)
2712
{
2713
int i;
2714
2715
CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_CTRL, 0);
2716
2717
#define NRETRY 10
2718
2719
for (i = 0; i < NRETRY; ++i) {
2720
uint32_t status;
2721
2722
status = CSR_READ_4(sc, rx_ctrl + BWI_RX32_STATUS);
2723
if (__SHIFTOUT(status, BWI_RX32_STATUS_STATE_MASK) ==
2724
BWI_RX32_STATUS_STATE_DISABLED)
2725
break;
2726
2727
DELAY(1000);
2728
}
2729
if (i == NRETRY)
2730
device_printf(sc->sc_dev, "reset rx ring timedout\n");
2731
2732
#undef NRETRY
2733
2734
CSR_WRITE_4(sc, rx_ctrl + BWI_RX32_RINGINFO, 0);
2735
}
2736
2737
static void
2738
bwi_free_txstats32(struct bwi_softc *sc)
2739
{
2740
bwi_reset_rx_ring32(sc, sc->sc_txstats->stats_ctrl_base);
2741
}
2742
2743
static void
2744
bwi_free_rx_ring32(struct bwi_softc *sc)
2745
{
2746
struct bwi_ring_data *rd = &sc->sc_rx_rdata;
2747
struct bwi_rxbuf_data *rbd = &sc->sc_rx_bdata;
2748
int i;
2749
2750
bwi_reset_rx_ring32(sc, rd->rdata_txrx_ctrl);
2751
2752
for (i = 0; i < BWI_RX_NDESC; ++i) {
2753
struct bwi_rxbuf *rb = &rbd->rbd_buf[i];
2754
2755
if (rb->rb_mbuf != NULL) {
2756
bus_dmamap_unload(sc->sc_buf_dtag, rb->rb_dmap);
2757
m_freem(rb->rb_mbuf);
2758
rb->rb_mbuf = NULL;
2759
}
2760
}
2761
}
2762
2763
static void
2764
bwi_free_tx_ring32(struct bwi_softc *sc, int ring_idx)
2765
{
2766
struct bwi_ring_data *rd;
2767
struct bwi_txbuf_data *tbd;
2768
uint32_t state, val;
2769
int i;
2770
2771
KASSERT(ring_idx < BWI_TX_NRING, ("ring_idx %d", ring_idx));
2772
rd = &sc->sc_tx_rdata[ring_idx];
2773
tbd = &sc->sc_tx_bdata[ring_idx];
2774
2775
#define NRETRY 10
2776
2777
for (i = 0; i < NRETRY; ++i) {
2778
val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS);
2779
state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK);
2780
if (state == BWI_TX32_STATUS_STATE_DISABLED ||
2781
state == BWI_TX32_STATUS_STATE_IDLE ||
2782
state == BWI_TX32_STATUS_STATE_STOPPED)
2783
break;
2784
2785
DELAY(1000);
2786
}
2787
if (i == NRETRY) {
2788
device_printf(sc->sc_dev,
2789
"%s: wait for TX ring(%d) stable timed out\n",
2790
__func__, ring_idx);
2791
}
2792
2793
CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_CTRL, 0);
2794
for (i = 0; i < NRETRY; ++i) {
2795
val = CSR_READ_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_STATUS);
2796
state = __SHIFTOUT(val, BWI_TX32_STATUS_STATE_MASK);
2797
if (state == BWI_TX32_STATUS_STATE_DISABLED)
2798
break;
2799
2800
DELAY(1000);
2801
}
2802
if (i == NRETRY)
2803
device_printf(sc->sc_dev, "%s: reset TX ring (%d) timed out\n",
2804
__func__, ring_idx);
2805
2806
#undef NRETRY
2807
2808
DELAY(1000);
2809
2810
CSR_WRITE_4(sc, rd->rdata_txrx_ctrl + BWI_TX32_RINGINFO, 0);
2811
2812
for (i = 0; i < BWI_TX_NDESC; ++i) {
2813
struct bwi_txbuf *tb = &tbd->tbd_buf[i];
2814
2815
if (tb->tb_mbuf != NULL) {
2816
bus_dmamap_unload(sc->sc_buf_dtag, tb->tb_dmap);
2817
m_freem(tb->tb_mbuf);
2818
tb->tb_mbuf = NULL;
2819
}
2820
if (tb->tb_ni != NULL) {
2821
ieee80211_free_node(tb->tb_ni);
2822
tb->tb_ni = NULL;
2823
}
2824
}
2825
}
2826
2827
static void
2828
bwi_free_txstats64(struct bwi_softc *sc)
2829
{
2830
/* TODO:64 */
2831
}
2832
2833
static void
2834
bwi_free_rx_ring64(struct bwi_softc *sc)
2835
{
2836
/* TODO:64 */
2837
}
2838
2839
static void
2840
bwi_free_tx_ring64(struct bwi_softc *sc, int ring_idx)
2841
{
2842
/* TODO:64 */
2843
}
2844
2845
/* XXX does not belong here */
2846
#define IEEE80211_OFDM_PLCP_RATE_MASK __BITS(3, 0)
2847
#define IEEE80211_OFDM_PLCP_LEN_MASK __BITS(16, 5)
2848
2849
static __inline void
2850
bwi_ofdm_plcp_header(uint32_t *plcp0, int pkt_len, uint8_t rate)
2851
{
2852
uint32_t plcp;
2853
2854
plcp = __SHIFTIN(ieee80211_rate2plcp(rate, IEEE80211_T_OFDM),
2855
IEEE80211_OFDM_PLCP_RATE_MASK) |
2856
__SHIFTIN(pkt_len, IEEE80211_OFDM_PLCP_LEN_MASK);
2857
*plcp0 = htole32(plcp);
2858
}
2859
2860
static __inline void
2861
bwi_ds_plcp_header(struct ieee80211_ds_plcp_hdr *plcp, int pkt_len,
2862
uint8_t rate)
2863
{
2864
int len, service, pkt_bitlen;
2865
2866
pkt_bitlen = pkt_len * NBBY;
2867
len = howmany(pkt_bitlen * 2, rate);
2868
2869
service = IEEE80211_PLCP_SERVICE_LOCKED;
2870
if (rate == (11 * 2)) {
2871
int pkt_bitlen1;
2872
2873
/*
2874
* PLCP service field needs to be adjusted,
2875
* if TX rate is 11Mbytes/s
2876
*/
2877
pkt_bitlen1 = len * 11;
2878
if (pkt_bitlen1 - pkt_bitlen >= NBBY)
2879
service |= IEEE80211_PLCP_SERVICE_LENEXT7;
2880
}
2881
2882
plcp->i_signal = ieee80211_rate2plcp(rate, IEEE80211_T_CCK);
2883
plcp->i_service = service;
2884
plcp->i_length = htole16(len);
2885
/* NOTE: do NOT touch i_crc */
2886
}
2887
2888
static __inline void
2889
bwi_plcp_header(const struct ieee80211_rate_table *rt,
2890
void *plcp, int pkt_len, uint8_t rate)
2891
{
2892
enum ieee80211_phytype modtype;
2893
2894
/*
2895
* Assume caller has zeroed 'plcp'
2896
*/
2897
modtype = ieee80211_rate2phytype(rt, rate);
2898
if (modtype == IEEE80211_T_OFDM)
2899
bwi_ofdm_plcp_header(plcp, pkt_len, rate);
2900
else if (modtype == IEEE80211_T_DS)
2901
bwi_ds_plcp_header(plcp, pkt_len, rate);
2902
else
2903
panic("unsupport modulation type %u\n", modtype);
2904
}
2905
2906
static int
2907
bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m,
2908
struct ieee80211_node *ni)
2909
{
2910
struct ieee80211vap *vap = ni->ni_vap;
2911
struct ieee80211com *ic = &sc->sc_ic;
2912
struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING];
2913
struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
2914
struct bwi_txbuf *tb = &tbd->tbd_buf[idx];
2915
struct bwi_mac *mac;
2916
struct bwi_txbuf_hdr *hdr;
2917
struct ieee80211_frame *wh;
2918
const struct ieee80211_txparam *tp = ni->ni_txparms;
2919
uint8_t rate, rate_fb;
2920
uint32_t mac_ctrl;
2921
uint16_t phy_ctrl;
2922
bus_addr_t paddr;
2923
int type, ismcast, pkt_len, error;
2924
#if 0
2925
const uint8_t *p;
2926
int i;
2927
#endif
2928
2929
KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
2930
("current regwin type %d", sc->sc_cur_regwin->rw_type));
2931
mac = (struct bwi_mac *)sc->sc_cur_regwin;
2932
2933
wh = mtod(m, struct ieee80211_frame *);
2934
type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
2935
ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
2936
2937
/* Get 802.11 frame len before prepending TX header */
2938
pkt_len = m->m_pkthdr.len + IEEE80211_CRC_LEN;
2939
2940
/*
2941
* Find TX rate
2942
*/
2943
if (type != IEEE80211_FC0_TYPE_DATA || (m->m_flags & M_EAPOL)) {
2944
rate = rate_fb = tp->mgmtrate;
2945
} else if (ismcast) {
2946
rate = rate_fb = tp->mcastrate;
2947
} else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) {
2948
rate = rate_fb = tp->ucastrate;
2949
} else {
2950
ieee80211_ratectl_rate(ni, NULL, pkt_len);
2951
rate = ieee80211_node_get_txrate_dot11rate(ni);
2952
/* TODO: assign rate_fb the previous rate, if available */
2953
rate_fb = rate;
2954
}
2955
tb->tb_rate[0] = rate;
2956
tb->tb_rate[1] = rate_fb;
2957
sc->sc_tx_rate = rate;
2958
2959
/*
2960
* TX radio tap
2961
*/
2962
if (ieee80211_radiotap_active_vap(vap)) {
2963
sc->sc_tx_th.wt_flags = 0;
2964
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
2965
sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
2966
if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_DS &&
2967
(ic->ic_flags & IEEE80211_F_SHPREAMBLE) &&
2968
rate != (1 * 2)) {
2969
sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
2970
}
2971
sc->sc_tx_th.wt_rate = rate;
2972
2973
ieee80211_radiotap_tx(vap, m);
2974
}
2975
2976
/*
2977
* Setup the embedded TX header
2978
*/
2979
M_PREPEND(m, sizeof(*hdr), M_NOWAIT);
2980
if (m == NULL) {
2981
device_printf(sc->sc_dev, "%s: prepend TX header failed\n",
2982
__func__);
2983
return ENOBUFS;
2984
}
2985
hdr = mtod(m, struct bwi_txbuf_hdr *);
2986
2987
bzero(hdr, sizeof(*hdr));
2988
2989
bcopy(wh->i_fc, hdr->txh_fc, sizeof(hdr->txh_fc));
2990
bcopy(wh->i_addr1, hdr->txh_addr1, sizeof(hdr->txh_addr1));
2991
2992
if (!ismcast) {
2993
uint16_t dur;
2994
2995
dur = ieee80211_ack_duration(sc->sc_rates, rate,
2996
ic->ic_flags & ~IEEE80211_F_SHPREAMBLE);
2997
2998
hdr->txh_fb_duration = htole16(dur);
2999
}
3000
3001
hdr->txh_id = __SHIFTIN(BWI_TX_DATA_RING, BWI_TXH_ID_RING_MASK) |
3002
__SHIFTIN(idx, BWI_TXH_ID_IDX_MASK);
3003
3004
bwi_plcp_header(sc->sc_rates, hdr->txh_plcp, pkt_len, rate);
3005
bwi_plcp_header(sc->sc_rates, hdr->txh_fb_plcp, pkt_len, rate_fb);
3006
3007
phy_ctrl = __SHIFTIN(mac->mac_rf.rf_ant_mode,
3008
BWI_TXH_PHY_C_ANTMODE_MASK);
3009
if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM)
3010
phy_ctrl |= BWI_TXH_PHY_C_OFDM;
3011
else if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && rate != (2 * 1))
3012
phy_ctrl |= BWI_TXH_PHY_C_SHPREAMBLE;
3013
3014
mac_ctrl = BWI_TXH_MAC_C_HWSEQ | BWI_TXH_MAC_C_FIRST_FRAG;
3015
if (!ismcast)
3016
mac_ctrl |= BWI_TXH_MAC_C_ACK;
3017
if (ieee80211_rate2phytype(sc->sc_rates, rate_fb) == IEEE80211_T_OFDM)
3018
mac_ctrl |= BWI_TXH_MAC_C_FB_OFDM;
3019
3020
hdr->txh_mac_ctrl = htole32(mac_ctrl);
3021
hdr->txh_phy_ctrl = htole16(phy_ctrl);
3022
3023
/* Catch any further usage */
3024
hdr = NULL;
3025
wh = NULL;
3026
3027
/* DMA load */
3028
error = bus_dmamap_load_mbuf(sc->sc_buf_dtag, tb->tb_dmap, m,
3029
bwi_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
3030
if (error && error != EFBIG) {
3031
device_printf(sc->sc_dev, "%s: can't load TX buffer (1) %d\n",
3032
__func__, error);
3033
goto back;
3034
}
3035
3036
if (error) { /* error == EFBIG */
3037
struct mbuf *m_new;
3038
3039
m_new = m_defrag(m, M_NOWAIT);
3040
if (m_new == NULL) {
3041
device_printf(sc->sc_dev,
3042
"%s: can't defrag TX buffer\n", __func__);
3043
error = ENOBUFS;
3044
goto back;
3045
} else {
3046
m = m_new;
3047
}
3048
3049
error = bus_dmamap_load_mbuf(sc->sc_buf_dtag, tb->tb_dmap, m,
3050
bwi_dma_buf_addr, &paddr,
3051
BUS_DMA_NOWAIT);
3052
if (error) {
3053
device_printf(sc->sc_dev,
3054
"%s: can't load TX buffer (2) %d\n",
3055
__func__, error);
3056
goto back;
3057
}
3058
}
3059
error = 0;
3060
3061
bus_dmamap_sync(sc->sc_buf_dtag, tb->tb_dmap, BUS_DMASYNC_PREWRITE);
3062
3063
tb->tb_mbuf = m;
3064
tb->tb_ni = ni;
3065
3066
#if 0
3067
p = mtod(m, const uint8_t *);
3068
for (i = 0; i < m->m_pkthdr.len; ++i) {
3069
if (i != 0 && i % 8 == 0)
3070
printf("\n");
3071
printf("%02x ", p[i]);
3072
}
3073
printf("\n");
3074
#endif
3075
DPRINTF(sc, BWI_DBG_TX, "idx %d, pkt_len %d, buflen %d\n",
3076
idx, pkt_len, m->m_pkthdr.len);
3077
3078
/* Setup TX descriptor */
3079
sc->sc_setup_txdesc(sc, rd, idx, paddr, m->m_pkthdr.len);
3080
bus_dmamap_sync(sc->sc_txring_dtag, rd->rdata_dmap,
3081
BUS_DMASYNC_PREWRITE);
3082
3083
/* Kick start */
3084
sc->sc_start_tx(sc, rd->rdata_txrx_ctrl, idx);
3085
3086
back:
3087
if (error)
3088
m_freem(m);
3089
return error;
3090
}
3091
3092
static int
3093
bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m,
3094
struct ieee80211_node *ni, const struct ieee80211_bpf_params *params)
3095
{
3096
struct ieee80211vap *vap = ni->ni_vap;
3097
struct ieee80211com *ic = ni->ni_ic;
3098
struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING];
3099
struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING];
3100
struct bwi_txbuf *tb = &tbd->tbd_buf[idx];
3101
struct bwi_mac *mac;
3102
struct bwi_txbuf_hdr *hdr;
3103
struct ieee80211_frame *wh;
3104
uint8_t rate, rate_fb;
3105
uint32_t mac_ctrl;
3106
uint16_t phy_ctrl;
3107
bus_addr_t paddr;
3108
int ismcast, pkt_len, error;
3109
3110
KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
3111
("current regwin type %d", sc->sc_cur_regwin->rw_type));
3112
mac = (struct bwi_mac *)sc->sc_cur_regwin;
3113
3114
wh = mtod(m, struct ieee80211_frame *);
3115
ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1);
3116
3117
/* Get 802.11 frame len before prepending TX header */
3118
pkt_len = m->m_pkthdr.len + IEEE80211_CRC_LEN;
3119
3120
/*
3121
* Find TX rate
3122
*/
3123
rate = params->ibp_rate0;
3124
if (!ieee80211_isratevalid(ic->ic_rt, rate)) {
3125
/* XXX fall back to mcast/mgmt rate? */
3126
m_freem(m);
3127
return EINVAL;
3128
}
3129
if (params->ibp_try1 != 0) {
3130
rate_fb = params->ibp_rate1;
3131
if (!ieee80211_isratevalid(ic->ic_rt, rate_fb)) {
3132
/* XXX fall back to rate0? */
3133
m_freem(m);
3134
return EINVAL;
3135
}
3136
} else
3137
rate_fb = rate;
3138
tb->tb_rate[0] = rate;
3139
tb->tb_rate[1] = rate_fb;
3140
sc->sc_tx_rate = rate;
3141
3142
/*
3143
* TX radio tap
3144
*/
3145
if (ieee80211_radiotap_active_vap(vap)) {
3146
sc->sc_tx_th.wt_flags = 0;
3147
/* XXX IEEE80211_BPF_CRYPTO */
3148
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
3149
sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP;
3150
if (params->ibp_flags & IEEE80211_BPF_SHORTPRE)
3151
sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
3152
sc->sc_tx_th.wt_rate = rate;
3153
3154
ieee80211_radiotap_tx(vap, m);
3155
}
3156
3157
/*
3158
* Setup the embedded TX header
3159
*/
3160
M_PREPEND(m, sizeof(*hdr), M_NOWAIT);
3161
if (m == NULL) {
3162
device_printf(sc->sc_dev, "%s: prepend TX header failed\n",
3163
__func__);
3164
return ENOBUFS;
3165
}
3166
hdr = mtod(m, struct bwi_txbuf_hdr *);
3167
3168
bzero(hdr, sizeof(*hdr));
3169
3170
bcopy(wh->i_fc, hdr->txh_fc, sizeof(hdr->txh_fc));
3171
bcopy(wh->i_addr1, hdr->txh_addr1, sizeof(hdr->txh_addr1));
3172
3173
mac_ctrl = BWI_TXH_MAC_C_HWSEQ | BWI_TXH_MAC_C_FIRST_FRAG;
3174
if (!ismcast && (params->ibp_flags & IEEE80211_BPF_NOACK) == 0) {
3175
uint16_t dur;
3176
3177
dur = ieee80211_ack_duration(sc->sc_rates, rate_fb, 0);
3178
3179
hdr->txh_fb_duration = htole16(dur);
3180
mac_ctrl |= BWI_TXH_MAC_C_ACK;
3181
}
3182
3183
hdr->txh_id = __SHIFTIN(BWI_TX_DATA_RING, BWI_TXH_ID_RING_MASK) |
3184
__SHIFTIN(idx, BWI_TXH_ID_IDX_MASK);
3185
3186
bwi_plcp_header(sc->sc_rates, hdr->txh_plcp, pkt_len, rate);
3187
bwi_plcp_header(sc->sc_rates, hdr->txh_fb_plcp, pkt_len, rate_fb);
3188
3189
phy_ctrl = __SHIFTIN(mac->mac_rf.rf_ant_mode,
3190
BWI_TXH_PHY_C_ANTMODE_MASK);
3191
if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) {
3192
phy_ctrl |= BWI_TXH_PHY_C_OFDM;
3193
mac_ctrl |= BWI_TXH_MAC_C_FB_OFDM;
3194
} else if (params->ibp_flags & IEEE80211_BPF_SHORTPRE)
3195
phy_ctrl |= BWI_TXH_PHY_C_SHPREAMBLE;
3196
3197
hdr->txh_mac_ctrl = htole32(mac_ctrl);
3198
hdr->txh_phy_ctrl = htole16(phy_ctrl);
3199
3200
/* Catch any further usage */
3201
hdr = NULL;
3202
wh = NULL;
3203
3204
/* DMA load */
3205
error = bus_dmamap_load_mbuf(sc->sc_buf_dtag, tb->tb_dmap, m,
3206
bwi_dma_buf_addr, &paddr, BUS_DMA_NOWAIT);
3207
if (error != 0) {
3208
struct mbuf *m_new;
3209
3210
if (error != EFBIG) {
3211
device_printf(sc->sc_dev,
3212
"%s: can't load TX buffer (1) %d\n",
3213
__func__, error);
3214
goto back;
3215
}
3216
m_new = m_defrag(m, M_NOWAIT);
3217
if (m_new == NULL) {
3218
device_printf(sc->sc_dev,
3219
"%s: can't defrag TX buffer\n", __func__);
3220
error = ENOBUFS;
3221
goto back;
3222
}
3223
m = m_new;
3224
error = bus_dmamap_load_mbuf(sc->sc_buf_dtag, tb->tb_dmap, m,
3225
bwi_dma_buf_addr, &paddr,
3226
BUS_DMA_NOWAIT);
3227
if (error) {
3228
device_printf(sc->sc_dev,
3229
"%s: can't load TX buffer (2) %d\n",
3230
__func__, error);
3231
goto back;
3232
}
3233
}
3234
3235
bus_dmamap_sync(sc->sc_buf_dtag, tb->tb_dmap, BUS_DMASYNC_PREWRITE);
3236
3237
tb->tb_mbuf = m;
3238
tb->tb_ni = ni;
3239
3240
DPRINTF(sc, BWI_DBG_TX, "idx %d, pkt_len %d, buflen %d\n",
3241
idx, pkt_len, m->m_pkthdr.len);
3242
3243
/* Setup TX descriptor */
3244
sc->sc_setup_txdesc(sc, rd, idx, paddr, m->m_pkthdr.len);
3245
bus_dmamap_sync(sc->sc_txring_dtag, rd->rdata_dmap,
3246
BUS_DMASYNC_PREWRITE);
3247
3248
/* Kick start */
3249
sc->sc_start_tx(sc, rd->rdata_txrx_ctrl, idx);
3250
back:
3251
if (error)
3252
m_freem(m);
3253
return error;
3254
}
3255
3256
static void
3257
bwi_start_tx32(struct bwi_softc *sc, uint32_t tx_ctrl, int idx)
3258
{
3259
idx = (idx + 1) % BWI_TX_NDESC;
3260
CSR_WRITE_4(sc, tx_ctrl + BWI_TX32_INDEX,
3261
idx * sizeof(struct bwi_desc32));
3262
}
3263
3264
static void
3265
bwi_start_tx64(struct bwi_softc *sc, uint32_t tx_ctrl, int idx)
3266
{
3267
/* TODO:64 */
3268
}
3269
3270
static void
3271
bwi_txeof_status32(struct bwi_softc *sc)
3272
{
3273
uint32_t val, ctrl_base;
3274
int end_idx;
3275
3276
ctrl_base = sc->sc_txstats->stats_ctrl_base;
3277
3278
val = CSR_READ_4(sc, ctrl_base + BWI_RX32_STATUS);
3279
end_idx = __SHIFTOUT(val, BWI_RX32_STATUS_INDEX_MASK) /
3280
sizeof(struct bwi_desc32);
3281
3282
bwi_txeof_status(sc, end_idx);
3283
3284
CSR_WRITE_4(sc, ctrl_base + BWI_RX32_INDEX,
3285
end_idx * sizeof(struct bwi_desc32));
3286
3287
bwi_start_locked(sc);
3288
}
3289
3290
static void
3291
bwi_txeof_status64(struct bwi_softc *sc)
3292
{
3293
/* TODO:64 */
3294
}
3295
3296
static void
3297
_bwi_txeof(struct bwi_softc *sc, uint16_t tx_id, int acked, int data_txcnt)
3298
{
3299
struct bwi_txbuf_data *tbd;
3300
struct bwi_txbuf *tb;
3301
int ring_idx, buf_idx;
3302
struct ieee80211_node *ni;
3303
3304
if (tx_id == 0) {
3305
device_printf(sc->sc_dev, "%s: zero tx id\n", __func__);
3306
return;
3307
}
3308
3309
ring_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_RING_MASK);
3310
buf_idx = __SHIFTOUT(tx_id, BWI_TXH_ID_IDX_MASK);
3311
3312
KASSERT(ring_idx == BWI_TX_DATA_RING, ("ring_idx %d", ring_idx));
3313
KASSERT(buf_idx < BWI_TX_NDESC, ("buf_idx %d", buf_idx));
3314
3315
tbd = &sc->sc_tx_bdata[ring_idx];
3316
KASSERT(tbd->tbd_used > 0, ("tbd_used %d", tbd->tbd_used));
3317
tbd->tbd_used--;
3318
3319
tb = &tbd->tbd_buf[buf_idx];
3320
DPRINTF(sc, BWI_DBG_TXEOF, "txeof idx %d, "
3321
"acked %d, data_txcnt %d, ni %p\n",
3322
buf_idx, acked, data_txcnt, tb->tb_ni);
3323
3324
bus_dmamap_unload(sc->sc_buf_dtag, tb->tb_dmap);
3325
3326
if ((ni = tb->tb_ni) != NULL) {
3327
const struct bwi_txbuf_hdr *hdr =
3328
mtod(tb->tb_mbuf, const struct bwi_txbuf_hdr *);
3329
struct ieee80211_ratectl_tx_status txs;
3330
3331
/* NB: update rate control only for unicast frames */
3332
if (hdr->txh_mac_ctrl & htole32(BWI_TXH_MAC_C_ACK)) {
3333
/*
3334
* Feed back 'acked and data_txcnt'. Note that the
3335
* generic AMRR code only understands one tx rate
3336
* and the estimator doesn't handle real retry counts
3337
* well so to avoid over-aggressive downshifting we
3338
* treat any number of retries as "1".
3339
*/
3340
txs.flags = IEEE80211_RATECTL_STATUS_LONG_RETRY;
3341
txs.long_retries = acked;
3342
if (data_txcnt > 1)
3343
txs.status = IEEE80211_RATECTL_TX_SUCCESS;
3344
else {
3345
txs.status =
3346
IEEE80211_RATECTL_TX_FAIL_UNSPECIFIED;
3347
}
3348
ieee80211_ratectl_tx_complete(ni, &txs);
3349
}
3350
ieee80211_tx_complete(ni, tb->tb_mbuf, !acked);
3351
tb->tb_ni = NULL;
3352
} else
3353
m_freem(tb->tb_mbuf);
3354
tb->tb_mbuf = NULL;
3355
3356
if (tbd->tbd_used == 0)
3357
sc->sc_tx_timer = 0;
3358
}
3359
3360
static void
3361
bwi_txeof_status(struct bwi_softc *sc, int end_idx)
3362
{
3363
struct bwi_txstats_data *st = sc->sc_txstats;
3364
int idx;
3365
3366
bus_dmamap_sync(st->stats_dtag, st->stats_dmap, BUS_DMASYNC_POSTREAD);
3367
3368
idx = st->stats_idx;
3369
while (idx != end_idx) {
3370
const struct bwi_txstats *stats = &st->stats[idx];
3371
3372
if ((stats->txs_flags & BWI_TXS_F_PENDING) == 0) {
3373
int data_txcnt;
3374
3375
data_txcnt = __SHIFTOUT(stats->txs_txcnt,
3376
BWI_TXS_TXCNT_DATA);
3377
_bwi_txeof(sc, le16toh(stats->txs_id),
3378
stats->txs_flags & BWI_TXS_F_ACKED,
3379
data_txcnt);
3380
}
3381
idx = (idx + 1) % BWI_TXSTATS_NDESC;
3382
}
3383
st->stats_idx = idx;
3384
}
3385
3386
static void
3387
bwi_txeof(struct bwi_softc *sc)
3388
{
3389
3390
for (;;) {
3391
uint32_t tx_status0, tx_status1 __unused;
3392
uint16_t tx_id;
3393
int data_txcnt;
3394
3395
tx_status0 = CSR_READ_4(sc, BWI_TXSTATUS0);
3396
if ((tx_status0 & BWI_TXSTATUS0_VALID) == 0)
3397
break;
3398
tx_status1 = CSR_READ_4(sc, BWI_TXSTATUS1);
3399
3400
tx_id = __SHIFTOUT(tx_status0, BWI_TXSTATUS0_TXID_MASK);
3401
data_txcnt = __SHIFTOUT(tx_status0,
3402
BWI_TXSTATUS0_DATA_TXCNT_MASK);
3403
3404
if (tx_status0 & (BWI_TXSTATUS0_AMPDU | BWI_TXSTATUS0_PENDING))
3405
continue;
3406
3407
_bwi_txeof(sc, le16toh(tx_id), tx_status0 & BWI_TXSTATUS0_ACKED,
3408
data_txcnt);
3409
}
3410
3411
bwi_start_locked(sc);
3412
}
3413
3414
static int
3415
bwi_bbp_power_on(struct bwi_softc *sc, enum bwi_clock_mode clk_mode)
3416
{
3417
bwi_power_on(sc, 1);
3418
return bwi_set_clock_mode(sc, clk_mode);
3419
}
3420
3421
static void
3422
bwi_bbp_power_off(struct bwi_softc *sc)
3423
{
3424
bwi_set_clock_mode(sc, BWI_CLOCK_MODE_SLOW);
3425
bwi_power_off(sc, 1);
3426
}
3427
3428
static int
3429
bwi_get_pwron_delay(struct bwi_softc *sc)
3430
{
3431
struct bwi_regwin *com, *old;
3432
struct bwi_clock_freq freq;
3433
uint32_t val;
3434
int error;
3435
3436
com = &sc->sc_com_regwin;
3437
KASSERT(BWI_REGWIN_EXIST(com), ("no regwin"));
3438
3439
if ((sc->sc_cap & BWI_CAP_CLKMODE) == 0)
3440
return 0;
3441
3442
error = bwi_regwin_switch(sc, com, &old);
3443
if (error)
3444
return error;
3445
3446
bwi_get_clock_freq(sc, &freq);
3447
3448
val = CSR_READ_4(sc, BWI_PLL_ON_DELAY);
3449
sc->sc_pwron_delay = howmany((val + 2) * 1000000, freq.clkfreq_min);
3450
DPRINTF(sc, BWI_DBG_ATTACH, "power on delay %u\n", sc->sc_pwron_delay);
3451
3452
return bwi_regwin_switch(sc, old, NULL);
3453
}
3454
3455
static int
3456
bwi_bus_attach(struct bwi_softc *sc)
3457
{
3458
struct bwi_regwin *bus, *old;
3459
int error;
3460
3461
bus = &sc->sc_bus_regwin;
3462
3463
error = bwi_regwin_switch(sc, bus, &old);
3464
if (error)
3465
return error;
3466
3467
if (!bwi_regwin_is_enabled(sc, bus))
3468
bwi_regwin_enable(sc, bus, 0);
3469
3470
/* Disable interripts */
3471
CSR_WRITE_4(sc, BWI_INTRVEC, 0);
3472
3473
return bwi_regwin_switch(sc, old, NULL);
3474
}
3475
3476
static const char *
3477
bwi_regwin_name(const struct bwi_regwin *rw)
3478
{
3479
switch (rw->rw_type) {
3480
case BWI_REGWIN_T_COM:
3481
return "COM";
3482
case BWI_REGWIN_T_BUSPCI:
3483
return "PCI";
3484
case BWI_REGWIN_T_MAC:
3485
return "MAC";
3486
case BWI_REGWIN_T_BUSPCIE:
3487
return "PCIE";
3488
}
3489
panic("unknown regwin type 0x%04x\n", rw->rw_type);
3490
return NULL;
3491
}
3492
3493
static uint32_t
3494
bwi_regwin_disable_bits(struct bwi_softc *sc)
3495
{
3496
uint32_t busrev;
3497
3498
/* XXX cache this */
3499
busrev = __SHIFTOUT(CSR_READ_4(sc, BWI_ID_LO), BWI_ID_LO_BUSREV_MASK);
3500
DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT | BWI_DBG_MISC,
3501
"bus rev %u\n", busrev);
3502
3503
if (busrev == BWI_BUSREV_0)
3504
return BWI_STATE_LO_DISABLE1;
3505
else if (busrev == BWI_BUSREV_1)
3506
return BWI_STATE_LO_DISABLE2;
3507
else
3508
return (BWI_STATE_LO_DISABLE1 | BWI_STATE_LO_DISABLE2);
3509
}
3510
3511
int
3512
bwi_regwin_is_enabled(struct bwi_softc *sc, struct bwi_regwin *rw)
3513
{
3514
uint32_t val, disable_bits;
3515
3516
disable_bits = bwi_regwin_disable_bits(sc);
3517
val = CSR_READ_4(sc, BWI_STATE_LO);
3518
3519
if ((val & (BWI_STATE_LO_CLOCK |
3520
BWI_STATE_LO_RESET |
3521
disable_bits)) == BWI_STATE_LO_CLOCK) {
3522
DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT, "%s is enabled\n",
3523
bwi_regwin_name(rw));
3524
return 1;
3525
} else {
3526
DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT, "%s is disabled\n",
3527
bwi_regwin_name(rw));
3528
return 0;
3529
}
3530
}
3531
3532
void
3533
bwi_regwin_disable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags)
3534
{
3535
uint32_t state_lo, disable_bits;
3536
int i;
3537
3538
state_lo = CSR_READ_4(sc, BWI_STATE_LO);
3539
3540
/*
3541
* If current regwin is in 'reset' state, it was already disabled.
3542
*/
3543
if (state_lo & BWI_STATE_LO_RESET) {
3544
DPRINTF(sc, BWI_DBG_ATTACH | BWI_DBG_INIT,
3545
"%s was already disabled\n", bwi_regwin_name(rw));
3546
return;
3547
}
3548
3549
disable_bits = bwi_regwin_disable_bits(sc);
3550
3551
/*
3552
* Disable normal clock
3553
*/
3554
state_lo = BWI_STATE_LO_CLOCK | disable_bits;
3555
CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
3556
3557
/*
3558
* Wait until normal clock is disabled
3559
*/
3560
#define NRETRY 1000
3561
for (i = 0; i < NRETRY; ++i) {
3562
state_lo = CSR_READ_4(sc, BWI_STATE_LO);
3563
if (state_lo & disable_bits)
3564
break;
3565
DELAY(10);
3566
}
3567
if (i == NRETRY) {
3568
device_printf(sc->sc_dev, "%s disable clock timeout\n",
3569
bwi_regwin_name(rw));
3570
}
3571
3572
for (i = 0; i < NRETRY; ++i) {
3573
uint32_t state_hi;
3574
3575
state_hi = CSR_READ_4(sc, BWI_STATE_HI);
3576
if ((state_hi & BWI_STATE_HI_BUSY) == 0)
3577
break;
3578
DELAY(10);
3579
}
3580
if (i == NRETRY) {
3581
device_printf(sc->sc_dev, "%s wait BUSY unset timeout\n",
3582
bwi_regwin_name(rw));
3583
}
3584
#undef NRETRY
3585
3586
/*
3587
* Reset and disable regwin with gated clock
3588
*/
3589
state_lo = BWI_STATE_LO_RESET | disable_bits |
3590
BWI_STATE_LO_CLOCK | BWI_STATE_LO_GATED_CLOCK |
3591
__SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
3592
CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
3593
3594
/* Flush pending bus write */
3595
CSR_READ_4(sc, BWI_STATE_LO);
3596
DELAY(1);
3597
3598
/* Reset and disable regwin */
3599
state_lo = BWI_STATE_LO_RESET | disable_bits |
3600
__SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
3601
CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
3602
3603
/* Flush pending bus write */
3604
CSR_READ_4(sc, BWI_STATE_LO);
3605
DELAY(1);
3606
}
3607
3608
void
3609
bwi_regwin_enable(struct bwi_softc *sc, struct bwi_regwin *rw, uint32_t flags)
3610
{
3611
uint32_t state_lo, state_hi, imstate;
3612
3613
bwi_regwin_disable(sc, rw, flags);
3614
3615
/* Reset regwin with gated clock */
3616
state_lo = BWI_STATE_LO_RESET |
3617
BWI_STATE_LO_CLOCK |
3618
BWI_STATE_LO_GATED_CLOCK |
3619
__SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
3620
CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
3621
3622
/* Flush pending bus write */
3623
CSR_READ_4(sc, BWI_STATE_LO);
3624
DELAY(1);
3625
3626
state_hi = CSR_READ_4(sc, BWI_STATE_HI);
3627
if (state_hi & BWI_STATE_HI_SERROR)
3628
CSR_WRITE_4(sc, BWI_STATE_HI, 0);
3629
3630
imstate = CSR_READ_4(sc, BWI_IMSTATE);
3631
if (imstate & (BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT)) {
3632
imstate &= ~(BWI_IMSTATE_INBAND_ERR | BWI_IMSTATE_TIMEOUT);
3633
CSR_WRITE_4(sc, BWI_IMSTATE, imstate);
3634
}
3635
3636
/* Enable regwin with gated clock */
3637
state_lo = BWI_STATE_LO_CLOCK |
3638
BWI_STATE_LO_GATED_CLOCK |
3639
__SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
3640
CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
3641
3642
/* Flush pending bus write */
3643
CSR_READ_4(sc, BWI_STATE_LO);
3644
DELAY(1);
3645
3646
/* Enable regwin with normal clock */
3647
state_lo = BWI_STATE_LO_CLOCK |
3648
__SHIFTIN(flags, BWI_STATE_LO_FLAGS_MASK);
3649
CSR_WRITE_4(sc, BWI_STATE_LO, state_lo);
3650
3651
/* Flush pending bus write */
3652
CSR_READ_4(sc, BWI_STATE_LO);
3653
DELAY(1);
3654
}
3655
3656
static void
3657
bwi_set_bssid(struct bwi_softc *sc, const uint8_t *bssid)
3658
{
3659
struct bwi_mac *mac;
3660
struct bwi_myaddr_bssid buf;
3661
const uint8_t *p;
3662
uint32_t val;
3663
int n, i;
3664
3665
KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
3666
("current regwin type %d", sc->sc_cur_regwin->rw_type));
3667
mac = (struct bwi_mac *)sc->sc_cur_regwin;
3668
3669
bwi_set_addr_filter(sc, BWI_ADDR_FILTER_BSSID, bssid);
3670
3671
bcopy(sc->sc_ic.ic_macaddr, buf.myaddr, sizeof(buf.myaddr));
3672
bcopy(bssid, buf.bssid, sizeof(buf.bssid));
3673
3674
n = sizeof(buf) / sizeof(val);
3675
p = (const uint8_t *)&buf;
3676
for (i = 0; i < n; ++i) {
3677
int j;
3678
3679
val = 0;
3680
for (j = 0; j < sizeof(val); ++j)
3681
val |= ((uint32_t)(*p++)) << (j * 8);
3682
3683
TMPLT_WRITE_4(mac, 0x20 + (i * sizeof(val)), val);
3684
}
3685
}
3686
3687
static void
3688
bwi_updateslot(struct ieee80211com *ic)
3689
{
3690
struct bwi_softc *sc = ic->ic_softc;
3691
struct bwi_mac *mac;
3692
3693
BWI_LOCK(sc);
3694
if (sc->sc_flags & BWI_F_RUNNING) {
3695
DPRINTF(sc, BWI_DBG_80211, "%s\n", __func__);
3696
3697
KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
3698
("current regwin type %d", sc->sc_cur_regwin->rw_type));
3699
mac = (struct bwi_mac *)sc->sc_cur_regwin;
3700
3701
bwi_mac_updateslot(mac, (ic->ic_flags & IEEE80211_F_SHSLOT));
3702
}
3703
BWI_UNLOCK(sc);
3704
}
3705
3706
static void
3707
bwi_calibrate(void *xsc)
3708
{
3709
struct bwi_softc *sc = xsc;
3710
struct bwi_mac *mac;
3711
3712
BWI_ASSERT_LOCKED(sc);
3713
3714
KASSERT(sc->sc_ic.ic_opmode != IEEE80211_M_MONITOR,
3715
("opmode %d", sc->sc_ic.ic_opmode));
3716
3717
KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
3718
("current regwin type %d", sc->sc_cur_regwin->rw_type));
3719
mac = (struct bwi_mac *)sc->sc_cur_regwin;
3720
3721
bwi_mac_calibrate_txpower(mac, sc->sc_txpwrcb_type);
3722
sc->sc_txpwrcb_type = BWI_TXPWR_CALIB;
3723
3724
/* XXX 15 seconds */
3725
callout_reset(&sc->sc_calib_ch, hz * 15, bwi_calibrate, sc);
3726
}
3727
3728
static int
3729
bwi_calc_rssi(struct bwi_softc *sc, const struct bwi_rxbuf_hdr *hdr)
3730
{
3731
struct bwi_mac *mac;
3732
3733
KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
3734
("current regwin type %d", sc->sc_cur_regwin->rw_type));
3735
mac = (struct bwi_mac *)sc->sc_cur_regwin;
3736
3737
return bwi_rf_calc_rssi(mac, hdr);
3738
}
3739
3740
static int
3741
bwi_calc_noise(struct bwi_softc *sc)
3742
{
3743
struct bwi_mac *mac;
3744
3745
KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC,
3746
("current regwin type %d", sc->sc_cur_regwin->rw_type));
3747
mac = (struct bwi_mac *)sc->sc_cur_regwin;
3748
3749
return bwi_rf_calc_noise(mac);
3750
}
3751
3752
static __inline uint8_t
3753
bwi_plcp2rate(const uint32_t plcp0, enum ieee80211_phytype type)
3754
{
3755
uint32_t plcp = le32toh(plcp0) & IEEE80211_OFDM_PLCP_RATE_MASK;
3756
return (ieee80211_plcp2rate(plcp, type));
3757
}
3758
3759
static void
3760
bwi_rx_radiotap(struct bwi_softc *sc, struct mbuf *m,
3761
struct bwi_rxbuf_hdr *hdr, const void *plcp, int rate, int rssi, int noise)
3762
{
3763
const struct ieee80211_frame_min *wh;
3764
3765
sc->sc_rx_th.wr_flags = IEEE80211_RADIOTAP_F_FCS;
3766
if (htole16(hdr->rxh_flags1) & BWI_RXH_F1_SHPREAMBLE)
3767
sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
3768
3769
wh = mtod(m, const struct ieee80211_frame_min *);
3770
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED)
3771
sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP;
3772
3773
sc->sc_rx_th.wr_tsf = hdr->rxh_tsf; /* No endian conversion */
3774
sc->sc_rx_th.wr_rate = rate;
3775
sc->sc_rx_th.wr_antsignal = rssi;
3776
sc->sc_rx_th.wr_antnoise = noise;
3777
}
3778
3779
static void
3780
bwi_led_attach(struct bwi_softc *sc)
3781
{
3782
const uint8_t *led_act = NULL;
3783
uint16_t gpio, val[BWI_LED_MAX];
3784
int i;
3785
3786
for (i = 0; i < nitems(bwi_vendor_led_act); ++i) {
3787
if (sc->sc_pci_subvid == bwi_vendor_led_act[i].vid) {
3788
led_act = bwi_vendor_led_act[i].led_act;
3789
break;
3790
}
3791
}
3792
if (led_act == NULL)
3793
led_act = bwi_default_led_act;
3794
3795
gpio = bwi_read_sprom(sc, BWI_SPROM_GPIO01);
3796
val[0] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_0);
3797
val[1] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_1);
3798
3799
gpio = bwi_read_sprom(sc, BWI_SPROM_GPIO23);
3800
val[2] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_2);
3801
val[3] = __SHIFTOUT(gpio, BWI_SPROM_GPIO_3);
3802
3803
for (i = 0; i < BWI_LED_MAX; ++i) {
3804
struct bwi_led *led = &sc->sc_leds[i];
3805
3806
if (val[i] == 0xff) {
3807
led->l_act = led_act[i];
3808
} else {
3809
if (val[i] & BWI_LED_ACT_LOW)
3810
led->l_flags |= BWI_LED_F_ACTLOW;
3811
led->l_act = __SHIFTOUT(val[i], BWI_LED_ACT_MASK);
3812
}
3813
led->l_mask = (1 << i);
3814
3815
if (led->l_act == BWI_LED_ACT_BLINK_SLOW ||
3816
led->l_act == BWI_LED_ACT_BLINK_POLL ||
3817
led->l_act == BWI_LED_ACT_BLINK) {
3818
led->l_flags |= BWI_LED_F_BLINK;
3819
if (led->l_act == BWI_LED_ACT_BLINK_POLL)
3820
led->l_flags |= BWI_LED_F_POLLABLE;
3821
else if (led->l_act == BWI_LED_ACT_BLINK_SLOW)
3822
led->l_flags |= BWI_LED_F_SLOW;
3823
3824
if (sc->sc_blink_led == NULL) {
3825
sc->sc_blink_led = led;
3826
if (led->l_flags & BWI_LED_F_SLOW)
3827
BWI_LED_SLOWDOWN(sc->sc_led_idle);
3828
}
3829
}
3830
3831
DPRINTF(sc, BWI_DBG_LED | BWI_DBG_ATTACH,
3832
"%dth led, act %d, lowact %d\n", i,
3833
led->l_act, led->l_flags & BWI_LED_F_ACTLOW);
3834
}
3835
callout_init_mtx(&sc->sc_led_blink_ch, &sc->sc_mtx, 0);
3836
}
3837
3838
static __inline uint16_t
3839
bwi_led_onoff(const struct bwi_led *led, uint16_t val, int on)
3840
{
3841
if (led->l_flags & BWI_LED_F_ACTLOW)
3842
on = !on;
3843
if (on)
3844
val |= led->l_mask;
3845
else
3846
val &= ~led->l_mask;
3847
return val;
3848
}
3849
3850
static void
3851
bwi_led_newstate(struct bwi_softc *sc, enum ieee80211_state nstate)
3852
{
3853
struct ieee80211com *ic = &sc->sc_ic;
3854
uint16_t val;
3855
int i;
3856
3857
if (nstate == IEEE80211_S_INIT) {
3858
callout_stop(&sc->sc_led_blink_ch);
3859
sc->sc_led_blinking = 0;
3860
}
3861
3862
if ((sc->sc_flags & BWI_F_RUNNING) == 0)
3863
return;
3864
3865
val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL);
3866
for (i = 0; i < BWI_LED_MAX; ++i) {
3867
struct bwi_led *led = &sc->sc_leds[i];
3868
int on;
3869
3870
if (led->l_act == BWI_LED_ACT_UNKN ||
3871
led->l_act == BWI_LED_ACT_NULL)
3872
continue;
3873
3874
if ((led->l_flags & BWI_LED_F_BLINK) &&
3875
nstate != IEEE80211_S_INIT)
3876
continue;
3877
3878
switch (led->l_act) {
3879
case BWI_LED_ACT_ON: /* Always on */
3880
on = 1;
3881
break;
3882
case BWI_LED_ACT_OFF: /* Always off */
3883
case BWI_LED_ACT_5GHZ: /* TODO: 11A */
3884
on = 0;
3885
break;
3886
default:
3887
on = 1;
3888
switch (nstate) {
3889
case IEEE80211_S_INIT:
3890
on = 0;
3891
break;
3892
case IEEE80211_S_RUN:
3893
if (led->l_act == BWI_LED_ACT_11G &&
3894
ic->ic_curmode != IEEE80211_MODE_11G)
3895
on = 0;
3896
break;
3897
default:
3898
if (led->l_act == BWI_LED_ACT_ASSOC)
3899
on = 0;
3900
break;
3901
}
3902
break;
3903
}
3904
3905
val = bwi_led_onoff(led, val, on);
3906
}
3907
CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val);
3908
}
3909
static void
3910
bwi_led_event(struct bwi_softc *sc, int event)
3911
{
3912
struct bwi_led *led = sc->sc_blink_led;
3913
int rate;
3914
3915
if (event == BWI_LED_EVENT_POLL) {
3916
if ((led->l_flags & BWI_LED_F_POLLABLE) == 0)
3917
return;
3918
if (ticks - sc->sc_led_ticks < sc->sc_led_idle)
3919
return;
3920
}
3921
3922
sc->sc_led_ticks = ticks;
3923
if (sc->sc_led_blinking)
3924
return;
3925
3926
switch (event) {
3927
case BWI_LED_EVENT_RX:
3928
rate = sc->sc_rx_rate;
3929
break;
3930
case BWI_LED_EVENT_TX:
3931
rate = sc->sc_tx_rate;
3932
break;
3933
case BWI_LED_EVENT_POLL:
3934
rate = 0;
3935
break;
3936
default:
3937
panic("unknown LED event %d\n", event);
3938
break;
3939
}
3940
bwi_led_blink_start(sc, bwi_led_duration[rate].on_dur,
3941
bwi_led_duration[rate].off_dur);
3942
}
3943
3944
static void
3945
bwi_led_blink_start(struct bwi_softc *sc, int on_dur, int off_dur)
3946
{
3947
struct bwi_led *led = sc->sc_blink_led;
3948
uint16_t val;
3949
3950
val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL);
3951
val = bwi_led_onoff(led, val, 1);
3952
CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val);
3953
3954
if (led->l_flags & BWI_LED_F_SLOW) {
3955
BWI_LED_SLOWDOWN(on_dur);
3956
BWI_LED_SLOWDOWN(off_dur);
3957
}
3958
3959
sc->sc_led_blinking = 1;
3960
sc->sc_led_blink_offdur = off_dur;
3961
3962
callout_reset(&sc->sc_led_blink_ch, on_dur, bwi_led_blink_next, sc);
3963
}
3964
3965
static void
3966
bwi_led_blink_next(void *xsc)
3967
{
3968
struct bwi_softc *sc = xsc;
3969
uint16_t val;
3970
3971
val = CSR_READ_2(sc, BWI_MAC_GPIO_CTRL);
3972
val = bwi_led_onoff(sc->sc_blink_led, val, 0);
3973
CSR_WRITE_2(sc, BWI_MAC_GPIO_CTRL, val);
3974
3975
callout_reset(&sc->sc_led_blink_ch, sc->sc_led_blink_offdur,
3976
bwi_led_blink_end, sc);
3977
}
3978
3979
static void
3980
bwi_led_blink_end(void *xsc)
3981
{
3982
struct bwi_softc *sc = xsc;
3983
sc->sc_led_blinking = 0;
3984
}
3985
3986
static void
3987
bwi_restart(void *xsc, int pending)
3988
{
3989
struct bwi_softc *sc = xsc;
3990
3991
device_printf(sc->sc_dev, "%s begin, help!\n", __func__);
3992
BWI_LOCK(sc);
3993
bwi_init_statechg(sc, 0);
3994
#if 0
3995
bwi_start_locked(sc);
3996
#endif
3997
BWI_UNLOCK(sc);
3998
}
3999
4000