/*- * Copyright (c) 2009-2010 Weongyo Jeong * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * * $FreeBSD$ */ #ifndef _IF_BWNVAR_H #define _IF_BWNVAR_H struct siba_dev_softc; struct bwn_softc; struct bwn_mac; #define N(a) (sizeof(a) / sizeof(a[0])) #define BWN_ALIGN 0x1000 #define BWN_BUS_SPACE_MAXADDR_30BIT 0x3fffffff #define BWN_RETRY_SHORT 7 #define BWN_RETRY_LONG 4 #define BWN_STAID_MAX 64 #define BWN_TXPWR_IGNORE_TIME (1 << 0) #define BWN_TXPWR_IGNORE_TSSI (1 << 1) #define BWN_HAS_TXMAG(phy) \ (((phy)->rev >= 2) && ((phy)->rf_ver == 0x2050) && \ ((phy)->rf_rev == 8)) #define BWN_HAS_LOOPBACK(phy) \ (((phy)->rev > 1) || ((phy)->gmode)) #define BWN_TXERROR_MAX 1000 #define BWN_GETTIME(v) do { \ struct timespec ts; \ nanouptime(&ts); \ (v) = ts.tv_nsec / 1000000 + ts.tv_sec * 1000; \ } while (0) #define BWN_ISOLDFMT(mac) ((mac)->mac_fw.rev <= 351) #define BWN_TSSI2DBM(num, den) \ ((int32_t)((num < 0) ? num / den : (num + den / 2) / den)) #define BWN_HDRSIZE(mac) \ ((BWN_ISOLDFMT(mac)) ? (100 + sizeof(struct bwn_plcp6)) : \ (104 + sizeof(struct bwn_plcp6))) #define BWN_PIO_COOKIE(tq, tp) \ ((uint16_t)((((uint16_t)tq->tq_index + 1) << 12) | tp->tp_index)) #define BWN_DMA_COOKIE(dr, slot) \ ((uint16_t)(((uint16_t)dr->dr_index + 1) << 12) | (uint16_t)slot) #define BWN_READ_2(mac, o) (siba_read_2(mac->mac_sc->sc_dev, o)) #define BWN_READ_4(mac, o) (siba_read_4(mac->mac_sc->sc_dev, o)) #define BWN_WRITE_2(mac, o, v) \ (siba_write_2(mac->mac_sc->sc_dev, o, v)) #define BWN_WRITE_4(mac, o, v) \ (siba_write_4(mac->mac_sc->sc_dev, o, v)) #define BWN_PIO_TXQOFFSET(mac) \ ((siba_get_revid(mac->mac_sc->sc_dev) >= 11) ? 0x18 : 0) #define BWN_PIO_RXQOFFSET(mac) \ ((siba_get_revid(mac->mac_sc->sc_dev) >= 11) ? 0x38 : 8) #define BWN_SEC_NEWAPI(mac) (mac->mac_fw.rev >= 351) #define BWN_SEC_KEY2FW(mac, idx) \ (BWN_SEC_NEWAPI(mac) ? idx : ((idx >= 4) ? idx - 4 : idx)) #define BWN_RF_READ(mac, r) (mac->mac_phy.rf_read(mac, r)) #define BWN_RF_WRITE(mac, r, v) (mac->mac_phy.rf_write(mac, r, v)) #define BWN_RF_MASK(mac, o, m) \ BWN_RF_WRITE(mac, o, BWN_RF_READ(mac, o) & m) #define BWN_RF_SETMASK(mac, offset, mask, set) \ BWN_RF_WRITE(mac, offset, (BWN_RF_READ(mac, offset) & mask) | set) #define BWN_RF_SET(mac, offset, set) \ BWN_RF_WRITE(mac, offset, BWN_RF_READ(mac, offset) | set) #define BWN_PHY_READ(mac, r) (mac->mac_phy.phy_read(mac, r)) #define BWN_PHY_WRITE(mac, r, v) \ (mac->mac_phy.phy_write(mac, r, v)) #define BWN_PHY_SET(mac, offset, set) do { \ if (mac->mac_phy.phy_maskset != NULL) { \ KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED || \ mac->mac_suspended > 0, \ ("dont access PHY or RF registers after turning on MAC")); \ mac->mac_phy.phy_maskset(mac, offset, 0xffff, set); \ } else \ BWN_PHY_WRITE(mac, offset, \ BWN_PHY_READ(mac, offset) | (set)); \ } while (0) #define BWN_PHY_SETMASK(mac, offset, mask, set) do { \ if (mac->mac_phy.phy_maskset != NULL) { \ KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED || \ mac->mac_suspended > 0, \ ("dont access PHY or RF registers after turning on MAC")); \ mac->mac_phy.phy_maskset(mac, offset, mask, set); \ } else \ BWN_PHY_WRITE(mac, offset, \ (BWN_PHY_READ(mac, offset) & (mask)) | (set)); \ } while (0) #define BWN_PHY_MASK(mac, offset, mask) do { \ if (mac->mac_phy.phy_maskset != NULL) { \ KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED || \ mac->mac_suspended > 0, \ ("dont access PHY or RF registers after turning on MAC")); \ mac->mac_phy.phy_maskset(mac, offset, mask, 0); \ } else \ BWN_PHY_WRITE(mac, offset, \ BWN_PHY_READ(mac, offset) & mask); \ } while (0) #define BWN_PHY_COPY(mac, dst, src) do { \ KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED || \ mac->mac_suspended > 0, \ ("dont access PHY or RF registers after turning on MAC")); \ BWN_PHY_WRITE(mac, dst, BWN_PHY_READ(mac, src)); \ } while (0) #define BWN_LO_CALIB_EXPIRE (1000 * (30 - 2)) #define BWN_LO_PWRVEC_EXPIRE (1000 * (30 - 2)) #define BWN_LO_TXCTL_EXPIRE (1000 * (180 - 4)) #define BWN_DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) #define BWN_LPD(L, P, D) (((L) << 2) | ((P) << 1) | ((D) << 0)) #define BWN_BITREV4(tmp) (BWN_BITREV8(tmp) >> 4) #define BWN_BITREV8(byte) (bwn_bitrev_table[byte]) #define BWN_BBATTCMP(a, b) ((a)->att == (b)->att) #define BWN_RFATTCMP(a, b) \ (((a)->att == (b)->att) && ((a)->padmix == (b)->padmix)) #define BWN_PIO_WRITE_2(mac, tq, offset, value) \ BWN_WRITE_2(mac, (tq)->tq_base + offset, value) #define BWN_PIO_READ_4(mac, tq, offset) \ BWN_READ_4(mac, tq->tq_base + offset) #define BWN_ISCCKRATE(rate) \ (rate == BWN_CCK_RATE_1MB || rate == BWN_CCK_RATE_2MB || \ rate == BWN_CCK_RATE_5MB || rate == BWN_CCK_RATE_11MB) #define BWN_ISOFDMRATE(rate) (!BWN_ISCCKRATE(rate)) #define BWN_BARRIER(mac, flags) siba_barrier(mac->mac_sc->sc_dev, flags) #define BWN_DMA_READ(dr, offset) \ (BWN_READ_4(dr->dr_mac, dr->dr_base + offset)) #define BWN_DMA_WRITE(dr, offset, value) \ (BWN_WRITE_4(dr->dr_mac, dr->dr_base + offset, value)) struct bwn_rate { uint16_t rateid; uint32_t flags; }; #define BWN_ANT0 0 #define BWN_ANT1 1 #define BWN_ANTAUTO0 2 #define BWN_ANTAUTO1 3 #define BWN_ANT2 4 #define BWN_ANT3 8 #define BWN_ANTAUTO BWN_ANTAUTO0 #define BWN_ANT_DEFAULT BWN_ANTAUTO #define BWN_TX_SLOTS_PER_FRAME 2 struct bwn_channel { unsigned freq; unsigned ieee; unsigned maxTxPow; }; struct bwn_channelinfo { struct bwn_channel channels[IEEE80211_CHAN_MAX]; unsigned nchannels; }; struct bwn_bbatt { uint8_t att; }; struct bwn_bbatt_list { const struct bwn_bbatt *array; uint8_t len; uint8_t min; uint8_t max; }; struct bwn_rfatt { uint8_t att; int padmix; }; struct bwn_rfatt_list { const struct bwn_rfatt *array; uint8_t len; uint8_t min; uint8_t max; }; #define BWN_DC_LT_SIZE 32 struct bwn_loctl { int8_t i; int8_t q; }; struct bwn_lo_calib { struct bwn_bbatt bbatt; struct bwn_rfatt rfatt; struct bwn_loctl ctl; unsigned long calib_time; TAILQ_ENTRY(bwn_lo_calib) list; }; struct bwn_rxhdr4 { uint16_t frame_len; uint8_t pad1[2]; uint16_t phy_status0; union { struct { uint8_t rssi; uint8_t sig_qual; } __packed abg; struct { int8_t power0; int8_t power1; } __packed n; } __packed phy; uint16_t phy_status2; uint16_t phy_status3; uint32_t mac_status; uint16_t mac_time; uint16_t channel; } __packed; struct bwn_txstatus { uint16_t cookie; uint16_t seq; uint8_t phy_stat; uint8_t framecnt; uint8_t rtscnt; uint8_t sreason; uint8_t pm; uint8_t im; uint8_t ampdu; uint8_t ack; }; #define BWN_TXCTL_PA3DB 0x40 #define BWN_TXCTL_PA2DB 0x20 #define BWN_TXCTL_TXMIX 0x10 struct bwn_txpwr_loctl { struct bwn_rfatt_list rfatt; struct bwn_bbatt_list bbatt; uint16_t dc_lt[BWN_DC_LT_SIZE]; TAILQ_HEAD(, bwn_lo_calib) calib_list; unsigned long pwr_vec_read_time; unsigned long txctl_measured_time; uint8_t tx_bias; uint8_t tx_magn; uint64_t power_vector; }; #define BWN_OFDMTAB_DIR_UNKNOWN 0 #define BWN_OFDMTAB_DIR_READ 1 #define BWN_OFDMTAB_DIR_WRITE 2 struct bwn_phy_g { unsigned pg_flags; #define BWN_PHY_G_FLAG_TSSITABLE_ALLOC (1 << 0) #define BWN_PHY_G_FLAG_RADIOCTX_VALID (1 << 1) int pg_aci_enable; int pg_aci_wlan_automatic; int pg_aci_hw_rssi; int pg_rf_on; uint16_t pg_radioctx_over; uint16_t pg_radioctx_overval; uint16_t pg_minlowsig[2]; uint16_t pg_minlowsigpos[2]; int8_t *pg_tssi2dbm; int pg_idletssi; int pg_curtssi; uint8_t pg_avgtssi; struct bwn_bbatt pg_bbatt; struct bwn_rfatt pg_rfatt; uint8_t pg_txctl; int pg_bbatt_delta; int pg_rfatt_delta; struct bwn_txpwr_loctl pg_loctl; int16_t pg_max_lb_gain; int16_t pg_trsw_rx_gain; int16_t pg_lna_lod_gain; int16_t pg_lna_gain; int16_t pg_pga_gain; int pg_immode; #define BWN_INTERFSTACK_SIZE 26 uint32_t pg_interfstack[BWN_INTERFSTACK_SIZE]; int16_t pg_nrssi[2]; int32_t pg_nrssi_slope; int8_t pg_nrssi_lt[64]; uint16_t pg_lofcal; uint16_t pg_initval; uint16_t pg_ofdmtab_addr; unsigned pg_ofdmtab_dir; }; #define BWN_IMMODE_NONE 0 #define BWN_IMMODE_NONWLAN 1 #define BWN_IMMODE_MANUAL 2 #define BWN_IMMODE_AUTO 3 #define BWN_TXPWR_RES_NEED_ADJUST 0 #define BWN_TXPWR_RES_DONE 1 #define BWN_PHYLP_TXPCTL_UNKNOWN 0 #define BWN_PHYLP_TXPCTL_OFF 1 #define BWN_PHYLP_TXPCTL_ON_SW 2 #define BWN_PHYLP_TXPCTL_ON_HW 3 struct bwn_phy_lp { uint8_t plp_chan; uint8_t plp_chanfullcal; int32_t plp_antenna; uint8_t plp_txpctlmode; uint8_t plp_txisoband_h; uint8_t plp_txisoband_m; uint8_t plp_txisoband_l; uint8_t plp_rxpwroffset; int8_t plp_txpwridx; uint16_t plp_tssiidx; uint16_t plp_tssinpt; uint8_t plp_rssivf; uint8_t plp_rssivc; uint8_t plp_rssigs; uint8_t plp_rccap; uint8_t plp_bxarch; uint8_t plp_crsusr_off; uint8_t plp_crssys_off; uint32_t plp_div; int32_t plp_tonefreq; uint16_t plp_digfilt[9]; }; /* for LP */ struct bwn_txgain { uint16_t tg_gm; uint16_t tg_pga; uint16_t tg_pad; uint16_t tg_dac; }; struct bwn_rxcompco { uint8_t rc_chan; int8_t rc_c1; int8_t rc_c0; }; struct bwn_phy_lp_iq_est { uint32_t ie_iqprod; uint32_t ie_ipwr; uint32_t ie_qpwr; }; struct bwn_txgain_entry { uint8_t te_gm; uint8_t te_pga; uint8_t te_pad; uint8_t te_dac; uint8_t te_bbmult; }; /* only for LP PHY */ struct bwn_stxtable { uint16_t st_phyoffset; uint16_t st_physhift; uint16_t st_rfaddr; uint16_t st_rfshift; uint16_t st_mask; }; struct bwn_b206x_chan { uint8_t bc_chan; uint16_t bc_freq; const uint8_t *bc_data; }; struct bwn_b206x_rfinit_entry { uint16_t br_offset; uint16_t br_valuea; uint16_t br_valueg; uint8_t br_flags; }; struct bwn_phy { uint8_t type; uint8_t rev; uint8_t analog; int supports_2ghz; int supports_5ghz; int gmode; struct bwn_phy_g phy_g; struct bwn_phy_lp phy_lp; uint16_t rf_manuf; uint16_t rf_ver; uint8_t rf_rev; int rf_on; int txpower; int hwpctl; unsigned long nexttime; unsigned int chan; int txerrors; int (*attach)(struct bwn_mac *); void (*detach)(struct bwn_mac *); int (*prepare_hw)(struct bwn_mac *); void (*init_pre)(struct bwn_mac *); int (*init)(struct bwn_mac *); void (*exit)(struct bwn_mac *); uint16_t (*phy_read)(struct bwn_mac *, uint16_t); void (*phy_write)(struct bwn_mac *, uint16_t, uint16_t); void (*phy_maskset)(struct bwn_mac *, uint16_t, uint16_t, uint16_t); uint16_t (*rf_read)(struct bwn_mac *, uint16_t); void (*rf_write)(struct bwn_mac *, uint16_t, uint16_t); int (*use_hwpctl)(struct bwn_mac *); void (*rf_onoff)(struct bwn_mac *, int); void (*switch_analog)(struct bwn_mac *, int); int (*switch_channel)(struct bwn_mac *, unsigned int); uint32_t (*get_default_chan)(struct bwn_mac *); void (*set_antenna)(struct bwn_mac *, int); int (*set_im)(struct bwn_mac *, int); int (*recalc_txpwr)(struct bwn_mac *, int); void (*set_txpwr)(struct bwn_mac *); void (*task_15s)(struct bwn_mac *); void (*task_60s)(struct bwn_mac *); }; struct bwn_chan_band { uint32_t flags; uint8_t nchan; #define BWN_MAX_CHAN_PER_BAND 14 uint8_t chan[BWN_MAX_CHAN_PER_BAND]; }; #define BWN_NR_WMEPARAMS 16 enum { BWN_WMEPARAM_TXOP = 0, BWN_WMEPARAM_CWMIN, BWN_WMEPARAM_CWMAX, BWN_WMEPARAM_CWCUR, BWN_WMEPARAM_AIFS, BWN_WMEPARAM_BSLOTS, BWN_WMEPARAM_REGGAP, BWN_WMEPARAM_STATUS, }; #define BWN_WME_PARAMS(queue) \ (BWN_SHARED_EDCFQ + (BWN_NR_WMEPARAMS * sizeof(uint16_t) * (queue))) #define BWN_WME_BACKGROUND BWN_WME_PARAMS(0) #define BWN_WME_BESTEFFORT BWN_WME_PARAMS(1) #define BWN_WME_VIDEO BWN_WME_PARAMS(2) #define BWN_WME_VOICE BWN_WME_PARAMS(3) /* * Radio capture format. */ #define BWN_RX_RADIOTAP_PRESENT ( \ (1 << IEEE80211_RADIOTAP_TSFT) | \ (1 << IEEE80211_RADIOTAP_FLAGS) | \ (1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_CHANNEL) | \ (1 << IEEE80211_RADIOTAP_ANTENNA) | \ (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \ 0) struct bwn_rx_radiotap_header { struct ieee80211_radiotap_header wr_ihdr; uint64_t wr_tsf; u_int8_t wr_flags; u_int8_t wr_rate; u_int16_t wr_chan_freq; u_int16_t wr_chan_flags; int8_t wr_antsignal; int8_t wr_antnoise; u_int8_t wr_antenna; }; #define BWN_TX_RADIOTAP_PRESENT ( \ (1 << IEEE80211_RADIOTAP_FLAGS) | \ (1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_CHANNEL) | \ (1 << IEEE80211_RADIOTAP_DBM_TX_POWER) | \ (1 << IEEE80211_RADIOTAP_ANTENNA) | \ 0) struct bwn_tx_radiotap_header { struct ieee80211_radiotap_header wt_ihdr; u_int8_t wt_flags; u_int8_t wt_rate; u_int16_t wt_chan_freq; u_int16_t wt_chan_flags; u_int8_t wt_txpower; u_int8_t wt_antenna; }; struct bwn_stats { int32_t rtsfail; int32_t rts; int32_t link_noise; }; /* Noise Calculation (Link Quality) */ struct bwn_noise { uint8_t noi_running; uint8_t noi_nsamples; int8_t noi_samples[8][4]; }; #define BWN_DMA_30BIT 30 #define BWN_DMA_32BIT 32 #define BWN_DMA_64BIT 64 struct bwn_dmadesc_meta { bus_dmamap_t mt_dmap; bus_addr_t mt_paddr; struct mbuf *mt_m; struct ieee80211_node *mt_ni; uint8_t mt_txtype; #define BWN_DMADESC_METATYPE_HEADER 0 #define BWN_DMADESC_METATYPE_BODY 1 uint8_t mt_islast; }; #define BWN_DMAINTR_FATALMASK \ ((1 << 10) | (1 << 11) | (1 << 12) | (1 << 14) | (1 << 15)) #define BWN_DMAINTR_NONFATALMASK (1 << 13) #define BWN_DMAINTR_RX_DONE (1 << 16) #define BWN_DMA32_DCTL_BYTECNT 0x00001fff #define BWN_DMA32_DCTL_ADDREXT_MASK 0x00030000 #define BWN_DMA32_DCTL_ADDREXT_SHIFT 16 #define BWN_DMA32_DCTL_DTABLEEND 0x10000000 #define BWN_DMA32_DCTL_IRQ 0x20000000 #define BWN_DMA32_DCTL_FRAMEEND 0x40000000 #define BWN_DMA32_DCTL_FRAMESTART 0x80000000 struct bwn_dmadesc32 { uint32_t control; uint32_t address; } __packed; #define BWN_DMA64_DCTL0_DTABLEEND 0x10000000 #define BWN_DMA64_DCTL0_IRQ 0x20000000 #define BWN_DMA64_DCTL0_FRAMEEND 0x40000000 #define BWN_DMA64_DCTL0_FRAMESTART 0x80000000 #define BWN_DMA64_DCTL1_BYTECNT 0x00001fff #define BWN_DMA64_DCTL1_ADDREXT_MASK 0x00030000 #define BWN_DMA64_DCTL1_ADDREXT_SHIFT 16 struct bwn_dmadesc64 { uint32_t control0; uint32_t control1; uint32_t address_low; uint32_t address_high; } __packed; struct bwn_dmadesc_generic { union { struct bwn_dmadesc32 dma32; struct bwn_dmadesc64 dma64; } __packed dma; } __packed; struct bwn_dma_ring; struct bwn_dma_ring { struct bwn_mac *dr_mac; const struct bwn_dma_ops *dr_ops; struct bwn_dmadesc_meta *dr_meta; void *dr_txhdr_cache; bus_dma_tag_t dr_ring_dtag; bus_dma_tag_t dr_txring_dtag; bus_dmamap_t dr_spare_dmap; /* only for RX */ bus_dmamap_t dr_ring_dmap; bus_addr_t dr_txring_paddr; void *dr_ring_descbase; bus_addr_t dr_ring_dmabase; int dr_numslots; int dr_usedslot; int dr_curslot; uint32_t dr_frameoffset; uint16_t dr_rx_bufsize; uint16_t dr_base; int dr_index; uint8_t dr_tx; uint8_t dr_stop; int dr_type; void (*getdesc)(struct bwn_dma_ring *, int, struct bwn_dmadesc_generic **, struct bwn_dmadesc_meta **); void (*setdesc)(struct bwn_dma_ring *, struct bwn_dmadesc_generic *, bus_addr_t, uint16_t, int, int, int); void (*start_transfer)(struct bwn_dma_ring *, int); void (*suspend)(struct bwn_dma_ring *); void (*resume)(struct bwn_dma_ring *); int (*get_curslot)(struct bwn_dma_ring *); void (*set_curslot)(struct bwn_dma_ring *, int); }; struct bwn_dma { int dmatype; bus_dma_tag_t parent_dtag; bus_dma_tag_t rxbuf_dtag; bus_dma_tag_t txbuf_dtag; struct bwn_dma_ring *wme[5]; struct bwn_dma_ring *mcast; struct bwn_dma_ring *rx; uint64_t lastseq; /* XXX FIXME */ }; struct bwn_pio_rxqueue { struct bwn_mac *prq_mac; uint16_t prq_base; uint8_t prq_rev; }; struct bwn_pio_txqueue; struct bwn_pio_txpkt { struct bwn_pio_txqueue *tp_queue; struct ieee80211_node *tp_ni; struct mbuf *tp_m; uint8_t tp_index; TAILQ_ENTRY(bwn_pio_txpkt) tp_list; }; #define BWN_PIO_MAX_TXPACKETS 32 struct bwn_pio_txqueue { uint16_t tq_base; uint16_t tq_size; uint16_t tq_used; uint16_t tq_free; uint8_t tq_stop; uint8_t tq_index; struct bwn_pio_txpkt tq_pkts[BWN_PIO_MAX_TXPACKETS]; TAILQ_HEAD(, bwn_pio_txpkt) tq_pktlist; }; struct bwn_pio { struct bwn_pio_txqueue wme[5]; struct bwn_pio_txqueue mcast; struct bwn_pio_rxqueue rx; }; struct bwn_plcp4 { union { uint32_t data; uint8_t raw[4]; } __packed o; } __packed; struct bwn_plcp6 { union { uint32_t data; uint8_t raw[6]; } __packed o; } __packed; struct bwn_txhdr { uint32_t macctl; uint8_t macfc[2]; uint16_t tx_festime; uint16_t phyctl; uint16_t phyctl_1; uint16_t phyctl_1fb; uint16_t phyctl_1rts; uint16_t phyctl_1rtsfb; uint8_t phyrate; uint8_t phyrate_rts; uint8_t eftypes; /* extra frame types */ uint8_t chan; uint8_t iv[16]; uint8_t addr1[IEEE80211_ADDR_LEN]; uint16_t tx_festime_fb; struct bwn_plcp6 rts_plcp_fb; uint16_t rts_dur_fb; struct bwn_plcp6 plcp_fb; uint16_t dur_fb; uint16_t mimo_modelen; uint16_t mimo_ratelen_fb; uint32_t timeout; union { /* format <= r351 */ struct { uint8_t pad0[2]; uint16_t cookie; uint16_t tx_status; struct bwn_plcp6 rts_plcp; uint8_t rts_frame[16]; uint8_t pad1[2];; struct bwn_plcp6 plcp; } __packed old; /* format > r410 */ struct { uint16_t mimo_antenna; uint16_t preload_size; uint8_t pad0[2]; uint16_t cookie; uint16_t tx_status; struct bwn_plcp6 rts_plcp; uint8_t rts_frame[16]; uint8_t pad1[2]; struct bwn_plcp6 plcp; } __packed new; } __packed body; } __packed; #define BWN_FWTYPE_UCODE 'u' #define BWN_FWTYPE_PCM 'p' #define BWN_FWTYPE_IV 'i' struct bwn_fwhdr { uint8_t type; uint8_t ver; uint8_t pad[2]; uint32_t size; } __packed; #define BWN_FWINITVALS_OFFSET_MASK 0x7fff #define BWN_FWINITVALS_32BIT 0x8000 struct bwn_fwinitvals { uint16_t offset_size; union { uint16_t d16; uint32_t d32; } __packed data; } __packed; enum bwn_fwtype { BWN_FWTYPE_DEFAULT, BWN_FWTYPE_OPENSOURCE, BWN_NR_FWTYPES, }; struct bwn_fwfile { const char *filename; const struct firmware *fw; enum bwn_fwtype type; }; struct bwn_key { void *keyconf; uint8_t algorithm; }; struct bwn_fw { struct bwn_fwfile ucode; struct bwn_fwfile pcm; struct bwn_fwfile initvals; struct bwn_fwfile initvals_band; uint16_t rev; uint16_t patch; uint8_t opensource; uint8_t no_pcmfile; }; struct bwn_lo_g_sm { int curstate; int nmeasure; int multipler; uint16_t feedth; struct bwn_loctl loctl; }; struct bwn_lo_g_value { uint8_t old_channel; uint16_t phy_lomask; uint16_t phy_extg; uint16_t phy_dacctl_hwpctl; uint16_t phy_dacctl; uint16_t phy_hpwr_tssictl; uint16_t phy_analogover; uint16_t phy_analogoverval; uint16_t phy_rfover; uint16_t phy_rfoverval; uint16_t phy_classctl; uint16_t phy_crs0; uint16_t phy_pgactl; uint16_t phy_syncctl; uint16_t phy_cck0; uint16_t phy_cck1; uint16_t phy_cck2; uint16_t phy_cck3; uint16_t phy_cck4; uint16_t reg0; uint16_t reg1; uint16_t rf0; uint16_t rf1; uint16_t rf2; }; #define BWN_LED_MAX 4 #define BWN_LED_EVENT_NONE -1 #define BWN_LED_EVENT_POLL 0 #define BWN_LED_EVENT_TX 1 #define BWN_LED_EVENT_RX 2 #define BWN_LED_SLOWDOWN(dur) (dur) = (((dur) * 3) / 2) struct bwn_led { uint8_t led_flags; /* BWN_LED_F_ */ uint8_t led_act; /* BWN_LED_ACT_ */ uint8_t led_mask; }; #define BWN_LED_F_ACTLOW 0x1 #define BWN_LED_F_BLINK 0x2 #define BWN_LED_F_POLLABLE 0x4 #define BWN_LED_F_SLOW 0x8 struct bwn_mac { struct bwn_softc *mac_sc; unsigned mac_status; #define BWN_MAC_STATUS_UNINIT 0 #define BWN_MAC_STATUS_INITED 1 #define BWN_MAC_STATUS_STARTED 2 unsigned mac_flags; /* use "Bad Frames Preemption" */ #define BWN_MAC_FLAG_BADFRAME_PREEMP (1 << 0) #define BWN_MAC_FLAG_DFQVALID (1 << 1) #define BWN_MAC_FLAG_RADIO_ON (1 << 2) #define BWN_MAC_FLAG_DMA (1 << 3) #define BWN_MAC_FLAG_WME (1 << 4) #define BWN_MAC_FLAG_HWCRYPTO (1 << 5) struct resource_spec *mac_intr_spec; #define BWN_MSI_MESSAGES 1 struct resource *mac_res_irq[BWN_MSI_MESSAGES]; void *mac_intrhand[BWN_MSI_MESSAGES]; int mac_msi; struct bwn_noise mac_noise; struct bwn_phy mac_phy; struct bwn_stats mac_stats; uint32_t mac_reason_intr; uint32_t mac_reason[6]; uint32_t mac_intr_mask; int mac_suspended; struct bwn_fw mac_fw; union { struct bwn_dma dma; struct bwn_pio pio; } mac_method; uint16_t mac_ktp; /* Key table pointer */ uint8_t mac_max_nr_keys; struct bwn_key mac_key[58]; unsigned int mac_task_state; struct task mac_intrtask; struct task mac_hwreset; struct task mac_txpower; TAILQ_ENTRY(bwn_mac) mac_list; }; /* * Driver-specific vap state. */ struct bwn_vap { struct ieee80211vap bv_vap; /* base class */ int (*bv_newstate)(struct ieee80211vap *, enum ieee80211_state, int); }; #define BWN_VAP(vap) ((struct bwn_vap *)(vap)) #define BWN_VAP_CONST(vap) ((const struct mwl_vap *)(vap)) struct bwn_softc { device_t sc_dev; struct mtx sc_mtx; struct ifnet *sc_ifp; unsigned sc_flags; #define BWN_FLAG_ATTACHED (1 << 0) #define BWN_FLAG_INVALID (1 << 1) #define BWN_FLAG_NEED_BEACON_TP (1 << 2) unsigned sc_debug; struct bwn_mac *sc_curmac; TAILQ_HEAD(, bwn_mac) sc_maclist; uint8_t sc_macaddr[IEEE80211_ADDR_LEN]; uint8_t sc_bssid[IEEE80211_ADDR_LEN]; unsigned int sc_filters; uint8_t sc_beacons[2]; uint8_t sc_rf_enabled; struct wmeParams sc_wmeParams[4]; struct callout sc_rfswitch_ch; /* for laptop */ struct callout sc_task_ch; struct callout sc_watchdog_ch; int sc_watchdog_timer; struct taskqueue *sc_tq; /* private task queue */ int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int); void (*sc_node_cleanup)( struct ieee80211_node *); int sc_rx_rate; int sc_tx_rate; int sc_led_blinking; int sc_led_ticks; struct bwn_led *sc_blink_led; struct callout sc_led_blink_ch; int sc_led_blink_offdur; struct bwn_led sc_leds[BWN_LED_MAX]; int sc_led_idle; int sc_led_blink; struct bwn_tx_radiotap_header sc_tx_th; struct bwn_rx_radiotap_header sc_rx_th; }; #define BWN_LOCK_INIT(sc) \ mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->sc_dev), \ MTX_NETWORK_LOCK, MTX_DEF) #define BWN_LOCK_DESTROY(sc) mtx_destroy(&(sc)->sc_mtx) #define BWN_LOCK(sc) mtx_lock(&(sc)->sc_mtx) #define BWN_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) #define BWN_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) #endif /* !_IF_BWNVAR_H */