145d9abdbSWeongyo Jeong /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni *
445d9abdbSWeongyo Jeong * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
545d9abdbSWeongyo Jeong * All rights reserved.
645d9abdbSWeongyo Jeong *
745d9abdbSWeongyo Jeong * Redistribution and use in source and binary forms, with or without
845d9abdbSWeongyo Jeong * modification, are permitted provided that the following conditions
945d9abdbSWeongyo Jeong * are met:
1045d9abdbSWeongyo Jeong * 1. Redistributions of source code must retain the above copyright
1145d9abdbSWeongyo Jeong * notice, this list of conditions and the following disclaimer,
1245d9abdbSWeongyo Jeong * without modification.
1345d9abdbSWeongyo Jeong * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1445d9abdbSWeongyo Jeong * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
1545d9abdbSWeongyo Jeong * redistribution must be conditioned upon including a substantially
1645d9abdbSWeongyo Jeong * similar Disclaimer requirement for further binary redistribution.
1745d9abdbSWeongyo Jeong *
1845d9abdbSWeongyo Jeong * NO WARRANTY
1945d9abdbSWeongyo Jeong * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2045d9abdbSWeongyo Jeong * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2145d9abdbSWeongyo Jeong * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
2245d9abdbSWeongyo Jeong * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
2345d9abdbSWeongyo Jeong * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
2445d9abdbSWeongyo Jeong * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2545d9abdbSWeongyo Jeong * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2645d9abdbSWeongyo Jeong * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
2745d9abdbSWeongyo Jeong * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2845d9abdbSWeongyo Jeong * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2945d9abdbSWeongyo Jeong * THE POSSIBILITY OF SUCH DAMAGES.
3045d9abdbSWeongyo Jeong */
3145d9abdbSWeongyo Jeong
3245d9abdbSWeongyo Jeong #ifndef _IF_BWNVAR_H
3345d9abdbSWeongyo Jeong #define _IF_BWNVAR_H
3445d9abdbSWeongyo Jeong
35d177c199SLandon J. Fuller #include <dev/bhnd/bhnd.h>
368d14ca9cSLandon J. Fuller
3745d9abdbSWeongyo Jeong struct bwn_softc;
3845d9abdbSWeongyo Jeong struct bwn_mac;
3945d9abdbSWeongyo Jeong
4045d9abdbSWeongyo Jeong #define N(a) (sizeof(a) / sizeof(a[0]))
4145d9abdbSWeongyo Jeong #define BWN_ALIGN 0x1000
4245d9abdbSWeongyo Jeong #define BWN_RETRY_SHORT 7
4345d9abdbSWeongyo Jeong #define BWN_RETRY_LONG 4
4445d9abdbSWeongyo Jeong #define BWN_STAID_MAX 64
4545d9abdbSWeongyo Jeong #define BWN_TXPWR_IGNORE_TIME (1 << 0)
4645d9abdbSWeongyo Jeong #define BWN_TXPWR_IGNORE_TSSI (1 << 1)
4745d9abdbSWeongyo Jeong #define BWN_HAS_TXMAG(phy) \
4845d9abdbSWeongyo Jeong (((phy)->rev >= 2) && ((phy)->rf_ver == 0x2050) && \
4945d9abdbSWeongyo Jeong ((phy)->rf_rev == 8))
5045d9abdbSWeongyo Jeong #define BWN_HAS_LOOPBACK(phy) \
5145d9abdbSWeongyo Jeong (((phy)->rev > 1) || ((phy)->gmode))
5245d9abdbSWeongyo Jeong #define BWN_TXERROR_MAX 1000
5345d9abdbSWeongyo Jeong #define BWN_GETTIME(v) do { \
5445d9abdbSWeongyo Jeong struct timespec ts; \
5545d9abdbSWeongyo Jeong nanouptime(&ts); \
5645d9abdbSWeongyo Jeong (v) = ts.tv_nsec / 1000000 + ts.tv_sec * 1000; \
5745d9abdbSWeongyo Jeong } while (0)
5845d9abdbSWeongyo Jeong #define BWN_ISOLDFMT(mac) ((mac)->mac_fw.rev <= 351)
5945d9abdbSWeongyo Jeong #define BWN_TSSI2DBM(num, den) \
6045d9abdbSWeongyo Jeong ((int32_t)((num < 0) ? num / den : (num + den / 2) / den))
611ea96818SAdrian Chadd #define BWN_HDRSIZE(mac) bwn_tx_hdrsize(mac)
62f629a238SAdrian Chadd #define BWN_MAXTXHDRSIZE (112 + (sizeof(struct bwn_plcp6)))
631ea96818SAdrian Chadd
6445d9abdbSWeongyo Jeong #define BWN_PIO_COOKIE(tq, tp) \
6545d9abdbSWeongyo Jeong ((uint16_t)((((uint16_t)tq->tq_index + 1) << 12) | tp->tp_index))
6645d9abdbSWeongyo Jeong #define BWN_DMA_COOKIE(dr, slot) \
6745d9abdbSWeongyo Jeong ((uint16_t)(((uint16_t)dr->dr_index + 1) << 12) | (uint16_t)slot)
68d177c199SLandon J. Fuller #define BWN_READ_2(mac, o) \
69d177c199SLandon J. Fuller (bus_read_2((mac)->mac_sc->sc_mem_res, (o)))
70d177c199SLandon J. Fuller #define BWN_READ_4(mac, o) \
71d177c199SLandon J. Fuller (bus_read_4((mac)->mac_sc->sc_mem_res, (o)))
72b9b64aa5SWeongyo Jeong #define BWN_WRITE_2(mac, o, v) \
73d177c199SLandon J. Fuller (bus_write_2((mac)->mac_sc->sc_mem_res, (o), (v)))
741ea96818SAdrian Chadd #define BWN_WRITE_2_F(mac, o, v) do { \
751ea96818SAdrian Chadd (BWN_WRITE_2(mac, o, v)); \
761ea96818SAdrian Chadd BWN_READ_2(mac, o); \
771ea96818SAdrian Chadd } while(0)
781ea96818SAdrian Chadd #define BWN_WRITE_SETMASK2(mac, offset, mask, set) \
791ea96818SAdrian Chadd BWN_WRITE_2(mac, offset, (BWN_READ_2(mac, offset) & mask) | set)
80b9b64aa5SWeongyo Jeong #define BWN_WRITE_4(mac, o, v) \
81d177c199SLandon J. Fuller (bus_write_4((mac)->mac_sc->sc_mem_res, (o), (v)))
821ea96818SAdrian Chadd #define BWN_WRITE_SETMASK4(mac, offset, mask, set) \
831ea96818SAdrian Chadd BWN_WRITE_4(mac, offset, (BWN_READ_4(mac, offset) & mask) | set)
8445d9abdbSWeongyo Jeong #define BWN_PIO_TXQOFFSET(mac) \
85d177c199SLandon J. Fuller ((bhnd_get_hwrev(mac->mac_sc->sc_dev) >= 11) ? 0x18 : 0)
8645d9abdbSWeongyo Jeong #define BWN_PIO_RXQOFFSET(mac) \
87d177c199SLandon J. Fuller ((bhnd_get_hwrev(mac->mac_sc->sc_dev) >= 11) ? 0x38 : 8)
8845d9abdbSWeongyo Jeong #define BWN_SEC_NEWAPI(mac) (mac->mac_fw.rev >= 351)
8945d9abdbSWeongyo Jeong #define BWN_SEC_KEY2FW(mac, idx) \
9045d9abdbSWeongyo Jeong (BWN_SEC_NEWAPI(mac) ? idx : ((idx >= 4) ? idx - 4 : idx))
9145d9abdbSWeongyo Jeong #define BWN_RF_READ(mac, r) (mac->mac_phy.rf_read(mac, r))
9245d9abdbSWeongyo Jeong #define BWN_RF_WRITE(mac, r, v) (mac->mac_phy.rf_write(mac, r, v))
9345d9abdbSWeongyo Jeong #define BWN_RF_MASK(mac, o, m) \
9445d9abdbSWeongyo Jeong BWN_RF_WRITE(mac, o, BWN_RF_READ(mac, o) & m)
9545d9abdbSWeongyo Jeong #define BWN_RF_SETMASK(mac, offset, mask, set) \
9645d9abdbSWeongyo Jeong BWN_RF_WRITE(mac, offset, (BWN_RF_READ(mac, offset) & mask) | set)
9745d9abdbSWeongyo Jeong #define BWN_RF_SET(mac, offset, set) \
9845d9abdbSWeongyo Jeong BWN_RF_WRITE(mac, offset, BWN_RF_READ(mac, offset) | set)
9945d9abdbSWeongyo Jeong #define BWN_PHY_READ(mac, r) (mac->mac_phy.phy_read(mac, r))
10045d9abdbSWeongyo Jeong #define BWN_PHY_WRITE(mac, r, v) \
10145d9abdbSWeongyo Jeong (mac->mac_phy.phy_write(mac, r, v))
10245d9abdbSWeongyo Jeong #define BWN_PHY_SET(mac, offset, set) do { \
10345d9abdbSWeongyo Jeong if (mac->mac_phy.phy_maskset != NULL) { \
10445d9abdbSWeongyo Jeong KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED || \
10545d9abdbSWeongyo Jeong mac->mac_suspended > 0, \
10645d9abdbSWeongyo Jeong ("dont access PHY or RF registers after turning on MAC")); \
10745d9abdbSWeongyo Jeong mac->mac_phy.phy_maskset(mac, offset, 0xffff, set); \
10845d9abdbSWeongyo Jeong } else \
10945d9abdbSWeongyo Jeong BWN_PHY_WRITE(mac, offset, \
11045d9abdbSWeongyo Jeong BWN_PHY_READ(mac, offset) | (set)); \
11145d9abdbSWeongyo Jeong } while (0)
11245d9abdbSWeongyo Jeong #define BWN_PHY_SETMASK(mac, offset, mask, set) do { \
11345d9abdbSWeongyo Jeong if (mac->mac_phy.phy_maskset != NULL) { \
11445d9abdbSWeongyo Jeong KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED || \
11545d9abdbSWeongyo Jeong mac->mac_suspended > 0, \
11645d9abdbSWeongyo Jeong ("dont access PHY or RF registers after turning on MAC")); \
11745d9abdbSWeongyo Jeong mac->mac_phy.phy_maskset(mac, offset, mask, set); \
11845d9abdbSWeongyo Jeong } else \
11945d9abdbSWeongyo Jeong BWN_PHY_WRITE(mac, offset, \
12045d9abdbSWeongyo Jeong (BWN_PHY_READ(mac, offset) & (mask)) | (set)); \
12145d9abdbSWeongyo Jeong } while (0)
12245d9abdbSWeongyo Jeong #define BWN_PHY_MASK(mac, offset, mask) do { \
12345d9abdbSWeongyo Jeong if (mac->mac_phy.phy_maskset != NULL) { \
12445d9abdbSWeongyo Jeong KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED || \
12545d9abdbSWeongyo Jeong mac->mac_suspended > 0, \
12645d9abdbSWeongyo Jeong ("dont access PHY or RF registers after turning on MAC")); \
12745d9abdbSWeongyo Jeong mac->mac_phy.phy_maskset(mac, offset, mask, 0); \
12845d9abdbSWeongyo Jeong } else \
12945d9abdbSWeongyo Jeong BWN_PHY_WRITE(mac, offset, \
1309005a5a0SBrooks Davis BWN_PHY_READ(mac, offset) & (mask)); \
13145d9abdbSWeongyo Jeong } while (0)
13245d9abdbSWeongyo Jeong #define BWN_PHY_COPY(mac, dst, src) do { \
13345d9abdbSWeongyo Jeong KASSERT(mac->mac_status < BWN_MAC_STATUS_INITED || \
13445d9abdbSWeongyo Jeong mac->mac_suspended > 0, \
13545d9abdbSWeongyo Jeong ("dont access PHY or RF registers after turning on MAC")); \
13645d9abdbSWeongyo Jeong BWN_PHY_WRITE(mac, dst, BWN_PHY_READ(mac, src)); \
13745d9abdbSWeongyo Jeong } while (0)
13845d9abdbSWeongyo Jeong #define BWN_LO_CALIB_EXPIRE (1000 * (30 - 2))
13945d9abdbSWeongyo Jeong #define BWN_LO_PWRVEC_EXPIRE (1000 * (30 - 2))
14045d9abdbSWeongyo Jeong #define BWN_LO_TXCTL_EXPIRE (1000 * (180 - 4))
14145d9abdbSWeongyo Jeong #define BWN_LPD(L, P, D) (((L) << 2) | ((P) << 1) | ((D) << 0))
14245d9abdbSWeongyo Jeong #define BWN_BITREV4(tmp) (BWN_BITREV8(tmp) >> 4)
14345d9abdbSWeongyo Jeong #define BWN_BITREV8(byte) (bwn_bitrev_table[byte])
14445d9abdbSWeongyo Jeong #define BWN_BBATTCMP(a, b) ((a)->att == (b)->att)
14545d9abdbSWeongyo Jeong #define BWN_RFATTCMP(a, b) \
14645d9abdbSWeongyo Jeong (((a)->att == (b)->att) && ((a)->padmix == (b)->padmix))
14745d9abdbSWeongyo Jeong #define BWN_PIO_WRITE_2(mac, tq, offset, value) \
14845d9abdbSWeongyo Jeong BWN_WRITE_2(mac, (tq)->tq_base + offset, value)
14945d9abdbSWeongyo Jeong #define BWN_PIO_READ_4(mac, tq, offset) \
15045d9abdbSWeongyo Jeong BWN_READ_4(mac, tq->tq_base + offset)
15145d9abdbSWeongyo Jeong #define BWN_ISCCKRATE(rate) \
15245d9abdbSWeongyo Jeong (rate == BWN_CCK_RATE_1MB || rate == BWN_CCK_RATE_2MB || \
15345d9abdbSWeongyo Jeong rate == BWN_CCK_RATE_5MB || rate == BWN_CCK_RATE_11MB)
15445d9abdbSWeongyo Jeong #define BWN_ISOFDMRATE(rate) (!BWN_ISCCKRATE(rate))
155d177c199SLandon J. Fuller #define BWN_BARRIER(mac, offset, length, flags) \
156d177c199SLandon J. Fuller bus_barrier((mac)->mac_sc->sc_mem_res, (offset), (length), (flags))
15745d9abdbSWeongyo Jeong #define BWN_DMA_READ(dr, offset) \
15845d9abdbSWeongyo Jeong (BWN_READ_4(dr->dr_mac, dr->dr_base + offset))
15945d9abdbSWeongyo Jeong #define BWN_DMA_WRITE(dr, offset, value) \
16045d9abdbSWeongyo Jeong (BWN_WRITE_4(dr->dr_mac, dr->dr_base + offset, value))
16145d9abdbSWeongyo Jeong
1621ea96818SAdrian Chadd typedef enum {
1631ea96818SAdrian Chadd BWN_PHY_BAND_2G = 0,
1641ea96818SAdrian Chadd BWN_PHY_BAND_5G_LO = 1,
1651ea96818SAdrian Chadd BWN_PHY_BAND_5G_MI = 2,
1661ea96818SAdrian Chadd BWN_PHY_BAND_5G_HI = 3
1671ea96818SAdrian Chadd } bwn_phy_band_t;
1681ea96818SAdrian Chadd
1691ea96818SAdrian Chadd typedef enum {
1701ea96818SAdrian Chadd BWN_BAND_2G,
1711ea96818SAdrian Chadd BWN_BAND_5G,
1721ea96818SAdrian Chadd } bwn_band_t;
1731ea96818SAdrian Chadd
1741ea96818SAdrian Chadd typedef enum {
1751ea96818SAdrian Chadd BWN_CHAN_TYPE_20,
1761ea96818SAdrian Chadd BWN_CHAN_TYPE_20_HT,
1771ea96818SAdrian Chadd BWN_CHAN_TYPE_40_HT_U,
1781ea96818SAdrian Chadd BWN_CHAN_TYPE_40_HT_D,
1791ea96818SAdrian Chadd } bwn_chan_type_t;
1801ea96818SAdrian Chadd
18145d9abdbSWeongyo Jeong struct bwn_rate {
18245d9abdbSWeongyo Jeong uint16_t rateid;
18345d9abdbSWeongyo Jeong uint32_t flags;
18445d9abdbSWeongyo Jeong };
18545d9abdbSWeongyo Jeong
18645d9abdbSWeongyo Jeong #define BWN_ANT0 0
18745d9abdbSWeongyo Jeong #define BWN_ANT1 1
18845d9abdbSWeongyo Jeong #define BWN_ANTAUTO0 2
18945d9abdbSWeongyo Jeong #define BWN_ANTAUTO1 3
19045d9abdbSWeongyo Jeong #define BWN_ANT2 4
19145d9abdbSWeongyo Jeong #define BWN_ANT3 8
19245d9abdbSWeongyo Jeong #define BWN_ANTAUTO BWN_ANTAUTO0
19345d9abdbSWeongyo Jeong #define BWN_ANT_DEFAULT BWN_ANTAUTO
19445d9abdbSWeongyo Jeong #define BWN_TX_SLOTS_PER_FRAME 2
19545d9abdbSWeongyo Jeong
19645d9abdbSWeongyo Jeong struct bwn_channel {
19745d9abdbSWeongyo Jeong unsigned freq;
19845d9abdbSWeongyo Jeong unsigned ieee;
19945d9abdbSWeongyo Jeong unsigned maxTxPow;
20045d9abdbSWeongyo Jeong };
20145d9abdbSWeongyo Jeong
20245d9abdbSWeongyo Jeong struct bwn_channelinfo {
20345d9abdbSWeongyo Jeong struct bwn_channel channels[IEEE80211_CHAN_MAX];
20445d9abdbSWeongyo Jeong unsigned nchannels;
20545d9abdbSWeongyo Jeong };
20645d9abdbSWeongyo Jeong
20745d9abdbSWeongyo Jeong struct bwn_bbatt {
20845d9abdbSWeongyo Jeong uint8_t att;
20945d9abdbSWeongyo Jeong };
21045d9abdbSWeongyo Jeong
21145d9abdbSWeongyo Jeong struct bwn_bbatt_list {
21245d9abdbSWeongyo Jeong const struct bwn_bbatt *array;
21345d9abdbSWeongyo Jeong uint8_t len;
21445d9abdbSWeongyo Jeong uint8_t min;
21545d9abdbSWeongyo Jeong uint8_t max;
21645d9abdbSWeongyo Jeong };
21745d9abdbSWeongyo Jeong
21845d9abdbSWeongyo Jeong struct bwn_rfatt {
21945d9abdbSWeongyo Jeong uint8_t att;
22045d9abdbSWeongyo Jeong int padmix;
22145d9abdbSWeongyo Jeong };
22245d9abdbSWeongyo Jeong
22345d9abdbSWeongyo Jeong struct bwn_rfatt_list {
22445d9abdbSWeongyo Jeong const struct bwn_rfatt *array;
22545d9abdbSWeongyo Jeong uint8_t len;
22645d9abdbSWeongyo Jeong uint8_t min;
22745d9abdbSWeongyo Jeong uint8_t max;
22845d9abdbSWeongyo Jeong };
22945d9abdbSWeongyo Jeong
23045d9abdbSWeongyo Jeong #define BWN_DC_LT_SIZE 32
23145d9abdbSWeongyo Jeong
23245d9abdbSWeongyo Jeong struct bwn_loctl {
23345d9abdbSWeongyo Jeong int8_t i;
23445d9abdbSWeongyo Jeong int8_t q;
23545d9abdbSWeongyo Jeong };
23645d9abdbSWeongyo Jeong
2371ea96818SAdrian Chadd typedef enum {
2381ea96818SAdrian Chadd BWN_TXPWR_RES_NEED_ADJUST,
2391ea96818SAdrian Chadd BWN_TXPWR_RES_DONE,
2401ea96818SAdrian Chadd } bwn_txpwr_result_t;
2411ea96818SAdrian Chadd
24245d9abdbSWeongyo Jeong struct bwn_lo_calib {
24345d9abdbSWeongyo Jeong struct bwn_bbatt bbatt;
24445d9abdbSWeongyo Jeong struct bwn_rfatt rfatt;
24545d9abdbSWeongyo Jeong struct bwn_loctl ctl;
24645d9abdbSWeongyo Jeong unsigned long calib_time;
24745d9abdbSWeongyo Jeong TAILQ_ENTRY(bwn_lo_calib) list;
24845d9abdbSWeongyo Jeong };
24945d9abdbSWeongyo Jeong
25045d9abdbSWeongyo Jeong struct bwn_rxhdr4 {
25145d9abdbSWeongyo Jeong uint16_t frame_len;
25245d9abdbSWeongyo Jeong uint8_t pad1[2];
25345d9abdbSWeongyo Jeong uint16_t phy_status0;
25445d9abdbSWeongyo Jeong union {
25545d9abdbSWeongyo Jeong struct {
25645d9abdbSWeongyo Jeong uint8_t rssi;
25745d9abdbSWeongyo Jeong uint8_t sig_qual;
25845d9abdbSWeongyo Jeong } __packed abg;
25945d9abdbSWeongyo Jeong struct {
26045d9abdbSWeongyo Jeong int8_t power0;
26145d9abdbSWeongyo Jeong int8_t power1;
26245d9abdbSWeongyo Jeong } __packed n;
26345d9abdbSWeongyo Jeong } __packed phy;
2641ea96818SAdrian Chadd union {
2651ea96818SAdrian Chadd struct {
2661ea96818SAdrian Chadd int8_t power2;
2671ea96818SAdrian Chadd uint8_t pad;
2681ea96818SAdrian Chadd } __packed n;
2691ea96818SAdrian Chadd struct {
2701ea96818SAdrian Chadd uint8_t pad;
2711ea96818SAdrian Chadd int8_t ht_power0;
2721ea96818SAdrian Chadd } __packed ht;
27345d9abdbSWeongyo Jeong uint16_t phy_status2;
2741ea96818SAdrian Chadd } __packed ps2;
275a74bf020SAdrian Chadd union {
276a74bf020SAdrian Chadd struct {
27745d9abdbSWeongyo Jeong uint16_t phy_status3;
278a74bf020SAdrian Chadd } __packed lp;
279a74bf020SAdrian Chadd struct {
280a74bf020SAdrian Chadd int8_t phy_ht_power1;
281a74bf020SAdrian Chadd int8_t phy_ht_power2;
282a74bf020SAdrian Chadd } __packed ht;
283a74bf020SAdrian Chadd } __packed ps3;
284a74bf020SAdrian Chadd union {
285a74bf020SAdrian Chadd struct {
28645d9abdbSWeongyo Jeong uint32_t mac_status;
28745d9abdbSWeongyo Jeong uint16_t mac_time;
28845d9abdbSWeongyo Jeong uint16_t channel;
289a74bf020SAdrian Chadd } __packed r351;
290a74bf020SAdrian Chadd struct {
291a74bf020SAdrian Chadd uint16_t phy_status4;
292a74bf020SAdrian Chadd uint16_t phy_status5;
293a74bf020SAdrian Chadd uint32_t mac_status;
294a74bf020SAdrian Chadd uint16_t mac_time;
295a74bf020SAdrian Chadd uint16_t channel;
296a74bf020SAdrian Chadd } __packed r598;
297a74bf020SAdrian Chadd } __packed ps4;
29845d9abdbSWeongyo Jeong } __packed;
29945d9abdbSWeongyo Jeong
30045d9abdbSWeongyo Jeong struct bwn_txstatus {
30145d9abdbSWeongyo Jeong uint16_t cookie;
30245d9abdbSWeongyo Jeong uint16_t seq;
30345d9abdbSWeongyo Jeong uint8_t phy_stat;
30445d9abdbSWeongyo Jeong uint8_t framecnt;
30545d9abdbSWeongyo Jeong uint8_t rtscnt;
30645d9abdbSWeongyo Jeong uint8_t sreason;
30745d9abdbSWeongyo Jeong uint8_t pm;
30845d9abdbSWeongyo Jeong uint8_t im;
30945d9abdbSWeongyo Jeong uint8_t ampdu;
31045d9abdbSWeongyo Jeong uint8_t ack;
31145d9abdbSWeongyo Jeong };
31245d9abdbSWeongyo Jeong
31345d9abdbSWeongyo Jeong #define BWN_TXCTL_PA3DB 0x40
31445d9abdbSWeongyo Jeong #define BWN_TXCTL_PA2DB 0x20
31545d9abdbSWeongyo Jeong #define BWN_TXCTL_TXMIX 0x10
31645d9abdbSWeongyo Jeong
31745d9abdbSWeongyo Jeong struct bwn_txpwr_loctl {
31845d9abdbSWeongyo Jeong struct bwn_rfatt_list rfatt;
31945d9abdbSWeongyo Jeong struct bwn_bbatt_list bbatt;
32045d9abdbSWeongyo Jeong uint16_t dc_lt[BWN_DC_LT_SIZE];
32145d9abdbSWeongyo Jeong TAILQ_HEAD(, bwn_lo_calib) calib_list;
32245d9abdbSWeongyo Jeong unsigned long pwr_vec_read_time;
32345d9abdbSWeongyo Jeong unsigned long txctl_measured_time;
32445d9abdbSWeongyo Jeong uint8_t tx_bias;
32545d9abdbSWeongyo Jeong uint8_t tx_magn;
32645d9abdbSWeongyo Jeong uint64_t power_vector;
32745d9abdbSWeongyo Jeong };
32845d9abdbSWeongyo Jeong
32945d9abdbSWeongyo Jeong #define BWN_OFDMTAB_DIR_UNKNOWN 0
33045d9abdbSWeongyo Jeong #define BWN_OFDMTAB_DIR_READ 1
33145d9abdbSWeongyo Jeong #define BWN_OFDMTAB_DIR_WRITE 2
33245d9abdbSWeongyo Jeong
33345d9abdbSWeongyo Jeong struct bwn_phy_g {
33445d9abdbSWeongyo Jeong unsigned pg_flags;
33545d9abdbSWeongyo Jeong #define BWN_PHY_G_FLAG_TSSITABLE_ALLOC (1 << 0)
33645d9abdbSWeongyo Jeong #define BWN_PHY_G_FLAG_RADIOCTX_VALID (1 << 1)
33745d9abdbSWeongyo Jeong int pg_aci_enable;
33845d9abdbSWeongyo Jeong int pg_aci_wlan_automatic;
33945d9abdbSWeongyo Jeong int pg_aci_hw_rssi;
34045d9abdbSWeongyo Jeong int pg_rf_on;
34145d9abdbSWeongyo Jeong uint16_t pg_radioctx_over;
34245d9abdbSWeongyo Jeong uint16_t pg_radioctx_overval;
34345d9abdbSWeongyo Jeong uint16_t pg_minlowsig[2];
34445d9abdbSWeongyo Jeong uint16_t pg_minlowsigpos[2];
345d177c199SLandon J. Fuller uint16_t pg_pa0maxpwr;
34645d9abdbSWeongyo Jeong int8_t *pg_tssi2dbm;
34745d9abdbSWeongyo Jeong int pg_idletssi;
34845d9abdbSWeongyo Jeong int pg_curtssi;
34945d9abdbSWeongyo Jeong uint8_t pg_avgtssi;
35045d9abdbSWeongyo Jeong struct bwn_bbatt pg_bbatt;
35145d9abdbSWeongyo Jeong struct bwn_rfatt pg_rfatt;
35245d9abdbSWeongyo Jeong uint8_t pg_txctl;
35345d9abdbSWeongyo Jeong int pg_bbatt_delta;
35445d9abdbSWeongyo Jeong int pg_rfatt_delta;
35545d9abdbSWeongyo Jeong
35645d9abdbSWeongyo Jeong struct bwn_txpwr_loctl pg_loctl;
35745d9abdbSWeongyo Jeong int16_t pg_max_lb_gain;
35845d9abdbSWeongyo Jeong int16_t pg_trsw_rx_gain;
35945d9abdbSWeongyo Jeong int16_t pg_lna_lod_gain;
36045d9abdbSWeongyo Jeong int16_t pg_lna_gain;
36145d9abdbSWeongyo Jeong int16_t pg_pga_gain;
36245d9abdbSWeongyo Jeong int pg_immode;
36345d9abdbSWeongyo Jeong #define BWN_INTERFSTACK_SIZE 26
36445d9abdbSWeongyo Jeong uint32_t pg_interfstack[BWN_INTERFSTACK_SIZE];
36545d9abdbSWeongyo Jeong
36645d9abdbSWeongyo Jeong int16_t pg_nrssi[2];
36745d9abdbSWeongyo Jeong int32_t pg_nrssi_slope;
36845d9abdbSWeongyo Jeong int8_t pg_nrssi_lt[64];
36945d9abdbSWeongyo Jeong
37045d9abdbSWeongyo Jeong uint16_t pg_lofcal;
37145d9abdbSWeongyo Jeong
37245d9abdbSWeongyo Jeong uint16_t pg_initval;
37345d9abdbSWeongyo Jeong uint16_t pg_ofdmtab_addr;
37445d9abdbSWeongyo Jeong unsigned pg_ofdmtab_dir;
37545d9abdbSWeongyo Jeong };
37645d9abdbSWeongyo Jeong
37745d9abdbSWeongyo Jeong #define BWN_IMMODE_NONE 0
37845d9abdbSWeongyo Jeong #define BWN_IMMODE_NONWLAN 1
37945d9abdbSWeongyo Jeong #define BWN_IMMODE_MANUAL 2
38045d9abdbSWeongyo Jeong #define BWN_IMMODE_AUTO 3
38145d9abdbSWeongyo Jeong
38245d9abdbSWeongyo Jeong #define BWN_PHYLP_TXPCTL_UNKNOWN 0
38345d9abdbSWeongyo Jeong #define BWN_PHYLP_TXPCTL_OFF 1
38445d9abdbSWeongyo Jeong #define BWN_PHYLP_TXPCTL_ON_SW 2
38545d9abdbSWeongyo Jeong #define BWN_PHYLP_TXPCTL_ON_HW 3
38645d9abdbSWeongyo Jeong
38745d9abdbSWeongyo Jeong struct bwn_phy_lp {
38845d9abdbSWeongyo Jeong uint8_t plp_chan;
38945d9abdbSWeongyo Jeong uint8_t plp_chanfullcal;
39045d9abdbSWeongyo Jeong int32_t plp_antenna;
39145d9abdbSWeongyo Jeong uint8_t plp_txpctlmode;
39245d9abdbSWeongyo Jeong uint8_t plp_txisoband_h;
39345d9abdbSWeongyo Jeong uint8_t plp_txisoband_m;
39445d9abdbSWeongyo Jeong uint8_t plp_txisoband_l;
39545d9abdbSWeongyo Jeong uint8_t plp_rxpwroffset;
39645d9abdbSWeongyo Jeong int8_t plp_txpwridx;
39745d9abdbSWeongyo Jeong uint16_t plp_tssiidx;
39845d9abdbSWeongyo Jeong uint16_t plp_tssinpt;
39945d9abdbSWeongyo Jeong uint8_t plp_rssivf;
40045d9abdbSWeongyo Jeong uint8_t plp_rssivc;
40145d9abdbSWeongyo Jeong uint8_t plp_rssigs;
40245d9abdbSWeongyo Jeong uint8_t plp_rccap;
40345d9abdbSWeongyo Jeong uint8_t plp_bxarch;
40445d9abdbSWeongyo Jeong uint8_t plp_crsusr_off;
40545d9abdbSWeongyo Jeong uint8_t plp_crssys_off;
40645d9abdbSWeongyo Jeong uint32_t plp_div;
40745d9abdbSWeongyo Jeong int32_t plp_tonefreq;
40845d9abdbSWeongyo Jeong uint16_t plp_digfilt[9];
40945d9abdbSWeongyo Jeong };
41045d9abdbSWeongyo Jeong
41145d9abdbSWeongyo Jeong /* for LP */
41245d9abdbSWeongyo Jeong struct bwn_txgain {
41345d9abdbSWeongyo Jeong uint16_t tg_gm;
41445d9abdbSWeongyo Jeong uint16_t tg_pga;
41545d9abdbSWeongyo Jeong uint16_t tg_pad;
41645d9abdbSWeongyo Jeong uint16_t tg_dac;
41745d9abdbSWeongyo Jeong };
41845d9abdbSWeongyo Jeong
41945d9abdbSWeongyo Jeong struct bwn_rxcompco {
42045d9abdbSWeongyo Jeong uint8_t rc_chan;
42145d9abdbSWeongyo Jeong int8_t rc_c1;
42245d9abdbSWeongyo Jeong int8_t rc_c0;
42345d9abdbSWeongyo Jeong };
42445d9abdbSWeongyo Jeong
42545d9abdbSWeongyo Jeong struct bwn_phy_lp_iq_est {
42645d9abdbSWeongyo Jeong uint32_t ie_iqprod;
42745d9abdbSWeongyo Jeong uint32_t ie_ipwr;
42845d9abdbSWeongyo Jeong uint32_t ie_qpwr;
42945d9abdbSWeongyo Jeong };
43045d9abdbSWeongyo Jeong
43145d9abdbSWeongyo Jeong struct bwn_txgain_entry {
43245d9abdbSWeongyo Jeong uint8_t te_gm;
43345d9abdbSWeongyo Jeong uint8_t te_pga;
43445d9abdbSWeongyo Jeong uint8_t te_pad;
43545d9abdbSWeongyo Jeong uint8_t te_dac;
43645d9abdbSWeongyo Jeong uint8_t te_bbmult;
43745d9abdbSWeongyo Jeong };
43845d9abdbSWeongyo Jeong
43945d9abdbSWeongyo Jeong /* only for LP PHY */
44045d9abdbSWeongyo Jeong struct bwn_stxtable {
44145d9abdbSWeongyo Jeong uint16_t st_phyoffset;
44245d9abdbSWeongyo Jeong uint16_t st_physhift;
44345d9abdbSWeongyo Jeong uint16_t st_rfaddr;
44445d9abdbSWeongyo Jeong uint16_t st_rfshift;
44545d9abdbSWeongyo Jeong uint16_t st_mask;
44645d9abdbSWeongyo Jeong };
44745d9abdbSWeongyo Jeong
44845d9abdbSWeongyo Jeong struct bwn_b206x_chan {
44945d9abdbSWeongyo Jeong uint8_t bc_chan;
45045d9abdbSWeongyo Jeong uint16_t bc_freq;
45145d9abdbSWeongyo Jeong const uint8_t *bc_data;
45245d9abdbSWeongyo Jeong };
45345d9abdbSWeongyo Jeong
45445d9abdbSWeongyo Jeong struct bwn_b206x_rfinit_entry {
45545d9abdbSWeongyo Jeong uint16_t br_offset;
45645d9abdbSWeongyo Jeong uint16_t br_valuea;
45745d9abdbSWeongyo Jeong uint16_t br_valueg;
45845d9abdbSWeongyo Jeong uint8_t br_flags;
45945d9abdbSWeongyo Jeong };
46045d9abdbSWeongyo Jeong
4611ea96818SAdrian Chadd struct bwn_phy_n;
4621ea96818SAdrian Chadd
46345d9abdbSWeongyo Jeong struct bwn_phy {
46445d9abdbSWeongyo Jeong uint8_t type;
46545d9abdbSWeongyo Jeong uint8_t rev;
46645d9abdbSWeongyo Jeong uint8_t analog;
46745d9abdbSWeongyo Jeong
46845d9abdbSWeongyo Jeong int supports_2ghz;
46945d9abdbSWeongyo Jeong int supports_5ghz;
47045d9abdbSWeongyo Jeong
47145d9abdbSWeongyo Jeong int gmode;
47245d9abdbSWeongyo Jeong struct bwn_phy_g phy_g;
47345d9abdbSWeongyo Jeong struct bwn_phy_lp phy_lp;
47445d9abdbSWeongyo Jeong
4751ea96818SAdrian Chadd /*
4761ea96818SAdrian Chadd * I'd like the newer PHY code to not hide in the top-level
4771ea96818SAdrian Chadd * structs..
4781ea96818SAdrian Chadd */
4791ea96818SAdrian Chadd struct bwn_phy_n *phy_n;
4801ea96818SAdrian Chadd
48145d9abdbSWeongyo Jeong uint16_t rf_manuf;
48245d9abdbSWeongyo Jeong uint16_t rf_ver;
48345d9abdbSWeongyo Jeong uint8_t rf_rev;
48445d9abdbSWeongyo Jeong int rf_on;
4851ea96818SAdrian Chadd int phy_do_full_init;
48645d9abdbSWeongyo Jeong
48745d9abdbSWeongyo Jeong int txpower;
48845d9abdbSWeongyo Jeong int hwpctl;
48945d9abdbSWeongyo Jeong unsigned long nexttime;
49045d9abdbSWeongyo Jeong unsigned int chan;
49145d9abdbSWeongyo Jeong int txerrors;
49245d9abdbSWeongyo Jeong
49345d9abdbSWeongyo Jeong int (*attach)(struct bwn_mac *);
49445d9abdbSWeongyo Jeong void (*detach)(struct bwn_mac *);
49545d9abdbSWeongyo Jeong int (*prepare_hw)(struct bwn_mac *);
49645d9abdbSWeongyo Jeong void (*init_pre)(struct bwn_mac *);
49745d9abdbSWeongyo Jeong int (*init)(struct bwn_mac *);
49845d9abdbSWeongyo Jeong void (*exit)(struct bwn_mac *);
49945d9abdbSWeongyo Jeong uint16_t (*phy_read)(struct bwn_mac *, uint16_t);
50045d9abdbSWeongyo Jeong void (*phy_write)(struct bwn_mac *, uint16_t,
50145d9abdbSWeongyo Jeong uint16_t);
50245d9abdbSWeongyo Jeong void (*phy_maskset)(struct bwn_mac *,
50345d9abdbSWeongyo Jeong uint16_t, uint16_t, uint16_t);
50445d9abdbSWeongyo Jeong uint16_t (*rf_read)(struct bwn_mac *, uint16_t);
50545d9abdbSWeongyo Jeong void (*rf_write)(struct bwn_mac *, uint16_t,
50645d9abdbSWeongyo Jeong uint16_t);
50745d9abdbSWeongyo Jeong int (*use_hwpctl)(struct bwn_mac *);
50845d9abdbSWeongyo Jeong void (*rf_onoff)(struct bwn_mac *, int);
50945d9abdbSWeongyo Jeong void (*switch_analog)(struct bwn_mac *, int);
51045d9abdbSWeongyo Jeong int (*switch_channel)(struct bwn_mac *,
51145d9abdbSWeongyo Jeong unsigned int);
51245d9abdbSWeongyo Jeong uint32_t (*get_default_chan)(struct bwn_mac *);
51345d9abdbSWeongyo Jeong void (*set_antenna)(struct bwn_mac *, int);
51445d9abdbSWeongyo Jeong int (*set_im)(struct bwn_mac *, int);
5151ea96818SAdrian Chadd bwn_txpwr_result_t (*recalc_txpwr)(struct bwn_mac *, int);
51645d9abdbSWeongyo Jeong void (*set_txpwr)(struct bwn_mac *);
51745d9abdbSWeongyo Jeong void (*task_15s)(struct bwn_mac *);
51845d9abdbSWeongyo Jeong void (*task_60s)(struct bwn_mac *);
51945d9abdbSWeongyo Jeong };
52045d9abdbSWeongyo Jeong
52145d9abdbSWeongyo Jeong struct bwn_chan_band {
52245d9abdbSWeongyo Jeong uint32_t flags;
52345d9abdbSWeongyo Jeong uint8_t nchan;
52445d9abdbSWeongyo Jeong #define BWN_MAX_CHAN_PER_BAND 14
52545d9abdbSWeongyo Jeong uint8_t chan[BWN_MAX_CHAN_PER_BAND];
52645d9abdbSWeongyo Jeong };
52745d9abdbSWeongyo Jeong
52845d9abdbSWeongyo Jeong #define BWN_NR_WMEPARAMS 16
52945d9abdbSWeongyo Jeong enum {
53045d9abdbSWeongyo Jeong BWN_WMEPARAM_TXOP = 0,
53145d9abdbSWeongyo Jeong BWN_WMEPARAM_CWMIN,
53245d9abdbSWeongyo Jeong BWN_WMEPARAM_CWMAX,
53345d9abdbSWeongyo Jeong BWN_WMEPARAM_CWCUR,
53445d9abdbSWeongyo Jeong BWN_WMEPARAM_AIFS,
53545d9abdbSWeongyo Jeong BWN_WMEPARAM_BSLOTS,
53645d9abdbSWeongyo Jeong BWN_WMEPARAM_REGGAP,
53745d9abdbSWeongyo Jeong BWN_WMEPARAM_STATUS,
53845d9abdbSWeongyo Jeong };
53945d9abdbSWeongyo Jeong
54045d9abdbSWeongyo Jeong #define BWN_WME_PARAMS(queue) \
54145d9abdbSWeongyo Jeong (BWN_SHARED_EDCFQ + (BWN_NR_WMEPARAMS * sizeof(uint16_t) * (queue)))
54245d9abdbSWeongyo Jeong #define BWN_WME_BACKGROUND BWN_WME_PARAMS(0)
54345d9abdbSWeongyo Jeong #define BWN_WME_BESTEFFORT BWN_WME_PARAMS(1)
54445d9abdbSWeongyo Jeong #define BWN_WME_VIDEO BWN_WME_PARAMS(2)
54545d9abdbSWeongyo Jeong #define BWN_WME_VOICE BWN_WME_PARAMS(3)
54645d9abdbSWeongyo Jeong
54745d9abdbSWeongyo Jeong /*
54845d9abdbSWeongyo Jeong * Radio capture format.
54945d9abdbSWeongyo Jeong */
55045d9abdbSWeongyo Jeong #define BWN_RX_RADIOTAP_PRESENT ( \
55145d9abdbSWeongyo Jeong (1 << IEEE80211_RADIOTAP_TSFT) | \
55245d9abdbSWeongyo Jeong (1 << IEEE80211_RADIOTAP_FLAGS) | \
55345d9abdbSWeongyo Jeong (1 << IEEE80211_RADIOTAP_RATE) | \
55445d9abdbSWeongyo Jeong (1 << IEEE80211_RADIOTAP_CHANNEL) | \
55545d9abdbSWeongyo Jeong (1 << IEEE80211_RADIOTAP_ANTENNA) | \
55645d9abdbSWeongyo Jeong (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
55745d9abdbSWeongyo Jeong (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \
55845d9abdbSWeongyo Jeong 0)
55945d9abdbSWeongyo Jeong
56045d9abdbSWeongyo Jeong struct bwn_rx_radiotap_header {
56145d9abdbSWeongyo Jeong struct ieee80211_radiotap_header wr_ihdr;
56245d9abdbSWeongyo Jeong uint64_t wr_tsf;
56345d9abdbSWeongyo Jeong u_int8_t wr_flags;
56445d9abdbSWeongyo Jeong u_int8_t wr_rate;
56545d9abdbSWeongyo Jeong u_int16_t wr_chan_freq;
56645d9abdbSWeongyo Jeong u_int16_t wr_chan_flags;
56745d9abdbSWeongyo Jeong int8_t wr_antsignal;
56845d9abdbSWeongyo Jeong int8_t wr_antnoise;
56945d9abdbSWeongyo Jeong u_int8_t wr_antenna;
570786ac703SAndriy Voskoboinyk } __packed __aligned(8);
57145d9abdbSWeongyo Jeong
57245d9abdbSWeongyo Jeong #define BWN_TX_RADIOTAP_PRESENT ( \
57345d9abdbSWeongyo Jeong (1 << IEEE80211_RADIOTAP_FLAGS) | \
57445d9abdbSWeongyo Jeong (1 << IEEE80211_RADIOTAP_RATE) | \
57545d9abdbSWeongyo Jeong (1 << IEEE80211_RADIOTAP_CHANNEL) | \
57645d9abdbSWeongyo Jeong (1 << IEEE80211_RADIOTAP_DBM_TX_POWER) | \
57745d9abdbSWeongyo Jeong (1 << IEEE80211_RADIOTAP_ANTENNA) | \
57845d9abdbSWeongyo Jeong 0)
57945d9abdbSWeongyo Jeong
58045d9abdbSWeongyo Jeong struct bwn_tx_radiotap_header {
58145d9abdbSWeongyo Jeong struct ieee80211_radiotap_header wt_ihdr;
58245d9abdbSWeongyo Jeong u_int8_t wt_flags;
58345d9abdbSWeongyo Jeong u_int8_t wt_rate;
58445d9abdbSWeongyo Jeong u_int16_t wt_chan_freq;
58545d9abdbSWeongyo Jeong u_int16_t wt_chan_flags;
58645d9abdbSWeongyo Jeong u_int8_t wt_txpower;
58745d9abdbSWeongyo Jeong u_int8_t wt_antenna;
588786ac703SAndriy Voskoboinyk } __packed;
58945d9abdbSWeongyo Jeong
59045d9abdbSWeongyo Jeong struct bwn_stats {
591d2ee7771SWeongyo Jeong int32_t rtsfail;
592d2ee7771SWeongyo Jeong int32_t rts;
59345d9abdbSWeongyo Jeong int32_t link_noise;
59445d9abdbSWeongyo Jeong };
59545d9abdbSWeongyo Jeong
59645d9abdbSWeongyo Jeong /* Noise Calculation (Link Quality) */
59745d9abdbSWeongyo Jeong struct bwn_noise {
59845d9abdbSWeongyo Jeong uint8_t noi_running;
59945d9abdbSWeongyo Jeong uint8_t noi_nsamples;
60045d9abdbSWeongyo Jeong int8_t noi_samples[8][4];
60145d9abdbSWeongyo Jeong };
60245d9abdbSWeongyo Jeong
60345d9abdbSWeongyo Jeong struct bwn_dmadesc_meta {
60445d9abdbSWeongyo Jeong bus_dmamap_t mt_dmap;
60545d9abdbSWeongyo Jeong bus_addr_t mt_paddr;
60645d9abdbSWeongyo Jeong struct mbuf *mt_m;
60745d9abdbSWeongyo Jeong struct ieee80211_node *mt_ni;
60845d9abdbSWeongyo Jeong uint8_t mt_txtype;
60945d9abdbSWeongyo Jeong #define BWN_DMADESC_METATYPE_HEADER 0
61045d9abdbSWeongyo Jeong #define BWN_DMADESC_METATYPE_BODY 1
61145d9abdbSWeongyo Jeong uint8_t mt_islast;
61245d9abdbSWeongyo Jeong };
61345d9abdbSWeongyo Jeong
61445d9abdbSWeongyo Jeong #define BWN_DMAINTR_FATALMASK \
61545d9abdbSWeongyo Jeong ((1 << 10) | (1 << 11) | (1 << 12) | (1 << 14) | (1 << 15))
61645d9abdbSWeongyo Jeong #define BWN_DMAINTR_NONFATALMASK (1 << 13)
61745d9abdbSWeongyo Jeong #define BWN_DMAINTR_RX_DONE (1 << 16)
61845d9abdbSWeongyo Jeong
61945d9abdbSWeongyo Jeong #define BWN_DMA32_DCTL_BYTECNT 0x00001fff
62045d9abdbSWeongyo Jeong #define BWN_DMA32_DCTL_ADDREXT_MASK 0x00030000
62145d9abdbSWeongyo Jeong #define BWN_DMA32_DCTL_ADDREXT_SHIFT 16
62245d9abdbSWeongyo Jeong #define BWN_DMA32_DCTL_DTABLEEND 0x10000000
62345d9abdbSWeongyo Jeong #define BWN_DMA32_DCTL_IRQ 0x20000000
62445d9abdbSWeongyo Jeong #define BWN_DMA32_DCTL_FRAMEEND 0x40000000
62545d9abdbSWeongyo Jeong #define BWN_DMA32_DCTL_FRAMESTART 0x80000000
62645d9abdbSWeongyo Jeong struct bwn_dmadesc32 {
62745d9abdbSWeongyo Jeong uint32_t control;
62845d9abdbSWeongyo Jeong uint32_t address;
62945d9abdbSWeongyo Jeong } __packed;
63045d9abdbSWeongyo Jeong
63145d9abdbSWeongyo Jeong #define BWN_DMA64_DCTL0_DTABLEEND 0x10000000
63245d9abdbSWeongyo Jeong #define BWN_DMA64_DCTL0_IRQ 0x20000000
63345d9abdbSWeongyo Jeong #define BWN_DMA64_DCTL0_FRAMEEND 0x40000000
63445d9abdbSWeongyo Jeong #define BWN_DMA64_DCTL0_FRAMESTART 0x80000000
63545d9abdbSWeongyo Jeong #define BWN_DMA64_DCTL1_BYTECNT 0x00001fff
63645d9abdbSWeongyo Jeong #define BWN_DMA64_DCTL1_ADDREXT_MASK 0x00030000
63745d9abdbSWeongyo Jeong #define BWN_DMA64_DCTL1_ADDREXT_SHIFT 16
63845d9abdbSWeongyo Jeong struct bwn_dmadesc64 {
63945d9abdbSWeongyo Jeong uint32_t control0;
64045d9abdbSWeongyo Jeong uint32_t control1;
64145d9abdbSWeongyo Jeong uint32_t address_low;
64245d9abdbSWeongyo Jeong uint32_t address_high;
64345d9abdbSWeongyo Jeong } __packed;
64445d9abdbSWeongyo Jeong
64545d9abdbSWeongyo Jeong struct bwn_dmadesc_generic {
64645d9abdbSWeongyo Jeong union {
64745d9abdbSWeongyo Jeong struct bwn_dmadesc32 dma32;
64845d9abdbSWeongyo Jeong struct bwn_dmadesc64 dma64;
64945d9abdbSWeongyo Jeong } __packed dma;
65045d9abdbSWeongyo Jeong } __packed;
65145d9abdbSWeongyo Jeong
65245d9abdbSWeongyo Jeong struct bwn_dma_ring;
65345d9abdbSWeongyo Jeong
65445d9abdbSWeongyo Jeong struct bwn_dma_ring {
65545d9abdbSWeongyo Jeong struct bwn_mac *dr_mac;
65645d9abdbSWeongyo Jeong const struct bwn_dma_ops *dr_ops;
65745d9abdbSWeongyo Jeong struct bwn_dmadesc_meta *dr_meta;
65845d9abdbSWeongyo Jeong void *dr_txhdr_cache;
65945d9abdbSWeongyo Jeong bus_dma_tag_t dr_ring_dtag;
66045d9abdbSWeongyo Jeong bus_dma_tag_t dr_txring_dtag;
66145d9abdbSWeongyo Jeong bus_dmamap_t dr_spare_dmap; /* only for RX */
66245d9abdbSWeongyo Jeong bus_dmamap_t dr_ring_dmap;
66345d9abdbSWeongyo Jeong bus_addr_t dr_txring_paddr;
66445d9abdbSWeongyo Jeong void *dr_ring_descbase;
66545d9abdbSWeongyo Jeong bus_addr_t dr_ring_dmabase;
66645d9abdbSWeongyo Jeong int dr_numslots;
66745d9abdbSWeongyo Jeong int dr_usedslot;
66845d9abdbSWeongyo Jeong int dr_curslot;
66945d9abdbSWeongyo Jeong uint32_t dr_frameoffset;
67045d9abdbSWeongyo Jeong uint16_t dr_rx_bufsize;
67145d9abdbSWeongyo Jeong uint16_t dr_base;
67245d9abdbSWeongyo Jeong int dr_index;
67345d9abdbSWeongyo Jeong uint8_t dr_tx;
67445d9abdbSWeongyo Jeong uint8_t dr_stop;
67545d9abdbSWeongyo Jeong int dr_type;
67645d9abdbSWeongyo Jeong
67745d9abdbSWeongyo Jeong void (*getdesc)(struct bwn_dma_ring *,
67845d9abdbSWeongyo Jeong int, struct bwn_dmadesc_generic **,
67945d9abdbSWeongyo Jeong struct bwn_dmadesc_meta **);
68045d9abdbSWeongyo Jeong void (*setdesc)(struct bwn_dma_ring *,
68145d9abdbSWeongyo Jeong struct bwn_dmadesc_generic *,
68245d9abdbSWeongyo Jeong bus_addr_t, uint16_t, int, int,
68345d9abdbSWeongyo Jeong int);
68445d9abdbSWeongyo Jeong void (*start_transfer)(struct bwn_dma_ring *,
68545d9abdbSWeongyo Jeong int);
68645d9abdbSWeongyo Jeong void (*suspend)(struct bwn_dma_ring *);
68745d9abdbSWeongyo Jeong void (*resume)(struct bwn_dma_ring *);
68845d9abdbSWeongyo Jeong int (*get_curslot)(struct bwn_dma_ring *);
68945d9abdbSWeongyo Jeong void (*set_curslot)(struct bwn_dma_ring *,
69045d9abdbSWeongyo Jeong int);
69145d9abdbSWeongyo Jeong };
69245d9abdbSWeongyo Jeong
69345d9abdbSWeongyo Jeong struct bwn_dma {
69445d9abdbSWeongyo Jeong bus_dma_tag_t parent_dtag;
69545d9abdbSWeongyo Jeong bus_dma_tag_t rxbuf_dtag;
69645d9abdbSWeongyo Jeong bus_dma_tag_t txbuf_dtag;
697d177c199SLandon J. Fuller struct bhnd_dma_translation translation;
698d177c199SLandon J. Fuller u_int addrext_shift;
69945d9abdbSWeongyo Jeong
70045d9abdbSWeongyo Jeong struct bwn_dma_ring *wme[5];
70145d9abdbSWeongyo Jeong struct bwn_dma_ring *mcast;
70245d9abdbSWeongyo Jeong struct bwn_dma_ring *rx;
70345d9abdbSWeongyo Jeong uint64_t lastseq; /* XXX FIXME */
70445d9abdbSWeongyo Jeong };
70545d9abdbSWeongyo Jeong
70645d9abdbSWeongyo Jeong struct bwn_pio_rxqueue {
70745d9abdbSWeongyo Jeong struct bwn_mac *prq_mac;
70845d9abdbSWeongyo Jeong uint16_t prq_base;
70945d9abdbSWeongyo Jeong uint8_t prq_rev;
71045d9abdbSWeongyo Jeong };
71145d9abdbSWeongyo Jeong
71245d9abdbSWeongyo Jeong struct bwn_pio_txqueue;
71345d9abdbSWeongyo Jeong struct bwn_pio_txpkt {
71445d9abdbSWeongyo Jeong struct bwn_pio_txqueue *tp_queue;
71545d9abdbSWeongyo Jeong struct ieee80211_node *tp_ni;
71645d9abdbSWeongyo Jeong struct mbuf *tp_m;
71745d9abdbSWeongyo Jeong uint8_t tp_index;
71845d9abdbSWeongyo Jeong TAILQ_ENTRY(bwn_pio_txpkt) tp_list;
71945d9abdbSWeongyo Jeong };
72045d9abdbSWeongyo Jeong
72145d9abdbSWeongyo Jeong #define BWN_PIO_MAX_TXPACKETS 32
72245d9abdbSWeongyo Jeong struct bwn_pio_txqueue {
72345d9abdbSWeongyo Jeong uint16_t tq_base;
72445d9abdbSWeongyo Jeong uint16_t tq_size;
72545d9abdbSWeongyo Jeong uint16_t tq_used;
72645d9abdbSWeongyo Jeong uint16_t tq_free;
72745d9abdbSWeongyo Jeong uint8_t tq_index;
72845d9abdbSWeongyo Jeong struct bwn_pio_txpkt tq_pkts[BWN_PIO_MAX_TXPACKETS];
72945d9abdbSWeongyo Jeong TAILQ_HEAD(, bwn_pio_txpkt) tq_pktlist;
73045d9abdbSWeongyo Jeong };
73145d9abdbSWeongyo Jeong
73245d9abdbSWeongyo Jeong struct bwn_pio {
73345d9abdbSWeongyo Jeong struct bwn_pio_txqueue wme[5];
73445d9abdbSWeongyo Jeong struct bwn_pio_txqueue mcast;
73545d9abdbSWeongyo Jeong struct bwn_pio_rxqueue rx;
73645d9abdbSWeongyo Jeong };
73745d9abdbSWeongyo Jeong
73845d9abdbSWeongyo Jeong struct bwn_plcp4 {
73945d9abdbSWeongyo Jeong union {
74045d9abdbSWeongyo Jeong uint32_t data;
74145d9abdbSWeongyo Jeong uint8_t raw[4];
74245d9abdbSWeongyo Jeong } __packed o;
74345d9abdbSWeongyo Jeong } __packed;
74445d9abdbSWeongyo Jeong
74545d9abdbSWeongyo Jeong struct bwn_plcp6 {
74645d9abdbSWeongyo Jeong union {
74745d9abdbSWeongyo Jeong uint32_t data;
74845d9abdbSWeongyo Jeong uint8_t raw[6];
74945d9abdbSWeongyo Jeong } __packed o;
75045d9abdbSWeongyo Jeong } __packed;
75145d9abdbSWeongyo Jeong
75245d9abdbSWeongyo Jeong struct bwn_txhdr {
75345d9abdbSWeongyo Jeong uint32_t macctl;
75445d9abdbSWeongyo Jeong uint8_t macfc[2];
75545d9abdbSWeongyo Jeong uint16_t tx_festime;
75645d9abdbSWeongyo Jeong uint16_t phyctl;
75745d9abdbSWeongyo Jeong uint16_t phyctl_1;
75845d9abdbSWeongyo Jeong uint16_t phyctl_1fb;
75945d9abdbSWeongyo Jeong uint16_t phyctl_1rts;
76045d9abdbSWeongyo Jeong uint16_t phyctl_1rtsfb;
76145d9abdbSWeongyo Jeong uint8_t phyrate;
76245d9abdbSWeongyo Jeong uint8_t phyrate_rts;
76345d9abdbSWeongyo Jeong uint8_t eftypes; /* extra frame types */
76445d9abdbSWeongyo Jeong uint8_t chan;
76545d9abdbSWeongyo Jeong uint8_t iv[16];
76645d9abdbSWeongyo Jeong uint8_t addr1[IEEE80211_ADDR_LEN];
76745d9abdbSWeongyo Jeong uint16_t tx_festime_fb;
76845d9abdbSWeongyo Jeong struct bwn_plcp6 rts_plcp_fb;
76945d9abdbSWeongyo Jeong uint16_t rts_dur_fb;
77045d9abdbSWeongyo Jeong struct bwn_plcp6 plcp_fb;
77145d9abdbSWeongyo Jeong uint16_t dur_fb;
77245d9abdbSWeongyo Jeong uint16_t mimo_modelen;
77345d9abdbSWeongyo Jeong uint16_t mimo_ratelen_fb;
77445d9abdbSWeongyo Jeong uint32_t timeout;
77545d9abdbSWeongyo Jeong
77645d9abdbSWeongyo Jeong union {
77745d9abdbSWeongyo Jeong /* format <= r351 */
77845d9abdbSWeongyo Jeong struct {
77945d9abdbSWeongyo Jeong uint8_t pad0[2];
78045d9abdbSWeongyo Jeong uint16_t cookie;
78145d9abdbSWeongyo Jeong uint16_t tx_status;
78245d9abdbSWeongyo Jeong struct bwn_plcp6 rts_plcp;
78345d9abdbSWeongyo Jeong uint8_t rts_frame[16];
784a506169aSEitan Adler uint8_t pad1[2];
78545d9abdbSWeongyo Jeong struct bwn_plcp6 plcp;
786a74bf020SAdrian Chadd } __packed r351;
787a74bf020SAdrian Chadd /* format > r410 < r598 */
78845d9abdbSWeongyo Jeong struct {
78945d9abdbSWeongyo Jeong uint16_t mimo_antenna;
79045d9abdbSWeongyo Jeong uint16_t preload_size;
79145d9abdbSWeongyo Jeong uint8_t pad0[2];
79245d9abdbSWeongyo Jeong uint16_t cookie;
79345d9abdbSWeongyo Jeong uint16_t tx_status;
79445d9abdbSWeongyo Jeong struct bwn_plcp6 rts_plcp;
79545d9abdbSWeongyo Jeong uint8_t rts_frame[16];
79645d9abdbSWeongyo Jeong uint8_t pad1[2];
79745d9abdbSWeongyo Jeong struct bwn_plcp6 plcp;
798a74bf020SAdrian Chadd } __packed r410;
799a74bf020SAdrian Chadd struct {
800a74bf020SAdrian Chadd uint16_t mimo_antenna;
801a74bf020SAdrian Chadd uint16_t preload_size;
802a74bf020SAdrian Chadd uint8_t pad0[2];
803a74bf020SAdrian Chadd uint16_t cookie;
804a74bf020SAdrian Chadd uint16_t tx_status;
805a74bf020SAdrian Chadd uint16_t max_n_mpdus;
806a74bf020SAdrian Chadd uint16_t max_a_bytes_mrt;
807a74bf020SAdrian Chadd uint16_t max_a_bytes_fbr;
808a74bf020SAdrian Chadd uint16_t min_m_bytes;
809a74bf020SAdrian Chadd struct bwn_plcp6 rts_plcp;
810a74bf020SAdrian Chadd uint8_t rts_frame[16];
811a74bf020SAdrian Chadd uint8_t pad1[2];
812a74bf020SAdrian Chadd struct bwn_plcp6 plcp;
813a74bf020SAdrian Chadd } __packed r598;
81445d9abdbSWeongyo Jeong } __packed body;
81545d9abdbSWeongyo Jeong } __packed;
81645d9abdbSWeongyo Jeong
81745d9abdbSWeongyo Jeong #define BWN_FWTYPE_UCODE 'u'
81845d9abdbSWeongyo Jeong #define BWN_FWTYPE_PCM 'p'
81945d9abdbSWeongyo Jeong #define BWN_FWTYPE_IV 'i'
82045d9abdbSWeongyo Jeong struct bwn_fwhdr {
82145d9abdbSWeongyo Jeong uint8_t type;
82245d9abdbSWeongyo Jeong uint8_t ver;
82345d9abdbSWeongyo Jeong uint8_t pad[2];
82445d9abdbSWeongyo Jeong uint32_t size;
82545d9abdbSWeongyo Jeong } __packed;
82645d9abdbSWeongyo Jeong
82745d9abdbSWeongyo Jeong #define BWN_FWINITVALS_OFFSET_MASK 0x7fff
82845d9abdbSWeongyo Jeong #define BWN_FWINITVALS_32BIT 0x8000
82945d9abdbSWeongyo Jeong struct bwn_fwinitvals {
83045d9abdbSWeongyo Jeong uint16_t offset_size;
83145d9abdbSWeongyo Jeong union {
83245d9abdbSWeongyo Jeong uint16_t d16;
83345d9abdbSWeongyo Jeong uint32_t d32;
83445d9abdbSWeongyo Jeong } __packed data;
83545d9abdbSWeongyo Jeong } __packed;
83645d9abdbSWeongyo Jeong
837af4ae173SAdrian Chadd enum bwn_fw_hdr_format {
838af4ae173SAdrian Chadd BWN_FW_HDR_598,
839af4ae173SAdrian Chadd BWN_FW_HDR_410,
840af4ae173SAdrian Chadd BWN_FW_HDR_351,
841af4ae173SAdrian Chadd };
842af4ae173SAdrian Chadd
84345d9abdbSWeongyo Jeong enum bwn_fwtype {
84445d9abdbSWeongyo Jeong BWN_FWTYPE_DEFAULT,
84545d9abdbSWeongyo Jeong BWN_FWTYPE_OPENSOURCE,
84645d9abdbSWeongyo Jeong BWN_NR_FWTYPES,
84745d9abdbSWeongyo Jeong };
84845d9abdbSWeongyo Jeong
84945d9abdbSWeongyo Jeong struct bwn_fwfile {
85045d9abdbSWeongyo Jeong const char *filename;
85145d9abdbSWeongyo Jeong const struct firmware *fw;
85245d9abdbSWeongyo Jeong enum bwn_fwtype type;
85345d9abdbSWeongyo Jeong };
85445d9abdbSWeongyo Jeong
85545d9abdbSWeongyo Jeong struct bwn_key {
85645d9abdbSWeongyo Jeong void *keyconf;
85745d9abdbSWeongyo Jeong uint8_t algorithm;
85845d9abdbSWeongyo Jeong };
85945d9abdbSWeongyo Jeong
86045d9abdbSWeongyo Jeong struct bwn_fw {
86145d9abdbSWeongyo Jeong struct bwn_fwfile ucode;
86245d9abdbSWeongyo Jeong struct bwn_fwfile pcm;
86345d9abdbSWeongyo Jeong struct bwn_fwfile initvals;
86445d9abdbSWeongyo Jeong struct bwn_fwfile initvals_band;
865af4ae173SAdrian Chadd enum bwn_fw_hdr_format fw_hdr_format;
86645d9abdbSWeongyo Jeong
86745d9abdbSWeongyo Jeong uint16_t rev;
86845d9abdbSWeongyo Jeong uint16_t patch;
86945d9abdbSWeongyo Jeong uint8_t opensource;
87045d9abdbSWeongyo Jeong uint8_t no_pcmfile;
87145d9abdbSWeongyo Jeong };
87245d9abdbSWeongyo Jeong
87345d9abdbSWeongyo Jeong struct bwn_lo_g_sm {
87445d9abdbSWeongyo Jeong int curstate;
87545d9abdbSWeongyo Jeong int nmeasure;
87645d9abdbSWeongyo Jeong int multipler;
87745d9abdbSWeongyo Jeong uint16_t feedth;
87845d9abdbSWeongyo Jeong struct bwn_loctl loctl;
87945d9abdbSWeongyo Jeong };
88045d9abdbSWeongyo Jeong
88145d9abdbSWeongyo Jeong struct bwn_lo_g_value {
88245d9abdbSWeongyo Jeong uint8_t old_channel;
88345d9abdbSWeongyo Jeong uint16_t phy_lomask;
88445d9abdbSWeongyo Jeong uint16_t phy_extg;
88545d9abdbSWeongyo Jeong uint16_t phy_dacctl_hwpctl;
88645d9abdbSWeongyo Jeong uint16_t phy_dacctl;
88745d9abdbSWeongyo Jeong uint16_t phy_hpwr_tssictl;
88845d9abdbSWeongyo Jeong uint16_t phy_analogover;
88945d9abdbSWeongyo Jeong uint16_t phy_analogoverval;
89045d9abdbSWeongyo Jeong uint16_t phy_rfover;
89145d9abdbSWeongyo Jeong uint16_t phy_rfoverval;
89245d9abdbSWeongyo Jeong uint16_t phy_classctl;
89345d9abdbSWeongyo Jeong uint16_t phy_crs0;
89445d9abdbSWeongyo Jeong uint16_t phy_pgactl;
89545d9abdbSWeongyo Jeong uint16_t phy_syncctl;
89645d9abdbSWeongyo Jeong uint16_t phy_cck0;
89745d9abdbSWeongyo Jeong uint16_t phy_cck1;
89845d9abdbSWeongyo Jeong uint16_t phy_cck2;
89945d9abdbSWeongyo Jeong uint16_t phy_cck3;
90045d9abdbSWeongyo Jeong uint16_t phy_cck4;
90145d9abdbSWeongyo Jeong uint16_t reg0;
90245d9abdbSWeongyo Jeong uint16_t reg1;
90345d9abdbSWeongyo Jeong uint16_t rf0;
90445d9abdbSWeongyo Jeong uint16_t rf1;
90545d9abdbSWeongyo Jeong uint16_t rf2;
90645d9abdbSWeongyo Jeong };
90745d9abdbSWeongyo Jeong
90845d9abdbSWeongyo Jeong #define BWN_LED_MAX 4
90945d9abdbSWeongyo Jeong
91045d9abdbSWeongyo Jeong #define BWN_LED_EVENT_NONE -1
91145d9abdbSWeongyo Jeong #define BWN_LED_EVENT_POLL 0
91245d9abdbSWeongyo Jeong #define BWN_LED_EVENT_TX 1
91345d9abdbSWeongyo Jeong #define BWN_LED_EVENT_RX 2
91445d9abdbSWeongyo Jeong #define BWN_LED_SLOWDOWN(dur) (dur) = (((dur) * 3) / 2)
91545d9abdbSWeongyo Jeong
91645d9abdbSWeongyo Jeong struct bwn_led {
91745d9abdbSWeongyo Jeong uint8_t led_flags; /* BWN_LED_F_ */
91845d9abdbSWeongyo Jeong uint8_t led_act; /* BWN_LED_ACT_ */
91945d9abdbSWeongyo Jeong uint8_t led_mask;
92045d9abdbSWeongyo Jeong };
92145d9abdbSWeongyo Jeong
92245d9abdbSWeongyo Jeong #define BWN_LED_F_ACTLOW 0x1
92345d9abdbSWeongyo Jeong #define BWN_LED_F_BLINK 0x2
92445d9abdbSWeongyo Jeong #define BWN_LED_F_POLLABLE 0x4
92545d9abdbSWeongyo Jeong #define BWN_LED_F_SLOW 0x8
92645d9abdbSWeongyo Jeong
92745d9abdbSWeongyo Jeong struct bwn_mac {
92845d9abdbSWeongyo Jeong struct bwn_softc *mac_sc;
92945d9abdbSWeongyo Jeong unsigned mac_status;
93045d9abdbSWeongyo Jeong #define BWN_MAC_STATUS_UNINIT 0
93145d9abdbSWeongyo Jeong #define BWN_MAC_STATUS_INITED 1
93245d9abdbSWeongyo Jeong #define BWN_MAC_STATUS_STARTED 2
93345d9abdbSWeongyo Jeong unsigned mac_flags;
93445d9abdbSWeongyo Jeong /* use "Bad Frames Preemption" */
93545d9abdbSWeongyo Jeong #define BWN_MAC_FLAG_BADFRAME_PREEMP (1 << 0)
93645d9abdbSWeongyo Jeong #define BWN_MAC_FLAG_DFQVALID (1 << 1)
93745d9abdbSWeongyo Jeong #define BWN_MAC_FLAG_RADIO_ON (1 << 2)
93845d9abdbSWeongyo Jeong #define BWN_MAC_FLAG_DMA (1 << 3)
93945d9abdbSWeongyo Jeong #define BWN_MAC_FLAG_WME (1 << 4)
94045d9abdbSWeongyo Jeong #define BWN_MAC_FLAG_HWCRYPTO (1 << 5)
94145d9abdbSWeongyo Jeong
942d177c199SLandon J. Fuller struct resource *mac_res_irq;
943d177c199SLandon J. Fuller int mac_rid_irq;
944d177c199SLandon J. Fuller void *mac_intrhand;
94545d9abdbSWeongyo Jeong
94645d9abdbSWeongyo Jeong struct bwn_noise mac_noise;
94745d9abdbSWeongyo Jeong struct bwn_phy mac_phy;
94845d9abdbSWeongyo Jeong struct bwn_stats mac_stats;
94945d9abdbSWeongyo Jeong uint32_t mac_reason_intr;
95045d9abdbSWeongyo Jeong uint32_t mac_reason[6];
95145d9abdbSWeongyo Jeong uint32_t mac_intr_mask;
95245d9abdbSWeongyo Jeong int mac_suspended;
95345d9abdbSWeongyo Jeong
95445d9abdbSWeongyo Jeong struct bwn_fw mac_fw;
95545d9abdbSWeongyo Jeong
956d177c199SLandon J. Fuller int mac_dmatype;
95745d9abdbSWeongyo Jeong union {
95845d9abdbSWeongyo Jeong struct bwn_dma dma;
95945d9abdbSWeongyo Jeong struct bwn_pio pio;
96045d9abdbSWeongyo Jeong } mac_method;
96145d9abdbSWeongyo Jeong
96245d9abdbSWeongyo Jeong uint16_t mac_ktp; /* Key table pointer */
96345d9abdbSWeongyo Jeong uint8_t mac_max_nr_keys;
96445d9abdbSWeongyo Jeong struct bwn_key mac_key[58];
96545d9abdbSWeongyo Jeong
96645d9abdbSWeongyo Jeong unsigned int mac_task_state;
96745d9abdbSWeongyo Jeong struct task mac_intrtask;
96845d9abdbSWeongyo Jeong struct task mac_hwreset;
96945d9abdbSWeongyo Jeong struct task mac_txpower;
97045d9abdbSWeongyo Jeong
97145d9abdbSWeongyo Jeong TAILQ_ENTRY(bwn_mac) mac_list;
97245d9abdbSWeongyo Jeong };
97345d9abdbSWeongyo Jeong
9741ea96818SAdrian Chadd static inline int
bwn_tx_hdrsize(struct bwn_mac * mac)9751ea96818SAdrian Chadd bwn_tx_hdrsize(struct bwn_mac *mac)
9761ea96818SAdrian Chadd {
9771ea96818SAdrian Chadd switch (mac->mac_fw.fw_hdr_format) {
9781ea96818SAdrian Chadd case BWN_FW_HDR_598:
9791ea96818SAdrian Chadd return (112 + (sizeof(struct bwn_plcp6)));
9801ea96818SAdrian Chadd case BWN_FW_HDR_410:
9811ea96818SAdrian Chadd return (104 + (sizeof(struct bwn_plcp6)));
9821ea96818SAdrian Chadd case BWN_FW_HDR_351:
9831ea96818SAdrian Chadd return (100 + (sizeof(struct bwn_plcp6)));
9841ea96818SAdrian Chadd default:
9851ea96818SAdrian Chadd printf("%s: unknown header format (%d)\n", __func__,
9861ea96818SAdrian Chadd mac->mac_fw.fw_hdr_format);
9871ea96818SAdrian Chadd return (112 + (sizeof(struct bwn_plcp6)));
9881ea96818SAdrian Chadd }
9891ea96818SAdrian Chadd }
9901ea96818SAdrian Chadd
99145d9abdbSWeongyo Jeong /*
99245d9abdbSWeongyo Jeong * Driver-specific vap state.
99345d9abdbSWeongyo Jeong */
99445d9abdbSWeongyo Jeong struct bwn_vap {
99545d9abdbSWeongyo Jeong struct ieee80211vap bv_vap; /* base class */
99645d9abdbSWeongyo Jeong int (*bv_newstate)(struct ieee80211vap *,
99745d9abdbSWeongyo Jeong enum ieee80211_state, int);
99845d9abdbSWeongyo Jeong };
99945d9abdbSWeongyo Jeong #define BWN_VAP(vap) ((struct bwn_vap *)(vap))
100045d9abdbSWeongyo Jeong #define BWN_VAP_CONST(vap) ((const struct mwl_vap *)(vap))
100145d9abdbSWeongyo Jeong
1002d177c199SLandon J. Fuller enum bwn_quirk {
1003d177c199SLandon J. Fuller /**
1004d177c199SLandon J. Fuller * The ucode PCI slowclock workaround is required on this device.
1005d177c199SLandon J. Fuller * @see BWN_HF_PCI_SLOWCLOCK_WORKAROUND.
1006d177c199SLandon J. Fuller */
1007d177c199SLandon J. Fuller BWN_QUIRK_UCODE_SLOWCLOCK_WAR = (1<<0),
1008d177c199SLandon J. Fuller
1009d177c199SLandon J. Fuller /**
1010d177c199SLandon J. Fuller * DMA is unsupported on this device; PIO should be used instead.
1011d177c199SLandon J. Fuller */
1012d177c199SLandon J. Fuller BWN_QUIRK_NODMA = (1<<1),
1013d177c199SLandon J. Fuller };
1014d177c199SLandon J. Fuller
101545d9abdbSWeongyo Jeong struct bwn_softc {
101645d9abdbSWeongyo Jeong device_t sc_dev;
1017d177c199SLandon J. Fuller struct bhnd_board_info sc_board_info;
1018d177c199SLandon J. Fuller struct bhnd_chipid sc_cid;
1019d177c199SLandon J. Fuller uint32_t sc_quirks; /**< @see bwn_quirk */
1020d177c199SLandon J. Fuller struct resource *sc_mem_res;
10218d14ca9cSLandon J. Fuller int sc_mem_rid;
1022d177c199SLandon J. Fuller
1023d177c199SLandon J. Fuller device_t sc_chipc; /**< ChipCommon device */
1024d177c199SLandon J. Fuller device_t sc_gpio; /**< GPIO device */
1025d177c199SLandon J. Fuller device_t sc_pmu; /**< PMU device, or NULL if unsupported */
1026d177c199SLandon J. Fuller
102745d9abdbSWeongyo Jeong struct mtx sc_mtx;
10287a79cebfSGleb Smirnoff struct ieee80211com sc_ic;
10297a79cebfSGleb Smirnoff struct mbufq sc_snd;
103045d9abdbSWeongyo Jeong unsigned sc_flags;
103145d9abdbSWeongyo Jeong #define BWN_FLAG_ATTACHED (1 << 0)
103245d9abdbSWeongyo Jeong #define BWN_FLAG_INVALID (1 << 1)
103345d9abdbSWeongyo Jeong #define BWN_FLAG_NEED_BEACON_TP (1 << 2)
10347a79cebfSGleb Smirnoff #define BWN_FLAG_RUNNING (1 << 3)
103545d9abdbSWeongyo Jeong unsigned sc_debug;
103645d9abdbSWeongyo Jeong
103745d9abdbSWeongyo Jeong struct bwn_mac *sc_curmac;
103845d9abdbSWeongyo Jeong TAILQ_HEAD(, bwn_mac) sc_maclist;
103945d9abdbSWeongyo Jeong
104045d9abdbSWeongyo Jeong uint8_t sc_bssid[IEEE80211_ADDR_LEN];
104145d9abdbSWeongyo Jeong unsigned int sc_filters;
104245d9abdbSWeongyo Jeong uint8_t sc_beacons[2];
104345d9abdbSWeongyo Jeong uint8_t sc_rf_enabled;
104445d9abdbSWeongyo Jeong
104545d9abdbSWeongyo Jeong struct wmeParams sc_wmeParams[4];
104645d9abdbSWeongyo Jeong
104745d9abdbSWeongyo Jeong struct callout sc_rfswitch_ch; /* for laptop */
104845d9abdbSWeongyo Jeong struct callout sc_task_ch;
104945d9abdbSWeongyo Jeong struct callout sc_watchdog_ch;
105045d9abdbSWeongyo Jeong int sc_watchdog_timer;
105145d9abdbSWeongyo Jeong struct taskqueue *sc_tq; /* private task queue */
105245d9abdbSWeongyo Jeong int (*sc_newstate)(struct ieee80211com *,
105345d9abdbSWeongyo Jeong enum ieee80211_state, int);
105445d9abdbSWeongyo Jeong void (*sc_node_cleanup)(
105545d9abdbSWeongyo Jeong struct ieee80211_node *);
105645d9abdbSWeongyo Jeong
105745d9abdbSWeongyo Jeong int sc_rx_rate;
105845d9abdbSWeongyo Jeong int sc_tx_rate;
105945d9abdbSWeongyo Jeong
106045d9abdbSWeongyo Jeong int sc_led_blinking;
106145d9abdbSWeongyo Jeong int sc_led_ticks;
106245d9abdbSWeongyo Jeong struct bwn_led *sc_blink_led;
106345d9abdbSWeongyo Jeong struct callout sc_led_blink_ch;
106445d9abdbSWeongyo Jeong int sc_led_blink_offdur;
106545d9abdbSWeongyo Jeong struct bwn_led sc_leds[BWN_LED_MAX];
106645d9abdbSWeongyo Jeong int sc_led_idle;
106745d9abdbSWeongyo Jeong int sc_led_blink;
106845d9abdbSWeongyo Jeong
1069d177c199SLandon J. Fuller uint8_t sc_ant2g; /**< available 2GHz antennas */
1070d177c199SLandon J. Fuller uint8_t sc_ant5g; /**< available 5GHz antennas */
1071d177c199SLandon J. Fuller
107245d9abdbSWeongyo Jeong struct bwn_tx_radiotap_header sc_tx_th;
107345d9abdbSWeongyo Jeong struct bwn_rx_radiotap_header sc_rx_th;
107445d9abdbSWeongyo Jeong };
107545d9abdbSWeongyo Jeong
107645d9abdbSWeongyo Jeong #define BWN_LOCK_INIT(sc) \
107745d9abdbSWeongyo Jeong mtx_init(&(sc)->sc_mtx, device_get_nameunit((sc)->sc_dev), \
107845d9abdbSWeongyo Jeong MTX_NETWORK_LOCK, MTX_DEF)
107945d9abdbSWeongyo Jeong #define BWN_LOCK_DESTROY(sc) mtx_destroy(&(sc)->sc_mtx)
108045d9abdbSWeongyo Jeong #define BWN_LOCK(sc) mtx_lock(&(sc)->sc_mtx)
108145d9abdbSWeongyo Jeong #define BWN_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx)
108245d9abdbSWeongyo Jeong #define BWN_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED)
108345d9abdbSWeongyo Jeong
10841ea96818SAdrian Chadd static inline bwn_band_t
bwn_channel_band(struct bwn_mac * mac,struct ieee80211_channel * c)10851ea96818SAdrian Chadd bwn_channel_band(struct bwn_mac *mac, struct ieee80211_channel *c)
10861ea96818SAdrian Chadd {
10871ea96818SAdrian Chadd if (IEEE80211_IS_CHAN_5GHZ(c))
10881ea96818SAdrian Chadd return BWN_BAND_5G;
10891ea96818SAdrian Chadd /* XXX check 2g, log error if not 2g or 5g? */
10901ea96818SAdrian Chadd return BWN_BAND_2G;
10911ea96818SAdrian Chadd }
10921ea96818SAdrian Chadd
10931ea96818SAdrian Chadd static inline bwn_band_t
bwn_current_band(struct bwn_mac * mac)10941ea96818SAdrian Chadd bwn_current_band(struct bwn_mac *mac)
10951ea96818SAdrian Chadd {
10961ea96818SAdrian Chadd struct ieee80211com *ic = &mac->mac_sc->sc_ic;
10971ea96818SAdrian Chadd if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan))
10981ea96818SAdrian Chadd return BWN_BAND_5G;
10991ea96818SAdrian Chadd /* XXX check 2g, log error if not 2g or 5g? */
11001ea96818SAdrian Chadd return BWN_BAND_2G;
11011ea96818SAdrian Chadd }
11021ea96818SAdrian Chadd
11031ea96818SAdrian Chadd static inline bool
bwn_is_40mhz(struct bwn_mac * mac)11041ea96818SAdrian Chadd bwn_is_40mhz(struct bwn_mac *mac)
11051ea96818SAdrian Chadd {
11061ea96818SAdrian Chadd struct ieee80211com *ic = &mac->mac_sc->sc_ic;
11071ea96818SAdrian Chadd
11081ea96818SAdrian Chadd return !! (IEEE80211_IS_CHAN_HT40(ic->ic_curchan));
11091ea96818SAdrian Chadd }
11101ea96818SAdrian Chadd
11111ea96818SAdrian Chadd static inline int
bwn_get_centre_freq(struct bwn_mac * mac)11121ea96818SAdrian Chadd bwn_get_centre_freq(struct bwn_mac *mac)
11131ea96818SAdrian Chadd {
11141ea96818SAdrian Chadd
11151ea96818SAdrian Chadd struct ieee80211com *ic = &mac->mac_sc->sc_ic;
11161ea96818SAdrian Chadd /* XXX TODO: calculate correctly for HT40 mode */
11171ea96818SAdrian Chadd return ic->ic_curchan->ic_freq;
11181ea96818SAdrian Chadd }
11191ea96818SAdrian Chadd
11201ea96818SAdrian Chadd static inline int
bwn_get_chan_centre_freq(struct bwn_mac * mac,struct ieee80211_channel * chan)11211ea96818SAdrian Chadd bwn_get_chan_centre_freq(struct bwn_mac *mac, struct ieee80211_channel *chan)
11221ea96818SAdrian Chadd {
11231ea96818SAdrian Chadd
11241ea96818SAdrian Chadd /* XXX TODO: calculate correctly for HT40 mode */
11251ea96818SAdrian Chadd return chan->ic_freq;
11261ea96818SAdrian Chadd }
11271ea96818SAdrian Chadd
11281ea96818SAdrian Chadd static inline int
bwn_get_chan(struct bwn_mac * mac)11291ea96818SAdrian Chadd bwn_get_chan(struct bwn_mac *mac)
11301ea96818SAdrian Chadd {
11311ea96818SAdrian Chadd
11321ea96818SAdrian Chadd struct ieee80211com *ic = &mac->mac_sc->sc_ic;
11331ea96818SAdrian Chadd /* XXX TODO: calculate correctly for HT40 mode */
11341ea96818SAdrian Chadd return ic->ic_curchan->ic_ieee;
11351ea96818SAdrian Chadd }
11361ea96818SAdrian Chadd
11371ea96818SAdrian Chadd static inline struct ieee80211_channel *
bwn_get_channel(struct bwn_mac * mac)11381ea96818SAdrian Chadd bwn_get_channel(struct bwn_mac *mac)
11391ea96818SAdrian Chadd {
11401ea96818SAdrian Chadd
11411ea96818SAdrian Chadd struct ieee80211com *ic = &mac->mac_sc->sc_ic;
11421ea96818SAdrian Chadd return ic->ic_curchan;
11431ea96818SAdrian Chadd }
11441ea96818SAdrian Chadd
11451ea96818SAdrian Chadd static inline bool
bwn_is_chan_passive(struct bwn_mac * mac)11461ea96818SAdrian Chadd bwn_is_chan_passive(struct bwn_mac *mac)
11471ea96818SAdrian Chadd {
11481ea96818SAdrian Chadd
11491ea96818SAdrian Chadd struct ieee80211com *ic = &mac->mac_sc->sc_ic;
11501ea96818SAdrian Chadd return !! IEEE80211_IS_CHAN_PASSIVE(ic->ic_curchan);
11511ea96818SAdrian Chadd }
11521ea96818SAdrian Chadd
11531ea96818SAdrian Chadd static inline bwn_chan_type_t
bwn_get_chan_type(struct bwn_mac * mac,struct ieee80211_channel * c)11541ea96818SAdrian Chadd bwn_get_chan_type(struct bwn_mac *mac, struct ieee80211_channel *c)
11551ea96818SAdrian Chadd {
11561ea96818SAdrian Chadd struct ieee80211com *ic = &mac->mac_sc->sc_ic;
11571ea96818SAdrian Chadd if (c == NULL)
11581ea96818SAdrian Chadd c = ic->ic_curchan;
11591ea96818SAdrian Chadd if (IEEE80211_IS_CHAN_HT40U(c))
11601ea96818SAdrian Chadd return BWN_CHAN_TYPE_40_HT_U;
11611ea96818SAdrian Chadd else if (IEEE80211_IS_CHAN_HT40D(c))
11621ea96818SAdrian Chadd return BWN_CHAN_TYPE_40_HT_D;
11631ea96818SAdrian Chadd else if (IEEE80211_IS_CHAN_HT20(c))
11641ea96818SAdrian Chadd return BWN_CHAN_TYPE_20_HT;
11651ea96818SAdrian Chadd else
11661ea96818SAdrian Chadd return BWN_CHAN_TYPE_20;
11671ea96818SAdrian Chadd }
11681ea96818SAdrian Chadd
11691ea96818SAdrian Chadd static inline int
bwn_get_chan_power(struct bwn_mac * mac,struct ieee80211_channel * c)11701ea96818SAdrian Chadd bwn_get_chan_power(struct bwn_mac *mac, struct ieee80211_channel *c)
11711ea96818SAdrian Chadd {
11721ea96818SAdrian Chadd
11731ea96818SAdrian Chadd /* return in dbm */
11741ea96818SAdrian Chadd return c->ic_maxpower / 2;
11751ea96818SAdrian Chadd }
11761ea96818SAdrian Chadd
117745d9abdbSWeongyo Jeong #endif /* !_IF_BWNVAR_H */
1178