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