root/sys/dev/ic/bwfmreg.h
/* $OpenBSD: bwfmreg.h,v 1.26 2022/03/04 22:34:41 kettenis Exp $ */
/*
 * Copyright (c) 2010-2016 Broadcom Corporation
 * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/* Chip registers */
#define BWFM_CHIP_BASE                          0x18000000
#define BWFM_CHIP_REG_CHIPID                    0x00000000
#define  BWFM_CHIP_CHIPID_ID(x)                         (((x) >> 0) & 0xffff)
#define  BWFM_CHIP_CHIPID_REV(x)                        (((x) >> 16) & 0xf)
#define  BWFM_CHIP_CHIPID_PKG(x)                        (((x) >> 20) & 0xf)
#define  BWFM_CHIP_CHIPID_CC(x)                         (((x) >> 24) & 0xf)
#define  BWFM_CHIP_CHIPID_TYPE(x)                       (((x) >> 28) & 0xf)
#define  BWFM_CHIP_CHIPID_TYPE_SOCI_SB                  0
#define  BWFM_CHIP_CHIPID_TYPE_SOCI_AI                  1
#define BWFM_CHIP_REG_CAPABILITIES              0x00000004
#define  BWFM_CHIP_REG_CAPABILITIES_PMU                 0x10000000
#define BWFM_CHIP_REG_CAPABILITIES_EXT          0x000000AC
#define  BWFM_CHIP_REG_CAPABILITIES_EXT_AOB_PRESENT     0x00000040
#define BWFM_CHIP_REG_WATCHDOG                  0x00000080
#define BWFM_CHIP_REG_EROMPTR                   0x000000FC
#define BWFM_CHIP_REG_SROMCONTROL               0x00000190
#define  BWFM_CHIP_REG_SROMCONTROL_OTPSEL               (1 << 4)
#define  BWFM_CHIP_REG_SROMCONTROL_OTP_PRESENT          (1 << 5)
#define BWFM_CHIP_REG_SR_CAPABILITY             0x00000500
#define BWFM_CHIP_REG_SR_CONTROL0               0x00000504
#define  BWFM_CHIP_REG_SR_CONTROL0_ENABLE               (1 << 0)
#define BWFM_CHIP_REG_SR_CONTROL1               0x00000508
#define BWFM_CHIP_REG_PMUCONTROL                0x00000600
#define  BWFM_CHIP_REG_PMUCONTROL_RES_MASK              0x00006000
#define  BWFM_CHIP_REG_PMUCONTROL_RES_SHIFT             13
#define  BWFM_CHIP_REG_PMUCONTROL_RES_RELOAD            0x2
#define BWFM_CHIP_REG_PMUCAPABILITIES           0x00000604
#define  BWFM_CHIP_REG_PMUCAPABILITIES_REV_MASK         0x000000ff
#define BWFM_CHIP_REG_PMUCAPABILITIES_EXT       0x0000064C
#define  BWFM_CHIP_REG_PMUCAPABILITIES_SR_SUPP          (1 << 1)
#define BWFM_CHIP_REG_CHIPCONTROL_ADDR          0x00000650
#define BWFM_CHIP_REG_CHIPCONTROL_DATA          0x00000654
#define BWFM_CHIP_REG_RETENTION_CTL             0x00000670
#define  BWFM_CHIP_REG_RETENTION_CTL_MACPHY_DIS         (1 << 26)
#define  BWFM_CHIP_REG_RETENTION_CTL_LOGIC_DIS          (1 << 27)

/* Agent registers */
#define BWFM_AGENT_IOCTL                        0x0408
#define  BWFM_AGENT_IOCTL_CLK                           0x0001
#define  BWFM_AGENT_IOCTL_FGC                           0x0002
#define  BWFM_AGENT_IOCTL_CORE_BITS                     0x3FFC
#define  BWFM_AGENT_IOCTL_PME_EN                        0x4000
#define  BWFM_AGENT_IOCTL_BIST_EN                       0x8000
#define  BWFM_AGENT_IOCTL_ARMCR4_CPUHALT                0x0020
#define BWFM_AGENT_RESET_CTL                    0x0800
#define  BWFM_AGENT_RESET_CTL_RESET                     0x0001

/* Agent Core-IDs */
#define BWFM_AGENT_CORE_CHIPCOMMON              0x800
#define BWFM_AGENT_INTERNAL_MEM                 0x80E
#define BWFM_AGENT_CORE_80211                   0x812
#define BWFM_AGENT_CORE_PMU                     0x827
#define BWFM_AGENT_CORE_SDIO_DEV                0x829
#define BWFM_AGENT_CORE_ARM_CM3                 0x82A
#define BWFM_AGENT_CORE_PCIE2                   0x83C
#define BWFM_AGENT_CORE_ARM_CR4                 0x83E
#define BWFM_AGENT_CORE_GCI                     0x840
#define BWFM_AGENT_CORE_ARM_CA7                 0x847
#define BWFM_AGENT_SYS_MEM                      0x849

/* Specific Core Bits */
#define BWFM_AGENT_ARMCR4_IOCTL_CPUHALT         0x0020
#define BWFM_AGENT_D11_IOCTL_PHYCLOCKEN         0x0004
#define BWFM_AGENT_D11_IOCTL_PHYRESET           0x0008

/* CR4 registers */
#define BWFM_ARMCR4_CAP                         0x0004
#define  BWFM_ARMCR4_CAP_TCBANB_MASK                    0xf
#define  BWFM_ARMCR4_CAP_TCBANB_SHIFT                   0
#define  BWFM_ARMCR4_CAP_TCBBNB_MASK                    0xf0
#define  BWFM_ARMCR4_CAP_TCBBNB_SHIFT                   4
#define BWFM_ARMCR4_BANKIDX                     0x0040
#define BWFM_ARMCR4_BANKINFO                    0x0044
#define  BWFM_ARMCR4_BANKINFO_BSZ_MASK                  0x7f
#define  BWFM_ARMCR4_BANKINFO_BLK_1K_MASK               0x200
#define BWFM_ARMCR4_BANKPDA                     0x004C

/* SOCRAM registers */
#define BWFM_SOCRAM_COREINFO                    0x0000
#define  BWFM_SOCRAM_COREINFO_SRBSZ_BASE                14
#define  BWFM_SOCRAM_COREINFO_SRBSZ_MASK                0xf
#define  BWFM_SOCRAM_COREINFO_SRBSZ_SHIFT               0
#define  BWFM_SOCRAM_COREINFO_SRNB_MASK                 0xf0
#define  BWFM_SOCRAM_COREINFO_SRNB_SHIFT                4
#define  BWFM_SOCRAM_COREINFO_LSS_MASK                  0xf00000
#define  BWFM_SOCRAM_COREINFO_LSS_SHIFT                 20
#define BWFM_SOCRAM_BANKIDX                     0x0010
#define  BWFM_SOCRAM_BANKIDX_MEMTYPE_RAM                0
#define  BWFM_SOCRAM_BANKIDX_MEMTYPE_ROM                1
#define  BWFM_SOCRAM_BANKIDX_MEMTYPE_DEVRAM             2
#define  BWFM_SOCRAM_BANKIDX_MEMTYPE_SHIFT              8
#define BWFM_SOCRAM_BANKINFO                    0x0040
#define  BWFM_SOCRAM_BANKINFO_SZBASE                    8192
#define  BWFM_SOCRAM_BANKINFO_SZMASK                    0x7f
#define  BWFM_SOCRAM_BANKINFO_RETNTRAM_MASK             0x10000
#define BWFM_SOCRAM_BANKPDA                     0x0044

/* SDPCMD registers */
#define BWFM_SDPCMD_INTSTATUS                   0x0020

/* DMP descriptor */
#define BWFM_DMP_DESC_MASK                      0x0000000F
#define BWFM_DMP_DESC_EMPTY                     0x00000000
#define BWFM_DMP_DESC_VALID                     0x00000001
#define BWFM_DMP_DESC_COMPONENT                 0x00000001
#define BWFM_DMP_DESC_MASTER_PORT               0x00000003
#define BWFM_DMP_DESC_ADDRESS                   0x00000005
#define BWFM_DMP_DESC_ADDRSIZE_GT32             0x00000008
#define BWFM_DMP_DESC_EOT                       0x0000000F
#define BWFM_DMP_COMP_DESIGNER                  0xFFF00000
#define BWFM_DMP_COMP_DESIGNER_S                20
#define BWFM_DMP_COMP_PARTNUM                   0x000FFF00
#define BWFM_DMP_COMP_PARTNUM_S                 8
#define BWFM_DMP_COMP_CLASS                     0x000000F0
#define BWFM_DMP_COMP_CLASS_S                   4
#define BWFM_DMP_COMP_REVISION                  0xFF000000
#define BWFM_DMP_COMP_REVISION_S                24
#define BWFM_DMP_COMP_NUM_SWRAP                 0x00F80000
#define BWFM_DMP_COMP_NUM_SWRAP_S               19
#define BWFM_DMP_COMP_NUM_MWRAP                 0x0007C000
#define BWFM_DMP_COMP_NUM_MWRAP_S               14
#define BWFM_DMP_COMP_NUM_SPORT                 0x00003E00
#define BWFM_DMP_COMP_NUM_SPORT_S               9
#define BWFM_DMP_COMP_NUM_MPORT                 0x000001F0
#define BWFM_DMP_COMP_NUM_MPORT_S               4
#define BWFM_DMP_MASTER_PORT_UID                0x0000FF00
#define BWFM_DMP_MASTER_PORT_UID_S              8
#define BWFM_DMP_MASTER_PORT_NUM                0x000000F0
#define BWFM_DMP_MASTER_PORT_NUM_S              4
#define BWFM_DMP_SLAVE_ADDR_BASE                0xFFFFF000
#define BWFM_DMP_SLAVE_ADDR_BASE_S              12
#define BWFM_DMP_SLAVE_PORT_NUM                 0x00000F00
#define BWFM_DMP_SLAVE_PORT_NUM_S               8
#define BWFM_DMP_SLAVE_TYPE                     0x000000C0
#define BWFM_DMP_SLAVE_TYPE_S                   6
#define  BWFM_DMP_SLAVE_TYPE_SLAVE              0
#define  BWFM_DMP_SLAVE_TYPE_BRIDGE             1
#define  BWFM_DMP_SLAVE_TYPE_SWRAP              2
#define  BWFM_DMP_SLAVE_TYPE_MWRAP              3
#define BWFM_DMP_SLAVE_SIZE_TYPE                0x00000030
#define BWFM_DMP_SLAVE_SIZE_TYPE_S              4
#define  BWFM_DMP_SLAVE_SIZE_4K                 0
#define  BWFM_DMP_SLAVE_SIZE_8K                 1
#define  BWFM_DMP_SLAVE_SIZE_16K                2
#define  BWFM_DMP_SLAVE_SIZE_DESC               3

/* Security Parameters */
#define BWFM_AUTH_OPEN                          0
#define BWFM_AUTH_SHARED_KEY                    1
#define BWFM_AUTH_AUTO                          2
#define BWFM_CRYPTO_ALGO_OFF                    0
#define BWFM_CRYPTO_ALGO_WEP1                   1
#define BWFM_CRYPTO_ALGO_TKIP                   2
#define BWFM_CRYPTO_ALGO_WEP128                 3
#define BWFM_CRYPTO_ALGO_AES_CCM                4
#define BWFM_CRYPTO_ALGO_AES_RESERVED1          5
#define BWFM_CRYPTO_ALGO_AES_RESERVED2          6
#define BWFM_MFP_NONE                           0
#define BWFM_MFP_CAPABLE                        1
#define BWFM_MFP_REQUIRED                       2
#define BWFM_WPA_AUTH_DISABLED                  (0 << 0)
#define BWFM_WPA_AUTH_NONE                      (1 << 0)
#define BWFM_WPA_AUTH_WPA_UNSPECIFIED           (1 << 1)
#define BWFM_WPA_AUTH_WPA_PSK                   (1 << 2)
#define BWFM_WPA_AUTH_WPA2_UNSPECIFIED          (1 << 6)
#define BWFM_WPA_AUTH_WPA2_PSK                  (1 << 7)
#define BWFM_WPA_AUTH_WPA2_1X_SHA256            (1 << 12)
#define BWFM_WPA_AUTH_WPA2_PSK_SHA256           (1 << 15)
#define BWFM_WSEC_NONE                          (0 << 0)
#define BWFM_WSEC_WEP                           (1 << 0)
#define BWFM_WSEC_TKIP                          (1 << 1)
#define BWFM_WSEC_AES                           (1 << 2)

/* Channel Parameters */
#define BWFM_CHANSPEC_CHAN_MASK                 0xff
#define BWFM_CHANSPEC_CHAN_SHIFT                0
#define BWFM_CHANSPEC_D11N_SB_L                 (0x1 << 8) /* control lower */
#define BWFM_CHANSPEC_D11N_SB_U                 (0x2 << 8) /* control lower */
#define BWFM_CHANSPEC_D11N_SB_N                 (0x3 << 8) /* none */
#define BWFM_CHANSPEC_D11N_SB_MASK              (0x3 << 8)
#define BWFM_CHANSPEC_D11N_SB_SHIFT             8
#define BWFM_CHANSPEC_D11N_BW_10                (0x1 << 10)
#define BWFM_CHANSPEC_D11N_BW_20                (0x2 << 10)
#define BWFM_CHANSPEC_D11N_BW_40                (0x3 << 10)
#define BWFM_CHANSPEC_D11N_BW_MASK              (0x3 << 10)
#define BWFM_CHANSPEC_D11N_BW_SHIFT             10
#define BWFM_CHANSPEC_D11N_BND_5G               (0x1 << 12)
#define BWFM_CHANSPEC_D11N_BND_2G               (0x2 << 12)
#define BWFM_CHANSPEC_D11N_BND_MASK             (0x3 << 12)
#define BWFM_CHANSPEC_D11N_BND_SHIFT            12
#define BWFM_CHANSPEC_D11AC_SB_LLL              (0x0 << 8)
#define BWFM_CHANSPEC_D11AC_SB_LLU              (0x1 << 8)
#define BWFM_CHANSPEC_D11AC_SB_LUL              (0x2 << 8)
#define BWFM_CHANSPEC_D11AC_SB_LUU              (0x3 << 8)
#define BWFM_CHANSPEC_D11AC_SB_ULL              (0x4 << 8)
#define BWFM_CHANSPEC_D11AC_SB_ULU              (0x5 << 8)
#define BWFM_CHANSPEC_D11AC_SB_UUL              (0x6 << 8)
#define BWFM_CHANSPEC_D11AC_SB_UUU              (0x7 << 8)
#define BWFM_CHANSPEC_D11AC_SB_MASK             (0x7 << 8)
#define BWFM_CHANSPEC_D11AC_SB_SHIFT            8
#define BWFM_CHANSPEC_D11AC_BW_5                (0x0 << 11)
#define BWFM_CHANSPEC_D11AC_BW_10               (0x1 << 11)
#define BWFM_CHANSPEC_D11AC_BW_20               (0x2 << 11)
#define BWFM_CHANSPEC_D11AC_BW_40               (0x3 << 11)
#define BWFM_CHANSPEC_D11AC_BW_80               (0x4 << 11)
#define BWFM_CHANSPEC_D11AC_BW_160              (0x5 << 11)
#define BWFM_CHANSPEC_D11AC_BW_8080             (0x6 << 11)
#define BWFM_CHANSPEC_D11AC_BW_MASK             (0x7 << 11)
#define BWFM_CHANSPEC_D11AC_BW_SHIFT            11
#define BWFM_CHANSPEC_D11AC_BND_2G              (0x0 << 14)
#define BWFM_CHANSPEC_D11AC_BND_3G              (0x1 << 14)
#define BWFM_CHANSPEC_D11AC_BND_4G              (0x2 << 14)
#define BWFM_CHANSPEC_D11AC_BND_5G              (0x3 << 14)
#define BWFM_CHANSPEC_D11AC_BND_MASK            (0x3 << 14)
#define BWFM_CHANSPEC_D11AC_BND_SHIFT           14

#define BWFM_BAND_AUTO                          0
#define BWFM_BAND_5G                            1
#define BWFM_BAND_2G                            2
#define BWFM_BAND_ALL                           3

/* Power Modes */
#define BWFM_PM_CAM                             0
#define BWFM_PM_PS                              1
#define BWFM_PM_FAST_PS                         2

/* DCMD commands */
#define BWFM_C_GET_VERSION                      1
#define BWFM_C_UP                               2
#define BWFM_C_DOWN                             3
#define BWFM_C_SET_PROMISC                      10
#define BWFM_C_GET_RATE                         12
#define BWFM_C_GET_INFRA                        19
#define BWFM_C_SET_INFRA                        20
#define BWFM_C_GET_AUTH                         21
#define BWFM_C_SET_AUTH                         22
#define BWFM_C_GET_BSSID                        23
#define BWFM_C_GET_SSID                         25
#define BWFM_C_SET_SSID                         26
#define BWFM_C_TERMINATED                       28
#define BWFM_C_GET_CHANNEL                      29
#define BWFM_C_SET_CHANNEL                      30
#define BWFM_C_GET_SRL                          31
#define BWFM_C_SET_SRL                          32
#define BWFM_C_GET_LRL                          33
#define BWFM_C_SET_LRL                          34
#define BWFM_C_GET_RADIO                        37
#define BWFM_C_SET_RADIO                        38
#define BWFM_C_GET_PHYTYPE                      39
#define BWFM_C_SET_KEY                          45
#define BWFM_C_GET_REGULATORY                   46
#define BWFM_C_SET_REGULATORY                   47
#define BWFM_C_SET_PASSIVE_SCAN                 49
#define BWFM_C_SCAN                             50
#define BWFM_C_SCAN_RESULTS                     51
#define BWFM_C_DISASSOC                         52
#define BWFM_C_REASSOC                          53
#define BWFM_C_SET_ROAM_TRIGGER                 55
#define BWFM_C_SET_ROAM_DELTA                   57
#define BWFM_C_GET_BCNPRD                       75
#define BWFM_C_SET_BCNPRD                       76
#define BWFM_C_GET_DTIMPRD                      77
#define BWFM_C_SET_DTIMPRD                      78
#define BWFM_C_SET_COUNTRY                      84
#define BWFM_C_GET_PM                           85
#define BWFM_C_SET_PM                           86
#define BWFM_C_GET_REVINFO                      98
#define BWFM_C_GET_CURR_RATESET                 114
#define BWFM_C_GET_AP                           117
#define BWFM_C_SET_AP                           118
#define BWFM_C_SET_SCB_AUTHORIZE                121
#define BWFM_C_SET_SCB_DEAUTHORIZE              122
#define BWFM_C_GET_RSSI                         127
#define BWFM_C_GET_WSEC                         133
#define BWFM_C_SET_WSEC                         134
#define BWFM_C_GET_PHY_NOISE                    135
#define BWFM_C_GET_BSS_INFO                     136
#define BWFM_C_GET_GET_PKTCNTS                  137
#define BWFM_C_GET_BANDLIST                     140
#define BWFM_C_SET_SCB_TIMEOUT                  158
#define BWFM_C_GET_ASSOCLIST                    159
#define BWFM_C_GET_PHYLIST                      180
#define BWFM_C_SET_SCAN_CHANNEL_TIME            185
#define BWFM_C_SET_SCAN_UNASSOC_TIME            187
#define BWFM_C_SCB_DEAUTHENTICATE_FOR_REASON    201
#define BWFM_C_SET_ASSOC_PREFER                 205
#define BWFM_C_GET_VALID_CHANNELS               217
#define BWFM_C_GET_KEY_PRIMARY                  235
#define BWFM_C_SET_KEY_PRIMARY                  236
#define BWFM_C_SET_SCAN_PASSIVE_TIME            258
#define BWFM_C_GET_VAR                          262
#define BWFM_C_SET_VAR                          263
#define BWFM_C_SET_WSEC_PMK                     268

struct bwfm_proto_bcdc_dcmd {
        struct {
                uint32_t cmd;
                uint32_t len;
                uint32_t flags;
#define BWFM_BCDC_DCMD_ERROR            (1 << 0)
#define BWFM_BCDC_DCMD_GET              (0 << 1)
#define BWFM_BCDC_DCMD_SET              (1 << 1)
#define BWFM_BCDC_DCMD_IF_GET(x)        (((x) >> 12) & 0xf)
#define BWFM_BCDC_DCMD_IF_SET(x)        (((x) & 0xf) << 12)
#define BWFM_BCDC_DCMD_ID_GET(x)        (((x) >> 16) & 0xffff)
#define BWFM_BCDC_DCMD_ID_SET(x)        (((x) & 0xffff) << 16)
                uint32_t status;
        } hdr;
        char buf[8192];
};

struct bwfm_proto_bcdc_hdr {
        uint8_t flags;
#define BWFM_BCDC_FLAG_PROTO_VER        2
#define BWFM_BCDC_FLAG_VER(x)           (((x) & 0xf) << 4)
#define BWFM_BCDC_FLAG_SUM_GOOD         (1 << 2) /* rx */
#define BWFM_BCDC_FLAG_SUM_NEEDED       (1 << 3) /* tx */
        uint8_t priority;
#define BWFM_BCDC_PRIORITY_MASK         0x7
        uint8_t flags2;
#define BWFM_BCDC_FLAG2_IF_MASK         0xf
        uint8_t data_offset;
};

#define BWFM_MCSSET_LEN                         16
#define BWFM_MAX_SSID_LEN                       32
struct bwfm_bss_info {
        uint32_t version;
        uint32_t length;
        uint8_t bssid[ETHER_ADDR_LEN];
        uint16_t beacon_period;
        uint16_t capability;
        uint8_t ssid_len;
        uint8_t ssid[BWFM_MAX_SSID_LEN];
        uint8_t pad0;
        uint32_t nrates;
        uint8_t rates[16];
        uint16_t chanspec;
        uint16_t atim_window;
        uint8_t dtim_period;
        uint8_t pad1;
        uint16_t rssi;
        uint8_t phy_noise;
        uint8_t n_cap;
        uint16_t pad2;
        uint32_t nbss_cap;
        uint8_t ctl_ch;
        uint8_t pad3[3];
        uint32_t reserved32[1];
        uint8_t flags;
        uint8_t reserved[3];
        uint8_t basic_mcs[BWFM_MCSSET_LEN];
        uint16_t ie_offset;
        uint16_t pad4;
        uint32_t ie_length;
        uint16_t snr;
};

#define BWFM_MAXRATES_IN_SET            BWFM_MCSSET_LEN
#define BWFM_ANT_MAX                    4
#define BWFM_VHT_CAP_MCS_MAP_NSS_MAX    8
#define BWFM_HE_CAP_MCS_MAP_NSS_MAX     BWFM_VHT_CAP_MCS_MAP_NSS_MAX

struct bwfm_sta_rateset_v5 {
        uint32_t count;
        /* rates in 500kbps units w/hi bit set if basic */
        uint8_t rates[BWFM_MAXRATES_IN_SET];
        uint8_t mcs[BWFM_MCSSET_LEN];
        uint16_t vht_mcs[BWFM_VHT_CAP_MCS_MAP_NSS_MAX];
};

struct bwfm_sta_rateset_v7 {
        uint16_t version;
        uint16_t len;
        uint32_t count;
        /* rates in 500kbps units w/hi bit set if basic */
        uint8_t rates[BWFM_MAXRATES_IN_SET];
        uint8_t mcs[BWFM_MCSSET_LEN];
        uint16_t vht_mcs[BWFM_VHT_CAP_MCS_MAP_NSS_MAX];
        uint16_t he_mcs[BWFM_HE_CAP_MCS_MAP_NSS_MAX];
};

struct bwfm_sta_info {
        uint16_t ver;
        uint16_t len;
        uint16_t cap;           /* sta's advertised capabilities */

        uint32_t flags;
#define BWFM_STA_BRCM           0x00000001 /* Running a Broadcom driver */
#define BWFM_STA_WME            0x00000002 /* WMM association */
#define BWFM_STA_NONERP         0x00000004 /* No ERP */
#define BWFM_STA_AUTHE          0x00000008 /* Authenticated */
#define BWFM_STA_ASSOC          0x00000010 /* Associated */
#define BWFM_STA_AUTHO          0x00000020 /* Authorized */
#define BWFM_STA_WDS            0x00000040 /* Wireless Distribution System */
#define BWFM_STA_WDS_LINKUP     0x00000080 /* WDS traffic/probes flowing */
#define BWFM_STA_PS             0x00000100 /* STA in power save mode, says AP */
#define BWFM_STA_APSD_BE        0x00000200 /* APSD for AC_BE default enabled */
#define BWFM_STA_APSD_BK        0x00000400 /* APSD for AC_BK default enabled */
#define BWFM_STA_APSD_VI        0x00000800 /* APSD for AC_VI default enabled */
#define BWFM_STA_APSD_VO        0x00001000 /* APSD for AC_VO default enabled */
#define BWFM_STA_N_CAP          0x00002000 /* STA 802.11n capable */
#define BWFM_STA_SCBSTATS       0x00004000 /* Per STA debug stats */
#define BWFM_STA_AMPDU_CAP      0x00008000 /* STA AMPDU capable */
#define BWFM_STA_AMSDU_CAP      0x00010000 /* STA AMSDU capable */
#define BWFM_STA_MIMO_PS        0x00020000 /* mimo ps mode is enabled */
#define BWFM_STA_MIMO_RTS       0x00040000 /* send rts in mimo ps mode */
#define BWFM_STA_RIFS_CAP       0x00080000 /* rifs enabled */
#define BWFM_STA_VHT_CAP        0x00100000 /* STA VHT(11ac) capable */
#define BWFM_STA_WPS            0x00200000 /* WPS state */
#define BWFM_STA_DWDS_CAP       0x01000000 /* DWDS CAP */
#define BWFM_STA_DWDS           0x02000000 /* DWDS active */

        uint32_t idle;          /* time since data pkt rx'd from sta */
        uint8_t ea[ETHER_ADDR_LEN];
        uint32_t count;                 /* # rates in this set */
        uint8_t rates[BWFM_MAXRATES_IN_SET];    /* rates in 500kbps units */
                                                /* w/hi bit set if basic */
        uint32_t in;            /* seconds elapsed since associated */
        uint32_t listen_interval_inms; /* Min Listen interval in ms for STA */

        /* Fields valid for ver >= 3 */
        uint32_t tx_pkts;       /* # of packets transmitted */
        uint32_t tx_failures;   /* # of packets failed */
        uint32_t rx_ucast_pkts; /* # of unicast packets received */
        uint32_t rx_mcast_pkts; /* # of multicast packets received */
        uint32_t tx_rate;       /* Rate of last successful tx frame, in bps */
        uint32_t rx_rate;       /* Rate of last successful rx frame, in bps */
        uint32_t rx_decrypt_succeeds;   /* # of packet decrypted successfully */
        uint32_t rx_decrypt_failures;   /* # of packet decrypted failed */

        /* Fields valid for ver >= 4 */
        uint32_t tx_tot_pkts;    /* # of tx pkts (ucast + mcast) */
        uint32_t rx_tot_pkts;    /* # of data packets recvd (uni + mcast) */
        uint32_t tx_mcast_pkts;  /* # of mcast pkts txed */
        uint64_t tx_tot_bytes;   /* data bytes txed (ucast + mcast) */
        uint64_t rx_tot_bytes;   /* data bytes recvd (ucast + mcast) */
        uint64_t tx_ucast_bytes; /* data bytes txed (ucast) */
        uint64_t tx_mcast_bytes; /* # data bytes txed (mcast) */
        uint64_t rx_ucast_bytes; /* data bytes recvd (ucast) */
        uint64_t rx_mcast_bytes; /* data bytes recvd (mcast) */
        int8_t rssi[BWFM_ANT_MAX];   /* per antenna rssi */
        int8_t nf[BWFM_ANT_MAX];     /* per antenna noise floor */
        uint16_t aid;                    /* association ID */
        uint16_t ht_capabilities;        /* advertised ht caps */
        uint16_t vht_flags;              /* converted vht flags */
        uint32_t tx_pkts_retry_cnt;      /* # of frames where a retry was
                                         * exhausted.
                                         */
        uint32_t tx_pkts_retry_exhausted; /* # of user frames where a retry
                                         * was exhausted
                                         */
        int8_t rx_lastpkt_rssi[BWFM_ANT_MAX]; /* Per antenna RSSI of last
                                            * received data frame.
                                            */
        /* TX WLAN retry/failure statistics:
         * Separated for host requested frames and locally generated frames.
         * Include unicast frame only where the retries/failures can be counted.
         */
        uint32_t tx_pkts_total;          /* # user frames sent successfully */
        uint32_t tx_pkts_retries;        /* # user frames retries */
        uint32_t tx_pkts_fw_total;       /* # FW generated sent successfully */
        uint32_t tx_pkts_fw_retries;     /* # retries for FW generated frames */
        uint32_t tx_pkts_fw_retry_exhausted;    /* # FW generated where a retry
                                                * was exhausted
                                                */
        uint32_t rx_pkts_retried;        /* # rx with retry bit set */
        uint32_t tx_rate_fallback;       /* lowest fallback TX rate */

        union {
                struct {
                        struct bwfm_sta_rateset_v5 rateset_adv;
                } v5;

                struct {
                        uint32_t rx_dur_total; /* user RX duration (estimate) */
                        uint16_t chanspec;
                        uint16_t pad_1;
                        struct bwfm_sta_rateset_v7 rateset_adv;
                        uint16_t wpauth;        /* authentication type */
                        uint8_t algo;           /* crypto algorithm */
                        uint8_t pad_2;
                        uint32_t tx_rspec;/* Rate of last successful tx frame */
                        uint32_t rx_rspec;/* Rate of last successful rx frame */
                        uint32_t wnm_cap;
                } v7;
        };
};

struct bwfm_ssid {
        uint32_t len;
        uint8_t ssid[BWFM_MAX_SSID_LEN];
};

struct bwfm_scan_params_v0 {
        struct bwfm_ssid ssid;
        uint8_t bssid[ETHER_ADDR_LEN];
        uint8_t bss_type;
#define DOT11_BSSTYPE_ANY               2
        uint8_t scan_type;
#define BWFM_SCANTYPE_ACTIVE            0
#define BWFM_SCANTYPE_PASSIVE           1
#define BWFM_SCANTYPE_DEFAULT           0xff
        uint32_t nprobes;
        uint32_t active_time;
        uint32_t passive_time;
        uint32_t home_time;
        uint32_t channel_num;
#define BWFM_CHANNUM_NSSID_SHIFT        16
#define BWFM_CHANNUM_NSSID_MASK         0xffff
#define BWFM_CHANNUM_NCHAN_SHIFT        0
#define BWFM_CHANNUM_NCHAN_MASK         0xffff
        uint16_t channel_list[];
};

struct bwfm_scan_params_v2 {
        uint16_t version;
        uint16_t length;
        struct bwfm_ssid ssid;
        uint8_t bssid[ETHER_ADDR_LEN];
        uint8_t bss_type;
        uint8_t pad;
        uint32_t scan_type;
        uint32_t nprobes;
        uint32_t active_time;
        uint32_t passive_time;
        uint32_t home_time;
        uint32_t channel_num;
        uint16_t channel_list[];
};

struct bwfm_scan_results {
        uint32_t buflen;
        uint32_t version;
        uint32_t count;
        struct bwfm_bss_info bss_info[];
};

struct bwfm_escan_params_v0 {
        uint32_t version;
#define BWFM_ESCAN_REQ_VERSION          1
        uint16_t action;
#define WL_ESCAN_ACTION_START           1
#define WL_ESCAN_ACTION_CONTINUE        2
#define WL_ESCAN_ACTION_ABORT           3
        uint16_t sync_id;
        struct bwfm_scan_params_v0 scan_params;
};

struct bwfm_escan_params_v2 {
        uint32_t version;
#define BWFM_ESCAN_REQ_VERSION_V2       2
        uint16_t action;
        uint16_t sync_id;
        struct bwfm_scan_params_v2 scan_params;
};

struct bwfm_escan_results {
        uint32_t buflen;
        uint32_t version;
        uint16_t sync_id;
        uint16_t bss_count;
        struct bwfm_bss_info bss_info[];
};

struct bwfm_assoc_params {
        uint8_t bssid[ETHER_ADDR_LEN];
        uint16_t pad;
        uint32_t chanspec_num;
        uint16_t chanspec_list[];
};

struct bwfm_join_pref_params {
        uint8_t type;
#define BWFM_JOIN_PREF_RSSI             1
#define BWFM_JOIN_PREF_WPA              2
#define BWFM_JOIN_PREF_BAND             3
#define BWFM_JOIN_PREF_RSSI_DELTA       4
        uint8_t len;
        uint8_t rssi_gain;
#define BWFM_JOIN_PREF_RSSI_BOOST       8
        uint8_t band;
#define BWFM_JOIN_PREF_BAND_AUTO        0
#define BWFM_JOIN_PREF_BAND_5G          1
#define BWFM_JOIN_PREF_BAND_2G          2
#define BWFM_JOIN_PREF_BAND_ALL         3
};

struct bwfm_join_params {
        struct bwfm_ssid ssid;
        struct bwfm_assoc_params assoc;
};

struct bwfm_join_scan_params {
        uint8_t scan_type;
        uint8_t pad[3];
        uint32_t nprobes;
        uint32_t active_time;
        uint32_t passive_time;
        uint32_t home_time;
};

struct bwfm_ext_join_params {
        struct bwfm_ssid ssid;
        struct bwfm_join_scan_params scan;
        struct bwfm_assoc_params assoc;
};

struct bwfm_wsec_key {
        uint32_t index;
        uint32_t len;
        uint8_t data[32];
        uint32_t pad_1[18];
        uint32_t algo;
        uint32_t flags;
#define BWFM_WSEC_PRIMARY_KEY           (1 << 1)
        uint32_t pad_2[3];
        uint32_t iv_initialized;
        uint32_t pad_3;
        /* Rx IV */
        struct {
                uint32_t hi;
                uint16_t lo;
                uint16_t pad_4;
        } rxiv;
        uint32_t pad_5[2];
        uint8_t ea[ETHER_ADDR_LEN];
};

struct bwfm_wsec_pmk {
        uint16_t key_len;
#define BWFM_WSEC_MAX_PSK_LEN           32
        uint16_t flags;
#define BWFM_WSEC_PASSPHRASE            (1 << 0)
        uint8_t key[2 * BWFM_WSEC_MAX_PSK_LEN + 1];
};

/* Event handling */
enum bwfm_fweh_event_code {
        BWFM_E_SET_SSID = 0,
        BWFM_E_JOIN = 1,
        BWFM_E_START = 2,
        BWFM_E_AUTH = 3,
        BWFM_E_AUTH_IND = 4,
        BWFM_E_DEAUTH = 5,
        BWFM_E_DEAUTH_IND = 6,
        BWFM_E_ASSOC = 7,
        BWFM_E_ASSOC_IND = 8,
        BWFM_E_REASSOC = 9,
        BWFM_E_REASSOC_IND = 10,
        BWFM_E_DISASSOC = 11,
        BWFM_E_DISASSOC_IND = 12,
        BWFM_E_QUIET_START = 13,
        BWFM_E_QUIET_END = 14,
        BWFM_E_BEACON_RX = 15,
        BWFM_E_LINK = 16,
        BWFM_E_MIC_ERROR = 17,
        BWFM_E_NDIS_LINK = 18,
        BWFM_E_ROAM = 19,
        BWFM_E_TXFAIL = 20,
        BWFM_E_PMKID_CACHE = 21,
        BWFM_E_RETROGRADE_TSF = 22,
        BWFM_E_PRUNE = 23,
        BWFM_E_AUTOAUTH = 24,
        BWFM_E_EAPOL_MSG = 25,
        BWFM_E_SCAN_COMPLETE = 26,
        BWFM_E_ADDTS_IND = 27,
        BWFM_E_DELTS_IND = 28,
        BWFM_E_BCNSENT_IND = 29,
        BWFM_E_BCNRX_MSG = 30,
        BWFM_E_BCNLOST_MSG = 31,
        BWFM_E_ROAM_PREP = 32,
        BWFM_E_PFN_NET_FOUND = 33,
        BWFM_E_PFN_NET_LOST = 34,
        BWFM_E_RESET_COMPLETE = 35,
        BWFM_E_JOIN_START = 36,
        BWFM_E_ROAM_START = 37,
        BWFM_E_ASSOC_START = 38,
        BWFM_E_IBSS_ASSOC = 39,
        BWFM_E_RADIO = 40,
        BWFM_E_PSM_WATCHDOG = 41,
        BWFM_E_PROBREQ_MSG = 44,
        BWFM_E_SCAN_CONFIRM_IND = 45,
        BWFM_E_PSK_SUP = 46,
        BWFM_E_COUNTRY_CODE_CHANGED = 47,
        BWFM_E_EXCEEDED_MEDIUM_TIME = 48,
        BWFM_E_ICV_ERROR = 49,
        BWFM_E_UNICAST_DECODE_ERROR = 50,
        BWFM_E_MULTICAST_DECODE_ERROR = 51,
        BWFM_E_TRACE = 52,
        BWFM_E_IF = 54,
        BWFM_E_P2P_DISC_LISTEN_COMPLETE = 55,
        BWFM_E_RSSI = 56,
        BWFM_E_EXTLOG_MSG = 58,
        BWFM_E_ACTION_FRAME = 59,
        BWFM_E_ACTION_FRAME_COMPLETE = 60,
        BWFM_E_PRE_ASSOC_IND = 61,
        BWFM_E_PRE_REASSOC_IND = 62,
        BWFM_E_CHANNEL_ADOPTED = 63,
        BWFM_E_AP_STARTED = 64,
        BWFM_E_DFS_AP_STOP = 65,
        BWFM_E_DFS_AP_RESUME = 66,
        BWFM_E_ESCAN_RESULT = 69,
        BWFM_E_ACTION_FRAME_OFF_CHAN_COMPLETE = 70,
        BWFM_E_PROBERESP_MSG = 71,
        BWFM_E_P2P_PROBEREQ_MSG = 72,
        BWFM_E_DCS_REQUEST = 73,
        BWFM_E_FIFO_CREDIT_MAP = 74,
        BWFM_E_ACTION_FRAME_RX = 75,
        BWFM_E_TDLS_PEER_EVENT = 92,
        BWFM_E_BCMC_CREDIT_SUPPORT = 127,
        BWFM_E_LAST = 139
};
#define BWFM_EVENT_MASK_LEN             (roundup(BWFM_E_LAST, 8) / 8)

enum bwfm_fweh_event_status {
        BWFM_E_STATUS_SUCCESS = 0,
        BWFM_E_STATUS_FAIL = 1,
        BWFM_E_STATUS_TIMEOUT = 2,
        BWFM_E_STATUS_NO_NETWORKS = 3,
        BWFM_E_STATUS_ABORT = 4,
        BWFM_E_STATUS_NO_ACK = 5,
        BWFM_E_STATUS_UNSOLICITED = 6,
        BWFM_E_STATUS_ATTEMPT = 7,
        BWFM_E_STATUS_PARTIAL = 8,
        BWFM_E_STATUS_NEWSCAN = 9,
        BWFM_E_STATUS_NEWASSOC = 10,
        BWFM_E_STATUS_11HQUIET = 11,
        BWFM_E_STATUS_SUPPRESS = 12,
        BWFM_E_STATUS_NOCHANS = 13,
        BWFM_E_STATUS_CS_ABORT = 15,
        BWFM_E_STATUS_ERROR = 16,
};

struct bwfm_ethhdr {
        uint16_t subtype;
        uint16_t length;
        uint8_t version;
        uint8_t oui[3];
#define BWFM_BRCM_OUI                   "\x00\x10\x18"
        uint16_t usr_subtype;
#define BWFM_BRCM_SUBTYPE_EVENT         1
} __packed;

struct bwfm_event_msg {
        uint16_t version;
        uint16_t flags;
        uint32_t event_type;
        uint32_t status;
        uint32_t reason;
        uint32_t auth_type;
        uint32_t datalen;
        struct ether_addr addr;
        char ifname[IFNAMSIZ];
        uint8_t ifidx;
        uint8_t bsscfgidx;
} __packed;

struct bwfm_event {
        struct ether_header ehdr;
#define BWFM_ETHERTYPE_LINK_CTL                 0x886c
        struct bwfm_ethhdr hdr;
        struct bwfm_event_msg msg;
} __packed;

struct bwfm_dload_data {
        uint16_t flag;
#define BWFM_DLOAD_FLAG_BEGIN                   (1 << 1)
#define BWFM_DLOAD_FLAG_END                     (1 << 2)
#define BWFM_DLOAD_FLAG_HANDLER_VER_1           (1 << 12)
#define BWFM_DLOAD_FLAG_HANDLER_VER_MASK        (0xf << 12)
        uint16_t type;
#define BWFM_DLOAD_TYPE_CLM                     2
        uint32_t len;
#define BWFM_DLOAD_MAX_LEN                      1400
        uint32_t crc;
        uint8_t data[];
} __packed;