2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
37 struct siba_dev_softc;
41 #define N(a) (sizeof(a) / sizeof(a[0]))
42 #define BWN_ALIGN 0x1000
43 #define BWN_BUS_SPACE_MAXADDR_30BIT 0x3fffffff
44 #define BWN_RETRY_SHORT 7
45 #define BWN_RETRY_LONG 4
46 #define BWN_STAID_MAX 64
47 #define BWN_TXPWR_IGNORE_TIME (1 << 0)
48 #define BWN_TXPWR_IGNORE_TSSI (1 << 1)
49 #define BWN_HAS_TXMAG(phy) \
50 (((phy)->rev >= 2) && ((phy)->rf_ver == 0x2050) && \
52 #define BWN_HAS_LOOPBACK(phy) \
53 (((phy)->rev > 1) || ((phy)->gmode))
54 #define BWN_TXERROR_MAX 1000
55 #define BWN_GETTIME(v) do { \
58 (v) = ts.tv_nsec / 1000000 + ts.tv_sec * 1000; \
60 #define BWN_ISOLDFMT(mac) ((mac)->mac_fw.rev <= 351)
61 #define BWN_TSSI2DBM(num, den) \
62 ((int32_t)((num < 0) ? num / den : (num + den / 2) / den))
63 #define BWN_HDRSIZE(mac) bwn_tx_hdrsize(mac)
64 #define BWN_MAXTXHDRSIZE (112 + (sizeof(struct bwn_plcp6)))
66 #define BWN_PIO_COOKIE(tq, tp) \
67 ((uint16_t)((((uint16_t)tq->tq_index + 1) << 12) | tp->tp_index))
68 #define BWN_DMA_COOKIE(dr, slot) \
69 ((uint16_t)(((uint16_t)dr->dr_index + 1) << 12) | (uint16_t)slot)
70 #define BWN_READ_2(mac, o) (siba_read_2(mac->mac_sc->sc_dev, o))
71 #define BWN_READ_4(mac, o) (siba_read_4(mac->mac_sc->sc_dev, o))
72 #define BWN_WRITE_2(mac, o, v) \
73 (siba_write_2(mac->mac_sc->sc_dev, o, v))
74 #define BWN_WRITE_2_F(mac, o, v) do { \
75 (BWN_WRITE_2(mac, o, v)); \
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 (siba_write_4(mac->mac_sc->sc_dev, 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 ((siba_get_revid(mac->mac_sc->sc_dev) >= 11) ? 0x18 : 0)
86 #define BWN_PIO_RXQOFFSET(mac) \
87 ((siba_get_revid(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); \
109 BWN_PHY_WRITE(mac, offset, \
110 BWN_PHY_READ(mac, offset) | (set)); \
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); \
119 BWN_PHY_WRITE(mac, offset, \
120 (BWN_PHY_READ(mac, offset) & (mask)) | (set)); \
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); \
129 BWN_PHY_WRITE(mac, offset, \
130 BWN_PHY_READ(mac, offset) & mask); \
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)); \
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_DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
142 #define BWN_LPD(L, P, D) (((L) << 2) | ((P) << 1) | ((D) << 0))
143 #define BWN_BITREV4(tmp) (BWN_BITREV8(tmp) >> 4)
144 #define BWN_BITREV8(byte) (bwn_bitrev_table[byte])
145 #define BWN_BBATTCMP(a, b) ((a)->att == (b)->att)
146 #define BWN_RFATTCMP(a, b) \
147 (((a)->att == (b)->att) && ((a)->padmix == (b)->padmix))
148 #define BWN_PIO_WRITE_2(mac, tq, offset, value) \
149 BWN_WRITE_2(mac, (tq)->tq_base + offset, value)
150 #define BWN_PIO_READ_4(mac, tq, offset) \
151 BWN_READ_4(mac, tq->tq_base + offset)
152 #define BWN_ISCCKRATE(rate) \
153 (rate == BWN_CCK_RATE_1MB || rate == BWN_CCK_RATE_2MB || \
154 rate == BWN_CCK_RATE_5MB || rate == BWN_CCK_RATE_11MB)
155 #define BWN_ISOFDMRATE(rate) (!BWN_ISCCKRATE(rate))
156 #define BWN_BARRIER(mac, flags) siba_barrier(mac->mac_sc->sc_dev, 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))
165 BWN_PHY_BAND_5G_LO = 1,
166 BWN_PHY_BAND_5G_MI = 2,
167 BWN_PHY_BAND_5G_HI = 3
178 BWN_CHAN_TYPE_40_HT_U,
179 BWN_CHAN_TYPE_40_HT_D,
189 #define BWN_ANTAUTO0 2
190 #define BWN_ANTAUTO1 3
193 #define BWN_ANTAUTO BWN_ANTAUTO0
194 #define BWN_ANT_DEFAULT BWN_ANTAUTO
195 #define BWN_TX_SLOTS_PER_FRAME 2
203 struct bwn_channelinfo {
204 struct bwn_channel channels[IEEE80211_CHAN_MAX];
212 struct bwn_bbatt_list {
213 const struct bwn_bbatt *array;
224 struct bwn_rfatt_list {
225 const struct bwn_rfatt *array;
231 #define BWN_DC_LT_SIZE 32
239 BWN_TXPWR_RES_NEED_ADJUST,
241 } bwn_txpwr_result_t;
243 struct bwn_lo_calib {
244 struct bwn_bbatt bbatt;
245 struct bwn_rfatt rfatt;
246 struct bwn_loctl ctl;
247 unsigned long calib_time;
248 TAILQ_ENTRY(bwn_lo_calib) list;
254 uint16_t phy_status0;
274 uint16_t phy_status2;
278 uint16_t phy_status3;
281 int8_t phy_ht_power1;
282 int8_t phy_ht_power2;
292 uint16_t phy_status4;
293 uint16_t phy_status5;
301 struct bwn_txstatus {
314 #define BWN_TXCTL_PA3DB 0x40
315 #define BWN_TXCTL_PA2DB 0x20
316 #define BWN_TXCTL_TXMIX 0x10
318 struct bwn_txpwr_loctl {
319 struct bwn_rfatt_list rfatt;
320 struct bwn_bbatt_list bbatt;
321 uint16_t dc_lt[BWN_DC_LT_SIZE];
322 TAILQ_HEAD(, bwn_lo_calib) calib_list;
323 unsigned long pwr_vec_read_time;
324 unsigned long txctl_measured_time;
327 uint64_t power_vector;
330 #define BWN_OFDMTAB_DIR_UNKNOWN 0
331 #define BWN_OFDMTAB_DIR_READ 1
332 #define BWN_OFDMTAB_DIR_WRITE 2
336 #define BWN_PHY_G_FLAG_TSSITABLE_ALLOC (1 << 0)
337 #define BWN_PHY_G_FLAG_RADIOCTX_VALID (1 << 1)
339 int pg_aci_wlan_automatic;
342 uint16_t pg_radioctx_over;
343 uint16_t pg_radioctx_overval;
344 uint16_t pg_minlowsig[2];
345 uint16_t pg_minlowsigpos[2];
350 struct bwn_bbatt pg_bbatt;
351 struct bwn_rfatt pg_rfatt;
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;
363 #define BWN_INTERFSTACK_SIZE 26
364 uint32_t pg_interfstack[BWN_INTERFSTACK_SIZE];
367 int32_t pg_nrssi_slope;
368 int8_t pg_nrssi_lt[64];
373 uint16_t pg_ofdmtab_addr;
374 unsigned pg_ofdmtab_dir;
377 #define BWN_IMMODE_NONE 0
378 #define BWN_IMMODE_NONWLAN 1
379 #define BWN_IMMODE_MANUAL 2
380 #define BWN_IMMODE_AUTO 3
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
389 uint8_t plp_chanfullcal;
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;
397 uint16_t plp_tssiidx;
398 uint16_t plp_tssinpt;
404 uint8_t plp_crsusr_off;
405 uint8_t plp_crssys_off;
407 int32_t plp_tonefreq;
408 uint16_t plp_digfilt[9];
419 struct bwn_rxcompco {
425 struct bwn_phy_lp_iq_est {
431 struct bwn_txgain_entry {
439 /* only for LP PHY */
440 struct bwn_stxtable {
441 uint16_t st_phyoffset;
442 uint16_t st_physhift;
448 struct bwn_b206x_chan {
451 const uint8_t *bc_data;
454 struct bwn_b206x_rfinit_entry {
472 struct bwn_phy_g phy_g;
473 struct bwn_phy_lp phy_lp;
476 * I'd like the newer PHY code to not hide in the top-level
479 struct bwn_phy_n *phy_n;
485 int phy_do_full_init;
489 unsigned long nexttime;
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,
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,
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 *,
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 *);
521 struct bwn_chan_band {
524 #define BWN_MAX_CHAN_PER_BAND 14
525 uint8_t chan[BWN_MAX_CHAN_PER_BAND];
528 #define BWN_NR_WMEPARAMS 16
530 BWN_WMEPARAM_TXOP = 0,
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)
548 * Radio capture format.
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) | \
560 struct bwn_rx_radiotap_header {
561 struct ieee80211_radiotap_header wr_ihdr;
565 u_int16_t wr_chan_freq;
566 u_int16_t wr_chan_flags;
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) | \
580 struct bwn_tx_radiotap_header {
581 struct ieee80211_radiotap_header wt_ihdr;
584 u_int16_t wt_chan_freq;
585 u_int16_t wt_chan_flags;
596 /* Noise Calculation (Link Quality) */
599 uint8_t noi_nsamples;
600 int8_t noi_samples[8][4];
603 #define BWN_DMA_30BIT 30
604 #define BWN_DMA_32BIT 32
605 #define BWN_DMA_64BIT 64
607 struct bwn_dmadesc_meta {
608 bus_dmamap_t mt_dmap;
611 struct ieee80211_node *mt_ni;
613 #define BWN_DMADESC_METATYPE_HEADER 0
614 #define BWN_DMADESC_METATYPE_BODY 1
618 #define BWN_DMAINTR_FATALMASK \
619 ((1 << 10) | (1 << 11) | (1 << 12) | (1 << 14) | (1 << 15))
620 #define BWN_DMAINTR_NONFATALMASK (1 << 13)
621 #define BWN_DMAINTR_RX_DONE (1 << 16)
623 #define BWN_DMA32_DCTL_BYTECNT 0x00001fff
624 #define BWN_DMA32_DCTL_ADDREXT_MASK 0x00030000
625 #define BWN_DMA32_DCTL_ADDREXT_SHIFT 16
626 #define BWN_DMA32_DCTL_DTABLEEND 0x10000000
627 #define BWN_DMA32_DCTL_IRQ 0x20000000
628 #define BWN_DMA32_DCTL_FRAMEEND 0x40000000
629 #define BWN_DMA32_DCTL_FRAMESTART 0x80000000
630 struct bwn_dmadesc32 {
635 #define BWN_DMA64_DCTL0_DTABLEEND 0x10000000
636 #define BWN_DMA64_DCTL0_IRQ 0x20000000
637 #define BWN_DMA64_DCTL0_FRAMEEND 0x40000000
638 #define BWN_DMA64_DCTL0_FRAMESTART 0x80000000
639 #define BWN_DMA64_DCTL1_BYTECNT 0x00001fff
640 #define BWN_DMA64_DCTL1_ADDREXT_MASK 0x00030000
641 #define BWN_DMA64_DCTL1_ADDREXT_SHIFT 16
642 struct bwn_dmadesc64 {
645 uint32_t address_low;
646 uint32_t address_high;
649 struct bwn_dmadesc_generic {
651 struct bwn_dmadesc32 dma32;
652 struct bwn_dmadesc64 dma64;
658 struct bwn_dma_ring {
659 struct bwn_mac *dr_mac;
660 const struct bwn_dma_ops *dr_ops;
661 struct bwn_dmadesc_meta *dr_meta;
662 void *dr_txhdr_cache;
663 bus_dma_tag_t dr_ring_dtag;
664 bus_dma_tag_t dr_txring_dtag;
665 bus_dmamap_t dr_spare_dmap; /* only for RX */
666 bus_dmamap_t dr_ring_dmap;
667 bus_addr_t dr_txring_paddr;
668 void *dr_ring_descbase;
669 bus_addr_t dr_ring_dmabase;
673 uint32_t dr_frameoffset;
674 uint16_t dr_rx_bufsize;
681 void (*getdesc)(struct bwn_dma_ring *,
682 int, struct bwn_dmadesc_generic **,
683 struct bwn_dmadesc_meta **);
684 void (*setdesc)(struct bwn_dma_ring *,
685 struct bwn_dmadesc_generic *,
686 bus_addr_t, uint16_t, int, int,
688 void (*start_transfer)(struct bwn_dma_ring *,
690 void (*suspend)(struct bwn_dma_ring *);
691 void (*resume)(struct bwn_dma_ring *);
692 int (*get_curslot)(struct bwn_dma_ring *);
693 void (*set_curslot)(struct bwn_dma_ring *,
699 bus_dma_tag_t parent_dtag;
700 bus_dma_tag_t rxbuf_dtag;
701 bus_dma_tag_t txbuf_dtag;
703 struct bwn_dma_ring *wme[5];
704 struct bwn_dma_ring *mcast;
705 struct bwn_dma_ring *rx;
706 uint64_t lastseq; /* XXX FIXME */
709 struct bwn_pio_rxqueue {
710 struct bwn_mac *prq_mac;
715 struct bwn_pio_txqueue;
716 struct bwn_pio_txpkt {
717 struct bwn_pio_txqueue *tp_queue;
718 struct ieee80211_node *tp_ni;
721 TAILQ_ENTRY(bwn_pio_txpkt) tp_list;
724 #define BWN_PIO_MAX_TXPACKETS 32
725 struct bwn_pio_txqueue {
731 struct bwn_pio_txpkt tq_pkts[BWN_PIO_MAX_TXPACKETS];
732 TAILQ_HEAD(, bwn_pio_txpkt) tq_pktlist;
736 struct bwn_pio_txqueue wme[5];
737 struct bwn_pio_txqueue mcast;
738 struct bwn_pio_rxqueue rx;
762 uint16_t phyctl_1rts;
763 uint16_t phyctl_1rtsfb;
766 uint8_t eftypes; /* extra frame types */
769 uint8_t addr1[IEEE80211_ADDR_LEN];
770 uint16_t tx_festime_fb;
771 struct bwn_plcp6 rts_plcp_fb;
773 struct bwn_plcp6 plcp_fb;
775 uint16_t mimo_modelen;
776 uint16_t mimo_ratelen_fb;
785 struct bwn_plcp6 rts_plcp;
786 uint8_t rts_frame[16];
788 struct bwn_plcp6 plcp;
790 /* format > r410 < r598 */
792 uint16_t mimo_antenna;
793 uint16_t preload_size;
797 struct bwn_plcp6 rts_plcp;
798 uint8_t rts_frame[16];
800 struct bwn_plcp6 plcp;
803 uint16_t mimo_antenna;
804 uint16_t preload_size;
808 uint16_t max_n_mpdus;
809 uint16_t max_a_bytes_mrt;
810 uint16_t max_a_bytes_fbr;
811 uint16_t min_m_bytes;
812 struct bwn_plcp6 rts_plcp;
813 uint8_t rts_frame[16];
815 struct bwn_plcp6 plcp;
820 #define BWN_FWTYPE_UCODE 'u'
821 #define BWN_FWTYPE_PCM 'p'
822 #define BWN_FWTYPE_IV 'i'
830 #define BWN_FWINITVALS_OFFSET_MASK 0x7fff
831 #define BWN_FWINITVALS_32BIT 0x8000
832 struct bwn_fwinitvals {
833 uint16_t offset_size;
840 enum bwn_fw_hdr_format {
848 BWN_FWTYPE_OPENSOURCE,
853 const char *filename;
854 const struct firmware *fw;
855 enum bwn_fwtype type;
864 struct bwn_fwfile ucode;
865 struct bwn_fwfile pcm;
866 struct bwn_fwfile initvals;
867 struct bwn_fwfile initvals_band;
868 enum bwn_fw_hdr_format fw_hdr_format;
881 struct bwn_loctl loctl;
884 struct bwn_lo_g_value {
888 uint16_t phy_dacctl_hwpctl;
890 uint16_t phy_hpwr_tssictl;
891 uint16_t phy_analogover;
892 uint16_t phy_analogoverval;
894 uint16_t phy_rfoverval;
895 uint16_t phy_classctl;
898 uint16_t phy_syncctl;
911 #define BWN_LED_MAX 4
913 #define BWN_LED_EVENT_NONE -1
914 #define BWN_LED_EVENT_POLL 0
915 #define BWN_LED_EVENT_TX 1
916 #define BWN_LED_EVENT_RX 2
917 #define BWN_LED_SLOWDOWN(dur) (dur) = (((dur) * 3) / 2)
920 uint8_t led_flags; /* BWN_LED_F_ */
921 uint8_t led_act; /* BWN_LED_ACT_ */
925 #define BWN_LED_F_ACTLOW 0x1
926 #define BWN_LED_F_BLINK 0x2
927 #define BWN_LED_F_POLLABLE 0x4
928 #define BWN_LED_F_SLOW 0x8
931 struct bwn_softc *mac_sc;
933 #define BWN_MAC_STATUS_UNINIT 0
934 #define BWN_MAC_STATUS_INITED 1
935 #define BWN_MAC_STATUS_STARTED 2
937 /* use "Bad Frames Preemption" */
938 #define BWN_MAC_FLAG_BADFRAME_PREEMP (1 << 0)
939 #define BWN_MAC_FLAG_DFQVALID (1 << 1)
940 #define BWN_MAC_FLAG_RADIO_ON (1 << 2)
941 #define BWN_MAC_FLAG_DMA (1 << 3)
942 #define BWN_MAC_FLAG_WME (1 << 4)
943 #define BWN_MAC_FLAG_HWCRYPTO (1 << 5)
945 struct resource_spec *mac_intr_spec;
946 #define BWN_MSI_MESSAGES 1
947 struct resource *mac_res_irq[BWN_MSI_MESSAGES];
948 void *mac_intrhand[BWN_MSI_MESSAGES];
951 struct bwn_noise mac_noise;
952 struct bwn_phy mac_phy;
953 struct bwn_stats mac_stats;
954 uint32_t mac_reason_intr;
955 uint32_t mac_reason[6];
956 uint32_t mac_intr_mask;
959 struct bwn_fw mac_fw;
966 uint16_t mac_ktp; /* Key table pointer */
967 uint8_t mac_max_nr_keys;
968 struct bwn_key mac_key[58];
970 unsigned int mac_task_state;
971 struct task mac_intrtask;
972 struct task mac_hwreset;
973 struct task mac_txpower;
975 TAILQ_ENTRY(bwn_mac) mac_list;
979 bwn_tx_hdrsize(struct bwn_mac *mac)
981 switch (mac->mac_fw.fw_hdr_format) {
983 return (112 + (sizeof(struct bwn_plcp6)));
985 return (104 + (sizeof(struct bwn_plcp6)));
987 return (100 + (sizeof(struct bwn_plcp6)));
989 printf("%s: unknown header format (%d)\n", __func__,
990 mac->mac_fw.fw_hdr_format);
991 return (112 + (sizeof(struct bwn_plcp6)));
996 * Driver-specific vap state.
999 struct ieee80211vap bv_vap; /* base class */
1000 int (*bv_newstate)(struct ieee80211vap *,
1001 enum ieee80211_state, int);
1003 #define BWN_VAP(vap) ((struct bwn_vap *)(vap))
1004 #define BWN_VAP_CONST(vap) ((const struct mwl_vap *)(vap))
1009 struct ieee80211com sc_ic;
1010 struct mbufq sc_snd;
1012 #define BWN_FLAG_ATTACHED (1 << 0)
1013 #define BWN_FLAG_INVALID (1 << 1)
1014 #define BWN_FLAG_NEED_BEACON_TP (1 << 2)
1015 #define BWN_FLAG_RUNNING (1 << 3)
1018 struct bwn_mac *sc_curmac;
1019 TAILQ_HEAD(, bwn_mac) sc_maclist;
1021 uint8_t sc_bssid[IEEE80211_ADDR_LEN];
1022 unsigned int sc_filters;
1023 uint8_t sc_beacons[2];
1024 uint8_t sc_rf_enabled;
1026 struct wmeParams sc_wmeParams[4];
1028 struct callout sc_rfswitch_ch; /* for laptop */
1029 struct callout sc_task_ch;
1030 struct callout sc_watchdog_ch;
1031 int sc_watchdog_timer;
1032 struct taskqueue *sc_tq; /* private task queue */
1033 int (*sc_newstate)(struct ieee80211com *,
1034 enum ieee80211_state, int);
1035 void (*sc_node_cleanup)(
1036 struct ieee80211_node *);
1041 int sc_led_blinking;
1043 struct bwn_led *sc_blink_led;
1044 struct callout sc_led_blink_ch;
1045 int sc_led_blink_offdur;
1046 struct bwn_led sc_leds[BWN_LED_MAX];
1050 struct bwn_tx_radiotap_header sc_tx_th;
1051 struct bwn_rx_radiotap_header sc_rx_th;
1054 #define BWN_LOCK_INIT(sc) \
1055 mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->sc_dev), \
1056 MTX_NETWORK_LOCK, MTX_DEF)
1057 #define BWN_LOCK_DESTROY(sc) mtx_destroy(&(sc)->sc_mtx)
1058 #define BWN_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
1059 #define BWN_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
1060 #define BWN_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
1062 static inline bwn_band_t
1063 bwn_channel_band(struct bwn_mac *mac, struct ieee80211_channel *c)
1065 if (IEEE80211_IS_CHAN_5GHZ(c))
1067 /* XXX check 2g, log error if not 2g or 5g? */
1071 static inline bwn_band_t
1072 bwn_current_band(struct bwn_mac *mac)
1074 struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1075 if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
1077 /* XXX check 2g, log error if not 2g or 5g? */
1082 bwn_is_40mhz(struct bwn_mac *mac)
1084 struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1086 return !! (IEEE80211_IS_CHAN_HT40(ic->ic_curchan));
1090 bwn_get_centre_freq(struct bwn_mac *mac)
1093 struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1094 /* XXX TODO: calculate correctly for HT40 mode */
1095 return ic->ic_curchan->ic_freq;
1099 bwn_get_chan_centre_freq(struct bwn_mac *mac, struct ieee80211_channel *chan)
1102 /* XXX TODO: calculate correctly for HT40 mode */
1103 return chan->ic_freq;
1107 bwn_get_chan(struct bwn_mac *mac)
1110 struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1111 /* XXX TODO: calculate correctly for HT40 mode */
1112 return ic->ic_curchan->ic_ieee;
1115 static inline struct ieee80211_channel *
1116 bwn_get_channel(struct bwn_mac *mac)
1119 struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1120 return ic->ic_curchan;
1124 bwn_is_chan_passive(struct bwn_mac *mac)
1127 struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1128 return !! IEEE80211_IS_CHAN_PASSIVE(ic->ic_curchan);
1131 static inline bwn_chan_type_t
1132 bwn_get_chan_type(struct bwn_mac *mac, struct ieee80211_channel *c)
1134 struct ieee80211com *ic = &mac->mac_sc->sc_ic;
1137 if (IEEE80211_IS_CHAN_HT40U(c))
1138 return BWN_CHAN_TYPE_40_HT_U;
1139 else if (IEEE80211_IS_CHAN_HT40D(c))
1140 return BWN_CHAN_TYPE_40_HT_D;
1141 else if (IEEE80211_IS_CHAN_HT20(c))
1142 return BWN_CHAN_TYPE_20_HT;
1144 return BWN_CHAN_TYPE_20;
1148 bwn_get_chan_power(struct bwn_mac *mac, struct ieee80211_channel *c)
1152 return c->ic_maxpower / 2;
1156 * For now there's no bhnd bus support. Places where it matters
1157 * should call this routine so we can start logging things.
1160 bwn_is_bus_siba(struct bwn_mac *mac)
1165 #endif /* !_IF_BWNVAR_H */