Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/bwn/if_bwnvar.h
39507 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2009-2010 Weongyo Jeong <[email protected]>
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer,
12
* without modification.
13
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
14
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
15
* redistribution must be conditioned upon including a substantially
16
* similar Disclaimer requirement for further binary redistribution.
17
*
18
* NO WARRANTY
19
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
22
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
24
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
29
* THE POSSIBILITY OF SUCH DAMAGES.
30
*/
31
32
#ifndef _IF_BWNVAR_H
33
#define _IF_BWNVAR_H
34
35
#include <dev/bhnd/bhnd.h>
36
37
struct bwn_softc;
38
struct bwn_mac;
39
40
#define N(a) (sizeof(a) / sizeof(a[0]))
41
#define BWN_ALIGN 0x1000
42
#define BWN_RETRY_SHORT 7
43
#define BWN_RETRY_LONG 4
44
#define BWN_STAID_MAX 64
45
#define BWN_TXPWR_IGNORE_TIME (1 << 0)
46
#define BWN_TXPWR_IGNORE_TSSI (1 << 1)
47
#define BWN_HAS_TXMAG(phy) \
48
(((phy)->rev >= 2) && ((phy)->rf_ver == 0x2050) && \
49
((phy)->rf_rev == 8))
50
#define BWN_HAS_LOOPBACK(phy) \
51
(((phy)->rev > 1) || ((phy)->gmode))
52
#define BWN_TXERROR_MAX 1000
53
#define BWN_GETTIME(v) do { \
54
struct timespec ts; \
55
nanouptime(&ts); \
56
(v) = ts.tv_nsec / 1000000 + ts.tv_sec * 1000; \
57
} while (0)
58
#define BWN_ISOLDFMT(mac) ((mac)->mac_fw.rev <= 351)
59
#define BWN_TSSI2DBM(num, den) \
60
((int32_t)((num < 0) ? num / den : (num + den / 2) / den))
61
#define BWN_HDRSIZE(mac) bwn_tx_hdrsize(mac)
62
#define BWN_MAXTXHDRSIZE (112 + (sizeof(struct bwn_plcp6)))
63
64
#define BWN_PIO_COOKIE(tq, tp) \
65
((uint16_t)((((uint16_t)tq->tq_index + 1) << 12) | tp->tp_index))
66
#define BWN_DMA_COOKIE(dr, slot) \
67
((uint16_t)(((uint16_t)dr->dr_index + 1) << 12) | (uint16_t)slot)
68
#define BWN_READ_2(mac, o) \
69
(bus_read_2((mac)->mac_sc->sc_mem_res, (o)))
70
#define BWN_READ_4(mac, o) \
71
(bus_read_4((mac)->mac_sc->sc_mem_res, (o)))
72
#define BWN_WRITE_2(mac, o, v) \
73
(bus_write_2((mac)->mac_sc->sc_mem_res, (o), (v)))
74
#define BWN_WRITE_2_F(mac, o, v) do { \
75
(BWN_WRITE_2(mac, o, v)); \
76
BWN_READ_2(mac, o); \
77
} while(0)
78
#define BWN_WRITE_SETMASK2(mac, offset, mask, set) \
79
BWN_WRITE_2(mac, offset, (BWN_READ_2(mac, offset) & mask) | set)
80
#define BWN_WRITE_4(mac, o, v) \
81
(bus_write_4((mac)->mac_sc->sc_mem_res, (o), (v)))
82
#define BWN_WRITE_SETMASK4(mac, offset, mask, set) \
83
BWN_WRITE_4(mac, offset, (BWN_READ_4(mac, offset) & mask) | set)
84
#define BWN_PIO_TXQOFFSET(mac) \
85
((bhnd_get_hwrev(mac->mac_sc->sc_dev) >= 11) ? 0x18 : 0)
86
#define BWN_PIO_RXQOFFSET(mac) \
87
((bhnd_get_hwrev(mac->mac_sc->sc_dev) >= 11) ? 0x38 : 8)
88
#define BWN_SEC_NEWAPI(mac) (mac->mac_fw.rev >= 351)
89
#define BWN_SEC_KEY2FW(mac, idx) \
90
(BWN_SEC_NEWAPI(mac) ? idx : ((idx >= 4) ? idx - 4 : idx))
91
#define BWN_RF_READ(mac, r) (mac->mac_phy.rf_read(mac, r))
92
#define BWN_RF_WRITE(mac, r, v) (mac->mac_phy.rf_write(mac, r, v))
93
#define BWN_RF_MASK(mac, o, m) \
94
BWN_RF_WRITE(mac, o, BWN_RF_READ(mac, o) & m)
95
#define BWN_RF_SETMASK(mac, offset, mask, set) \
96
BWN_RF_WRITE(mac, offset, (BWN_RF_READ(mac, offset) & mask) | set)
97
#define BWN_RF_SET(mac, offset, set) \
98
BWN_RF_WRITE(mac, offset, BWN_RF_READ(mac, offset) | set)
99
#define BWN_PHY_READ(mac, r) (mac->mac_phy.phy_read(mac, r))
100
#define BWN_PHY_WRITE(mac, r, v) \
101
(mac->mac_phy.phy_write(mac, r, v))
102
#define BWN_PHY_SET(mac, offset, set) do { \
103
if (mac->mac_phy.phy_maskset != NULL) { \
104
KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED || \
105
mac->mac_suspended > 0, \
106
("dont access PHY or RF registers after turning on MAC")); \
107
mac->mac_phy.phy_maskset(mac, offset, 0xffff, set); \
108
} else \
109
BWN_PHY_WRITE(mac, offset, \
110
BWN_PHY_READ(mac, offset) | (set)); \
111
} while (0)
112
#define BWN_PHY_SETMASK(mac, offset, mask, set) do { \
113
if (mac->mac_phy.phy_maskset != NULL) { \
114
KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED || \
115
mac->mac_suspended > 0, \
116
("dont access PHY or RF registers after turning on MAC")); \
117
mac->mac_phy.phy_maskset(mac, offset, mask, set); \
118
} else \
119
BWN_PHY_WRITE(mac, offset, \
120
(BWN_PHY_READ(mac, offset) & (mask)) | (set)); \
121
} while (0)
122
#define BWN_PHY_MASK(mac, offset, mask) do { \
123
if (mac->mac_phy.phy_maskset != NULL) { \
124
KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED || \
125
mac->mac_suspended > 0, \
126
("dont access PHY or RF registers after turning on MAC")); \
127
mac->mac_phy.phy_maskset(mac, offset, mask, 0); \
128
} else \
129
BWN_PHY_WRITE(mac, offset, \
130
BWN_PHY_READ(mac, offset) & (mask)); \
131
} while (0)
132
#define BWN_PHY_COPY(mac, dst, src) do { \
133
KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED || \
134
mac->mac_suspended > 0, \
135
("dont access PHY or RF registers after turning on MAC")); \
136
BWN_PHY_WRITE(mac, dst, BWN_PHY_READ(mac, src)); \
137
} while (0)
138
#define BWN_LO_CALIB_EXPIRE (1000 * (30 - 2))
139
#define BWN_LO_PWRVEC_EXPIRE (1000 * (30 - 2))
140
#define BWN_LO_TXCTL_EXPIRE (1000 * (180 - 4))
141
#define BWN_LPD(L, P, D) (((L) << 2) | ((P) << 1) | ((D) << 0))
142
#define BWN_BITREV4(tmp) (BWN_BITREV8(tmp) >> 4)
143
#define BWN_BITREV8(byte) (bwn_bitrev_table[byte])
144
#define BWN_BBATTCMP(a, b) ((a)->att == (b)->att)
145
#define BWN_RFATTCMP(a, b) \
146
(((a)->att == (b)->att) && ((a)->padmix == (b)->padmix))
147
#define BWN_PIO_WRITE_2(mac, tq, offset, value) \
148
BWN_WRITE_2(mac, (tq)->tq_base + offset, value)
149
#define BWN_PIO_READ_4(mac, tq, offset) \
150
BWN_READ_4(mac, tq->tq_base + offset)
151
#define BWN_ISCCKRATE(rate) \
152
(rate == BWN_CCK_RATE_1MB || rate == BWN_CCK_RATE_2MB || \
153
rate == BWN_CCK_RATE_5MB || rate == BWN_CCK_RATE_11MB)
154
#define BWN_ISOFDMRATE(rate) (!BWN_ISCCKRATE(rate))
155
#define BWN_BARRIER(mac, offset, length, flags) \
156
bus_barrier((mac)->mac_sc->sc_mem_res, (offset), (length), (flags))
157
#define BWN_DMA_READ(dr, offset) \
158
(BWN_READ_4(dr->dr_mac, dr->dr_base + offset))
159
#define BWN_DMA_WRITE(dr, offset, value) \
160
(BWN_WRITE_4(dr->dr_mac, dr->dr_base + offset, value))
161
162
typedef enum {
163
BWN_PHY_BAND_2G = 0,
164
BWN_PHY_BAND_5G_LO = 1,
165
BWN_PHY_BAND_5G_MI = 2,
166
BWN_PHY_BAND_5G_HI = 3
167
} bwn_phy_band_t;
168
169
typedef enum {
170
BWN_BAND_2G,
171
BWN_BAND_5G,
172
} bwn_band_t;
173
174
typedef enum {
175
BWN_CHAN_TYPE_20,
176
BWN_CHAN_TYPE_20_HT,
177
BWN_CHAN_TYPE_40_HT_U,
178
BWN_CHAN_TYPE_40_HT_D,
179
} bwn_chan_type_t;
180
181
struct bwn_rate {
182
uint16_t rateid;
183
uint32_t flags;
184
};
185
186
#define BWN_ANT0 0
187
#define BWN_ANT1 1
188
#define BWN_ANTAUTO0 2
189
#define BWN_ANTAUTO1 3
190
#define BWN_ANT2 4
191
#define BWN_ANT3 8
192
#define BWN_ANTAUTO BWN_ANTAUTO0
193
#define BWN_ANT_DEFAULT BWN_ANTAUTO
194
#define BWN_TX_SLOTS_PER_FRAME 2
195
196
struct bwn_channel {
197
unsigned freq;
198
unsigned ieee;
199
unsigned maxTxPow;
200
};
201
202
struct bwn_channelinfo {
203
struct bwn_channel channels[IEEE80211_CHAN_MAX];
204
unsigned nchannels;
205
};
206
207
struct bwn_bbatt {
208
uint8_t att;
209
};
210
211
struct bwn_bbatt_list {
212
const struct bwn_bbatt *array;
213
uint8_t len;
214
uint8_t min;
215
uint8_t max;
216
};
217
218
struct bwn_rfatt {
219
uint8_t att;
220
int padmix;
221
};
222
223
struct bwn_rfatt_list {
224
const struct bwn_rfatt *array;
225
uint8_t len;
226
uint8_t min;
227
uint8_t max;
228
};
229
230
#define BWN_DC_LT_SIZE 32
231
232
struct bwn_loctl {
233
int8_t i;
234
int8_t q;
235
};
236
237
typedef enum {
238
BWN_TXPWR_RES_NEED_ADJUST,
239
BWN_TXPWR_RES_DONE,
240
} bwn_txpwr_result_t;
241
242
struct bwn_lo_calib {
243
struct bwn_bbatt bbatt;
244
struct bwn_rfatt rfatt;
245
struct bwn_loctl ctl;
246
unsigned long calib_time;
247
TAILQ_ENTRY(bwn_lo_calib) list;
248
};
249
250
struct bwn_rxhdr4 {
251
uint16_t frame_len;
252
uint8_t pad1[2];
253
uint16_t phy_status0;
254
union {
255
struct {
256
uint8_t rssi;
257
uint8_t sig_qual;
258
} __packed abg;
259
struct {
260
int8_t power0;
261
int8_t power1;
262
} __packed n;
263
} __packed phy;
264
union {
265
struct {
266
int8_t power2;
267
uint8_t pad;
268
} __packed n;
269
struct {
270
uint8_t pad;
271
int8_t ht_power0;
272
} __packed ht;
273
uint16_t phy_status2;
274
} __packed ps2;
275
union {
276
struct {
277
uint16_t phy_status3;
278
} __packed lp;
279
struct {
280
int8_t phy_ht_power1;
281
int8_t phy_ht_power2;
282
} __packed ht;
283
} __packed ps3;
284
union {
285
struct {
286
uint32_t mac_status;
287
uint16_t mac_time;
288
uint16_t channel;
289
} __packed r351;
290
struct {
291
uint16_t phy_status4;
292
uint16_t phy_status5;
293
uint32_t mac_status;
294
uint16_t mac_time;
295
uint16_t channel;
296
} __packed r598;
297
} __packed ps4;
298
} __packed;
299
300
struct bwn_txstatus {
301
uint16_t cookie;
302
uint16_t seq;
303
uint8_t phy_stat;
304
uint8_t framecnt;
305
uint8_t rtscnt;
306
uint8_t sreason;
307
uint8_t pm;
308
uint8_t im;
309
uint8_t ampdu;
310
uint8_t ack;
311
};
312
313
#define BWN_TXCTL_PA3DB 0x40
314
#define BWN_TXCTL_PA2DB 0x20
315
#define BWN_TXCTL_TXMIX 0x10
316
317
struct bwn_txpwr_loctl {
318
struct bwn_rfatt_list rfatt;
319
struct bwn_bbatt_list bbatt;
320
uint16_t dc_lt[BWN_DC_LT_SIZE];
321
TAILQ_HEAD(, bwn_lo_calib) calib_list;
322
unsigned long pwr_vec_read_time;
323
unsigned long txctl_measured_time;
324
uint8_t tx_bias;
325
uint8_t tx_magn;
326
uint64_t power_vector;
327
};
328
329
#define BWN_OFDMTAB_DIR_UNKNOWN 0
330
#define BWN_OFDMTAB_DIR_READ 1
331
#define BWN_OFDMTAB_DIR_WRITE 2
332
333
struct bwn_phy_g {
334
unsigned pg_flags;
335
#define BWN_PHY_G_FLAG_TSSITABLE_ALLOC (1 << 0)
336
#define BWN_PHY_G_FLAG_RADIOCTX_VALID (1 << 1)
337
int pg_aci_enable;
338
int pg_aci_wlan_automatic;
339
int pg_aci_hw_rssi;
340
int pg_rf_on;
341
uint16_t pg_radioctx_over;
342
uint16_t pg_radioctx_overval;
343
uint16_t pg_minlowsig[2];
344
uint16_t pg_minlowsigpos[2];
345
uint16_t pg_pa0maxpwr;
346
int8_t *pg_tssi2dbm;
347
int pg_idletssi;
348
int pg_curtssi;
349
uint8_t pg_avgtssi;
350
struct bwn_bbatt pg_bbatt;
351
struct bwn_rfatt pg_rfatt;
352
uint8_t pg_txctl;
353
int pg_bbatt_delta;
354
int pg_rfatt_delta;
355
356
struct bwn_txpwr_loctl pg_loctl;
357
int16_t pg_max_lb_gain;
358
int16_t pg_trsw_rx_gain;
359
int16_t pg_lna_lod_gain;
360
int16_t pg_lna_gain;
361
int16_t pg_pga_gain;
362
int pg_immode;
363
#define BWN_INTERFSTACK_SIZE 26
364
uint32_t pg_interfstack[BWN_INTERFSTACK_SIZE];
365
366
int16_t pg_nrssi[2];
367
int32_t pg_nrssi_slope;
368
int8_t pg_nrssi_lt[64];
369
370
uint16_t pg_lofcal;
371
372
uint16_t pg_initval;
373
uint16_t pg_ofdmtab_addr;
374
unsigned pg_ofdmtab_dir;
375
};
376
377
#define BWN_IMMODE_NONE 0
378
#define BWN_IMMODE_NONWLAN 1
379
#define BWN_IMMODE_MANUAL 2
380
#define BWN_IMMODE_AUTO 3
381
382
#define BWN_PHYLP_TXPCTL_UNKNOWN 0
383
#define BWN_PHYLP_TXPCTL_OFF 1
384
#define BWN_PHYLP_TXPCTL_ON_SW 2
385
#define BWN_PHYLP_TXPCTL_ON_HW 3
386
387
struct bwn_phy_lp {
388
uint8_t plp_chan;
389
uint8_t plp_chanfullcal;
390
int32_t plp_antenna;
391
uint8_t plp_txpctlmode;
392
uint8_t plp_txisoband_h;
393
uint8_t plp_txisoband_m;
394
uint8_t plp_txisoband_l;
395
uint8_t plp_rxpwroffset;
396
int8_t plp_txpwridx;
397
uint16_t plp_tssiidx;
398
uint16_t plp_tssinpt;
399
uint8_t plp_rssivf;
400
uint8_t plp_rssivc;
401
uint8_t plp_rssigs;
402
uint8_t plp_rccap;
403
uint8_t plp_bxarch;
404
uint8_t plp_crsusr_off;
405
uint8_t plp_crssys_off;
406
uint32_t plp_div;
407
int32_t plp_tonefreq;
408
uint16_t plp_digfilt[9];
409
};
410
411
/* for LP */
412
struct bwn_txgain {
413
uint16_t tg_gm;
414
uint16_t tg_pga;
415
uint16_t tg_pad;
416
uint16_t tg_dac;
417
};
418
419
struct bwn_rxcompco {
420
uint8_t rc_chan;
421
int8_t rc_c1;
422
int8_t rc_c0;
423
};
424
425
struct bwn_phy_lp_iq_est {
426
uint32_t ie_iqprod;
427
uint32_t ie_ipwr;
428
uint32_t ie_qpwr;
429
};
430
431
struct bwn_txgain_entry {
432
uint8_t te_gm;
433
uint8_t te_pga;
434
uint8_t te_pad;
435
uint8_t te_dac;
436
uint8_t te_bbmult;
437
};
438
439
/* only for LP PHY */
440
struct bwn_stxtable {
441
uint16_t st_phyoffset;
442
uint16_t st_physhift;
443
uint16_t st_rfaddr;
444
uint16_t st_rfshift;
445
uint16_t st_mask;
446
};
447
448
struct bwn_b206x_chan {
449
uint8_t bc_chan;
450
uint16_t bc_freq;
451
const uint8_t *bc_data;
452
};
453
454
struct bwn_b206x_rfinit_entry {
455
uint16_t br_offset;
456
uint16_t br_valuea;
457
uint16_t br_valueg;
458
uint8_t br_flags;
459
};
460
461
struct bwn_phy_n;
462
463
struct bwn_phy {
464
uint8_t type;
465
uint8_t rev;
466
uint8_t analog;
467
468
int supports_2ghz;
469
int supports_5ghz;
470
471
int gmode;
472
struct bwn_phy_g phy_g;
473
struct bwn_phy_lp phy_lp;
474
475
/*
476
* I'd like the newer PHY code to not hide in the top-level
477
* structs..
478
*/
479
struct bwn_phy_n *phy_n;
480
481
uint16_t rf_manuf;
482
uint16_t rf_ver;
483
uint8_t rf_rev;
484
int rf_on;
485
int phy_do_full_init;
486
487
int txpower;
488
int hwpctl;
489
unsigned long nexttime;
490
unsigned int chan;
491
int txerrors;
492
493
int (*attach)(struct bwn_mac *);
494
void (*detach)(struct bwn_mac *);
495
int (*prepare_hw)(struct bwn_mac *);
496
void (*init_pre)(struct bwn_mac *);
497
int (*init)(struct bwn_mac *);
498
void (*exit)(struct bwn_mac *);
499
uint16_t (*phy_read)(struct bwn_mac *, uint16_t);
500
void (*phy_write)(struct bwn_mac *, uint16_t,
501
uint16_t);
502
void (*phy_maskset)(struct bwn_mac *,
503
uint16_t, uint16_t, uint16_t);
504
uint16_t (*rf_read)(struct bwn_mac *, uint16_t);
505
void (*rf_write)(struct bwn_mac *, uint16_t,
506
uint16_t);
507
int (*use_hwpctl)(struct bwn_mac *);
508
void (*rf_onoff)(struct bwn_mac *, int);
509
void (*switch_analog)(struct bwn_mac *, int);
510
int (*switch_channel)(struct bwn_mac *,
511
unsigned int);
512
uint32_t (*get_default_chan)(struct bwn_mac *);
513
void (*set_antenna)(struct bwn_mac *, int);
514
int (*set_im)(struct bwn_mac *, int);
515
bwn_txpwr_result_t (*recalc_txpwr)(struct bwn_mac *, int);
516
void (*set_txpwr)(struct bwn_mac *);
517
void (*task_15s)(struct bwn_mac *);
518
void (*task_60s)(struct bwn_mac *);
519
};
520
521
struct bwn_chan_band {
522
uint32_t flags;
523
uint8_t nchan;
524
#define BWN_MAX_CHAN_PER_BAND 14
525
uint8_t chan[BWN_MAX_CHAN_PER_BAND];
526
};
527
528
#define BWN_NR_WMEPARAMS 16
529
enum {
530
BWN_WMEPARAM_TXOP = 0,
531
BWN_WMEPARAM_CWMIN,
532
BWN_WMEPARAM_CWMAX,
533
BWN_WMEPARAM_CWCUR,
534
BWN_WMEPARAM_AIFS,
535
BWN_WMEPARAM_BSLOTS,
536
BWN_WMEPARAM_REGGAP,
537
BWN_WMEPARAM_STATUS,
538
};
539
540
#define BWN_WME_PARAMS(queue) \
541
(BWN_SHARED_EDCFQ + (BWN_NR_WMEPARAMS * sizeof(uint16_t) * (queue)))
542
#define BWN_WME_BACKGROUND BWN_WME_PARAMS(0)
543
#define BWN_WME_BESTEFFORT BWN_WME_PARAMS(1)
544
#define BWN_WME_VIDEO BWN_WME_PARAMS(2)
545
#define BWN_WME_VOICE BWN_WME_PARAMS(3)
546
547
/*
548
* Radio capture format.
549
*/
550
#define BWN_RX_RADIOTAP_PRESENT ( \
551
(1 << IEEE80211_RADIOTAP_TSFT) | \
552
(1 << IEEE80211_RADIOTAP_FLAGS) | \
553
(1 << IEEE80211_RADIOTAP_RATE) | \
554
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
555
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
556
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
557
(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \
558
0)
559
560
struct bwn_rx_radiotap_header {
561
struct ieee80211_radiotap_header wr_ihdr;
562
uint64_t wr_tsf;
563
u_int8_t wr_flags;
564
u_int8_t wr_rate;
565
u_int16_t wr_chan_freq;
566
u_int16_t wr_chan_flags;
567
int8_t wr_antsignal;
568
int8_t wr_antnoise;
569
u_int8_t wr_antenna;
570
} __packed __aligned(8);
571
572
#define BWN_TX_RADIOTAP_PRESENT ( \
573
(1 << IEEE80211_RADIOTAP_FLAGS) | \
574
(1 << IEEE80211_RADIOTAP_RATE) | \
575
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
576
(1 << IEEE80211_RADIOTAP_DBM_TX_POWER) | \
577
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
578
0)
579
580
struct bwn_tx_radiotap_header {
581
struct ieee80211_radiotap_header wt_ihdr;
582
u_int8_t wt_flags;
583
u_int8_t wt_rate;
584
u_int16_t wt_chan_freq;
585
u_int16_t wt_chan_flags;
586
u_int8_t wt_txpower;
587
u_int8_t wt_antenna;
588
} __packed;
589
590
struct bwn_stats {
591
int32_t rtsfail;
592
int32_t rts;
593
int32_t link_noise;
594
};
595
596
/* Noise Calculation (Link Quality) */
597
struct bwn_noise {
598
uint8_t noi_running;
599
uint8_t noi_nsamples;
600
int8_t noi_samples[8][4];
601
};
602
603
struct bwn_dmadesc_meta {
604
bus_dmamap_t mt_dmap;
605
bus_addr_t mt_paddr;
606
struct mbuf *mt_m;
607
struct ieee80211_node *mt_ni;
608
uint8_t mt_txtype;
609
#define BWN_DMADESC_METATYPE_HEADER 0
610
#define BWN_DMADESC_METATYPE_BODY 1
611
uint8_t mt_islast;
612
};
613
614
#define BWN_DMAINTR_FATALMASK \
615
((1 << 10) | (1 << 11) | (1 << 12) | (1 << 14) | (1 << 15))
616
#define BWN_DMAINTR_NONFATALMASK (1 << 13)
617
#define BWN_DMAINTR_RX_DONE (1 << 16)
618
619
#define BWN_DMA32_DCTL_BYTECNT 0x00001fff
620
#define BWN_DMA32_DCTL_ADDREXT_MASK 0x00030000
621
#define BWN_DMA32_DCTL_ADDREXT_SHIFT 16
622
#define BWN_DMA32_DCTL_DTABLEEND 0x10000000
623
#define BWN_DMA32_DCTL_IRQ 0x20000000
624
#define BWN_DMA32_DCTL_FRAMEEND 0x40000000
625
#define BWN_DMA32_DCTL_FRAMESTART 0x80000000
626
struct bwn_dmadesc32 {
627
uint32_t control;
628
uint32_t address;
629
} __packed;
630
631
#define BWN_DMA64_DCTL0_DTABLEEND 0x10000000
632
#define BWN_DMA64_DCTL0_IRQ 0x20000000
633
#define BWN_DMA64_DCTL0_FRAMEEND 0x40000000
634
#define BWN_DMA64_DCTL0_FRAMESTART 0x80000000
635
#define BWN_DMA64_DCTL1_BYTECNT 0x00001fff
636
#define BWN_DMA64_DCTL1_ADDREXT_MASK 0x00030000
637
#define BWN_DMA64_DCTL1_ADDREXT_SHIFT 16
638
struct bwn_dmadesc64 {
639
uint32_t control0;
640
uint32_t control1;
641
uint32_t address_low;
642
uint32_t address_high;
643
} __packed;
644
645
struct bwn_dmadesc_generic {
646
union {
647
struct bwn_dmadesc32 dma32;
648
struct bwn_dmadesc64 dma64;
649
} __packed dma;
650
} __packed;
651
652
struct bwn_dma_ring;
653
654
struct bwn_dma_ring {
655
struct bwn_mac *dr_mac;
656
const struct bwn_dma_ops *dr_ops;
657
struct bwn_dmadesc_meta *dr_meta;
658
void *dr_txhdr_cache;
659
bus_dma_tag_t dr_ring_dtag;
660
bus_dma_tag_t dr_txring_dtag;
661
bus_dmamap_t dr_spare_dmap; /* only for RX */
662
bus_dmamap_t dr_ring_dmap;
663
bus_addr_t dr_txring_paddr;
664
void *dr_ring_descbase;
665
bus_addr_t dr_ring_dmabase;
666
int dr_numslots;
667
int dr_usedslot;
668
int dr_curslot;
669
uint32_t dr_frameoffset;
670
uint16_t dr_rx_bufsize;
671
uint16_t dr_base;
672
int dr_index;
673
uint8_t dr_tx;
674
uint8_t dr_stop;
675
int dr_type;
676
677
void (*getdesc)(struct bwn_dma_ring *,
678
int, struct bwn_dmadesc_generic **,
679
struct bwn_dmadesc_meta **);
680
void (*setdesc)(struct bwn_dma_ring *,
681
struct bwn_dmadesc_generic *,
682
bus_addr_t, uint16_t, int, int,
683
int);
684
void (*start_transfer)(struct bwn_dma_ring *,
685
int);
686
void (*suspend)(struct bwn_dma_ring *);
687
void (*resume)(struct bwn_dma_ring *);
688
int (*get_curslot)(struct bwn_dma_ring *);
689
void (*set_curslot)(struct bwn_dma_ring *,
690
int);
691
};
692
693
struct bwn_dma {
694
bus_dma_tag_t parent_dtag;
695
bus_dma_tag_t rxbuf_dtag;
696
bus_dma_tag_t txbuf_dtag;
697
struct bhnd_dma_translation translation;
698
u_int addrext_shift;
699
700
struct bwn_dma_ring *wme[5];
701
struct bwn_dma_ring *mcast;
702
struct bwn_dma_ring *rx;
703
uint64_t lastseq; /* XXX FIXME */
704
};
705
706
struct bwn_pio_rxqueue {
707
struct bwn_mac *prq_mac;
708
uint16_t prq_base;
709
uint8_t prq_rev;
710
};
711
712
struct bwn_pio_txqueue;
713
struct bwn_pio_txpkt {
714
struct bwn_pio_txqueue *tp_queue;
715
struct ieee80211_node *tp_ni;
716
struct mbuf *tp_m;
717
uint8_t tp_index;
718
TAILQ_ENTRY(bwn_pio_txpkt) tp_list;
719
};
720
721
#define BWN_PIO_MAX_TXPACKETS 32
722
struct bwn_pio_txqueue {
723
uint16_t tq_base;
724
uint16_t tq_size;
725
uint16_t tq_used;
726
uint16_t tq_free;
727
uint8_t tq_index;
728
struct bwn_pio_txpkt tq_pkts[BWN_PIO_MAX_TXPACKETS];
729
TAILQ_HEAD(, bwn_pio_txpkt) tq_pktlist;
730
};
731
732
struct bwn_pio {
733
struct bwn_pio_txqueue wme[5];
734
struct bwn_pio_txqueue mcast;
735
struct bwn_pio_rxqueue rx;
736
};
737
738
struct bwn_plcp4 {
739
union {
740
uint32_t data;
741
uint8_t raw[4];
742
} __packed o;
743
} __packed;
744
745
struct bwn_plcp6 {
746
union {
747
uint32_t data;
748
uint8_t raw[6];
749
} __packed o;
750
} __packed;
751
752
struct bwn_txhdr {
753
uint32_t macctl;
754
uint8_t macfc[2];
755
uint16_t tx_festime;
756
uint16_t phyctl;
757
uint16_t phyctl_1;
758
uint16_t phyctl_1fb;
759
uint16_t phyctl_1rts;
760
uint16_t phyctl_1rtsfb;
761
uint8_t phyrate;
762
uint8_t phyrate_rts;
763
uint8_t eftypes; /* extra frame types */
764
uint8_t chan;
765
uint8_t iv[16];
766
uint8_t addr1[IEEE80211_ADDR_LEN];
767
uint16_t tx_festime_fb;
768
struct bwn_plcp6 rts_plcp_fb;
769
uint16_t rts_dur_fb;
770
struct bwn_plcp6 plcp_fb;
771
uint16_t dur_fb;
772
uint16_t mimo_modelen;
773
uint16_t mimo_ratelen_fb;
774
uint32_t timeout;
775
776
union {
777
/* format <= r351 */
778
struct {
779
uint8_t pad0[2];
780
uint16_t cookie;
781
uint16_t tx_status;
782
struct bwn_plcp6 rts_plcp;
783
uint8_t rts_frame[16];
784
uint8_t pad1[2];
785
struct bwn_plcp6 plcp;
786
} __packed r351;
787
/* format > r410 < r598 */
788
struct {
789
uint16_t mimo_antenna;
790
uint16_t preload_size;
791
uint8_t pad0[2];
792
uint16_t cookie;
793
uint16_t tx_status;
794
struct bwn_plcp6 rts_plcp;
795
uint8_t rts_frame[16];
796
uint8_t pad1[2];
797
struct bwn_plcp6 plcp;
798
} __packed r410;
799
struct {
800
uint16_t mimo_antenna;
801
uint16_t preload_size;
802
uint8_t pad0[2];
803
uint16_t cookie;
804
uint16_t tx_status;
805
uint16_t max_n_mpdus;
806
uint16_t max_a_bytes_mrt;
807
uint16_t max_a_bytes_fbr;
808
uint16_t min_m_bytes;
809
struct bwn_plcp6 rts_plcp;
810
uint8_t rts_frame[16];
811
uint8_t pad1[2];
812
struct bwn_plcp6 plcp;
813
} __packed r598;
814
} __packed body;
815
} __packed;
816
817
#define BWN_FWTYPE_UCODE 'u'
818
#define BWN_FWTYPE_PCM 'p'
819
#define BWN_FWTYPE_IV 'i'
820
struct bwn_fwhdr {
821
uint8_t type;
822
uint8_t ver;
823
uint8_t pad[2];
824
uint32_t size;
825
} __packed;
826
827
#define BWN_FWINITVALS_OFFSET_MASK 0x7fff
828
#define BWN_FWINITVALS_32BIT 0x8000
829
struct bwn_fwinitvals {
830
uint16_t offset_size;
831
union {
832
uint16_t d16;
833
uint32_t d32;
834
} __packed data;
835
} __packed;
836
837
enum bwn_fw_hdr_format {
838
BWN_FW_HDR_598,
839
BWN_FW_HDR_410,
840
BWN_FW_HDR_351,
841
};
842
843
enum bwn_fwtype {
844
BWN_FWTYPE_DEFAULT,
845
BWN_FWTYPE_OPENSOURCE,
846
BWN_NR_FWTYPES,
847
};
848
849
struct bwn_fwfile {
850
const char *filename;
851
const struct firmware *fw;
852
enum bwn_fwtype type;
853
};
854
855
struct bwn_key {
856
void *keyconf;
857
uint8_t algorithm;
858
};
859
860
struct bwn_fw {
861
struct bwn_fwfile ucode;
862
struct bwn_fwfile pcm;
863
struct bwn_fwfile initvals;
864
struct bwn_fwfile initvals_band;
865
enum bwn_fw_hdr_format fw_hdr_format;
866
867
uint16_t rev;
868
uint16_t patch;
869
uint8_t opensource;
870
uint8_t no_pcmfile;
871
};
872
873
struct bwn_lo_g_sm {
874
int curstate;
875
int nmeasure;
876
int multipler;
877
uint16_t feedth;
878
struct bwn_loctl loctl;
879
};
880
881
struct bwn_lo_g_value {
882
uint8_t old_channel;
883
uint16_t phy_lomask;
884
uint16_t phy_extg;
885
uint16_t phy_dacctl_hwpctl;
886
uint16_t phy_dacctl;
887
uint16_t phy_hpwr_tssictl;
888
uint16_t phy_analogover;
889
uint16_t phy_analogoverval;
890
uint16_t phy_rfover;
891
uint16_t phy_rfoverval;
892
uint16_t phy_classctl;
893
uint16_t phy_crs0;
894
uint16_t phy_pgactl;
895
uint16_t phy_syncctl;
896
uint16_t phy_cck0;
897
uint16_t phy_cck1;
898
uint16_t phy_cck2;
899
uint16_t phy_cck3;
900
uint16_t phy_cck4;
901
uint16_t reg0;
902
uint16_t reg1;
903
uint16_t rf0;
904
uint16_t rf1;
905
uint16_t rf2;
906
};
907
908
#define BWN_LED_MAX 4
909
910
#define BWN_LED_EVENT_NONE -1
911
#define BWN_LED_EVENT_POLL 0
912
#define BWN_LED_EVENT_TX 1
913
#define BWN_LED_EVENT_RX 2
914
#define BWN_LED_SLOWDOWN(dur) (dur) = (((dur) * 3) / 2)
915
916
struct bwn_led {
917
uint8_t led_flags; /* BWN_LED_F_ */
918
uint8_t led_act; /* BWN_LED_ACT_ */
919
uint8_t led_mask;
920
};
921
922
#define BWN_LED_F_ACTLOW 0x1
923
#define BWN_LED_F_BLINK 0x2
924
#define BWN_LED_F_POLLABLE 0x4
925
#define BWN_LED_F_SLOW 0x8
926
927
struct bwn_mac {
928
struct bwn_softc *mac_sc;
929
unsigned mac_status;
930
#define BWN_MAC_STATUS_UNINIT 0
931
#define BWN_MAC_STATUS_INITED 1
932
#define BWN_MAC_STATUS_STARTED 2
933
unsigned mac_flags;
934
/* use "Bad Frames Preemption" */
935
#define BWN_MAC_FLAG_BADFRAME_PREEMP (1 << 0)
936
#define BWN_MAC_FLAG_DFQVALID (1 << 1)
937
#define BWN_MAC_FLAG_RADIO_ON (1 << 2)
938
#define BWN_MAC_FLAG_DMA (1 << 3)
939
#define BWN_MAC_FLAG_WME (1 << 4)
940
#define BWN_MAC_FLAG_HWCRYPTO (1 << 5)
941
942
struct resource *mac_res_irq;
943
int mac_rid_irq;
944
void *mac_intrhand;
945
946
struct bwn_noise mac_noise;
947
struct bwn_phy mac_phy;
948
struct bwn_stats mac_stats;
949
uint32_t mac_reason_intr;
950
uint32_t mac_reason[6];
951
uint32_t mac_intr_mask;
952
int mac_suspended;
953
954
struct bwn_fw mac_fw;
955
956
int mac_dmatype;
957
union {
958
struct bwn_dma dma;
959
struct bwn_pio pio;
960
} mac_method;
961
962
uint16_t mac_ktp; /* Key table pointer */
963
uint8_t mac_max_nr_keys;
964
struct bwn_key mac_key[58];
965
966
unsigned int mac_task_state;
967
struct task mac_intrtask;
968
struct task mac_hwreset;
969
struct task mac_txpower;
970
971
TAILQ_ENTRY(bwn_mac) mac_list;
972
};
973
974
static inline int
975
bwn_tx_hdrsize(struct bwn_mac *mac)
976
{
977
switch (mac->mac_fw.fw_hdr_format) {
978
case BWN_FW_HDR_598:
979
return (112 + (sizeof(struct bwn_plcp6)));
980
case BWN_FW_HDR_410:
981
return (104 + (sizeof(struct bwn_plcp6)));
982
case BWN_FW_HDR_351:
983
return (100 + (sizeof(struct bwn_plcp6)));
984
default:
985
printf("%s: unknown header format (%d)\n", __func__,
986
mac->mac_fw.fw_hdr_format);
987
return (112 + (sizeof(struct bwn_plcp6)));
988
}
989
}
990
991
/*
992
* Driver-specific vap state.
993
*/
994
struct bwn_vap {
995
struct ieee80211vap bv_vap; /* base class */
996
int (*bv_newstate)(struct ieee80211vap *,
997
enum ieee80211_state, int);
998
};
999
#define BWN_VAP(vap) ((struct bwn_vap *)(vap))
1000
#define BWN_VAP_CONST(vap) ((const struct mwl_vap *)(vap))
1001
1002
enum bwn_quirk {
1003
/**
1004
* The ucode PCI slowclock workaround is required on this device.
1005
* @see BWN_HF_PCI_SLOWCLOCK_WORKAROUND.
1006
*/
1007
BWN_QUIRK_UCODE_SLOWCLOCK_WAR = (1<<0),
1008
1009
/**
1010
* DMA is unsupported on this device; PIO should be used instead.
1011
*/
1012
BWN_QUIRK_NODMA = (1<<1),
1013
};
1014
1015
struct bwn_softc {
1016
device_t sc_dev;
1017
struct bhnd_board_info sc_board_info;
1018
struct bhnd_chipid sc_cid;
1019
uint32_t sc_quirks; /**< @see bwn_quirk */
1020
struct resource *sc_mem_res;
1021
int sc_mem_rid;
1022
1023
device_t sc_chipc; /**< ChipCommon device */
1024
device_t sc_gpio; /**< GPIO device */
1025
device_t sc_pmu; /**< PMU device, or NULL if unsupported */
1026
1027
struct mtx sc_mtx;
1028
struct ieee80211com sc_ic;
1029
struct mbufq sc_snd;
1030
unsigned sc_flags;
1031
#define BWN_FLAG_ATTACHED (1 << 0)
1032
#define BWN_FLAG_INVALID (1 << 1)
1033
#define BWN_FLAG_NEED_BEACON_TP (1 << 2)
1034
#define BWN_FLAG_RUNNING (1 << 3)
1035
unsigned sc_debug;
1036
1037
struct bwn_mac *sc_curmac;
1038
TAILQ_HEAD(, bwn_mac) sc_maclist;
1039
1040
uint8_t sc_bssid[IEEE80211_ADDR_LEN];
1041
unsigned int sc_filters;
1042
uint8_t sc_beacons[2];
1043
uint8_t sc_rf_enabled;
1044
1045
struct wmeParams sc_wmeParams[4];
1046
1047
struct callout sc_rfswitch_ch; /* for laptop */
1048
struct callout sc_task_ch;
1049
struct callout sc_watchdog_ch;
1050
int sc_watchdog_timer;
1051
struct taskqueue *sc_tq; /* private task queue */
1052
int (*sc_newstate)(struct ieee80211com *,
1053
enum ieee80211_state, int);
1054
void (*sc_node_cleanup)(
1055
struct ieee80211_node *);
1056
1057
int sc_rx_rate;
1058
int sc_tx_rate;
1059
1060
int sc_led_blinking;
1061
int sc_led_ticks;
1062
struct bwn_led *sc_blink_led;
1063
struct callout sc_led_blink_ch;
1064
int sc_led_blink_offdur;
1065
struct bwn_led sc_leds[BWN_LED_MAX];
1066
int sc_led_idle;
1067
int sc_led_blink;
1068
1069
uint8_t sc_ant2g; /**< available 2GHz antennas */
1070
uint8_t sc_ant5g; /**< available 5GHz antennas */
1071
1072
struct bwn_tx_radiotap_header sc_tx_th;
1073
struct bwn_rx_radiotap_header sc_rx_th;
1074
};
1075
1076
#define BWN_LOCK_INIT(sc) \
1077
mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->sc_dev), \
1078
MTX_NETWORK_LOCK, MTX_DEF)
1079
#define BWN_LOCK_DESTROY(sc) mtx_destroy(&(sc)->sc_mtx)
1080
#define BWN_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
1081
#define BWN_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
1082
#define BWN_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
1083
1084
static inline bwn_band_t
1085
bwn_channel_band(struct bwn_mac *mac, struct ieee80211_channel *c)
1086
{
1087
if (IEEE80211_IS_CHAN_5GHZ(c))
1088
return BWN_BAND_5G;
1089
/* XXX check 2g, log error if not 2g or 5g? */
1090
return BWN_BAND_2G;
1091
}
1092
1093
static inline bwn_band_t
1094
bwn_current_band(struct bwn_mac *mac)
1095
{
1096
struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1097
if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
1098
return BWN_BAND_5G;
1099
/* XXX check 2g, log error if not 2g or 5g? */
1100
return BWN_BAND_2G;
1101
}
1102
1103
static inline bool
1104
bwn_is_40mhz(struct bwn_mac *mac)
1105
{
1106
struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1107
1108
return !! (IEEE80211_IS_CHAN_HT40(ic->ic_curchan));
1109
}
1110
1111
static inline int
1112
bwn_get_centre_freq(struct bwn_mac *mac)
1113
{
1114
1115
struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1116
/* XXX TODO: calculate correctly for HT40 mode */
1117
return ic->ic_curchan->ic_freq;
1118
}
1119
1120
static inline int
1121
bwn_get_chan_centre_freq(struct bwn_mac *mac, struct ieee80211_channel *chan)
1122
{
1123
1124
/* XXX TODO: calculate correctly for HT40 mode */
1125
return chan->ic_freq;
1126
}
1127
1128
static inline int
1129
bwn_get_chan(struct bwn_mac *mac)
1130
{
1131
1132
struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1133
/* XXX TODO: calculate correctly for HT40 mode */
1134
return ic->ic_curchan->ic_ieee;
1135
}
1136
1137
static inline struct ieee80211_channel *
1138
bwn_get_channel(struct bwn_mac *mac)
1139
{
1140
1141
struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1142
return ic->ic_curchan;
1143
}
1144
1145
static inline bool
1146
bwn_is_chan_passive(struct bwn_mac *mac)
1147
{
1148
1149
struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1150
return !! IEEE80211_IS_CHAN_PASSIVE(ic->ic_curchan);
1151
}
1152
1153
static inline bwn_chan_type_t
1154
bwn_get_chan_type(struct bwn_mac *mac, struct ieee80211_channel *c)
1155
{
1156
struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1157
if (c == NULL)
1158
c = ic->ic_curchan;
1159
if (IEEE80211_IS_CHAN_HT40U(c))
1160
return BWN_CHAN_TYPE_40_HT_U;
1161
else if (IEEE80211_IS_CHAN_HT40D(c))
1162
return BWN_CHAN_TYPE_40_HT_D;
1163
else if (IEEE80211_IS_CHAN_HT20(c))
1164
return BWN_CHAN_TYPE_20_HT;
1165
else
1166
return BWN_CHAN_TYPE_20;
1167
}
1168
1169
static inline int
1170
bwn_get_chan_power(struct bwn_mac *mac, struct ieee80211_channel *c)
1171
{
1172
1173
/* return in dbm */
1174
return c->ic_maxpower / 2;
1175
}
1176
1177
#endif /* !_IF_BWNVAR_H */
1178
1179