/* $NetBSD: bwfmreg.h,v 1.8 2022/03/14 06:40:12 mlelstv Exp $ */
/* $OpenBSD: bwfmreg.h,v 1.16 2018/02/07 21:44:09 patrick Exp $ */
/*
* Copyright (c) 2010-2016 Broadcom Corporation
* Copyright (c) 2016,2017 Patrick Wildt <[email protected]>
*
* 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.
*/

#ifndef _DEV_IC_BWFMREG_H
#define _DEV_IC_BWFMREG_H

#include <sys/param.h>
#include <sys/types.h>

#include <sys/cdefs.h>

#include <net/if.h>
#include <net/if_ether.h>

#include <net80211/ieee80211.h>

/* SDIO registers */
#define BWFM_SDIO_FUNC1_SBADDRLOW               0x1000A
#define BWFM_SDIO_FUNC1_SBADDRMID               0x1000B
#define BWFM_SDIO_FUNC1_SBADDRHIGH              0x1000C
#define BWFM_SDIO_FUNC1_CHIPCLKCSR              0x1000E
#define  BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_ALP                   0x01
#define  BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_HT                    0x02
#define  BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_ILP                   0x04
#define  BWFM_SDIO_FUNC1_CHIPCLKCSR_ALP_AVAIL_REQ               0x08
#define  BWFM_SDIO_FUNC1_CHIPCLKCSR_HT_AVAIL_REQ                0x10
#define  BWFM_SDIO_FUNC1_CHIPCLKCSR_FORCE_HW_CLKREQ_OFF         0x20
#define  BWFM_SDIO_FUNC1_CHIPCLKCSR_ALP_AVAIL                   0x40
#define  BWFM_SDIO_FUNC1_CHIPCLKCSR_HT_AVAIL                    0x80
#define  BWFM_SDIO_FUNC1_CHIPCLKCSR_CSR_MASK                    0x1F
#define BWFM_SDIO_FUNC1_SDIOPULLUP              0x1000F

#define BWFM_SDIO_SB_OFT_ADDR_MASK              0x07FFF
#define BWFM_SDIO_SB_ACCESS_2_4B_FLAG           0x08000

/* 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_SR_CAPABILITY             0x00000500
#define BWFM_CHIP_REG_SR_CONTROL0               0x00000504
#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_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                  0x3f
#define  BWFM_ARMCR4_BANKINFO_BSZ_MULT                  8192
#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

/* Small, medium, and maximum buffer size for dcmd */
#define BWFM_DCMD_SMLEN                         256
#define BWFM_DCMD_MEDLEN                        1536
#define BWFM_DCMD_MAXLEN                        8192

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
#define BWFM_BSS_INFO_BUFLEN                    2048
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 alogorithm */
                       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 {
       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;
       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 {
       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 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_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];
};

struct bwfm_wsec_key {
       uint32_t index;
       uint32_t len;
       uint8_t data[32];
       uint32_t pad_1[18];
       uint32_t algo;
#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
       uint32_t flags;
#define BWFM_WSEC_PRIMARY_KEY           (1 << 1)
#define BWFM_PRIMARY_KEY                BWFM_WSEC_PRIMARY_KEY
       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[IEEE80211_ADDR_LEN];
};

#define BWFM_BAND_5G                    1
#define BWFM_BAND_2G                    2

/* 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;

#endif  /* _DEV_IC_BWFMREG_H */