1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
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
bwn_tx_hdrsize(struct bwn_mac * mac)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
bwn_channel_band(struct bwn_mac * mac,struct ieee80211_channel * c)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
bwn_current_band(struct bwn_mac * mac)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
bwn_is_40mhz(struct bwn_mac * mac)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
bwn_get_centre_freq(struct bwn_mac * mac)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
bwn_get_chan_centre_freq(struct bwn_mac * mac,struct ieee80211_channel * chan)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
bwn_get_chan(struct bwn_mac * mac)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 *
bwn_get_channel(struct bwn_mac * mac)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
bwn_is_chan_passive(struct bwn_mac * mac)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
bwn_get_chan_type(struct bwn_mac * mac,struct ieee80211_channel * c)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
bwn_get_chan_power(struct bwn_mac * mac,struct ieee80211_channel * c)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