Page MenuHomeFreeBSD

D6196.diff
No OneTemporary

D6196.diff

Index: head/sys/conf/files
===================================================================
--- head/sys/conf/files
+++ head/sys/conf/files
@@ -9,6 +9,16 @@
compile-with "${AWK} -f $S/tools/acpi_quirks2h.awk $S/dev/acpica/acpi_quirks" \
no-obj no-implicit-rule before-depend \
clean "acpi_quirks.h"
+bhnd_nvram_map.h optional bhndbus | bhnd \
+ dependency "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/tools/nvram_map_gen.awk $S/dev/bhnd/nvram/nvram_map" \
+ compile-with "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/nvram/nvram_map -h" \
+ no-obj no-implicit-rule before-depend \
+ clean "bhnd_nvram_map.h"
+bhnd_nvram_map_data.h optional bhndbus | bhnd \
+ dependency "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/tools/nvram_map_gen.awk $S/dev/bhnd/nvram/nvram_map" \
+ compile-with "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/nvram/nvram_map -d" \
+ no-obj no-implicit-rule before-depend \
+ clean "bhnd_nvram_map_data.h"
#
# The 'fdt_dtb_file' target covers an actual DTB file name, which is derived
# from the specified source (DTS) file: <platform>.dts -> <platform>.dtb
@@ -1121,6 +1131,7 @@
dev/bhnd/bhndb/bhndb_if.m optional bhndbus | bhndb
dev/bhnd/bhndb/bhndb_pci.c optional bhndbus pci | bhndb pci
dev/bhnd/bhndb/bhndb_pci_hwdata.c optional bhndbus pci | bhndb pci
+dev/bhnd/bhndb/bhndb_pci_sprom.c optional bhndbus pci | bhndb pci
dev/bhnd/bhndb/bhndb_subr.c optional bhndbus pci | bhndb
dev/bhnd/bcma/bcma.c optional bhndbus | bcma
dev/bhnd/bcma/bcma_bhndb.c optional bhndbus | bcma bhndb
@@ -1132,6 +1143,8 @@
dev/bhnd/cores/pci/bhnd_pci_hostb.c optional bhndbus pci | bhndb pci
dev/bhnd/cores/pci/bhnd_pcib.c optional bhnd_pcib bhnd pci
dev/bhnd/nvram/bhnd_nvram_if.m optional bhndbus | bhnd
+dev/bhnd/nvram/bhnd_sprom.c optional bhndbus | bhnd
+dev/bhnd/nvram/nvram_subr.c optional bhndbus | bhnd
dev/bhnd/siba/siba.c optional bhndbus | siba
dev/bhnd/siba/siba_bhndb.c optional bhndbus | siba bhndb
dev/bhnd/siba/siba_nexus.c optional siba_nexus siba
Index: head/sys/conf/kmod.mk
===================================================================
--- head/sys/conf/kmod.mk
+++ head/sys/conf/kmod.mk
@@ -411,6 +411,26 @@
.endif
.endfor # _i
+.if !empty(SRCS:Mbhnd_nvram_map.h)
+CLEANFILES+= bhnd_nvram_map.h
+bhnd_nvram_map.h: ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.awk \
+ ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.sh \
+ ${SYSDIR}/dev/bhnd/nvram/nvram_map
+bhnd_nvram_map.h:
+ ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.sh \
+ ${SYSDIR}/dev/bhnd/nvram/nvram_map -h
+.endif
+
+.if !empty(SRCS:Mbhnd_nvram_map_data.h)
+CLEANFILES+= bhnd_nvram_map_data.h
+bhnd_nvram_map_data.h: ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.awk \
+ ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.sh \
+ ${SYSDIR}/dev/bhnd/nvram/nvram_map
+bhnd_nvram_map_data.h:
+ ${SYSDIR}/dev/bhnd/tools/nvram_map_gen.sh \
+ ${SYSDIR}/dev/bhnd/nvram/nvram_map -d
+.endif
+
.if !empty(SRCS:Musbdevs.h)
CLEANFILES+= usbdevs.h
usbdevs.h: ${SYSDIR}/tools/usbdevs2h.awk ${SYSDIR}/dev/usb/usbdevs
Index: head/sys/dev/bhnd/bcmsrom_fmt.h
===================================================================
--- head/sys/dev/bhnd/bcmsrom_fmt.h
+++ head/sys/dev/bhnd/bcmsrom_fmt.h
@@ -1,373 +0,0 @@
-/*-
- * Copyright (c) 2010 Broadcom Corporation
- *
- * This file is derived from the bcmsrom.h header distributed with Broadcom's
- * brcm80211 Linux driver release, as contributed to the Linux staging
- * repository.
- *
- * 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _BHND_BCMSROM_FMT_H_
-#define _BHND_BCMSROM_FMT_H_
-
-/* Maximum srom: 6 Kilobits == 768 bytes */
-#define SROM_MAX 768
-#define SROM_MAXW 384
-#define VARS_MAX 4096
-
-/* PCI fields */
-#define PCI_F0DEVID 48
-
-#define SROM_WORDS 64
-
-#define SROM3_SWRGN_OFF 28 /* s/w region offset in words */
-
-#define SROM_SSID 2
-
-#define SROM_WL1LHMAXP 29
-
-#define SROM_WL1LPAB0 30
-#define SROM_WL1LPAB1 31
-#define SROM_WL1LPAB2 32
-
-#define SROM_WL1HPAB0 33
-#define SROM_WL1HPAB1 34
-#define SROM_WL1HPAB2 35
-
-#define SROM_MACHI_IL0 36
-#define SROM_MACMID_IL0 37
-#define SROM_MACLO_IL0 38
-#define SROM_MACHI_ET0 39
-#define SROM_MACMID_ET0 40
-#define SROM_MACLO_ET0 41
-#define SROM_MACHI_ET1 42
-#define SROM_MACMID_ET1 43
-#define SROM_MACLO_ET1 44
-#define SROM3_MACHI 37
-#define SROM3_MACMID 38
-#define SROM3_MACLO 39
-
-#define SROM_BXARSSI2G 40
-#define SROM_BXARSSI5G 41
-
-#define SROM_TRI52G 42
-#define SROM_TRI5GHL 43
-
-#define SROM_RXPO52G 45
-
-#define SROM2_ENETPHY 45
-
-#define SROM_AABREV 46
-/* Fields in AABREV */
-#define SROM_BR_MASK 0x00ff
-#define SROM_CC_MASK 0x0f00
-#define SROM_CC_SHIFT 8
-#define SROM_AA0_MASK 0x3000
-#define SROM_AA0_SHIFT 12
-#define SROM_AA1_MASK 0xc000
-#define SROM_AA1_SHIFT 14
-
-#define SROM_WL0PAB0 47
-#define SROM_WL0PAB1 48
-#define SROM_WL0PAB2 49
-
-#define SROM_LEDBH10 50
-#define SROM_LEDBH32 51
-
-#define SROM_WL10MAXP 52
-
-#define SROM_WL1PAB0 53
-#define SROM_WL1PAB1 54
-#define SROM_WL1PAB2 55
-
-#define SROM_ITT 56
-
-#define SROM_BFL 57
-#define SROM_BFL2 28
-#define SROM3_BFL2 61
-
-#define SROM_AG10 58
-
-#define SROM_CCODE 59
-
-#define SROM_OPO 60
-
-#define SROM3_LEDDC 62
-
-#define SROM_CRCREV 63
-
-/* SROM Rev 4: Reallocate the software part of the srom to accommodate
- * MIMO features. It assumes up to two PCIE functions and 440 bytes
- * of useable srom i.e. the useable storage in chips with OTP that
- * implements hardware redundancy.
- */
-
-#define SROM4_WORDS 220
-
-#define SROM4_SIGN 32
-#define SROM4_SIGNATURE 0x5372
-
-#define SROM4_BREV 33
-
-#define SROM4_BFL0 34
-#define SROM4_BFL1 35
-#define SROM4_BFL2 36
-#define SROM4_BFL3 37
-#define SROM5_BFL0 37
-#define SROM5_BFL1 38
-#define SROM5_BFL2 39
-#define SROM5_BFL3 40
-
-#define SROM4_MACHI 38
-#define SROM4_MACMID 39
-#define SROM4_MACLO 40
-#define SROM5_MACHI 41
-#define SROM5_MACMID 42
-#define SROM5_MACLO 43
-
-#define SROM4_CCODE 41
-#define SROM4_REGREV 42
-#define SROM5_CCODE 34
-#define SROM5_REGREV 35
-
-#define SROM4_LEDBH10 43
-#define SROM4_LEDBH32 44
-#define SROM5_LEDBH10 59
-#define SROM5_LEDBH32 60
-
-#define SROM4_LEDDC 45
-#define SROM5_LEDDC 45
-
-#define SROM4_AA 46
-#define SROM4_AA2G_MASK 0x00ff
-#define SROM4_AA2G_SHIFT 0
-#define SROM4_AA5G_MASK 0xff00
-#define SROM4_AA5G_SHIFT 8
-
-#define SROM4_AG10 47
-#define SROM4_AG32 48
-
-#define SROM4_TXPID2G 49
-#define SROM4_TXPID5G 51
-#define SROM4_TXPID5GL 53
-#define SROM4_TXPID5GH 55
-
-#define SROM4_TXRXC 61
-#define SROM4_TXCHAIN_MASK 0x000f
-#define SROM4_TXCHAIN_SHIFT 0
-#define SROM4_RXCHAIN_MASK 0x00f0
-#define SROM4_RXCHAIN_SHIFT 4
-#define SROM4_SWITCH_MASK 0xff00
-#define SROM4_SWITCH_SHIFT 8
-
-/* Per-path fields */
-#define MAX_PATH_SROM 4
-#define SROM4_PATH0 64
-#define SROM4_PATH1 87
-#define SROM4_PATH2 110
-#define SROM4_PATH3 133
-
-#define SROM4_2G_ITT_MAXP 0
-#define SROM4_2G_PA 1
-#define SROM4_5G_ITT_MAXP 5
-#define SROM4_5GLH_MAXP 6
-#define SROM4_5G_PA 7
-#define SROM4_5GL_PA 11
-#define SROM4_5GH_PA 15
-
-/* Fields in the ITT_MAXP and 5GLH_MAXP words */
-#define B2G_MAXP_MASK 0xff
-#define B2G_ITT_SHIFT 8
-#define B5G_MAXP_MASK 0xff
-#define B5G_ITT_SHIFT 8
-#define B5GH_MAXP_MASK 0xff
-#define B5GL_MAXP_SHIFT 8
-
-/* All the miriad power offsets */
-#define SROM4_2G_CCKPO 156
-#define SROM4_2G_OFDMPO 157
-#define SROM4_5G_OFDMPO 159
-#define SROM4_5GL_OFDMPO 161
-#define SROM4_5GH_OFDMPO 163
-#define SROM4_2G_MCSPO 165
-#define SROM4_5G_MCSPO 173
-#define SROM4_5GL_MCSPO 181
-#define SROM4_5GH_MCSPO 189
-#define SROM4_CDDPO 197
-#define SROM4_STBCPO 198
-#define SROM4_BW40PO 199
-#define SROM4_BWDUPPO 200
-
-#define SROM4_CRCREV 219
-
-/* SROM Rev 8: Make space for a 48word hardware header for PCIe rev >= 6.
- * This is acombined srom for both MIMO and SISO boards, usable in
- * the .130 4Kilobit OTP with hardware redundancy.
- */
-
-#define SROM8_SIGN 64
-
-#define SROM8_BREV 65
-
-#define SROM8_BFL0 66
-#define SROM8_BFL1 67
-#define SROM8_BFL2 68
-#define SROM8_BFL3 69
-
-#define SROM8_MACHI 70
-#define SROM8_MACMID 71
-#define SROM8_MACLO 72
-
-#define SROM8_CCODE 73
-#define SROM8_REGREV 74
-
-#define SROM8_LEDBH10 75
-#define SROM8_LEDBH32 76
-
-#define SROM8_LEDDC 77
-
-#define SROM8_AA 78
-
-#define SROM8_AG10 79
-#define SROM8_AG32 80
-
-#define SROM8_TXRXC 81
-
-#define SROM8_BXARSSI2G 82
-#define SROM8_BXARSSI5G 83
-#define SROM8_TRI52G 84
-#define SROM8_TRI5GHL 85
-#define SROM8_RXPO52G 86
-
-#define SROM8_FEM2G 87
-#define SROM8_FEM5G 88
-#define SROM8_FEM_ANTSWLUT_MASK 0xf800
-#define SROM8_FEM_ANTSWLUT_SHIFT 11
-#define SROM8_FEM_TR_ISO_MASK 0x0700
-#define SROM8_FEM_TR_ISO_SHIFT 8
-#define SROM8_FEM_PDET_RANGE_MASK 0x00f8
-#define SROM8_FEM_PDET_RANGE_SHIFT 3
-#define SROM8_FEM_EXTPA_GAIN_MASK 0x0006
-#define SROM8_FEM_EXTPA_GAIN_SHIFT 1
-#define SROM8_FEM_TSSIPOS_MASK 0x0001
-#define SROM8_FEM_TSSIPOS_SHIFT 0
-
-#define SROM8_THERMAL 89
-
-/* Temp sense related entries */
-#define SROM8_MPWR_RAWTS 90
-#define SROM8_TS_SLP_OPT_CORRX 91
-/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, IQSWP: IQ CAL swap disable */
-#define SROM8_FOC_HWIQ_IQSWP 92
-
-/* Temperature delta for PHY calibration */
-#define SROM8_PHYCAL_TEMPDELTA 93
-
-/* Per-path offsets & fields */
-#define SROM8_PATH0 96
-#define SROM8_PATH1 112
-#define SROM8_PATH2 128
-#define SROM8_PATH3 144
-
-#define SROM8_2G_ITT_MAXP 0
-#define SROM8_2G_PA 1
-#define SROM8_5G_ITT_MAXP 4
-#define SROM8_5GLH_MAXP 5
-#define SROM8_5G_PA 6
-#define SROM8_5GL_PA 9
-#define SROM8_5GH_PA 12
-
-/* All the miriad power offsets */
-#define SROM8_2G_CCKPO 160
-
-#define SROM8_2G_OFDMPO 161
-#define SROM8_5G_OFDMPO 163
-#define SROM8_5GL_OFDMPO 165
-#define SROM8_5GH_OFDMPO 167
-
-#define SROM8_2G_MCSPO 169
-#define SROM8_5G_MCSPO 177
-#define SROM8_5GL_MCSPO 185
-#define SROM8_5GH_MCSPO 193
-
-#define SROM8_CDDPO 201
-#define SROM8_STBCPO 202
-#define SROM8_BW40PO 203
-#define SROM8_BWDUPPO 204
-
-/* SISO PA parameters are in the path0 spaces */
-#define SROM8_SISO 96
-
-/* Legacy names for SISO PA parameters */
-#define SROM8_W0_ITTMAXP (SROM8_SISO + SROM8_2G_ITT_MAXP)
-#define SROM8_W0_PAB0 (SROM8_SISO + SROM8_2G_PA)
-#define SROM8_W0_PAB1 (SROM8_SISO + SROM8_2G_PA + 1)
-#define SROM8_W0_PAB2 (SROM8_SISO + SROM8_2G_PA + 2)
-#define SROM8_W1_ITTMAXP (SROM8_SISO + SROM8_5G_ITT_MAXP)
-#define SROM8_W1_MAXP_LCHC (SROM8_SISO + SROM8_5GLH_MAXP)
-#define SROM8_W1_PAB0 (SROM8_SISO + SROM8_5G_PA)
-#define SROM8_W1_PAB1 (SROM8_SISO + SROM8_5G_PA + 1)
-#define SROM8_W1_PAB2 (SROM8_SISO + SROM8_5G_PA + 2)
-#define SROM8_W1_PAB0_LC (SROM8_SISO + SROM8_5GL_PA)
-#define SROM8_W1_PAB1_LC (SROM8_SISO + SROM8_5GL_PA + 1)
-#define SROM8_W1_PAB2_LC (SROM8_SISO + SROM8_5GL_PA + 2)
-#define SROM8_W1_PAB0_HC (SROM8_SISO + SROM8_5GH_PA)
-#define SROM8_W1_PAB1_HC (SROM8_SISO + SROM8_5GH_PA + 1)
-#define SROM8_W1_PAB2_HC (SROM8_SISO + SROM8_5GH_PA + 2)
-
-#define SROM8_CRCREV 219
-
-/* SROM REV 9 */
-#define SROM9_2GPO_CCKBW20 160
-#define SROM9_2GPO_CCKBW20UL 161
-#define SROM9_2GPO_LOFDMBW20 162
-#define SROM9_2GPO_LOFDMBW20UL 164
-
-#define SROM9_5GLPO_LOFDMBW20 166
-#define SROM9_5GLPO_LOFDMBW20UL 168
-#define SROM9_5GMPO_LOFDMBW20 170
-#define SROM9_5GMPO_LOFDMBW20UL 172
-#define SROM9_5GHPO_LOFDMBW20 174
-#define SROM9_5GHPO_LOFDMBW20UL 176
-
-#define SROM9_2GPO_MCSBW20 178
-#define SROM9_2GPO_MCSBW20UL 180
-#define SROM9_2GPO_MCSBW40 182
-
-#define SROM9_5GLPO_MCSBW20 184
-#define SROM9_5GLPO_MCSBW20UL 186
-#define SROM9_5GLPO_MCSBW40 188
-#define SROM9_5GMPO_MCSBW20 190
-#define SROM9_5GMPO_MCSBW20UL 192
-#define SROM9_5GMPO_MCSBW40 194
-#define SROM9_5GHPO_MCSBW20 196
-#define SROM9_5GHPO_MCSBW20UL 198
-#define SROM9_5GHPO_MCSBW40 200
-
-#define SROM9_PO_MCS32 202
-#define SROM9_PO_LOFDM40DUP 203
-
-#define SROM9_REV_CRC 219
-
-typedef struct {
- u8 tssipos; /* TSSI positive slope, 1: positive, 0: negative */
- u8 extpagain; /* Ext PA gain-type: full-gain: 0, pa-lite: 1, no_pa: 2 */
- u8 pdetrange; /* support 32 combinations of different Pdet dynamic ranges */
- u8 triso; /* TR switch isolation */
- u8 antswctrllut; /* antswctrl lookup table configuration: 32 possible choices */
-} srom_fem_t;
-
-#endif /* _BHND_BCMSROM_TBL_H_ */
Index: head/sys/dev/bhnd/bcmsrom_tbl.h
===================================================================
--- head/sys/dev/bhnd/bcmsrom_tbl.h
+++ head/sys/dev/bhnd/bcmsrom_tbl.h
@@ -1,577 +0,0 @@
-/*-
- * Copyright (c) 2010 Broadcom Corporation
- *
- * This file is derived from the bcmsrom.h header distributed with Broadcom's
- * brcm80211 Linux driver release, as contributed to the Linux staging
- * repository.
- *
- * 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.
- *
- * $FreeBSD$
- */
-
-#ifndef _BHND_BCMSROM_TBL_H_
-#define _BHND_BCMSROM_TBL_H_
-
-#include "bcmsrom_fmt.h"
-
-typedef struct {
- const char *name;
- u32 revmask;
- u32 flags;
- u16 off;
- u16 mask;
-} sromvar_t;
-
-#define SRFL_MORE 1 /* value continues as described by the next entry */
-#define SRFL_NOFFS 2 /* value bits can't be all one's */
-#define SRFL_PRHEX 4 /* value is in hexdecimal format */
-#define SRFL_PRSIGN 8 /* value is in signed decimal format */
-#define SRFL_CCODE 0x10 /* value is in country code format */
-#define SRFL_ETHADDR 0x20 /* value is an Ethernet address */
-#define SRFL_LEDDC 0x40 /* value is an LED duty cycle */
-#define SRFL_NOVAR 0x80 /* do not generate a nvram param, entry is for mfgc */
-
-/* Assumptions:
- * - Ethernet address spans across 3 consective words
- *
- * Table rules:
- * - Add multiple entries next to each other if a value spans across multiple words
- * (even multiple fields in the same word) with each entry except the last having
- * it's SRFL_MORE bit set.
- * - Ethernet address entry does not follow above rule and must not have SRFL_MORE
- * bit set. Its SRFL_ETHADDR bit implies it takes multiple words.
- * - The last entry's name field must be NULL to indicate the end of the table. Other
- * entries must have non-NULL name.
- */
-
-static const sromvar_t pci_sromvars[] = {
- {"devid", 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, 0xffff},
- {"boardrev", 0x0000000e, SRFL_PRHEX, SROM_AABREV, SROM_BR_MASK},
- {"boardrev", 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff},
- {"boardrev", 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff},
- {"boardflags", 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff},
- {"boardflags", 0x00000004, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
- {"", 0, 0, SROM_BFL2, 0xffff},
- {"boardflags", 0x00000008, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
- {"", 0, 0, SROM3_BFL2, 0xffff},
- {"boardflags", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL0, 0xffff},
- {"", 0, 0, SROM4_BFL1, 0xffff},
- {"boardflags", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL0, 0xffff},
- {"", 0, 0, SROM5_BFL1, 0xffff},
- {"boardflags", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0, 0xffff},
- {"", 0, 0, SROM8_BFL1, 0xffff},
- {"boardflags2", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL2, 0xffff},
- {"", 0, 0, SROM4_BFL3, 0xffff},
- {"boardflags2", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL2, 0xffff},
- {"", 0, 0, SROM5_BFL3, 0xffff},
- {"boardflags2", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2, 0xffff},
- {"", 0, 0, SROM8_BFL3, 0xffff},
- {"boardtype", 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff},
- {"boardnum", 0x00000006, 0, SROM_MACLO_IL0, 0xffff},
- {"boardnum", 0x00000008, 0, SROM3_MACLO, 0xffff},
- {"boardnum", 0x00000010, 0, SROM4_MACLO, 0xffff},
- {"boardnum", 0x000000e0, 0, SROM5_MACLO, 0xffff},
- {"boardnum", 0xffffff00, 0, SROM8_MACLO, 0xffff},
- {"cc", 0x00000002, 0, SROM_AABREV, SROM_CC_MASK},
- {"regrev", 0x00000008, 0, SROM_OPO, 0xff00},
- {"regrev", 0x00000010, 0, SROM4_REGREV, 0x00ff},
- {"regrev", 0x000000e0, 0, SROM5_REGREV, 0x00ff},
- {"regrev", 0xffffff00, 0, SROM8_REGREV, 0x00ff},
- {"ledbh0", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0x00ff},
- {"ledbh1", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00},
- {"ledbh2", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0x00ff},
- {"ledbh3", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00},
- {"ledbh0", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0x00ff},
- {"ledbh1", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00},
- {"ledbh2", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0x00ff},
- {"ledbh3", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00},
- {"ledbh0", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0x00ff},
- {"ledbh1", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00},
- {"ledbh2", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0x00ff},
- {"ledbh3", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00},
- {"ledbh0", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff},
- {"ledbh1", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00},
- {"ledbh2", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff},
- {"ledbh3", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00},
- {"pa0b0", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff},
- {"pa0b1", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff},
- {"pa0b2", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff},
- {"pa0itssit", 0x0000000e, 0, SROM_ITT, 0x00ff},
- {"pa0maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0x00ff},
- {"pa0b0", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff},
- {"pa0b1", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff},
- {"pa0b2", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff},
- {"pa0itssit", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00},
- {"pa0maxpwr", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff},
- {"opo", 0x0000000c, 0, SROM_OPO, 0x00ff},
- {"opo", 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff},
- {"aa2g", 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK},
- {"aa2g", 0x000000f0, 0, SROM4_AA, 0x00ff},
- {"aa2g", 0xffffff00, 0, SROM8_AA, 0x00ff},
- {"aa5g", 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK},
- {"aa5g", 0x000000f0, 0, SROM4_AA, 0xff00},
- {"aa5g", 0xffffff00, 0, SROM8_AA, 0xff00},
- {"ag0", 0x0000000e, 0, SROM_AG10, 0x00ff},
- {"ag1", 0x0000000e, 0, SROM_AG10, 0xff00},
- {"ag0", 0x000000f0, 0, SROM4_AG10, 0x00ff},
- {"ag1", 0x000000f0, 0, SROM4_AG10, 0xff00},
- {"ag2", 0x000000f0, 0, SROM4_AG32, 0x00ff},
- {"ag3", 0x000000f0, 0, SROM4_AG32, 0xff00},
- {"ag0", 0xffffff00, 0, SROM8_AG10, 0x00ff},
- {"ag1", 0xffffff00, 0, SROM8_AG10, 0xff00},
- {"ag2", 0xffffff00, 0, SROM8_AG32, 0x00ff},
- {"ag3", 0xffffff00, 0, SROM8_AG32, 0xff00},
- {"pa1b0", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff},
- {"pa1b1", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff},
- {"pa1b2", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff},
- {"pa1lob0", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff},
- {"pa1lob1", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff},
- {"pa1lob2", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff},
- {"pa1hib0", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff},
- {"pa1hib1", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff},
- {"pa1hib2", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff},
- {"pa1itssit", 0x0000000e, 0, SROM_ITT, 0xff00},
- {"pa1maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0xff00},
- {"pa1lomaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00},
- {"pa1himaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0x00ff},
- {"pa1b0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff},
- {"pa1b1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff},
- {"pa1b2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff},
- {"pa1lob0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff},
- {"pa1lob1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff},
- {"pa1lob2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff},
- {"pa1hib0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff},
- {"pa1hib1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff},
- {"pa1hib2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff},
- {"pa1itssit", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0xff00},
- {"pa1maxpwr", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff},
- {"pa1lomaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00},
- {"pa1himaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff},
- {"bxa2g", 0x00000008, 0, SROM_BXARSSI2G, 0x1800},
- {"rssisav2g", 0x00000008, 0, SROM_BXARSSI2G, 0x0700},
- {"rssismc2g", 0x00000008, 0, SROM_BXARSSI2G, 0x00f0},
- {"rssismf2g", 0x00000008, 0, SROM_BXARSSI2G, 0x000f},
- {"bxa2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800},
- {"rssisav2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700},
- {"rssismc2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0},
- {"rssismf2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f},
- {"bxa5g", 0x00000008, 0, SROM_BXARSSI5G, 0x1800},
- {"rssisav5g", 0x00000008, 0, SROM_BXARSSI5G, 0x0700},
- {"rssismc5g", 0x00000008, 0, SROM_BXARSSI5G, 0x00f0},
- {"rssismf5g", 0x00000008, 0, SROM_BXARSSI5G, 0x000f},
- {"bxa5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800},
- {"rssisav5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700},
- {"rssismc5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0},
- {"rssismf5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f},
- {"tri2g", 0x00000008, 0, SROM_TRI52G, 0x00ff},
- {"tri5g", 0x00000008, 0, SROM_TRI52G, 0xff00},
- {"tri5gl", 0x00000008, 0, SROM_TRI5GHL, 0x00ff},
- {"tri5gh", 0x00000008, 0, SROM_TRI5GHL, 0xff00},
- {"tri2g", 0xffffff00, 0, SROM8_TRI52G, 0x00ff},
- {"tri5g", 0xffffff00, 0, SROM8_TRI52G, 0xff00},
- {"tri5gl", 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff},
- {"tri5gh", 0xffffff00, 0, SROM8_TRI5GHL, 0xff00},
- {"rxpo2g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0x00ff},
- {"rxpo5g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00},
- {"rxpo2g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff},
- {"rxpo5g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00},
- {"txchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_TXCHAIN_MASK},
- {"rxchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_RXCHAIN_MASK},
- {"antswitch", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_SWITCH_MASK},
- {"txchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_TXCHAIN_MASK},
- {"rxchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_RXCHAIN_MASK},
- {"antswitch", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_SWITCH_MASK},
- {"tssipos2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TSSIPOS_MASK},
- {"extpagain2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_EXTPA_GAIN_MASK},
- {"pdetrange2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_PDET_RANGE_MASK},
- {"triso2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TR_ISO_MASK},
- {"antswctl2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_ANTSWLUT_MASK},
- {"tssipos5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TSSIPOS_MASK},
- {"extpagain5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_EXTPA_GAIN_MASK},
- {"pdetrange5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_PDET_RANGE_MASK},
- {"triso5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TR_ISO_MASK},
- {"antswctl5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_ANTSWLUT_MASK},
- {"tempthresh", 0xffffff00, 0, SROM8_THERMAL, 0xff00},
- {"tempoffset", 0xffffff00, 0, SROM8_THERMAL, 0x00ff},
- {"txpid2ga0", 0x000000f0, 0, SROM4_TXPID2G, 0x00ff},
- {"txpid2ga1", 0x000000f0, 0, SROM4_TXPID2G, 0xff00},
- {"txpid2ga2", 0x000000f0, 0, SROM4_TXPID2G+1, 0x00ff},
- {"txpid2ga3", 0x000000f0, 0, SROM4_TXPID2G+1, 0xff00},
- {"txpid5ga0", 0x000000f0, 0, SROM4_TXPID5G, 0x00ff},
- {"txpid5ga1", 0x000000f0, 0, SROM4_TXPID5G, 0xff00},
- {"txpid5ga2", 0x000000f0, 0, SROM4_TXPID5G+1, 0x00ff},
- {"txpid5ga3", 0x000000f0, 0, SROM4_TXPID5G+1, 0xff00},
- {"txpid5gla0", 0x000000f0, 0, SROM4_TXPID5GL, 0x00ff},
- {"txpid5gla1", 0x000000f0, 0, SROM4_TXPID5GL, 0xff00},
- {"txpid5gla2", 0x000000f0, 0, SROM4_TXPID5GL+1, 0x00ff},
- {"txpid5gla3", 0x000000f0, 0, SROM4_TXPID5GL+1, 0xff00},
- {"txpid5gha0", 0x000000f0, 0, SROM4_TXPID5GH, 0x00ff},
- {"txpid5gha1", 0x000000f0, 0, SROM4_TXPID5GH, 0xff00},
- {"txpid5gha2", 0x000000f0, 0, SROM4_TXPID5GH+1, 0x00ff},
- {"txpid5gha3", 0x000000f0, 0, SROM4_TXPID5GH+1, 0xff00},
-
- {"ccode", 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff},
- {"ccode", 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff},
- {"ccode", 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff},
- {"ccode", 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff},
- {"macaddr", 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff},
- {"macaddr", 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff},
- {"macaddr", 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff},
- {"macaddr", 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff},
- {"il0macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0, 0xffff},
- {"et1macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1, 0xffff},
- {"leddc", 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC, 0xffff},
- {"leddc", 0x000000e0, SRFL_NOFFS | SRFL_LEDDC, SROM5_LEDDC, 0xffff},
- {"leddc", 0x00000010, SRFL_NOFFS | SRFL_LEDDC, SROM4_LEDDC, 0xffff},
- {"leddc", 0x00000008, SRFL_NOFFS | SRFL_LEDDC, SROM3_LEDDC, 0xffff},
- {"rawtempsense",0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0x01ff},
- {"measpower", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0xfe00},
- {"tempsense_slope",0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0x00ff},
- {"tempcorrx", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0xfc00},
- {"tempsense_option",0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0x0300},
- {"freqoffset_corr",0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x000f},
- {"iqcal_swp_dis",0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0010},
- {"hw_iqcal_en", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0020},
- {"phycal_tempdelta",0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA, 0x00ff},
-
- {"cck2gpo", 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff},
- {"cck2gpo", 0x00000100, 0, SROM8_2G_CCKPO, 0xffff},
- {"ofdm2gpo", 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff},
- {"", 0, 0, SROM4_2G_OFDMPO+1, 0xffff},
- {"ofdm5gpo", 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff},
- {"", 0, 0, SROM4_5G_OFDMPO+1, 0xffff},
- {"ofdm5glpo", 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff},
- {"", 0, 0, SROM4_5GL_OFDMPO+1, 0xffff},
- {"ofdm5ghpo", 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff},
- {"", 0, 0, SROM4_5GH_OFDMPO+1, 0xffff},
- {"ofdm2gpo", 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff},
- {"", 0, 0, SROM8_2G_OFDMPO+1, 0xffff},
- {"ofdm5gpo", 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff},
- {"", 0, 0, SROM8_5G_OFDMPO+1, 0xffff},
- {"ofdm5glpo", 0x00000100, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff},
- {"", 0, 0, SROM8_5GL_OFDMPO+1, 0xffff},
- {"ofdm5ghpo", 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff},
- {"", 0, 0, SROM8_5GH_OFDMPO+1, 0xffff},
-
- {"mcs2gpo0", 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff},
- {"mcs2gpo1", 0x000000f0, 0, SROM4_2G_MCSPO+1, 0xffff},
- {"mcs2gpo2", 0x000000f0, 0, SROM4_2G_MCSPO+2, 0xffff},
- {"mcs2gpo3", 0x000000f0, 0, SROM4_2G_MCSPO+3, 0xffff},
- {"mcs2gpo4", 0x000000f0, 0, SROM4_2G_MCSPO+4, 0xffff},
- {"mcs2gpo5", 0x000000f0, 0, SROM4_2G_MCSPO+5, 0xffff},
- {"mcs2gpo6", 0x000000f0, 0, SROM4_2G_MCSPO+6, 0xffff},
- {"mcs2gpo7", 0x000000f0, 0, SROM4_2G_MCSPO+7, 0xffff},
-
- {"mcs5gpo0", 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff},
- {"mcs5gpo1", 0x000000f0, 0, SROM4_5G_MCSPO+1, 0xffff},
- {"mcs5gpo2", 0x000000f0, 0, SROM4_5G_MCSPO+2, 0xffff},
- {"mcs5gpo3", 0x000000f0, 0, SROM4_5G_MCSPO+3, 0xffff},
- {"mcs5gpo4", 0x000000f0, 0, SROM4_5G_MCSPO+4, 0xffff},
- {"mcs5gpo5", 0x000000f0, 0, SROM4_5G_MCSPO+5, 0xffff},
- {"mcs5gpo6", 0x000000f0, 0, SROM4_5G_MCSPO+6, 0xffff},
- {"mcs5gpo7", 0x000000f0, 0, SROM4_5G_MCSPO+7, 0xffff},
-
- {"mcs5glpo0", 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff},
- {"mcs5glpo1", 0x000000f0, 0, SROM4_5GL_MCSPO+1, 0xffff},
- {"mcs5glpo2", 0x000000f0, 0, SROM4_5GL_MCSPO+2, 0xffff},
- {"mcs5glpo3", 0x000000f0, 0, SROM4_5GL_MCSPO+3, 0xffff},
- {"mcs5glpo4", 0x000000f0, 0, SROM4_5GL_MCSPO+4, 0xffff},
- {"mcs5glpo5", 0x000000f0, 0, SROM4_5GL_MCSPO+5, 0xffff},
- {"mcs5glpo6", 0x000000f0, 0, SROM4_5GL_MCSPO+6, 0xffff},
- {"mcs5glpo7", 0x000000f0, 0, SROM4_5GL_MCSPO+7, 0xffff},
-
- {"mcs5ghpo0", 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff},
- {"mcs5ghpo1", 0x000000f0, 0, SROM4_5GH_MCSPO+1, 0xffff},
- {"mcs5ghpo2", 0x000000f0, 0, SROM4_5GH_MCSPO+2, 0xffff},
- {"mcs5ghpo3", 0x000000f0, 0, SROM4_5GH_MCSPO+3, 0xffff},
- {"mcs5ghpo4", 0x000000f0, 0, SROM4_5GH_MCSPO+4, 0xffff},
- {"mcs5ghpo5", 0x000000f0, 0, SROM4_5GH_MCSPO+5, 0xffff},
- {"mcs5ghpo6", 0x000000f0, 0, SROM4_5GH_MCSPO+6, 0xffff},
- {"mcs5ghpo7", 0x000000f0, 0, SROM4_5GH_MCSPO+7, 0xffff},
-
- {"mcs2gpo0", 0x00000100, 0, SROM8_2G_MCSPO, 0xffff},
- {"mcs2gpo1", 0x00000100, 0, SROM8_2G_MCSPO+1, 0xffff},
- {"mcs2gpo2", 0x00000100, 0, SROM8_2G_MCSPO+2, 0xffff},
- {"mcs2gpo3", 0x00000100, 0, SROM8_2G_MCSPO+3, 0xffff},
- {"mcs2gpo4", 0x00000100, 0, SROM8_2G_MCSPO+4, 0xffff},
- {"mcs2gpo5", 0x00000100, 0, SROM8_2G_MCSPO+5, 0xffff},
- {"mcs2gpo6", 0x00000100, 0, SROM8_2G_MCSPO+6, 0xffff},
- {"mcs2gpo7", 0x00000100, 0, SROM8_2G_MCSPO+7, 0xffff},
-
- {"mcs5gpo0", 0x00000100, 0, SROM8_5G_MCSPO, 0xffff},
- {"mcs5gpo1", 0x00000100, 0, SROM8_5G_MCSPO+1, 0xffff},
- {"mcs5gpo2", 0x00000100, 0, SROM8_5G_MCSPO+2, 0xffff},
- {"mcs5gpo3", 0x00000100, 0, SROM8_5G_MCSPO+3, 0xffff},
- {"mcs5gpo4", 0x00000100, 0, SROM8_5G_MCSPO+4, 0xffff},
- {"mcs5gpo5", 0x00000100, 0, SROM8_5G_MCSPO+5, 0xffff},
- {"mcs5gpo6", 0x00000100, 0, SROM8_5G_MCSPO+6, 0xffff},
- {"mcs5gpo7", 0x00000100, 0, SROM8_5G_MCSPO+7, 0xffff},
-
- {"mcs5glpo0", 0x00000100, 0, SROM8_5GL_MCSPO, 0xffff},
- {"mcs5glpo1", 0x00000100, 0, SROM8_5GL_MCSPO+1, 0xffff},
- {"mcs5glpo2", 0x00000100, 0, SROM8_5GL_MCSPO+2, 0xffff},
- {"mcs5glpo3", 0x00000100, 0, SROM8_5GL_MCSPO+3, 0xffff},
- {"mcs5glpo4", 0x00000100, 0, SROM8_5GL_MCSPO+4, 0xffff},
- {"mcs5glpo5", 0x00000100, 0, SROM8_5GL_MCSPO+5, 0xffff},
- {"mcs5glpo6", 0x00000100, 0, SROM8_5GL_MCSPO+6, 0xffff},
- {"mcs5glpo7", 0x00000100, 0, SROM8_5GL_MCSPO+7, 0xffff},
- {"mcs5ghpo0", 0x00000100, 0, SROM8_5GH_MCSPO, 0xffff},
- {"mcs5ghpo1", 0x00000100, 0, SROM8_5GH_MCSPO+1, 0xffff},
- {"mcs5ghpo2", 0x00000100, 0, SROM8_5GH_MCSPO+2, 0xffff},
- {"mcs5ghpo3", 0x00000100, 0, SROM8_5GH_MCSPO+3, 0xffff},
- {"mcs5ghpo4", 0x00000100, 0, SROM8_5GH_MCSPO+4, 0xffff},
- {"mcs5ghpo5", 0x00000100, 0, SROM8_5GH_MCSPO+5, 0xffff},
- {"mcs5ghpo6", 0x00000100, 0, SROM8_5GH_MCSPO+6, 0xffff},
- {"mcs5ghpo7", 0x00000100, 0, SROM8_5GH_MCSPO+7, 0xffff},
- {"cddpo", 0x000000f0, 0, SROM4_CDDPO, 0xffff},
- {"stbcpo", 0x000000f0, 0, SROM4_STBCPO, 0xffff},
- {"bw40po", 0x000000f0, 0, SROM4_BW40PO, 0xffff},
- {"bwduppo", 0x000000f0, 0, SROM4_BWDUPPO, 0xffff},
- {"cddpo", 0x00000100, 0, SROM8_CDDPO, 0xffff},
- {"stbcpo", 0x00000100, 0, SROM8_STBCPO, 0xffff},
- {"bw40po", 0x00000100, 0, SROM8_BW40PO, 0xffff},
- {"bwduppo", 0x00000100, 0, SROM8_BWDUPPO, 0xffff},
-
- /* power per rate from sromrev 9 */
- {"cckbw202gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20, 0xffff},
- {"cckbw20ul2gpo",0xfffffe00, 0, SROM9_2GPO_CCKBW20UL, 0xffff},
- {"legofdmbw202gpo",0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20, 0xffff},
- {"", 0, 0, SROM9_2GPO_LOFDMBW20+1, 0xffff},
- {"legofdmbw20ul2gpo",0xfffffe00,SRFL_MORE, SROM9_2GPO_LOFDMBW20UL, 0xffff},
- {"", 0, 0, SROM9_2GPO_LOFDMBW20UL+1,0xffff},
- {"legofdmbw205glpo",0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20, 0xffff},
- {"", 0, 0, SROM9_5GLPO_LOFDMBW20+1,0xffff},
- {"legofdmbw20ul5glpo",0xfffffe00,SRFL_MORE, SROM9_5GLPO_LOFDMBW20UL,0xffff},
- {"", 0, 0, SROM9_5GLPO_LOFDMBW20UL+1,0xffff},
- {"legofdmbw205gmpo",0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20, 0xffff},
- {"", 0, 0, SROM9_5GMPO_LOFDMBW20+1,0xffff},
- {"legofdmbw20ul5gmpo",0xfffffe00,SRFL_MORE, SROM9_5GMPO_LOFDMBW20UL,0xffff},
- {"", 0, 0, SROM9_5GMPO_LOFDMBW20UL+1,0xffff},
- {"legofdmbw205ghpo",0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20, 0xffff},
- {"", 0, 0, SROM9_5GHPO_LOFDMBW20+1,0xffff},
- {"legofdmbw20ul5ghpo",0xfffffe00,SRFL_MORE, SROM9_5GHPO_LOFDMBW20UL,0xffff},
- {"", 0, 0, SROM9_5GHPO_LOFDMBW20UL+1,0xffff},
- {"mcsbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20, 0xffff},
- {"", 0, 0, SROM9_2GPO_MCSBW20+1, 0xffff},
- {"mcsbw20ul2gpo",0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20UL, 0xffff},
- {"", 0, 0, SROM9_2GPO_MCSBW20UL+1, 0xffff},
- {"mcsbw402gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW40, 0xffff},
- {"", 0, 0, SROM9_2GPO_MCSBW40+1, 0xffff},
- {"mcsbw205glpo",0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20, 0xffff},
- {"", 0, 0, SROM9_5GLPO_MCSBW20+1, 0xffff},
- {"mcsbw20ul5glpo",0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20UL, 0xffff},
- {"", 0, 0, SROM9_5GLPO_MCSBW20UL+1,0xffff},
- {"mcsbw405glpo",0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW40, 0xffff},
- {"", 0, 0, SROM9_5GLPO_MCSBW40+1, 0xffff},
- {"mcsbw205gmpo",0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20, 0xffff},
- {"", 0, 0, SROM9_5GMPO_MCSBW20+1, 0xffff},
- {"mcsbw20ul5gmpo",0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20UL, 0xffff},
- {"", 0, 0, SROM9_5GMPO_MCSBW20UL+1,0xffff},
- {"mcsbw405gmpo",0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW40, 0xffff},
- {"", 0, 0, SROM9_5GMPO_MCSBW40+1, 0xffff},
- {"mcsbw205ghpo",0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20, 0xffff},
- {"", 0, 0, SROM9_5GHPO_MCSBW20+1, 0xffff},
- {"mcsbw20ul5ghpo",0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20UL, 0xffff},
- {"", 0, 0, SROM9_5GHPO_MCSBW20UL+1,0xffff},
- {"mcsbw405ghpo",0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW40, 0xffff},
- {"", 0, 0, SROM9_5GHPO_MCSBW40+1, 0xffff},
- {"mcs32po", 0xfffffe00, 0, SROM9_PO_MCS32, 0xffff},
- {"legofdm40duppo",0xfffffe00, 0, SROM9_PO_LOFDM40DUP, 0xffff},
-
- {NULL, 0, 0, 0, 0}
-};
-
-static const sromvar_t perpath_pci_sromvars[] = {
- {"maxp2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff},
- {"itt2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00},
- {"itt5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00},
- {"pa2gw0a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff},
- {"pa2gw1a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA+1, 0xffff},
- {"pa2gw2a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA+2, 0xffff},
- {"pa2gw3a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA+3, 0xffff},
- {"maxp5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0x00ff},
- {"maxp5gha", 0x000000f0, 0, SROM4_5GLH_MAXP, 0x00ff},
- {"maxp5gla", 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00},
- {"pa5gw0a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff},
- {"pa5gw1a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA+1, 0xffff},
- {"pa5gw2a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA+2, 0xffff},
- {"pa5gw3a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA+3, 0xffff},
- {"pa5glw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff},
- {"pa5glw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA+1, 0xffff},
- {"pa5glw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA+2, 0xffff},
- {"pa5glw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA+3, 0xffff},
- {"pa5ghw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff},
- {"pa5ghw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA+1, 0xffff},
- {"pa5ghw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA+2, 0xffff},
- {"pa5ghw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA+3, 0xffff},
- {"maxp2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff},
- {"itt2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00},
- {"itt5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00},
- {"pa2gw0a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA, 0xffff},
- {"pa2gw1a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA+1, 0xffff},
- {"pa2gw2a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA+2, 0xffff},
- {"maxp5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0x00ff},
- {"maxp5gha", 0xffffff00, 0, SROM8_5GLH_MAXP, 0x00ff},
- {"maxp5gla", 0xffffff00, 0, SROM8_5GLH_MAXP, 0xff00},
- {"pa5gw0a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA, 0xffff},
- {"pa5gw1a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA+1, 0xffff},
- {"pa5gw2a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA+2, 0xffff},
- {"pa5glw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA, 0xffff},
- {"pa5glw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA+1, 0xffff},
- {"pa5glw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA+2, 0xffff},
- {"pa5ghw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA, 0xffff},
- {"pa5ghw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA+1, 0xffff},
- {"pa5ghw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA+2, 0xffff},
- {NULL, 0, 0, 0, 0}
-};
-
-#if !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP))
-#define PHY_TYPE_N 4 /* N-Phy value */
-#define PHY_TYPE_LP 5 /* LP-Phy value */
-#endif /* !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) */
-#if !defined(PHY_TYPE_NULL)
-#define PHY_TYPE_NULL 0xf /* Invalid Phy value */
-#endif /* !defined(PHY_TYPE_NULL) */
-
-typedef struct {
- u16 phy_type;
- u16 bandrange;
- u16 chain;
- const char *vars;
-} pavars_t;
-
-static const pavars_t pavars[] = {
- /* NPHY */
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 0, "pa2gw0a0 pa2gw1a0 pa2gw2a0"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 1, "pa2gw0a1 pa2gw1a1 pa2gw2a1"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 0, "pa5glw0a0 pa5glw1a0 pa5glw2a0"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 1, "pa5glw0a1 pa5glw1a1 pa5glw2a1"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 0, "pa5gw0a0 pa5gw1a0 pa5gw2a0"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 1, "pa5gw0a1 pa5gw1a1 pa5gw2a1"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 0, "pa5ghw0a0 pa5ghw1a0 pa5ghw2a0"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 1, "pa5ghw0a1 pa5ghw1a1 pa5ghw2a1"},
- /* LPPHY */
- {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_2G, 0, "pa0b0 pa0b1 pa0b2"},
- {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GL, 0, "pa1lob0 pa1lob1 pa1lob2"},
- {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GM, 0, "pa1b0 pa1b1 pa1b2"},
- {PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GH, 0, "pa1hib0 pa1hib1 pa1hib2"},
- {PHY_TYPE_NULL, 0, 0, ""}
-};
-
-typedef struct {
- u16 phy_type;
- u16 bandrange;
- const char *vars;
-} povars_t;
-
-static const povars_t povars[] = {
- /* NPHY */
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G,
- "mcs2gpo0 mcs2gpo1 mcs2gpo2 mcs2gpo3 "
- "mcs2gpo4 mcs2gpo5 mcs2gpo6 mcs2gpo7"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL,
- "mcs5glpo0 mcs5glpo1 mcs5glpo2 mcs5glpo3 "
- "mcs5glpo4 mcs5glpo5 mcs5glpo6 mcs5glpo7"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM,
- "mcs5gpo0 mcs5gpo1 mcs5gpo2 mcs5gpo3 "
- "mcs5gpo4 mcs5gpo5 mcs5gpo6 mcs5gpo7"},
- {PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH,
- "mcs5ghpo0 mcs5ghpo1 mcs5ghpo2 mcs5ghpo3 "
- "mcs5ghpo4 mcs5ghpo5 mcs5ghpo6 mcs5ghpo7"},
- {PHY_TYPE_NULL, 0, ""}
-};
-
-typedef struct {
- u8 tag; /* Broadcom subtag name */
- u8 len; /* Length field of the tuple, note that it includes the
- * subtag name (1 byte): 1 + tuple content length
- */
- const char *params;
-} cis_tuple_t;
-
-#define OTP_RAW (0xff - 1) /* Reserved tuple number for wrvar Raw input */
-#define OTP_VERS_1 (0xff - 2) /* CISTPL_VERS_1 */
-#define OTP_MANFID (0xff - 3) /* CISTPL_MANFID */
-#define OTP_RAW1 (0xff - 4) /* Like RAW, but comes first */
-
-static const cis_tuple_t cis_hnbuvars[] = {
- {OTP_RAW1, 0, ""}, /* special case */
- {OTP_VERS_1, 0, "smanf sproductname"}, /* special case (non BRCM tuple) */
- {OTP_MANFID, 4, "2manfid 2prodid"}, /* special case (non BRCM tuple) */
- {HNBU_SROMREV, 2, "1sromrev"},
- /* NOTE: subdevid is also written to boardtype.
- * Need to write HNBU_BOARDTYPE to change it if it is different.
- */
- {HNBU_CHIPID, 11, "2vendid 2devid 2chiprev 2subvendid 2subdevid"},
- {HNBU_BOARDREV, 3, "2boardrev"},
- {HNBU_PAPARMS, 10, "2pa0b0 2pa0b1 2pa0b2 1pa0itssit 1pa0maxpwr 1opo"},
- {HNBU_AA, 3, "1aa2g 1aa5g"},
- {HNBU_AA, 3, "1aa0 1aa1"}, /* backward compatibility */
- {HNBU_AG, 5, "1ag0 1ag1 1ag2 1ag3"},
- {HNBU_BOARDFLAGS, 9, "4boardflags 4boardflags2"},
- {HNBU_LEDS, 5, "1ledbh0 1ledbh1 1ledbh2 1ledbh3"},
- {HNBU_CCODE, 4, "2ccode 1cctl"},
- {HNBU_CCKPO, 3, "2cckpo"},
- {HNBU_OFDMPO, 5, "4ofdmpo"},
- {HNBU_RDLID, 3, "2rdlid"},
- {HNBU_RSSISMBXA2G, 3, "0rssismf2g 0rssismc2g 0rssisav2g 0bxa2g"}, /* special case */
- {HNBU_RSSISMBXA5G, 3, "0rssismf5g 0rssismc5g 0rssisav5g 0bxa5g"}, /* special case */
- {HNBU_XTALFREQ, 5, "4xtalfreq"},
- {HNBU_TRI2G, 2, "1tri2g"},
- {HNBU_TRI5G, 4, "1tri5gl 1tri5g 1tri5gh"},
- {HNBU_RXPO2G, 2, "1rxpo2g"},
- {HNBU_RXPO5G, 2, "1rxpo5g"},
- {HNBU_BOARDNUM, 3, "2boardnum"},
- {HNBU_MACADDR, 7, "6macaddr"}, /* special case */
- {HNBU_RDLSN, 3, "2rdlsn"},
- {HNBU_BOARDTYPE, 3, "2boardtype"},
- {HNBU_LEDDC, 3, "2leddc"},
- {HNBU_RDLRNDIS, 2, "1rdlndis"},
- {HNBU_CHAINSWITCH, 5, "1txchain 1rxchain 2antswitch"},
- {HNBU_REGREV, 2, "1regrev"},
- {HNBU_FEM, 5, "0antswctl2g, 0triso2g, 0pdetrange2g, 0extpagain2g, 0tssipos2g" "0antswctl5g, 0triso5g, 0pdetrange5g, 0extpagain5g, 0tssipos5g"}, /* special case */
- {HNBU_PAPARMS_C0, 31, "1maxp2ga0 1itt2ga0 2pa2gw0a0 2pa2gw1a0 "
- "2pa2gw2a0 1maxp5ga0 1itt5ga0 1maxp5gha0 1maxp5gla0 2pa5gw0a0 "
- "2pa5gw1a0 2pa5gw2a0 2pa5glw0a0 2pa5glw1a0 2pa5glw2a0 2pa5ghw0a0 "
- "2pa5ghw1a0 2pa5ghw2a0"},
- {HNBU_PAPARMS_C1, 31, "1maxp2ga1 1itt2ga1 2pa2gw0a1 2pa2gw1a1 "
- "2pa2gw2a1 1maxp5ga1 1itt5ga1 1maxp5gha1 1maxp5gla1 2pa5gw0a1 "
- "2pa5gw1a1 2pa5gw2a1 2pa5glw0a1 2pa5glw1a1 2pa5glw2a1 2pa5ghw0a1 "
- "2pa5ghw1a1 2pa5ghw2a1"},
- {HNBU_PO_CCKOFDM, 19, "2cck2gpo 4ofdm2gpo 4ofdm5gpo 4ofdm5glpo "
- "4ofdm5ghpo"},
- {HNBU_PO_MCS2G, 17, "2mcs2gpo0 2mcs2gpo1 2mcs2gpo2 2mcs2gpo3 "
- "2mcs2gpo4 2mcs2gpo5 2mcs2gpo6 2mcs2gpo7"},
- {HNBU_PO_MCS5GM, 17, "2mcs5gpo0 2mcs5gpo1 2mcs5gpo2 2mcs5gpo3 "
- "2mcs5gpo4 2mcs5gpo5 2mcs5gpo6 2mcs5gpo7"},
- {HNBU_PO_MCS5GLH, 33, "2mcs5glpo0 2mcs5glpo1 2mcs5glpo2 2mcs5glpo3 "
- "2mcs5glpo4 2mcs5glpo5 2mcs5glpo6 2mcs5glpo7 "
- "2mcs5ghpo0 2mcs5ghpo1 2mcs5ghpo2 2mcs5ghpo3 "
- "2mcs5ghpo4 2mcs5ghpo5 2mcs5ghpo6 2mcs5ghpo7"},
- {HNBU_CCKFILTTYPE, 2, "1cckdigfilttype"},
- {HNBU_PO_CDD, 3, "2cddpo"},
- {HNBU_PO_STBC, 3, "2stbcpo"},
- {HNBU_PO_40M, 3, "2bw40po"},
- {HNBU_PO_40MDUP, 3, "2bwduppo"},
- {HNBU_RDLRWU, 2, "1rdlrwu"},
- {HNBU_WPS, 3, "1wpsgpio 1wpsled"},
- {HNBU_USBFS, 2, "1usbfs"},
- {HNBU_CUSTOM1, 5, "4customvar1"},
- {OTP_RAW, 0, ""}, /* special case */
- {HNBU_OFDMPO5G, 13, "4ofdm5gpo 4ofdm5glpo 4ofdm5ghpo"},
- {HNBU_USBEPNUM, 3, "2usbepnum"},
- {0xFF, 0, ""}
-};
-
-#endif /* _BHND_BCMSROM_TBL_H_ */
Index: head/sys/dev/bhnd/bhnd.h
===================================================================
--- head/sys/dev/bhnd/bhnd.h
+++ head/sys/dev/bhnd/bhnd.h
@@ -464,6 +464,55 @@
return (BHND_BUS_GET_CHIPID(device_get_parent(dev), dev));
};
+/**
+ * Determine an NVRAM variable's expected size.
+ *
+ * @param dev A bhnd bus child device.
+ * @param name The variable name.
+ * @param[out] len On success, the variable's size, in bytes.
+ *
+ * @retval 0 success
+ * @retval ENOENT The requested variable was not found.
+ * @retval non-zero If reading @p name otherwise fails, a regular unix
+ * error code will be returned.
+ */
+static inline int
+bhnd_nvram_getvarlen(device_t dev, const char *name, size_t *len)
+{
+ return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), dev, name, NULL,
+ len));
+}
+
+/**
+ * Read an NVRAM variable.
+ *
+ * @param dev A bhnd bus child device.
+ * @param name The NVRAM variable name.
+ * @param buf A buffer large enough to hold @p len bytes. On success,
+ * the requested value will be written to this buffer.
+ * @param len The required variable length.
+ *
+ * @retval 0 success
+ * @retval ENOENT The requested variable was not found.
+ * @retval EINVAL If @p len does not match the actual variable size.
+ * @retval non-zero If reading @p name otherwise fails, a regular unix
+ * error code will be returned.
+ */
+static inline int
+bhnd_nvram_getvar(device_t dev, const char *name, void *buf, size_t len)
+{
+ size_t var_len;
+ int error;
+
+ if ((error = bhnd_nvram_getvarlen(dev, name, &var_len)))
+ return (error);
+
+ if (len != var_len)
+ return (EINVAL);
+
+ return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), dev, name, buf,
+ &len));
+}
/**
* Allocate a resource from a device's parent bhnd(4) bus.
Index: head/sys/dev/bhnd/bhnd.c
===================================================================
--- head/sys/dev/bhnd/bhnd.c
+++ head/sys/dev/bhnd/bhnd.c
@@ -58,11 +58,14 @@
#include <sys/rman.h>
#include <machine/resource.h>
-#include "bhnd.h"
-#include "bhndvar.h"
+#include "nvram/bhnd_nvram.h"
+#include "bhnd_chipc_if.h"
#include "bhnd_nvram_if.h"
+#include "bhnd.h"
+#include "bhndvar.h"
+
MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures");
/**
@@ -386,23 +389,27 @@
static device_t
find_nvram_child(device_t dev)
{
- device_t chipc, nvram;
+ device_t chipc, nvram;
/* Look for a directly-attached NVRAM child */
- nvram = device_find_child(dev, devclass_get_name(bhnd_nvram_devclass),
- -1);
- if (nvram == NULL)
- return (NULL);
+ nvram = device_find_child(dev, "bhnd_nvram", 0);
+ if (nvram != NULL)
+ return (nvram);
- /* Further checks require a bhnd(4) bus */
+ /* Remaining checks are only applicable when searching a bhnd(4)
+ * bus. */
if (device_get_devclass(dev) != bhnd_devclass)
return (NULL);
- /* Look for a ChipCommon-attached OTP device */
+ /* Look for a ChipCommon device */
if ((chipc = bhnd_find_child(dev, BHND_DEVCLASS_CC, -1)) != NULL) {
- /* Recursively search the ChipCommon device */
- if ((nvram = find_nvram_child(chipc)) != NULL)
- return (nvram);
+ bhnd_nvram_src_t src;
+
+ /* Query the NVRAM source and determine whether it's
+ * accessible via the ChipCommon device */
+ src = BHND_CHIPC_NVRAM_SRC(chipc);
+ if (BHND_NVRAM_SRC_CC(src))
+ return (chipc);
}
/* Not found */
@@ -410,22 +417,26 @@
}
/**
- * Default bhnd(4) bus driver implementation of BHND_BUS_READ_NVRAM_VAR().
+ * Default bhnd(4) bus driver implementation of BHND_BUS_GET_NVRAM_VAR().
+ *
+ * This implementation searches @p dev for a usable NVRAM child device:
+ * - The first child device implementing the bhnd_nvram devclass is
+ * returned, otherwise
+ * - If @p dev is a bhnd(4) bus, a ChipCommon core that advertises an
+ * attached NVRAM source.
*
- * This implementation searches @p dev for a valid NVRAM device. If no NVRAM
- * child device is found on @p dev, the request is delegated to the
- * BHND_BUS_READ_NVRAM_VAR() method on the parent
- * of @p dev.
+ * If no usable child device is found on @p dev, the request is delegated to
+ * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev.
*/
static int
-bhnd_generic_read_nvram_var(device_t dev, device_t child, const char *name,
+bhnd_generic_get_nvram_var(device_t dev, device_t child, const char *name,
void *buf, size_t *size)
{
device_t nvram;
/* Try to find an NVRAM device applicable to @p child */
if ((nvram = find_nvram_child(dev)) == NULL)
- return (BHND_BUS_READ_NVRAM_VAR(device_get_parent(dev), child,
+ return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child,
name, buf, size));
return BHND_NVRAM_GETVAR(nvram, name, buf, size);
@@ -682,7 +693,7 @@
DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order),
DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid),
DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled),
- DEVMETHOD(bhnd_bus_read_nvram_var, bhnd_generic_read_nvram_var),
+ DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_generic_get_nvram_var),
DEVMETHOD(bhnd_bus_read_1, bhnd_read_1),
DEVMETHOD(bhnd_bus_read_2, bhnd_read_2),
DEVMETHOD(bhnd_bus_read_4, bhnd_read_4),
Index: head/sys/dev/bhnd/bhnd_bus_if.m
===================================================================
--- head/sys/dev/bhnd/bhnd_bus_if.m
+++ head/sys/dev/bhnd/bhnd_bus_if.m
@@ -96,7 +96,7 @@
}
static int
- bhnd_bus_null_read_nvram_var(device_t dev, device_t child,
+ bhnd_bus_null_get_nvram_var(device_t dev, device_t child,
const char *name, void *buf, size_t *size)
{
return (ENOENT);
@@ -403,13 +403,13 @@
* @retval non-zero If reading @p name otherwise fails, a regular unix
* error code will be returned.
*/
-METHOD int read_nvram_var {
+METHOD int get_nvram_var {
device_t dev;
device_t child;
const char *name;
void *buf;
size_t *size;
-} DEFAULT bhnd_bus_null_read_nvram_var;
+} DEFAULT bhnd_bus_null_get_nvram_var;
/** An implementation of bus_read_1() compatible with bhnd_resource */
Index: head/sys/dev/bhnd/bhnd_ids.h
===================================================================
--- head/sys/dev/bhnd/bhnd_ids.h
+++ head/sys/dev/bhnd/bhnd_ids.h
@@ -328,6 +328,7 @@
#define BHND_CHIPID_BCM43428 43428 /* 43228 chipcommon chipid (OTP, RBBU) */
#define BHND_CHIPID_BCM43431 43431 /* 4331 chipcommon chipid (OTP, RBBU) */
#define BHND_CHIPID_BCM43460 43460 /* 4360 chipcommon chipid (OTP, RBBU) */
+#define BHND_CHIPID_BCM43462 0xA9C6 /* 43462 chipcommon chipid */
#define BHND_CHIPID_BCM4325 0x4325 /* 4325 chip id */
#define BHND_CHIPID_BCM4328 0x4328 /* 4328 chip id */
#define BHND_CHIPID_BCM4329 0x4329 /* 4329 chipcommon chipid */
@@ -345,6 +346,7 @@
#define BHND_CHIPID_BCM4334 0x4334 /* 4334 chipcommon chipid */
#define BHND_CHIPID_BCM4335 0x4335 /* 4335 chipcommon chipid */
#define BHND_CHIPID_BCM4360 0x4360 /* 4360 chipcommon chipid */
+#define BHND_CHIPID_BCM43602 0xaa52 /* 43602 chipcommon chipid */
#define BHND_CHIPID_BCM4352 0x4352 /* 4352 chipcommon chipid */
#define BHND_CHIPID_BCM43526 0xAA06
#define BHND_CHIPID_BCM43341 43341 /* 43341 chipcommon chipid */
@@ -433,7 +435,6 @@
#define BHND_PKGID_BCM4335_FCBGAD (0x3) /* FCBGA Debug Debug/Dev All if's. */
#define BHND_PKGID_PKG_MASK_BCM4335 (0x3)
-
/* Broadcom Core IDs */
#define BHND_COREID_INVALID 0x700 /* Invalid coreid */
#define BHND_COREID_CC 0x800 /* chipcommon core */
Index: head/sys/dev/bhnd/bhndb/bhndb.c
===================================================================
--- head/sys/dev/bhnd/bhndb/bhndb.c
+++ head/sys/dev/bhnd/bhndb/bhndb.c
@@ -51,6 +51,10 @@
#include <dev/bhnd/bhndreg.h>
#include <dev/bhnd/cores/chipc/chipcreg.h>
+#include <dev/bhnd/nvram/bhnd_nvram.h>
+
+#include "bhnd_chipc_if.h"
+#include "bhnd_nvram_if.h"
#include "bhndbvar.h"
#include "bhndb_bus_if.h"
@@ -609,7 +613,7 @@
goto cleanup;
}
- if (bootverbose)
+ if (bootverbose || BHNDB_DEBUG(PRIO))
device_printf(sc->dev, "%s resource configuration\n", hw->name);
/* Release existing resource state */
@@ -1298,9 +1302,10 @@
rman_get_size(r));
if (error) {
device_printf(sc->dev, "dynamic window initialization "
- "for 0x%llx-0x%llx failed\n",
+ "for 0x%llx-0x%llx failed: %d\n",
(unsigned long long) r_start,
- (unsigned long long) r_start + r_size - 1);
+ (unsigned long long) r_start + r_size - 1,
+ error);
return (NULL);
}
@@ -1709,6 +1714,26 @@
return (dwa);
}
+/**
+ * Default bhndb(4) implementation of BHND_BUS_GET_NVRAM_VAR().
+ */
+static int
+bhndb_get_nvram_var(device_t dev, device_t child, const char *name,
+ void *buf, size_t *size)
+{
+ device_t nvram;
+
+ /* Look for a directly-attached NVRAM child */
+ nvram = device_find_child(dev, devclass_get_name(bhnd_nvram_devclass),
+ 0);
+ if (nvram != NULL)
+ return (BHND_NVRAM_GETVAR(nvram, name, buf, size));
+
+ /* Otherwise, delegate to our parent */
+ return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child,
+ name, buf, size));
+}
+
/*
* BHND_BUS_(READ|WRITE_* implementations
*/
@@ -1936,6 +1961,7 @@
DEVMETHOD(bhnd_bus_get_chipid, bhndb_get_chipid),
DEVMETHOD(bhnd_bus_activate_resource, bhndb_activate_bhnd_resource),
DEVMETHOD(bhnd_bus_deactivate_resource, bhndb_deactivate_bhnd_resource),
+ DEVMETHOD(bhnd_bus_get_nvram_var, bhndb_get_nvram_var),
DEVMETHOD(bhnd_bus_read_1, bhndb_bus_read_1),
DEVMETHOD(bhnd_bus_read_2, bhndb_bus_read_2),
DEVMETHOD(bhnd_bus_read_4, bhndb_bus_read_4),
Index: head/sys/dev/bhnd/bhndb/bhndb_pci.c
===================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_pci.c
+++ head/sys/dev/bhnd/bhndb/bhndb_pci.c
@@ -61,15 +61,19 @@
#include "bhndb_pcivar.h"
#include "bhndb_private.h"
-static int bhndb_enable_pci_clocks(struct bhndb_pci_softc *sc);
-static int bhndb_disable_pci_clocks(struct bhndb_pci_softc *sc);
+static int bhndb_enable_pci_clocks(struct bhndb_pci_softc *sc);
+static int bhndb_disable_pci_clocks(struct bhndb_pci_softc *sc);
-static int bhndb_pci_compat_setregwin(struct bhndb_pci_softc *,
- const struct bhndb_regwin *, bhnd_addr_t);
-static int bhndb_pci_fast_setregwin(struct bhndb_pci_softc *,
- const struct bhndb_regwin *, bhnd_addr_t);
+static int bhndb_pci_compat_setregwin(struct bhndb_pci_softc *,
+ const struct bhndb_regwin *, bhnd_addr_t);
+static int bhndb_pci_fast_setregwin(struct bhndb_pci_softc *,
+ const struct bhndb_regwin *, bhnd_addr_t);
-static void bhndb_init_sromless_pci_config(struct bhndb_pci_softc *sc);
+static void bhndb_init_sromless_pci_config(
+ struct bhndb_pci_softc *sc);
+
+static bus_addr_t bhndb_pci_sprom_addr(struct bhndb_pci_softc *sc);
+static size_t bhndb_pci_sprom_size(struct bhndb_pci_softc *sc);
/**
* Default bhndb_pci implementation of device_probe().
@@ -104,13 +108,14 @@
sc = device_get_softc(dev);
sc->dev = dev;
+ sc->parent = device_get_parent(dev);
/* Enable PCI bus mastering */
- pci_enable_busmaster(device_get_parent(dev));
+ pci_enable_busmaster(sc->parent);
/* Determine our bridge device class */
sc->pci_devclass = BHND_DEVCLASS_PCI;
- if (pci_find_cap(device_get_parent(dev), PCIY_EXPRESS, &reg) == 0)
+ if (pci_find_cap(sc->parent, PCIY_EXPRESS, &reg) == 0)
sc->pci_devclass = BHND_DEVCLASS_PCIE;
/* Enable clocks (if supported by this hardware) */
@@ -142,6 +147,8 @@
const struct bhndb_hw_priority *hw_prio_table)
{
struct bhndb_pci_softc *sc;
+ device_t nv_dev;
+ bus_size_t nv_sz;
int error;
sc = device_get_softc(dev);
@@ -153,9 +160,126 @@
/* Fix-up power on defaults for SROM-less devices. */
bhndb_init_sromless_pci_config(sc);
+ /* If SPROM is mapped directly into BAR0, add NVRAM device. */
+ nv_sz = bhndb_pci_sprom_size(sc);
+ if (nv_sz > 0) {
+ struct bhndb_devinfo *dinfo;
+ const char *dname;
+
+ if (bootverbose) {
+ device_printf(dev, "found SPROM (%zu bytes)\n", nv_sz);
+ }
+
+ /* Add sprom device */
+ dname = "bhnd_nvram";
+ if ((nv_dev = BUS_ADD_CHILD(dev, 0, dname, -1)) == NULL) {
+ device_printf(dev, "failed to add sprom device\n");
+ return (ENXIO);
+ }
+
+ /* Initialize device address space and resource covering the
+ * BAR0 SPROM shadow. */
+ dinfo = device_get_ivars(nv_dev);
+ dinfo->addrspace = BHNDB_ADDRSPACE_NATIVE;
+ error = bus_set_resource(nv_dev, SYS_RES_MEMORY, 0,
+ bhndb_pci_sprom_addr(sc), nv_sz);
+
+ if (error) {
+ device_printf(dev,
+ "failed to register sprom resources\n");
+ return (error);
+ }
+
+ /* Attach the device */
+ if ((error = device_probe_and_attach(nv_dev))) {
+ device_printf(dev, "sprom attach failed\n");
+ return (error);
+ }
+ }
+
return (0);
}
+static const struct bhndb_regwin *
+bhndb_pci_sprom_regwin(struct bhndb_pci_softc *sc)
+{
+ struct bhndb_resources *bres;
+ const struct bhndb_hwcfg *cfg;
+ const struct bhndb_regwin *sprom_win;
+
+ bres = sc->bhndb.bus_res;
+ cfg = bres->cfg;
+
+ sprom_win = bhndb_regwin_find_type(cfg->register_windows,
+ BHNDB_REGWIN_T_SPROM, BHNDB_PCI_V0_BAR0_SPROM_SIZE);
+
+ return (sprom_win);
+}
+
+static bus_addr_t
+bhndb_pci_sprom_addr(struct bhndb_pci_softc *sc)
+{
+ const struct bhndb_regwin *sprom_win;
+ struct resource *r;
+
+ /* Fetch the SPROM register window */
+ sprom_win = bhndb_pci_sprom_regwin(sc);
+ KASSERT(sprom_win != NULL, ("requested sprom address on PCI_V2+"));
+
+ /* Fetch the associated resource */
+ r = bhndb_find_regwin_resource(sc->bhndb.bus_res, sprom_win);
+ KASSERT(r != NULL, ("missing resource for sprom window\n"));
+
+ return (rman_get_start(r) + sprom_win->win_offset);
+}
+
+static bus_size_t
+bhndb_pci_sprom_size(struct bhndb_pci_softc *sc)
+{
+ const struct bhndb_regwin *sprom_win;
+ uint32_t sctl;
+ bus_size_t sprom_sz;
+
+ sprom_win = bhndb_pci_sprom_regwin(sc);
+
+ /* PCI_V2 and later devices map SPROM/OTP via ChipCommon */
+ if (sprom_win == NULL)
+ return (0);
+
+ /* Determine SPROM size */
+ sctl = pci_read_config(sc->parent, BHNDB_PCI_SPROM_CONTROL, 4);
+ if (sctl & BHNDB_PCI_SPROM_BLANK)
+ return (0);
+
+ switch (sctl & BHNDB_PCI_SPROM_SZ_MASK) {
+ case BHNDB_PCI_SPROM_SZ_1KB:
+ sprom_sz = (1 * 1024);
+ break;
+
+ case BHNDB_PCI_SPROM_SZ_4KB:
+ sprom_sz = (4 * 1024);
+ break;
+
+ case BHNDB_PCI_SPROM_SZ_16KB:
+ sprom_sz = (16 * 1024);
+ break;
+
+ case BHNDB_PCI_SPROM_SZ_RESERVED:
+ default:
+ device_printf(sc->dev, "invalid PCI sprom size 0x%x\n", sctl);
+ return (0);
+ }
+
+ if (sprom_sz > sprom_win->win_size) {
+ device_printf(sc->dev,
+ "PCI sprom size (0x%x) overruns defined register window\n",
+ sctl);
+ return (0);
+ }
+
+ return (sprom_sz);
+}
+
/*
* On devices without a SROM, the PCI(e) cores will be initialized with
* their Power-on-Reset defaults; this can leave two of the BAR0 PCI windows
@@ -274,7 +398,7 @@
return (error);
/* Disable PCI bus mastering */
- pci_disable_busmaster(device_get_parent(dev));
+ pci_disable_busmaster(sc->parent);
return (0);
}
@@ -301,19 +425,18 @@
bhndb_pci_compat_setregwin(struct bhndb_pci_softc *sc,
const struct bhndb_regwin *rw, bhnd_addr_t addr)
{
- device_t parent;
int error;
-
- parent = sc->bhndb.parent_dev;
+ int reg;
if (rw->win_type != BHNDB_REGWIN_T_DYN)
return (ENODEV);
+ reg = rw->d.dyn.cfg_offset;
for (u_int i = 0; i < BHNDB_PCI_BARCTRL_WRITE_RETRY; i++) {
if ((error = bhndb_pci_fast_setregwin(sc, rw, addr)))
return (error);
- if (pci_read_config(parent, rw->d.dyn.cfg_offset, 4) == addr)
+ if (pci_read_config(sc->parent, reg, 4) == addr)
return (0);
DELAY(10);
@@ -330,8 +453,6 @@
bhndb_pci_fast_setregwin(struct bhndb_pci_softc *sc,
const struct bhndb_regwin *rw, bhnd_addr_t addr)
{
- device_t parent = sc->bhndb.parent_dev;
-
/* The PCI bridge core only supports 32-bit addressing, regardless
* of the bus' support for 64-bit addressing */
if (addr > UINT32_MAX)
@@ -343,7 +464,7 @@
if (addr % rw->win_size != 0)
return (EINVAL);
- pci_write_config(parent, rw->d.dyn.cfg_offset, addr, 4);
+ pci_write_config(sc->parent, rw->d.dyn.cfg_offset, addr, 4);
break;
default:
return (ENODEV);
@@ -366,7 +487,6 @@
static int
bhndb_enable_pci_clocks(struct bhndb_pci_softc *sc)
{
- device_t pci_parent;
uint32_t gpio_in, gpio_out, gpio_en;
uint32_t gpio_flags;
uint16_t pci_status;
@@ -375,35 +495,33 @@
if (sc->pci_devclass != BHND_DEVCLASS_PCI)
return (0);
- pci_parent = device_get_parent(sc->dev);
-
/* Read state of XTAL pin */
- gpio_in = pci_read_config(pci_parent, BHNDB_PCI_GPIO_IN, 4);
+ gpio_in = pci_read_config(sc->parent, BHNDB_PCI_GPIO_IN, 4);
if (gpio_in & BHNDB_PCI_GPIO_XTAL_ON)
return (0); /* already enabled */
/* Fetch current config */
- gpio_out = pci_read_config(pci_parent, BHNDB_PCI_GPIO_OUT, 4);
- gpio_en = pci_read_config(pci_parent, BHNDB_PCI_GPIO_OUTEN, 4);
+ gpio_out = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUT, 4);
+ gpio_en = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, 4);
/* Set PLL_OFF/XTAL_ON pins to HIGH and enable both pins */
gpio_flags = (BHNDB_PCI_GPIO_PLL_OFF|BHNDB_PCI_GPIO_XTAL_ON);
gpio_out |= gpio_flags;
gpio_en |= gpio_flags;
- pci_write_config(pci_parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
- pci_write_config(pci_parent, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4);
+ pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
+ pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4);
DELAY(1000);
/* Reset PLL_OFF */
gpio_out &= ~BHNDB_PCI_GPIO_PLL_OFF;
- pci_write_config(pci_parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
+ pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
DELAY(5000);
/* Clear any PCI 'sent target-abort' flag. */
- pci_status = pci_read_config(pci_parent, PCIR_STATUS, 2);
+ pci_status = pci_read_config(sc->parent, PCIR_STATUS, 2);
pci_status &= ~PCIM_STATUS_STABORT;
- pci_write_config(pci_parent, PCIR_STATUS, pci_status, 2);
+ pci_write_config(sc->parent, PCIR_STATUS, pci_status, 2);
return (0);
}
@@ -416,31 +534,28 @@
static int
bhndb_disable_pci_clocks(struct bhndb_pci_softc *sc)
{
- device_t parent_dev;
uint32_t gpio_out, gpio_en;
/* Only supported and required on PCI devices */
if (sc->pci_devclass != BHND_DEVCLASS_PCI)
return (0);
- parent_dev = device_get_parent(sc->dev);
-
// TODO: Check board flags for BFL2_XTALBUFOUTEN?
// TODO: Check PCI core revision?
// TODO: Switch to 'slow' clock?
/* Fetch current config */
- gpio_out = pci_read_config(parent_dev, BHNDB_PCI_GPIO_OUT, 4);
- gpio_en = pci_read_config(parent_dev, BHNDB_PCI_GPIO_OUTEN, 4);
+ gpio_out = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUT, 4);
+ gpio_en = pci_read_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, 4);
/* Set PLL_OFF to HIGH, XTAL_ON to LOW. */
gpio_out &= ~BHNDB_PCI_GPIO_XTAL_ON;
gpio_out |= BHNDB_PCI_GPIO_PLL_OFF;
- pci_write_config(parent_dev, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
+ pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUT, gpio_out, 4);
/* Enable both output pins */
gpio_en |= (BHNDB_PCI_GPIO_PLL_OFF|BHNDB_PCI_GPIO_XTAL_ON);
- pci_write_config(parent_dev, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4);
+ pci_write_config(sc->parent, BHNDB_PCI_GPIO_OUTEN, gpio_en, 4);
return (0);
}
Index: head/sys/dev/bhnd/bhndb/bhndb_pci_sprom.c
===================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_pci_sprom.c
+++ head/sys/dev/bhnd/bhndb/bhndb_pci_sprom.c
@@ -0,0 +1,210 @@
+/*-
+ * Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * BHNDB PCI SPROM driver.
+ *
+ * Provides support for early PCI bridge cores that vend SPROM CSRs
+ * via PCI configuration space.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/bus.h>
+#include <sys/limits.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/systm.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <dev/bhnd/bhnd.h>
+#include <dev/bhnd/cores/pci/bhnd_pci_hostbvar.h>
+#include <dev/bhnd/nvram/bhnd_spromvar.h>
+
+#include "bhnd_nvram_if.h"
+#include "bhndb_pcireg.h"
+#include "bhndb_pcivar.h"
+
+struct bhndb_pci_sprom_softc {
+ device_t dev;
+ struct bhnd_resource *sprom_res; /**< SPROM resource */
+ int sprom_rid; /**< SPROM RID */
+ struct bhnd_sprom shadow; /**< SPROM shadow */
+ struct mtx mtx; /**< SPROM shadow mutex */
+};
+
+#define SPROM_LOCK_INIT(sc) \
+ mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), \
+ "BHND PCI SPROM lock", MTX_DEF)
+#define SPROM_LOCK(sc) mtx_lock(&(sc)->mtx)
+#define SPROM_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
+#define SPROM_LOCK_ASSERT(sc, what) mtx_assert(&(sc)->mtx, what)
+#define SPROM_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx)
+
+static int
+bhndb_pci_sprom_probe(device_t dev)
+{
+ device_t bridge, bus;
+
+ /* Our parent must be a PCI-BHND bridge with an attached bhnd bus */
+ bridge = device_get_parent(dev);
+ if (device_get_driver(bridge) != &bhndb_pci_driver)
+ return (ENXIO);
+
+ bus = device_find_child(bridge, devclass_get_name(bhnd_devclass), 0);
+ if (bus == NULL)
+ return (ENXIO);
+
+ /* Found */
+ device_set_desc(dev, "PCI-BHNDB SPROM/OTP");
+ if (!bootverbose)
+ device_quiet(dev);
+
+ /* Refuse wildcard attachments */
+ return (BUS_PROBE_NOWILDCARD);
+}
+
+static int
+bhndb_pci_sprom_attach(device_t dev)
+{
+ struct bhndb_pci_sprom_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+ sc->dev = dev;
+
+ /* Allocate SPROM resource */
+ sc->sprom_rid = 0;
+ sc->sprom_res = bhnd_alloc_resource_any(dev, SYS_RES_MEMORY,
+ &sc->sprom_rid, RF_ACTIVE);
+ if (sc->sprom_res == NULL) {
+ device_printf(dev, "failed to allocate resources\n");
+ return (ENXIO);
+ }
+
+ /* Initialize SPROM shadow */
+ if ((error = bhnd_sprom_init(&sc->shadow, sc->sprom_res, 0))) {
+ device_printf(dev, "unrecognized SPROM format\n");
+ goto failed;
+ }
+
+ /* Initialize mutex */
+ SPROM_LOCK_INIT(sc);
+
+ return (0);
+
+failed:
+ bhnd_release_resource(dev, SYS_RES_MEMORY, sc->sprom_rid,
+ sc->sprom_res);
+ return (error);
+}
+
+static int
+bhndb_pci_sprom_resume(device_t dev)
+{
+ return (0);
+}
+
+static int
+bhndb_pci_sprom_suspend(device_t dev)
+{
+ return (0);
+}
+
+static int
+bhndb_pci_sprom_detach(device_t dev)
+{
+ struct bhndb_pci_sprom_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ bhnd_release_resource(dev, SYS_RES_MEMORY, sc->sprom_rid,
+ sc->sprom_res);
+ bhnd_sprom_fini(&sc->shadow);
+ SPROM_LOCK_DESTROY(sc);
+
+ return (0);
+}
+
+static int
+bhndb_pci_sprom_getvar(device_t dev, const char *name, void *buf, size_t *len)
+{
+ struct bhndb_pci_sprom_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+
+ SPROM_LOCK(sc);
+ error = bhnd_sprom_getvar(&sc->shadow, name, buf, len);
+ SPROM_UNLOCK(sc);
+
+ return (error);
+}
+
+static int
+bhndb_pci_sprom_setvar(device_t dev, const char *name, const void *buf,
+ size_t len)
+{
+ struct bhndb_pci_sprom_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+
+ SPROM_LOCK(sc);
+ error = bhnd_sprom_setvar(&sc->shadow, name, buf, len);
+ SPROM_UNLOCK(sc);
+
+ return (error);
+}
+
+static device_method_t bhndb_pci_sprom_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, bhndb_pci_sprom_probe),
+ DEVMETHOD(device_attach, bhndb_pci_sprom_attach),
+ DEVMETHOD(device_resume, bhndb_pci_sprom_resume),
+ DEVMETHOD(device_suspend, bhndb_pci_sprom_suspend),
+ DEVMETHOD(device_detach, bhndb_pci_sprom_detach),
+
+ /* NVRAM interface */
+ DEVMETHOD(bhnd_nvram_getvar, bhndb_pci_sprom_getvar),
+ DEVMETHOD(bhnd_nvram_setvar, bhndb_pci_sprom_setvar),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_0(bhnd_nvram, bhndb_pci_sprom_driver, bhndb_pci_sprom_methods, sizeof(struct bhndb_pci_sprom_softc));
+
+DRIVER_MODULE(bhndb_pci_sprom, bhndb, bhndb_pci_sprom_driver, bhnd_nvram_devclass, NULL, NULL);
+MODULE_DEPEND(bhndb_pci_sprom, bhnd, 1, 1, 1);
+MODULE_VERSION(bhndb_pci_sprom, 1);
Index: head/sys/dev/bhnd/bhndb/bhndb_pcireg.h
===================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_pcireg.h
+++ head/sys/dev/bhnd/bhndb/bhndb_pcireg.h
@@ -205,13 +205,17 @@
#define BHNDB_PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */
/* BHNDB_PCI_SPROM_CONTROL */
-#define BHNDB_PCI_SPROM_SZ_MSK 0x02 /* SPROM Size Mask */
-#define BHNDB_PCI_SPROM_LOCKED 0x08 /* SPROM Locked */
-#define BHNDB_PCI_SPROM_BLANK 0x04 /* indicating a blank SPROM */
-#define BHNDB_PCI_SPROM_WRITEEN 0x10 /* SPROM write enable */
-#define BHNDB_PCI_SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */
-#define BHNDB_PCI_SPROM_BACKPLANE_EN 0x40 /* Enable indirect backplane access */
-#define BHNDB_PCI_SPROM_OTPIN_USE 0x80 /* device OTP In use */
+#define BHNDB_PCI_SPROM_SZ_MASK 0x03 /**< sprom size mask */
+#define BHNDB_PCI_SPROM_SZ_1KB 0x00 /**< 1KB sprom size */
+#define BHNDB_PCI_SPROM_SZ_4KB 0x01 /**< 4KB sprom size */
+#define BHNDB_PCI_SPROM_SZ_16KB 0x02 /**< 16KB sprom size */
+#define BHNDB_PCI_SPROM_SZ_RESERVED 0x03 /**< unsupported sprom size */
+#define BHNDB_PCI_SPROM_LOCKED 0x08 /**< sprom locked */
+#define BHNDB_PCI_SPROM_BLANK 0x04 /**< sprom blank */
+#define BHNDB_PCI_SPROM_WRITEEN 0x10 /**< sprom write enable */
+#define BHNDB_PCI_SPROM_BOOTROM_WE 0x20 /**< external bootrom write enable */
+#define BHNDB_PCI_SPROM_BACKPLANE_EN 0x40 /**< enable indirect backplane access (BHNDB_PCI_BACKPLANE_*) */
+#define BHNDB_PCI_SPROM_OTPIN_USE 0x80 /**< device OTP in use */
/* PCI (non-PCIe) BHNDB_PCI_GPIO_OUTEN */
Index: head/sys/dev/bhnd/bhndb/bhndb_pcivar.h
===================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_pcivar.h
+++ head/sys/dev/bhnd/bhndb/bhndb_pcivar.h
@@ -51,6 +51,7 @@
struct bhndb_pci_softc {
struct bhndb_softc bhndb; /**< parent softc */
device_t dev; /**< bridge device */
+ device_t parent; /**< parent PCI device */
bhnd_devclass_t pci_devclass; /**< PCI core's devclass */
bhndb_pci_set_regwin_t set_regwin; /**< regwin handler */
};
Index: head/sys/dev/bhnd/cores/chipc/chipc.c
===================================================================
--- head/sys/dev/bhnd/cores/chipc/chipc.c
+++ head/sys/dev/bhnd/cores/chipc/chipc.c
@@ -52,6 +52,8 @@
#include <dev/bhnd/bhnd.h>
+#include "bhnd_nvram_if.h"
+
#include "chipcreg.h"
#include "chipcvar.h"
@@ -73,13 +75,44 @@
/* Device quirks table */
static struct bhnd_device_quirk chipc_quirks[] = {
- { BHND_HWREV_RANGE (0, 21), CHIPC_QUIRK_ALWAYS_HAS_SPROM },
- { BHND_HWREV_EQ (22), CHIPC_QUIRK_SPROM_CHECK_CST_R22 },
- { BHND_HWREV_RANGE (23, 31), CHIPC_QUIRK_SPROM_CHECK_CST_R23 },
- { BHND_HWREV_GTE (35), CHIPC_QUIRK_SUPPORTS_NFLASH },
+ { BHND_HWREV_GTE (32), CHIPC_QUIRK_SUPPORTS_SPROM },
+ { BHND_HWREV_GTE (35), CHIPC_QUIRK_SUPPORTS_NFLASH },
BHND_DEVICE_QUIRK_END
};
+/* Chip-specific quirks table */
+static struct bhnd_chip_quirk chipc_chip_quirks[] = {
+ /* 4331 12x9 packages */
+ {{ BHND_CHIP_IP(4331, 4331TN) },
+ CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM
+ },
+ {{ BHND_CHIP_IP(4331, 4331TNA0) },
+ CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM
+ },
+
+ /* 4331 12x12 packages */
+ {{ BHND_CHIP_IPR(4331, 4331TT, HWREV_GTE(1)) },
+ CHIPC_QUIRK_4331_EXTPA2_MUX_SPROM
+ },
+
+ /* 4331 (all packages/revisions) */
+ {{ BHND_CHIP_ID(4331) },
+ CHIPC_QUIRK_4331_EXTPA_MUX_SPROM
+ },
+
+ /* 4360 family (all revs <= 2) */
+ {{ BHND_CHIP_IR(4352, HWREV_LTE(2)) },
+ CHIPC_QUIRK_4360_FEM_MUX_SPROM },
+ {{ BHND_CHIP_IR(43460, HWREV_LTE(2)) },
+ CHIPC_QUIRK_4360_FEM_MUX_SPROM },
+ {{ BHND_CHIP_IR(43462, HWREV_LTE(2)) },
+ CHIPC_QUIRK_4360_FEM_MUX_SPROM },
+ {{ BHND_CHIP_IR(43602, HWREV_LTE(2)) },
+ CHIPC_QUIRK_4360_FEM_MUX_SPROM },
+
+ BHND_CHIP_QUIRK_END
+};
+
/* quirk and capability flag convenience macros */
#define CHIPC_QUIRK(_sc, _name) \
((_sc)->quirks & CHIPC_QUIRK_ ## _name)
@@ -91,7 +124,13 @@
KASSERT(CHIPC_QUIRK((_sc), name), ("quirk " __STRING(_name) " not set"))
#define CHIPC_ASSERT_CAP(_sc, name) \
- KASSERT(CHIPC_CAP((_sc), name), ("capability " __STRING(_name) " not set"))
+ KASSERT(CHIPC_CAP((_sc), name), ("capability " __STRING(_name) " not set"))
+
+static bhnd_nvram_src_t chipc_nvram_identify(struct chipc_softc *sc);
+static int chipc_sprom_init(struct chipc_softc *);
+static int chipc_enable_sprom_pins(struct chipc_softc *);
+static int chipc_disable_sprom_pins(struct chipc_softc *);
+
static int
chipc_probe(device_t dev)
@@ -119,6 +158,9 @@
sc->dev = dev;
sc->quirks = bhnd_device_quirks(dev, chipc_devices,
sizeof(chipc_devices[0]));
+ sc->quirks |= bhnd_chip_quirks(dev, chipc_chip_quirks);
+
+ CHIPC_LOCK_INIT(sc);
/* Allocate bus resources */
memcpy(sc->rspec, chipc_rspec, sizeof(sc->rspec));
@@ -152,22 +194,28 @@
sc->caps = bhnd_bus_read_4(sc->core, CHIPC_CAPABILITIES);
sc->cst = bhnd_bus_read_4(sc->core, CHIPC_CHIPST);
- // TODO
- switch (bhnd_chipc_nvram_src(dev)) {
- case BHND_NVRAM_SRC_CIS:
- device_printf(dev, "NVRAM source: CIS\n");
- break;
- case BHND_NVRAM_SRC_SPROM:
- device_printf(dev, "NVRAM source: SPROM\n");
- break;
+ /* Identify NVRAM source */
+ sc->nvram_src = chipc_nvram_identify(sc);
+
+ /* Read NVRAM data */
+ switch (sc->nvram_src) {
case BHND_NVRAM_SRC_OTP:
- device_printf(dev, "NVRAM source: OTP\n");
+ // TODO (requires access to OTP hardware)
+ device_printf(sc->dev, "NVRAM-OTP unsupported\n");
break;
+
case BHND_NVRAM_SRC_NFLASH:
- device_printf(dev, "NVRAM source: NFLASH\n");
+ // TODO (requires access to NFLASH hardware)
+ device_printf(sc->dev, "NVRAM-NFLASH unsupported\n");
+ break;
+
+ case BHND_NVRAM_SRC_SPROM:
+ if ((error = chipc_sprom_init(sc)))
+ goto cleanup;
break;
- case BHND_NVRAM_SRC_NONE:
- device_printf(dev, "NVRAM source: NONE\n");
+
+ case BHND_NVRAM_SRC_UNKNOWN:
+ /* Handled externally */
break;
}
@@ -175,6 +223,7 @@
cleanup:
bhnd_release_resources(dev, sc->rspec, sc->res);
+ CHIPC_LOCK_DESTROY(sc);
return (error);
}
@@ -185,6 +234,9 @@
sc = device_get_softc(dev);
bhnd_release_resources(dev, sc->rspec, sc->res);
+ bhnd_sprom_fini(&sc->sprom);
+
+ CHIPC_LOCK_DESTROY(sc);
return (0);
}
@@ -202,68 +254,64 @@
}
/**
- * Use device-specific ChipStatus flags to determine the preferred NVRAM
- * data source.
+ * Initialize local SPROM shadow, if required.
+ *
+ * @param sc chipc driver state.
*/
-static bhnd_nvram_src_t
-chipc_nvram_src_chipst(struct chipc_softc *sc)
+static int
+chipc_sprom_init(struct chipc_softc *sc)
{
- uint8_t nvram_sel;
+ int error;
- CHIPC_ASSERT_QUIRK(sc, SPROM_CHECK_CHIPST);
+ KASSERT(sc->nvram_src == BHND_NVRAM_SRC_SPROM,
+ ("non-SPROM source (%u)\n", sc->nvram_src));
- if (CHIPC_QUIRK(sc, SPROM_CHECK_CST_R22)) {
- // TODO: On these devices, the official driver code always
- // assumes SPROM availability if CHIPC_CST_OTP_SEL is not
- // set; we must review against the actual behavior of our
- // BCM4312 hardware
- nvram_sel = CHIPC_GET_ATTR(sc->cst, CST_SPROM_OTP_SEL_R22);
- } else if (CHIPC_QUIRK(sc, SPROM_CHECK_CST_R23)) {
- nvram_sel = CHIPC_GET_ATTR(sc->cst, CST_SPROM_OTP_SEL_R23);
- } else {
- panic("invalid CST OTP/SPROM chipc quirk flags");
- }
- device_printf(sc->dev, "querying chipst for 0x%x, 0x%x\n", sc->ccid.chip_id, sc->cst);
-
- switch (nvram_sel) {
- case CHIPC_CST_DEFCIS_SEL:
- return (BHND_NVRAM_SRC_CIS);
-
- case CHIPC_CST_SPROM_SEL:
- case CHIPC_CST_OTP_PWRDN:
- return (BHND_NVRAM_SRC_SPROM);
+ /* Enable access to the SPROM */
+ CHIPC_LOCK(sc);
+ if ((error = chipc_enable_sprom_pins(sc)))
+ goto failed;
+
+ /* Initialize SPROM parser */
+ error = bhnd_sprom_init(&sc->sprom, sc->core, CHIPC_SPROM_OTP);
+ if (error) {
+ device_printf(sc->dev, "SPROM identification failed: %d\n",
+ error);
- case CHIPC_CST_OTP_SEL:
- return (BHND_NVRAM_SRC_OTP);
+ chipc_disable_sprom_pins(sc);
+ goto failed;
+ }
- default:
- device_printf(sc->dev, "unrecognized OTP/SPROM type 0x%hhx",
- nvram_sel);
- return (BHND_NVRAM_SRC_NONE);
+ /* Drop access to the SPROM lines */
+ if ((error = chipc_disable_sprom_pins(sc))) {
+ bhnd_sprom_fini(&sc->sprom);
+ goto failed;
}
+ CHIPC_UNLOCK(sc);
+
+ return (0);
+
+failed:
+ CHIPC_UNLOCK(sc);
+ return (error);
}
/**
- * Determine the preferred NVRAM data source.
+ * Determine the NVRAM data source for this device.
+ *
+ * @param sc chipc driver state.
*/
static bhnd_nvram_src_t
-chipc_nvram_src(device_t dev)
+chipc_nvram_identify(struct chipc_softc *sc)
{
- struct chipc_softc *sc;
uint32_t srom_ctrl;
- sc = device_get_softc(dev);
-
- /* Very early devices always included a SPROM */
- if (CHIPC_QUIRK(sc, ALWAYS_HAS_SPROM))
- return (BHND_NVRAM_SRC_SPROM);
-
- /* Most other early devices require checking ChipStatus flags */
- if (CHIPC_QUIRK(sc, SPROM_CHECK_CHIPST))
- return (chipc_nvram_src_chipst(sc));
+ /* Very early devices vend SPROM/OTP/CIS (if at all) via the
+ * host bridge interface instead of ChipCommon. */
+ if (!CHIPC_QUIRK(sc, SUPPORTS_SPROM))
+ return (BHND_NVRAM_SRC_UNKNOWN);
/*
- * Later chipset revisions standardized the NVRAM capability flags and
+ * Later chipset revisions standardized the SPROM capability flags and
* register interfaces.
*
* We check for hardware presence in order of precedence. For example,
@@ -287,7 +335,158 @@
return (BHND_NVRAM_SRC_NFLASH);
/* No NVRAM hardware capability declared */
- return (BHND_NVRAM_SRC_NONE);
+ return (BHND_NVRAM_SRC_UNKNOWN);
+}
+
+
+/**
+ * If required by this device, enable access to the SPROM.
+ *
+ * @param sc chipc driver state.
+ */
+static int
+chipc_enable_sprom_pins(struct chipc_softc *sc)
+{
+ uint32_t cctrl;
+
+ CHIPC_LOCK_ASSERT(sc, MA_OWNED);
+
+ /* Nothing to do? */
+ if (!CHIPC_QUIRK(sc, MUX_SPROM))
+ return (0);
+
+ cctrl = bhnd_bus_read_4(sc->core, CHIPC_CHIPCTRL);
+
+ /* 4331 devices */
+ if (CHIPC_QUIRK(sc, 4331_EXTPA_MUX_SPROM)) {
+ cctrl &= ~CHIPC_CCTRL4331_EXTPA_EN;
+
+ if (CHIPC_QUIRK(sc, 4331_GPIO2_5_MUX_SPROM))
+ cctrl &= ~CHIPC_CCTRL4331_EXTPA_ON_GPIO2_5;
+
+ if (CHIPC_QUIRK(sc, 4331_EXTPA2_MUX_SPROM))
+ cctrl &= ~CHIPC_CCTRL4331_EXTPA_EN2;
+
+ bhnd_bus_write_4(sc->core, CHIPC_CHIPCTRL, cctrl);
+ return (0);
+ }
+
+ /* 4360 devices */
+ if (CHIPC_QUIRK(sc, 4360_FEM_MUX_SPROM)) {
+ /* Unimplemented */
+ }
+
+ /* Refuse to proceed on unsupported devices with muxed SPROM pins */
+ device_printf(sc->dev, "muxed sprom lines on unrecognized device\n");
+ return (ENXIO);
+}
+
+/**
+ * If required by this device, revert any GPIO/pin configuration applied
+ * to allow SPROM access.
+ *
+ * @param sc chipc driver state.
+ */
+static int
+chipc_disable_sprom_pins(struct chipc_softc *sc)
+{
+ uint32_t cctrl;
+
+ CHIPC_LOCK_ASSERT(sc, MA_OWNED);
+
+ /* Nothing to do? */
+ if (!CHIPC_QUIRK(sc, MUX_SPROM))
+ return (0);
+
+ cctrl = bhnd_bus_read_4(sc->core, CHIPC_CHIPCTRL);
+
+ /* 4331 devices */
+ if (CHIPC_QUIRK(sc, 4331_EXTPA_MUX_SPROM)) {
+ cctrl |= CHIPC_CCTRL4331_EXTPA_EN;
+
+ if (CHIPC_QUIRK(sc, 4331_GPIO2_5_MUX_SPROM))
+ cctrl |= CHIPC_CCTRL4331_EXTPA_ON_GPIO2_5;
+
+ if (CHIPC_QUIRK(sc, 4331_EXTPA2_MUX_SPROM))
+ cctrl |= CHIPC_CCTRL4331_EXTPA_EN2;
+
+ bhnd_bus_write_4(sc->core, CHIPC_CHIPCTRL, cctrl);
+ return (0);
+ }
+
+ /* 4360 devices */
+ if (CHIPC_QUIRK(sc, 4360_FEM_MUX_SPROM)) {
+ /* Unimplemented */
+ }
+
+ /* Refuse to proceed on unsupported devices with muxed SPROM pins */
+ device_printf(sc->dev, "muxed sprom lines on unrecognized device\n");
+ return (ENXIO);
+}
+
+static bhnd_nvram_src_t
+chipc_nvram_src(device_t dev)
+{
+ struct chipc_softc *sc = device_get_softc(dev);
+ return (sc->nvram_src);
+}
+
+static int
+chipc_nvram_getvar(device_t dev, const char *name, void *buf, size_t *len)
+{
+ struct chipc_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+
+ switch (sc->nvram_src) {
+ case BHND_NVRAM_SRC_SPROM:
+ CHIPC_LOCK(sc);
+ error = bhnd_sprom_getvar(&sc->sprom, name, buf, len);
+ CHIPC_UNLOCK(sc);
+ return (error);
+
+ case BHND_NVRAM_SRC_OTP:
+ case BHND_NVRAM_SRC_NFLASH:
+ /* Currently unsupported */
+ return (ENXIO);
+
+ case BHND_NVRAM_SRC_UNKNOWN:
+ return (ENODEV);
+ }
+
+ /* Unknown NVRAM source */
+ return (ENODEV);
+}
+
+static int
+chipc_nvram_setvar(device_t dev, const char *name, const void *buf,
+ size_t len)
+{
+ struct chipc_softc *sc;
+ int error;
+
+ sc = device_get_softc(dev);
+
+ switch (sc->nvram_src) {
+ case BHND_NVRAM_SRC_SPROM:
+ CHIPC_LOCK(sc);
+ error = bhnd_sprom_setvar(&sc->sprom, name, buf, len);
+ CHIPC_UNLOCK(sc);
+ return (error);
+
+ case BHND_NVRAM_SRC_OTP:
+ case BHND_NVRAM_SRC_NFLASH:
+ /* Currently unsupported */
+ return (ENXIO);
+
+ case BHND_NVRAM_SRC_UNKNOWN:
+ default:
+ return (ENODEV);
+ }
+
+ /* Unknown NVRAM source */
+ return (ENODEV);
}
static device_method_t chipc_methods[] = {
@@ -301,6 +500,10 @@
/* ChipCommon interface */
DEVMETHOD(bhnd_chipc_nvram_src, chipc_nvram_src),
+ /* NVRAM interface */
+ DEVMETHOD(bhnd_nvram_getvar, chipc_nvram_getvar),
+ DEVMETHOD(bhnd_nvram_setvar, chipc_nvram_setvar),
+
DEVMETHOD_END
};
Index: head/sys/dev/bhnd/cores/chipc/chipcreg.h
===================================================================
--- head/sys/dev/bhnd/cores/chipc/chipcreg.h
+++ head/sys/dev/bhnd/cores/chipc/chipcreg.h
@@ -36,26 +36,12 @@
#define CHIPC_GET_ATTR(_entry, _attr) \
((_entry & CHIPC_ ## _attr ## _MASK) >> CHIPC_ ## _attr ## _SHIFT)
-#define CHIPC_ID 0x0
-#define CHIPC_CAPABILITIES 0x04
-#define CHIPC_CHIPST 0x2c
-#define CHIPC_EROMPTR 0xfc /**< 32-bit EROM base address
- * on BCMA devices */
-
-/** chipid */
-#define CHIPC_ID 0x0 /**< identification register */
-#define CHIPC_ID_CHIP_MASK 0x0000FFFF /**< chip id */
-#define CHIPC_ID_CHIP_SHIFT 0
-#define CHIPC_ID_REV_MASK 0x000F0000 /**< chip revision */
-#define CHIPC_ID_REV_SHIFT 16
-#define CHIPC_ID_PKG_MASK 0x00F00000 /**< physical package ID */
-#define CHIPC_ID_PKG_SHIFT 20
-#define CHIPC_ID_NUMCORE_MASK 0x0F000000 /**< number of cores on chip (rev >= 4) */
-#define CHIPC_ID_NUMCORE_SHIFT 24
-#define CHIPC_ID_BUS_MASK 0xF0000000 /**< chip/interconnect type (BHND_CHIPTYPE_*) */
-#define CHIPC_ID_BUS_SHIFT 28
+#define CHIPC_ID 0x0
+#define CHIPC_CAPABILITIES 0x04
#define CHIPC_OTPST 0x10
+#define CHIPC_CHIPCTRL 0x28 /**< chip control */
+#define CHIPC_CHIPST 0x2c /**< chip status */
#define CHIPC_JTAGCMD 0x30
#define CHIPC_JTAGIR 0x34
#define CHIPC_JTAGDR 0x38
@@ -76,6 +62,8 @@
#define CHIPC_CLKC_M3 0xa0
#define CHIPC_CLKDIV 0xa4
#define CHIPC_SYS_CLK_CTL 0xc0
+#define CHIPC_EROMPTR 0xfc /**< 32-bit EROM base address
+ * on BCMA devices */
#define CHIPC_SPROM_CTRL 0x190 /**< SPROM interface (rev >= 32) */
#define CHIPC_SPROM_ADDR 0x194
#define CHIPC_SPROM_DATA 0x198
@@ -95,6 +83,19 @@
#define CHIPC_PMU_PLL_CONTROL_DATA 0x664
#define CHIPC_SPROM_OTP 0x800 /* SPROM/OTP address space */
+/** chipid */
+#define CHIPC_ID 0x0 /**< identification register */
+#define CHIPC_ID_CHIP_MASK 0x0000FFFF /**< chip id */
+#define CHIPC_ID_CHIP_SHIFT 0
+#define CHIPC_ID_REV_MASK 0x000F0000 /**< chip revision */
+#define CHIPC_ID_REV_SHIFT 16
+#define CHIPC_ID_PKG_MASK 0x00F00000 /**< physical package ID */
+#define CHIPC_ID_PKG_SHIFT 20
+#define CHIPC_ID_NUMCORE_MASK 0x0F000000 /**< number of cores on chip (rev >= 4) */
+#define CHIPC_ID_NUMCORE_SHIFT 24
+#define CHIPC_ID_BUS_MASK 0xF0000000 /**< chip/interconnect type (BHND_CHIPTYPE_*) */
+#define CHIPC_ID_BUS_SHIFT 28
+
/* capabilities */
#define CHIPC_CAP_UARTS_MASK 0x00000003 /* Number of UARTs */
#define CHIPC_CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */
@@ -1124,6 +1125,7 @@
#define CHIPC_CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9) /* override core control on pipe_AuxPowerDown */
#define CHIPC_CCTRL4331_PCIE_AUXCLKEN (1<<10) /* pcie_auxclkenable */
#define CHIPC_CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11) /* pcie_pipe_pllpowerdown */
+#define CHIPC_CCTRL4331_EXTPA_EN2 (1<<12) /* 0 ext pa2 disable, 1 ext pa2 enabled */
#define CHIPC_CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16) /* enable bt_shd0 at gpio4 */
#define CHIPC_CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17) /* enable bt_shd1 at gpio5 */
Index: head/sys/dev/bhnd/cores/chipc/chipcvar.h
===================================================================
--- head/sys/dev/bhnd/cores/chipc/chipcvar.h
+++ head/sys/dev/bhnd/cores/chipc/chipcvar.h
@@ -32,6 +32,8 @@
#ifndef _BHND_CORES_CHIPC_CHIPCVAR_H_
#define _BHND_CORES_CHIPC_CHIPCVAR_H_
+#include <dev/bhnd/nvram/bhnd_spromvar.h>
+
#include "chipc.h"
DECLARE_CLASS(bhnd_chipc);
@@ -45,37 +47,64 @@
*/
enum {
/** No quirks */
- CHIPC_QUIRK_NONE = 0,
+ CHIPC_QUIRK_NONE = 0,
/**
- * The device always provides an external SROM.
+ * ChipCommon-controlled SPROM/OTP is supported, along with the
+ * CHIPC_CAP_SPROM capability flag.
*/
- CHIPC_QUIRK_ALWAYS_HAS_SPROM = (1<<1),
-
-
+ CHIPC_QUIRK_SUPPORTS_SPROM = (1<<1),
+
/**
- * SROM availability must be determined through chip-specific
- * ChipStatus flags.
+ * External NAND NVRAM is supported, along with the CHIPC_CAP_NFLASH
+ * capability flag.
*/
- CHIPC_QUIRK_SPROM_CHECK_CHIPST = (1<<3),
+ CHIPC_QUIRK_SUPPORTS_NFLASH = (1<<2),
/**
- * Use the rev22 chipstatus register format when determining SPROM
- * availability.
+ * The SPROM is attached via muxed pins. The pins must be switched
+ * to allow reading/writing.
*/
- CHIPC_QUIRK_SPROM_CHECK_CST_R22 = (1<<4)|CHIPC_QUIRK_SPROM_CHECK_CHIPST,
+ CHIPC_QUIRK_MUX_SPROM = (1<<3),
/**
- * Use the rev23 chipstatus register format when determining SPROM
- * availability.
+ * Access to the SPROM uses pins shared with the 802.11a external PA.
+ *
+ * On modules using these 4331 packages, the CCTRL4331_EXTPA_EN flag
+ * must be cleared to allow SPROM access.
*/
- CHIPC_QUIRK_SPROM_CHECK_CST_R23 = (1<<5)|CHIPC_QUIRK_SPROM_CHECK_CHIPST,
+ CHIPC_QUIRK_4331_EXTPA_MUX_SPROM = (1<<4) |
+ CHIPC_QUIRK_MUX_SPROM,
/**
- * External NAND NVRAM is supported, along with the CHIPC_CAP_NFLASH
- * capability flag.
+ * Access to the SPROM uses pins shared with the 802.11a external PA.
+ *
+ * On modules using these 4331 chip packages, the external PA is
+ * attached via GPIO 2, 5, and sprom_dout pins.
+ *
+ * When enabling and disabling EXTPA to allow SPROM access, the
+ * CCTRL4331_EXTPA_ON_GPIO2_5 flag must also be set or cleared,
+ * respectively.
+ */
+ CHIPC_QUIRK_4331_GPIO2_5_MUX_SPROM = (1<<5) |
+ CHIPC_QUIRK_4331_EXTPA_MUX_SPROM,
+
+ /**
+ * Access to the SPROM uses pins shared with two 802.11a external PAs.
+ *
+ * When enabling and disabling EXTPA, the CCTRL4331_EXTPA_EN2 must also
+ * be cleared to allow SPROM access.
*/
- CHIPC_QUIRK_SUPPORTS_NFLASH = (1<<6),
+ CHIPC_QUIRK_4331_EXTPA2_MUX_SPROM = (1<<6) |
+ CHIPC_QUIRK_4331_EXTPA_MUX_SPROM,
+
+
+ /**
+ * SPROM pins are muxed with the FEM control lines on this 4360-family
+ * device. The muxed pins must be switched to allow reading/writing
+ * the SPROM.
+ */
+ CHIPC_QUIRK_4360_FEM_MUX_SPROM = (1<<5) | CHIPC_QUIRK_MUX_SPROM
};
struct chipc_softc {
@@ -89,6 +118,19 @@
uint32_t quirks; /**< CHIPC_QUIRK_* quirk flags */
uint32_t caps; /**< CHIPC_CAP_* capability register flags */
uint32_t cst; /**< CHIPC_CST* status register flags */
+ bhnd_nvram_src_t nvram_src; /**< NVRAM source */
+
+ struct mtx mtx; /**< state mutex. */
+
+ struct bhnd_sprom sprom; /**< OTP/SPROM shadow, if any */
};
+#define CHIPC_LOCK_INIT(sc) \
+ mtx_init(&(sc)->mtx, device_get_nameunit((sc)->dev), \
+ "BHND chipc driver lock", MTX_DEF)
+#define CHIPC_LOCK(sc) mtx_lock(&(sc)->mtx)
+#define CHIPC_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
+#define CHIPC_LOCK_ASSERT(sc, what) mtx_assert(&(sc)->mtx, what)
+#define CHIPC_LOCK_DESTROY(sc) mtx_destroy(&(sc)->mtx)
+
#endif /* _BHND_CORES_CHIPC_CHIPCVAR_H_ */
\ No newline at end of file
Index: head/sys/dev/bhnd/nvram/bhnd_nvram.h
===================================================================
--- head/sys/dev/bhnd/nvram/bhnd_nvram.h
+++ head/sys/dev/bhnd/nvram/bhnd_nvram.h
@@ -36,10 +36,6 @@
* NVRAM data sources supported by bhnd(4) devices.
*/
typedef enum {
- BHND_NVRAM_SRC_CIS, /**< Default CIS source; this may
- * apply, for example, to PCMCIA cards
- * vending Broadcom NVRAM data via
- * their standard CIS table. */
BHND_NVRAM_SRC_OTP, /**< On-chip one-time-programmable
* memory. */
@@ -51,15 +47,36 @@
* NVRAM. */
BHND_NVRAM_SRC_SPROM, /**< External serial EEPROM. */
- BHND_NVRAM_SRC_NONE /**< No NVRAM source is directly
- * attached. This is used on devices
- * attached via PCI(e) to BHND SoCs,
- * where to avoid unnecessary flash
- * hardware, NVRAM configuration for
- * individual devices is provided by
- * hardware attached to the SoC
- * itself.
+ BHND_NVRAM_SRC_UNKNOWN /**< No NVRAM source is directly
+ * attached.
+ *
+ * This will be returned by ChipCommon
+ * revisions (rev <= 31) used in early
+ * chipsets that vend SPROM/OTP via the
+ * native host bridge interface.
+ *
+ * For example, PCMCIA cards may vend
+ * Broadcom NVRAM data via their standard CIS
+ * table, and earlier PCI(e) devices map
+ * SPROM statically into PCI BARs, and the
+ * control registers into PCI config space.
+
+ * This will also be returned on later
+ * devices that are attached via PCI(e) to
+ * BHND SoCs, but do not include an attached
+ * SPROM, or programmed OTP. On such SoCs,
+ * NVRAM configuration for individual devices
+ * is provided by a common platform NVRAM
+ * device.
*/
} bhnd_nvram_src_t;
+/**
+ * Evaluates to true if the given NVRAM data source is accessible via
+ * ChipCommon.
+ */
+#define BHND_NVRAM_SRC_CC(_src) \
+ ((_src) == BHND_NVRAM_SRC_OTP || (_src) == BHND_NVRAM_SRC_SPROM)
+
+
#endif /* _BHND_NVRAM_BHND_NVRAM_H_ */
\ No newline at end of file
Index: head/sys/dev/bhnd/nvram/bhnd_nvram_if.m
===================================================================
--- head/sys/dev/bhnd/nvram/bhnd_nvram_if.m
+++ head/sys/dev/bhnd/nvram/bhnd_nvram_if.m
@@ -46,13 +46,16 @@
* @param[out] buf On success, the requested value will be written
* to this buffer. This argment may be NULL if
* the value is not desired.
- * @param[in,out] size The capacity of @p buf. On success, will be set
- * to the actual size of the requested value.
+ * @param[in,out] len The maximum capacity of @p buf. On success,
+ * will be set to the actual size of the requested
+ * value.
*
* @retval 0 success
* @retval ENOENT The requested variable was not found.
- * @retval ENOMEM If @p buf is non-NULL and a buffer of @p size is too
+ * @retval ENOMEM If @p buf is non-NULL and a buffer of @p len is too
* small to hold the requested value.
+ * @retval ENODEV If no supported NVRAM hardware is accessible via this
+ * device.
* @retval non-zero If reading @p name otherwise fails, a regular unix
* error code will be returned.
*/
@@ -60,5 +63,30 @@
device_t dev;
const char *name;
void *buf;
- size_t *size;
-};
\ No newline at end of file
+ size_t *len;
+};
+
+/**
+ * Set an NVRAM variable's local value.
+ *
+ * No changes should be written to non-volatile storage.
+ *
+ * @param dev The NVRAM device.
+ * @param name The NVRAM variable name.
+ * @param buf The new value.
+ * @param len The size of @p buf.
+ *
+ * @retval 0 success
+ * @retval ENOENT The specified variable name is not recognized.
+ * @retval EINVAL If @p len does not match the expected variable size.
+ * @retval ENODEV If no supported NVRAM hardware is accessible via this
+ * device.
+ * @retval non-zero If reading @p name otherwise fails, a regular unix
+ * error code will be returned.
+ */
+METHOD int setvar {
+ device_t dev;
+ const char *name;
+ const void *buf;
+ size_t len;
+};
Index: head/sys/dev/bhnd/nvram/bhnd_sprom.c
===================================================================
--- head/sys/dev/bhnd/nvram/bhnd_sprom.c
+++ head/sys/dev/bhnd/nvram/bhnd_sprom.c
@@ -0,0 +1,572 @@
+/*-
+ * Copyright (c) 2015 Landon Fuller <landon@landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/rman.h>
+#include <sys/systm.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+
+#include <dev/bhnd/bhndvar.h>
+
+#include "nvramvar.h"
+
+#include "bhnd_spromreg.h"
+#include "bhnd_spromvar.h"
+
+/*
+ * BHND SPROM Parsing
+ *
+ * Provides identification and parsing of BHND SPROM data.
+ */
+
+static int sprom_direct_read(struct bhnd_sprom *sc, size_t offset,
+ void *buf, size_t nbytes, uint8_t *crc);
+static int sprom_extend_shadow(struct bhnd_sprom *sc, size_t image_size,
+ uint8_t *crc);
+static int sprom_populate_shadow(struct bhnd_sprom *sc);
+
+static int sprom_var_defn(struct bhnd_sprom *sc, const char *name,
+ const struct bhnd_nvram_var **var,
+ const struct bhnd_sprom_var **sprom, size_t *size);
+
+/* SPROM revision is always located at the second-to-last byte */
+#define SPROM_REV(_sc) SPROM_READ_1((_sc), (_sc)->sp_size - 2)
+
+/* SPROM CRC is always located at the last byte */
+#define SPROM_CRC_OFF(_sc) SPROM_CRC_LEN(_sc)
+
+/* SPROM CRC covers all but the final CRC byte */
+#define SPROM_CRC_LEN(_sc) ((_sc)->sp_size - 1)
+
+/* SPROM shadow I/O (with byte-order translation) */
+#define SPROM_READ_1(_sc, _off) SPROM_READ_ENC_1(_sc, _off)
+#define SPROM_READ_2(_sc, _off) le16toh(SPROM_READ_ENC_2(_sc, _off))
+#define SPROM_READ_4(_sc, _off) le32toh(SPROM_READ_ENC_4(_sc, _off))
+
+#define SPROM_WRITE_1(_sc, _off, _v) SPROM_WRITE_ENC_1(_sc, _off, (_v))
+#define SPROM_WRITE_2(_sc, _off, _v) SPROM_WRITE_ENC_2(_sc, _off, \
+ htole16(_v))
+#define SPROM_WRITE_4(_sc, _off, _v) SPROM_WRITE_ENC_4(_sc, _off, \
+ htole32(_v))
+
+/* SPROM shadow I/O (without byte-order translation) */
+#define SPROM_READ_ENC_1(_sc, _off) (*(uint8_t *)((_sc)->sp_shadow + _off))
+#define SPROM_READ_ENC_2(_sc, _off) (*(uint16_t *)((_sc)->sp_shadow + _off))
+#define SPROM_READ_ENC_4(_sc, _off) (*(uint32_t *)((_sc)->sp_shadow + _off))
+
+#define SPROM_WRITE_ENC_1(_sc, _off, _v) \
+ *((uint8_t *)((_sc)->sp_shadow + _off)) = (_v)
+#define SPROM_WRITE_ENC_2(_sc, _off, _v) \
+ *((uint16_t *)((_sc)->sp_shadow + _off)) = (_v)
+#define SPROM_WRITE_ENC_4(_sc, _off, _v) \
+ *((uint32_t *)((_sc)->sp_shadow + _off)) = (_v)
+
+/* Call @p _next macro with the C type, widened (signed or unsigned) C
+ * type, and width associated with @p _dtype */
+#define SPROM_SWITCH_TYPE(_dtype, _next, ...) \
+do { \
+ switch (_dtype) { \
+ case BHND_NVRAM_DT_UINT8: \
+ _next (uint8_t, uint32_t, 1, \
+ ## __VA_ARGS__); \
+ break; \
+ case BHND_NVRAM_DT_UINT16: \
+ _next (uint16_t, uint32_t, 2, \
+ ## __VA_ARGS__); \
+ break; \
+ case BHND_NVRAM_DT_UINT32: \
+ _next (uint32_t, uint32_t, 4, \
+ ## __VA_ARGS__); \
+ break; \
+ case BHND_NVRAM_DT_INT8: \
+ _next (int8_t, int32_t, 1, \
+ ## __VA_ARGS__); \
+ break; \
+ case BHND_NVRAM_DT_INT16: \
+ _next (int16_t, int32_t, 2, \
+ ## __VA_ARGS__); \
+ break; \
+ case BHND_NVRAM_DT_INT32: \
+ _next (int32_t, int32_t, 4, \
+ ## __VA_ARGS__); \
+ break; \
+ case BHND_NVRAM_DT_CHAR: \
+ _next (uint8_t, uint32_t, 1, \
+ ## __VA_ARGS__); \
+ break; \
+ } \
+} while (0)
+
+/*
+ * Table of supported SPROM image formats, sorted by image size, ascending.
+ */
+#define SPROM_FMT(_sz, _revmin, _revmax, _sig) \
+ { SPROM_SZ_ ## _sz, _revmin, _revmax, \
+ SPROM_SIG_ ## _sig ## _OFF, \
+ SPROM_SIG_ ## _sig }
+
+static const struct sprom_fmt {
+ size_t size;
+ uint8_t rev_min;
+ uint8_t rev_max;
+ size_t sig_offset;
+ uint16_t sig_req;
+} sprom_fmts[] = {
+ SPROM_FMT(R1_3, 1, 3, NONE),
+ SPROM_FMT(R4_8_9, 4, 4, R4),
+ SPROM_FMT(R4_8_9, 8, 9, R8_9),
+ SPROM_FMT(R10, 10, 10, R10),
+ SPROM_FMT(R11, 11, 11, R11)
+};
+
+/**
+ * Identify the SPROM format at @p offset within @p r, verify the CRC,
+ * and allocate a local shadow copy of the SPROM data.
+ *
+ * After successful initialization, @p r will not be accessed; any pin
+ * configuration required for SPROM access may be reset.
+ *
+ * @param[out] sprom On success, will be initialized with shadow of the SPROM
+ * data.
+ * @param r An active resource mapping the SPROM data.
+ * @param offset Offset of the SPROM data within @p resource.
+ */
+int
+bhnd_sprom_init(struct bhnd_sprom *sprom, struct bhnd_resource *r,
+ bus_size_t offset)
+{
+ bus_size_t res_size;
+ int error;
+
+ sprom->dev = rman_get_device(r->res);
+ sprom->sp_res = r;
+ sprom->sp_res_off = offset;
+
+ /* Determine maximum possible SPROM image size */
+ res_size = rman_get_size(r->res);
+ if (offset >= res_size)
+ return (EINVAL);
+
+ sprom->sp_size_max = MIN(res_size - offset, SPROM_SZ_MAX);
+
+ /* Allocate and populate SPROM shadow */
+ sprom->sp_size = 0;
+ sprom->sp_capacity = sprom->sp_size_max;
+ sprom->sp_shadow = malloc(sprom->sp_capacity, M_BHND, M_NOWAIT);
+ if (sprom->sp_shadow == NULL)
+ return (ENOMEM);
+
+ /* Read and identify SPROM image */
+ if ((error = sprom_populate_shadow(sprom)))
+ return (error);
+
+ return (0);
+}
+
+/**
+ * Release all resources held by @p sprom.
+ *
+ * @param sprom A SPROM instance previously initialized via bhnd_sprom_init().
+ */
+void
+bhnd_sprom_fini(struct bhnd_sprom *sprom)
+{
+ free(sprom->sp_shadow, M_BHND);
+}
+
+/* Perform a read using a SPROM offset descriptor, safely widening the
+ * result to its 32-bit representation before assigning it to @p _dest. */
+#define SPROM_GETVAR_READ(_type, _widen, _width, _sc, _off, _dest) \
+do { \
+ _type _v = (_type)SPROM_READ_ ## _width(_sc, _off->offset); \
+ if (_off->shift > 0) { \
+ _v >>= _off->shift; \
+ } else if (off->shift < 0) { \
+ _v <<= -_off->shift; \
+ } \
+ _dest = ((uint32_t) (_widen) _v) & _off->mask; \
+} while(0)
+
+/* Emit a value read using a SPROM offset descriptor, narrowing the
+ * result output representation and, if necessary, OR'ing it with the
+ * previously read value from @p _buf. */
+#define SPROM_GETVAR_WRITE(_type, _widen, _width, _off, _src, _buf) \
+do { \
+ _type _v = (_type) (_widen) _src; \
+ if (_off->cont) \
+ _v |= *((_type *)_buf); \
+ *((_type *)_buf) = _v; \
+} while(0)
+
+/**
+ * Read a SPROM variable, performing conversion to host byte order.
+ *
+ * @param sc The SPROM parser state.
+ * @param name The SPROM variable name.
+ * @param[out] buf On success, the requested value will be written
+ * to this buffer. This argment may be NULL if
+ * the value is not desired.
+ * @param[in,out] len The capacity of @p buf. On success, will be set
+ * to the actual size of the requested value.
+ *
+ * @retval 0 success
+ * @retval ENOENT The requested variable was not found.
+ * @retval ENOMEM If @p buf is non-NULL and a buffer of @p len is too
+ * small to hold the requested value.
+ * @retval non-zero If reading @p name otherwise fails, a regular unix
+ * error code will be returned.
+ */
+int
+bhnd_sprom_getvar(struct bhnd_sprom *sc, const char *name, void *buf,
+ size_t *len)
+{
+ const struct bhnd_nvram_var *nv;
+ const struct bhnd_sprom_var *sv;
+ size_t all1_offs;
+ size_t req_size;
+ int error;
+
+ if ((error = sprom_var_defn(sc, name, &nv, &sv, &req_size)))
+ return (error);
+
+ /* Provide required size */
+ if (buf == NULL) {
+ *len = req_size;
+ return (0);
+ }
+
+ /* Check (and update) target buffer len */
+ if (*len < req_size)
+ return (ENOMEM);
+ else
+ *len = req_size;
+
+ /* Read data */
+ all1_offs = 0;
+ for (size_t i = 0; i < sv->num_offsets; i++) {
+ const struct bhnd_sprom_offset *off;
+ uint32_t val;
+
+ off = &sv->offsets[i];
+ KASSERT(!off->cont || i > 0, ("cont marked on first offset"));
+
+ /* If not a continuation, advance the output buffer */
+ if (i > 0 && !off->cont) {
+ buf = ((uint8_t *)buf) +
+ bhnd_nvram_type_width(sv->offsets[i-1].type);
+ }
+
+ /* Read the value, widening to a common uint32
+ * representation */
+ SPROM_SWITCH_TYPE(off->type, SPROM_GETVAR_READ, sc, off, val);
+
+ /* If IGNALL1, record whether value has all bits set. */
+ if (nv->flags & BHND_NVRAM_VF_IGNALL1) {
+ uint32_t all1;
+
+ all1 = off->mask;
+ if (off->shift > 0)
+ all1 >>= off->shift;
+ else if (off->shift < 0)
+ all1 <<= -off->shift;
+
+ if ((val & all1) == all1)
+ all1_offs++;
+ }
+
+ /* Write the value, narrowing to the appropriate output
+ * width. */
+ SPROM_SWITCH_TYPE(nv->type, SPROM_GETVAR_WRITE, off, val, buf);
+ }
+
+ /* Should value should be treated as uninitialized? */
+ if (nv->flags & BHND_NVRAM_VF_IGNALL1 && all1_offs == sv->num_offsets)
+ return (ENOENT);
+
+ return (0);
+}
+
+/* Perform a read of a variable offset from _src, safely widening the result
+ * to its 32-bit representation before assigning it to @p
+ * _dest. */
+#define SPROM_SETVAR_READ(_type, _widen, _width, _off, _src, _dest) \
+do { \
+ _type _v = *(const _type *)_src; \
+ if (_off->shift > 0) { \
+ _v <<= _off->shift; \
+ } else if (off->shift < 0) { \
+ _v >>= -_off->shift; \
+ } \
+ _dest = ((uint32_t) (_widen) _v) & _off->mask; \
+} while(0)
+
+
+/* Emit a value read using a SPROM offset descriptor, narrowing the
+ * result output representation and, if necessary, OR'ing it with the
+ * previously read value from @p _buf. */
+#define SPROM_SETVAR_WRITE(_type, _widen, _width, _sc, _off, _src) \
+do { \
+ _type _v = (_type) (_widen) _src; \
+ if (_off->cont) \
+ _v |= SPROM_READ_ ## _width(_sc, _off->offset); \
+ SPROM_WRITE_ ## _width(_sc, _off->offset, _v); \
+} while(0)
+
+/**
+ * Set a local value for a SPROM variable, performing conversion to SPROM byte
+ * order.
+ *
+ * The new value will be written to the backing SPROM shadow.
+ *
+ * @param sc The SPROM parser state.
+ * @param name The SPROM variable name.
+ * @param[out] buf The new value.
+ * @param[in,out] len The size of @p buf.
+ *
+ * @retval 0 success
+ * @retval ENOENT The requested variable was not found.
+ * @retval EINVAL If @p len does not match the expected variable size.
+ */
+int
+bhnd_sprom_setvar(struct bhnd_sprom *sc, const char *name, const void *buf,
+ size_t len)
+{
+ const struct bhnd_nvram_var *nv;
+ const struct bhnd_sprom_var *sv;
+ size_t req_size;
+ int error;
+ uint8_t crc;
+
+ if ((error = sprom_var_defn(sc, name, &nv, &sv, &req_size)))
+ return (error);
+
+ /* Provide required size */
+ if (len != req_size)
+ return (EINVAL);
+
+ /* Write data */
+ for (size_t i = 0; i < sv->num_offsets; i++) {
+ const struct bhnd_sprom_offset *off;
+ uint32_t val;
+
+ off = &sv->offsets[i];
+ KASSERT(!off->cont || i > 0, ("cont marked on first offset"));
+
+ /* If not a continuation, advance the input pointer */
+ if (i > 0 && !off->cont) {
+ buf = ((const uint8_t *)buf) +
+ bhnd_nvram_type_width(sv->offsets[i-1].type);
+ }
+
+ /* Read the value, widening to a common uint32
+ * representation */
+ SPROM_SWITCH_TYPE(nv->type, SPROM_SETVAR_READ, off, buf, val);
+
+ /* Write the value, narrowing to the appropriate output
+ * width. */
+ SPROM_SWITCH_TYPE(off->type, SPROM_SETVAR_WRITE, sc, off, val);
+ }
+
+ /* Update CRC */
+ crc = ~bhnd_nvram_crc8(sc->sp_shadow, SPROM_CRC_LEN(sc),
+ BHND_NVRAM_CRC8_INITIAL);
+ SPROM_WRITE_1(sc, SPROM_CRC_OFF(sc), crc);
+
+ return (0);
+}
+
+/* Read and identify the SPROM image by incrementally performing
+ * read + CRC of all supported image formats */
+static int
+sprom_populate_shadow(struct bhnd_sprom *sc)
+{
+ const struct sprom_fmt *fmt;
+ int error;
+ uint16_t sig;
+ uint8_t srom_rev;
+ uint8_t crc;
+
+ crc = BHND_NVRAM_CRC8_INITIAL;
+
+ /* Identify the SPROM revision (and populate the SPROM shadow) */
+ for (size_t i = 0; i < nitems(sprom_fmts); i++) {
+ fmt = &sprom_fmts[i];
+
+ /* Read image data and check CRC */
+ if ((error = sprom_extend_shadow(sc, fmt->size, &crc)))
+ return (error);
+
+ /* Skip on invalid CRC */
+ if (crc != BHND_NVRAM_CRC8_VALID)
+ continue;
+
+ /* Fetch SROM revision */
+ srom_rev = SPROM_REV(sc);
+
+ /* Early sromrev 1 devices (specifically some BCM440x enet
+ * cards) are reported to have been incorrectly programmed
+ * with a revision of 0x10. */
+ if (fmt->size == SPROM_SZ_R1_3 && srom_rev == 0x10)
+ srom_rev = 0x1;
+
+ /* Verify revision range */
+ if (srom_rev < fmt->rev_min || srom_rev > fmt->rev_max)
+ continue;
+
+ /* Verify signature (if any) */
+ sig = SPROM_SIG_NONE;
+ if (fmt->sig_offset != SPROM_SIG_NONE_OFF)
+ sig = SPROM_READ_2(sc, fmt->sig_offset);
+
+ if (sig != fmt->sig_req) {
+ device_printf(sc->dev,
+ "invalid sprom %hhu signature: 0x%hx "
+ "(expected 0x%hx)\n",
+ srom_rev, sig, fmt->sig_req);
+ return (EINVAL);
+ }
+
+ /* Identified */
+ sc->sp_rev = srom_rev;
+ return (0);
+ }
+
+ /* identification failed */
+ device_printf(sc->dev, "unrecognized sprom format\n");
+ return (EINVAL);
+}
+
+/*
+ * Extend the shadowed SPROM buffer to image_size, reading any required
+ * data from the backing SPROM resource and updating the CRC.
+ */
+static int
+sprom_extend_shadow(struct bhnd_sprom *sc, size_t image_size,
+ uint8_t *crc)
+{
+ int error;
+
+ KASSERT(image_size >= sc->sp_size, (("shadow truncation unsupported")));
+
+ /* Verify the request fits within our shadow buffer */
+ if (image_size > sc->sp_capacity)
+ return (ENOSPC);
+
+ /* Skip no-op requests */
+ if (sc->sp_size == image_size)
+ return (0);
+
+ /* Populate the extended range */
+ error = sprom_direct_read(sc, sc->sp_size, sc->sp_shadow + sc->sp_size,
+ image_size - sc->sp_size, crc);
+ if (error)
+ return (error);
+
+ sc->sp_size = image_size;
+ return (0);
+}
+
+/**
+ * Read nbytes at the given offset from the backing SPROM resource, and
+ * update the CRC.
+ */
+static int
+sprom_direct_read(struct bhnd_sprom *sc, size_t offset, void *buf,
+ size_t nbytes, uint8_t *crc)
+{
+ bus_size_t res_offset;
+ size_t nread;
+ uint16_t *p;
+
+ KASSERT(nbytes % sizeof(uint16_t) == 0, ("unaligned sprom size"));
+ KASSERT(offset % sizeof(uint16_t) == 0, ("unaligned sprom offset"));
+
+ /* Check for read overrun */
+ if (offset >= sc->sp_size_max || sc->sp_size_max - offset < nbytes) {
+ device_printf(sc->dev, "requested SPROM read would overrun\n");
+ return (EINVAL);
+ }
+
+ p = (uint16_t *)buf;
+ res_offset = sc->sp_res_off + offset;
+
+ /* Perform read */
+ for (nread = 0; nread < nbytes; nread += 2) {
+ *p = bhnd_bus_read_stream_2(sc->sp_res, res_offset+nread);
+ *crc = bhnd_nvram_crc8(p, sizeof(*p), *crc);
+ p++;
+ };
+
+ return (0);
+}
+
+
+/**
+ * Locate the variable and SPROM revision-specific definitions
+ * for variable with @p name.
+ */
+static int
+sprom_var_defn(struct bhnd_sprom *sc, const char *name,
+ const struct bhnd_nvram_var **var,
+ const struct bhnd_sprom_var **sprom,
+ size_t *size)
+{
+ /* Find variable definition */
+ *var = bhnd_nvram_var_defn(name);
+ if (*var == NULL)
+ return (ENOENT);
+
+ /* Find revision-specific SPROM definition */
+ for (size_t i = 0; i < (*var)->num_sp_descs; i++) {
+ const struct bhnd_sprom_var *sp = &(*var)->sprom_descs[i];
+
+ if (sc->sp_rev < sp->compat.first)
+ continue;
+
+ if (sc->sp_rev > sp->compat.last)
+ continue;
+
+ /* Found */
+ *sprom = sp;
+
+ /* Calculate size in bytes */
+ *size = bhnd_nvram_type_width((*var)->type) * sp->num_offsets;
+ return (0);
+ }
+
+ /* Not supported by this SPROM revision */
+ return (ENOENT);
+}
\ No newline at end of file
Index: head/sys/dev/bhnd/nvram/bhnd_spromreg.h
===================================================================
--- head/sys/dev/bhnd/nvram/bhnd_spromreg.h
+++ head/sys/dev/bhnd/nvram/bhnd_spromreg.h
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 2016 Landon Fuller <landon@landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BHND_NVRAM_SPROMREG_H_
+#define _BHND_NVRAM_SPROMREG_H_
+
+#define SPROM_SZ_R1_3 128 /**< SPROM image size (rev 1-3) */
+#define SPROM_SZ_R4_8_9 440 /**< SPROM image size (rev 4, 8-9) */
+#define SPROM_SZ_R10 460 /**< SPROM image size (rev 10) */
+#define SPROM_SZ_R11 468 /**< SPROM image size (rev 11) */
+
+/** Maximum supported SPROM image size */
+#define SPROM_SZ_MAX SPROM_SZ_R11
+
+#define SPROM_SIG_NONE 0x0
+#define SPROM_SIG_NONE_OFF 0x0
+
+/** SPROM signature (rev 4) */
+#define SPROM_SIG_R4 0x5372
+#define SPROM_SIG_R4_OFF 64 /**< SPROM signature offset (rev 4) */
+
+/** SPROM signature (rev 8, 9) */
+#define SPROM_SIG_R8_9 SPROM_SIG_R4
+#define SPROM_SIG_R8_9_OFF 128 /**< SPROM signature offset (rev 8-9) */
+
+/** SPROM signature (rev 10) */
+#define SPROM_SIG_R10 SPROM_SIG_R4
+#define SPROM_SIG_R10_OFF 438 /**< SPROM signature offset (rev 10) */
+
+/** SPROM signature (rev 11) */
+#define SPROM_SIG_R11 0x0634
+#define SPROM_SIG_R11_OFF 128 /**< SPROM signature offset (rev 11) */
+
+
+#endif /* _BHND_NVRAM_SPROMREG_H_ */
Index: head/sys/dev/bhnd/nvram/bhnd_spromvar.h
===================================================================
--- head/sys/dev/bhnd/nvram/bhnd_spromvar.h
+++ head/sys/dev/bhnd/nvram/bhnd_spromvar.h
@@ -0,0 +1,58 @@
+/*-
+ * Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BHND_NVRAM_BHND_SPROM_H_
+#define _BHND_NVRAM_BHND_SPROM_H_
+
+struct bhnd_sprom {
+ device_t dev; /**< sprom parent device */
+
+ uint8_t sp_rev; /**< sprom revision */
+
+ struct bhnd_resource *sp_res; /**< sprom resource. */
+ bus_size_t sp_res_off; /**< offset to sprom image */
+
+ uint8_t *sp_shadow; /**< sprom shadow */
+ bus_size_t sp_size_max; /**< maximum possible sprom length */
+ size_t sp_size; /**< shadow size */
+ size_t sp_capacity; /**< shadow buffer capacity */
+};
+
+int bhnd_sprom_init(struct bhnd_sprom *sprom, struct bhnd_resource *r,
+ bus_size_t offset);
+void bhnd_sprom_fini(struct bhnd_sprom *sprom);
+
+int bhnd_sprom_getvar(struct bhnd_sprom *sc, const char *name, void *buf,
+ size_t *len);
+int bhnd_sprom_setvar(struct bhnd_sprom *sc, const char *name,
+ const void *buf, size_t len);
+
+#endif /* _BHND_NVRAM_BHND_SPROM_H_ */
Index: head/sys/dev/bhnd/nvram/nvram_map
===================================================================
--- head/sys/dev/bhnd/nvram/nvram_map
+++ head/sys/dev/bhnd/nvram/nvram_map
@@ -0,0 +1,1445 @@
+#-
+# Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
+# Copyright (C) 2008-2015, Broadcom Corporation.
+# All Rights Reserved.
+#
+# The contents of this file (variable names, descriptions, and offsets) were
+# extracted or derived from Broadcom's ISC-licensed sources.
+#
+# 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.
+#
+# $FreeBSD$
+
+#
+# NVRAM variable definitions and revision-specific SPROM offsets.
+#
+# Processed by nvram_map_gen.awk to produce bhnd_nvram_map.h
+#
+# NOTE: file was originally generated automatically by using libclang
+# to analyze and extract format information and descriptions from Broadcom's
+# available ISC-licensed CIS and SROM code and associated headers.
+#
+
+# Antennas available
+u8 aa2g {
+ srom 1-3 0x5C (&0x30, >>4)
+ srom 4-7 0x5D
+ srom 8-10 0x9D
+ srom >= 11 0xA1
+}
+u8 aa5g {
+ srom 1-3 0x5C (&0xC0, >>6)
+ srom 4-7 0x5C
+ srom 8-10 0x9C
+ srom >= 11 0xA0
+}
+
+# ACPHY PA trimming parameters: 40
+u16[12] pa5gbw40a0 {
+ srom >= 11 0x110
+}
+
+# ACPHY PA trimming parameters: 80
+u16[12] pa5gbw80a0 {
+ srom >= 11 0x138
+}
+
+# ACPHY PA trimming parameters: 40/80
+u16[12] pa5gbw4080a0 {
+ srom >= 11 0x138
+}
+u16[12] pa5gbw4080a1 {
+ srom >= 11 u16 0xB6, u16 0xBC, u16 0xCE, u16 0xD4, u16[8] 0x128
+}
+
+# ACPHY PA trimming parameters: CCK
+u16[3] pa2gccka0 {
+ srom >= 11 0x102
+}
+
+# ACPHY Power-per-rate 2gpo
+u16 dot11agofdmhrbw202gpo {
+ srom >= 11 0x15C
+}
+u16 ofdmlrbw202gpo {
+ srom >= 11 0x15E
+}
+
+# ACPHY Power-per-rate 5gpo
+u32 mcsbw805glpo {
+ srom >= 11 0x168
+}
+u32 mcsbw805gmpo {
+ srom >= 11 0x178
+}
+u32 mcsbw805ghpo {
+ srom >= 11 0x188
+}
+u16 mcslr5glpo {
+ srom >= 11 0x190 (&0xFFF)
+}
+u16 mcslr5gmpo {
+ srom >= 11 0x192
+}
+u16 mcslr5ghpo {
+ srom >= 11 0x194
+}
+
+# ACPHY Power-per-rate sbpo
+u16 sb20in40hrpo {
+ srom >= 11 0x196
+}
+u16 sb20in80and160hr5glpo {
+ srom >= 11 0x198
+}
+u16 sb40and80hr5glpo {
+ srom >= 11 0x19A
+}
+u16 sb20in80and160hr5gmpo {
+ srom >= 11 0x19C
+}
+u16 sb40and80hr5gmpo {
+ srom >= 11 0x19E
+}
+u16 sb20in80and160hr5ghpo {
+ srom >= 11 0x1A0
+}
+u16 sb40and80hr5ghpo {
+ srom >= 11 0x1A2
+}
+u16 sb20in40lrpo {
+ srom >= 11 0x1A4
+}
+u16 sb20in80and160lr5glpo {
+ srom >= 11 0x1A6
+}
+u16 sb40and80lr5glpo {
+ srom >= 11 0x1A8
+}
+u16 sb20in80and160lr5gmpo {
+ srom >= 11 0x1AA
+}
+u16 sb40and80lr5gmpo {
+ srom >= 11 0x1AC
+}
+u16 sb20in80and160lr5ghpo {
+ srom >= 11 0x1AE
+}
+u16 sb40and80lr5ghpo {
+ srom >= 11 0x1B0
+}
+u16 dot11agduphrpo {
+ srom >= 11 0x1B2
+}
+u16 dot11agduplrpo {
+ srom >= 11 0x1B4
+}
+
+# Antenna gain
+u8 ag0 {
+ srom 1-3 0x75
+ srom 4-7 0x5F
+ srom 8-10 0x9F
+}
+u8 ag1 {
+ srom 1-3 0x74
+ srom 4-7 0x5E
+ srom 8-10 0x9E
+}
+u8 ag2 {
+ srom 4-7 0x61
+ srom 8-10 0xA1
+}
+u8 ag3 {
+ srom 4-7 0x60
+ srom 8-10 0xA0
+}
+
+u8 agbg0 {
+ srom >= 11 0xA2
+}
+u8 agbg1 {
+ srom >= 11 0xA3
+}
+u8 agbg2 {
+ srom >= 11 0xA4
+}
+u8 aga0 {
+ srom >= 11 0xA5
+}
+u8 aga1 {
+ srom >= 11 0xA6
+}
+u8 aga2 {
+ srom >= 11 0xA7
+}
+
+# board flags
+u32 boardflags {
+ srom 1 u16 0x72
+ srom 2 u16 0x72 | u16 0x38 (<<16)
+ srom 3 u16 0x72 | u16 0x7A (<<16)
+ srom 4 0x44
+ srom 5-7 0x4A
+ srom >= 8 0x84
+}
+u32 boardflags2 {
+ srom 4 0x48
+ srom 5-7 0x4E
+ srom >= 8 0x88
+}
+u32 boardflags3 {
+ srom >= 11 0x8C
+}
+
+# board serial number, independent of mac addr
+u16 boardnum {
+ srom 1-2 0x4C
+ srom 3 0x4E
+ srom 4 0x50
+ srom 5-7 0x56
+ srom 8-10 0x90
+ srom >= 11 0x94
+}
+
+# One byte board revision
+u16 boardrev {
+ srom 1-3 u8 0x5D
+ srom 4-7 0x42
+ srom >= 8 0x82
+}
+
+# 2 bytes; boardtype
+u16 boardtype {
+ srom >= 2 0x4
+}
+
+# Default country code (sromrev == 1)
+u8 cc {
+ srom 1 0x5C (&0xF)
+}
+
+# 2 bytes each
+# CCK Power offsets for 20 MHz rates (11, 5.5, 2, 1Mbps)
+# cckbw202gpo cckbw20ul2gpo
+#
+u16 cckbw202gpo {
+ srom 9-10 0x140
+ srom >= 11 0x150
+}
+u16 cckbw20ul2gpo {
+ srom 9-10 0x142
+ srom >= 11 0x152
+}
+
+# Country code (2 bytes ascii + 1 byte cctl)
+# in rev 2
+#
+char[2] ccode {
+ sfmt ccode
+ srom 0-3 0x76
+ srom 4 0x52
+ srom 5-7 0x44
+ srom 8-10 0x92
+ srom >= 11 0x96
+}
+
+# 2 byte; txchain, rxchain
+u8 txchain {
+ all1 ignore
+ srom 4-7 0x7B (&0xF)
+ srom 8-10 0xA3 (&0xF)
+ srom >= 11 0xA9 (&0xF)
+}
+u8 rxchain {
+ all1 ignore
+ srom 4-7 0x7B (&0xF0, >>4)
+ srom 8-10 0xA3 (&0xF0, >>4)
+ srom >= 11 0xA9 (&0xF0, >>4)
+}
+u16 antswitch {
+ all1 ignore
+ srom 4-7 u8 0x7A
+ srom 8-10 u8 0xA2
+ srom >= 11 u8 0xA8
+}
+
+# PCI device id
+private u16 devid {
+ srom >= 8 u16 0x60
+}
+
+u8 elna2g {
+ srom 8-10 0xBB
+}
+
+u8 elna5g {
+ srom 8-10 0xBA
+}
+
+# 11n front-end specification
+u8 antswctl2g {
+ srom 8-10 0xAE (&0xF8, >>3)
+}
+u8 triso2g {
+ srom 8-10 0xAE (&0x7)
+}
+u8 pdetrange2g {
+ srom 8-10 0xAF (&0xF8, >>3)
+}
+u8 extpagain2g {
+ srom 8-10 0xAF (&0x6, >>1)
+}
+u8 tssipos2g {
+ srom 8-10 0xAF (&0x1)
+}
+u8 antswctl5g {
+ srom 8-10 0xB0 (&0xF8, >>3)
+}
+u8 triso5g {
+ srom 8-10 0xB0 (&0x7)
+}
+u8 pdetrange5g {
+ srom 8-10 0xB1 (&0xF8, >>3)
+}
+u8 extpagain5g {
+ srom 8-10 0xB1 (&0x6, >>1)
+}
+u8 tssipos5g {
+ srom 8-10 0xB1 (&0x1)
+}
+
+# FEM config
+u8 femctrl {
+ sfmt decimal
+ srom >= 11 0xAA (&0xF8, >>3)
+}
+u8 papdcap2g {
+ sfmt decimal
+ srom >= 11 0xAA (&0x4, >>2)
+}
+u8 tworangetssi2g {
+ sfmt decimal
+ srom >= 11 0xAA (&0x2, >>1)
+}
+u8 pdgain2g {
+ sfmt decimal
+ srom >= 11 u16 0xAA (&0x1F0, >>4)
+}
+u8 epagain2g {
+ sfmt decimal
+ srom >= 11 0xAB (&0xE, >>1)
+}
+u8 tssiposslope2g {
+ sfmt decimal
+ srom >= 11 0xAB (&0x1)
+}
+u8 gainctrlsph {
+ sfmt decimal
+ srom >= 11 0xAC (&0xF8, >>3)
+}
+u8 papdcap5g {
+ sfmt decimal
+ srom >= 11 0xAC (&0x4, >>2)
+}
+u8 tworangetssi5g {
+ sfmt decimal
+ srom >= 11 0xAC (&0x2, >>1)
+}
+u8 pdgain5g {
+ sfmt decimal
+ srom >= 11 u16 0xAC (&0x1F0, >>4)
+}
+u8 epagain5g {
+ sfmt decimal
+ srom >= 11 0xAD (&0xE, >>1)
+}
+u8 tssiposslope5g {
+ sfmt decimal
+ srom >= 11 0xAD (&0x1)
+}
+
+# LED duty cycle
+u8[2] leddc {
+ sfmt led_dc
+ all1 ignore
+ srom 3 0x7C
+ srom 4 0x5A
+ srom 5-7 0x5A
+ srom 8-10 0x9A
+ srom >= 11 0x9E
+}
+
+# LED set
+u8 ledbh0 {
+ all1 ignore
+ srom 1-3 0x65
+ srom 4 0x57
+ srom 5-7 0x77
+ srom 8-10 0x97
+ srom >= 11 0x9B
+}
+u8 ledbh1 {
+ all1 ignore
+ srom 1-3 0x64
+ srom 4 0x56
+ srom 5-7 0x76
+ srom 8-10 0x96
+ srom >= 11 0x9A
+}
+u8 ledbh2 {
+ all1 ignore
+ srom 1-3 0x67
+ srom 4 0x59
+ srom 5-7 0x79
+ srom 8-10 0x99
+ srom >= 11 0x9D
+}
+u8 ledbh3 {
+ all1 ignore
+ srom 1-3 0x66
+ srom 4 0x58
+ srom 5-7 0x78
+ srom 8-10 0x98
+ srom >= 11 0x9C
+}
+
+# 2 bytes total
+# Additional power offset for Legacy Dup40 transmissions.
+# Applied in addition to legofdmbw20ulXpo, X=2g, 5gl, 5gm, or 5gh.
+# LSB nibble: 2G band, MSB nibble: 5G band high subband.
+# leg40dup5ghpo, leg40dup5gmpo, leg40dup5glpo, leg40dup2gpo
+#
+u16 legofdm40duppo {
+ srom 9-10 0x196
+}
+
+# 4 bytes each
+# OFDM power offsets for 20 MHz Legacy rates
+# (54, 48, 36, 24, 18, 12, 9, 6 Mbps)
+# legofdmbw202gpo legofdmbw20ul2gpo
+#
+u32 legofdmbw202gpo {
+ srom 9-10 0x144
+}
+u32 legofdmbw20ul2gpo {
+ srom 9-10 0x148
+}
+
+# 4 bytes each
+# 5G band: OFDM power offsets for 20 MHz Legacy rates
+# (54, 48, 36, 24, 18, 12, 9, 6 Mbps)
+# low subband : legofdmbw205glpo legofdmbw20ul2glpo
+# mid subband :legofdmbw205gmpo legofdmbw20ul2gmpo
+# high subband :legofdmbw205ghpo legofdmbw20ul2ghpo
+#
+u32 legofdmbw205glpo {
+ srom 9-10 0x14C
+}
+u32 legofdmbw20ul5glpo {
+ srom 9-10 0x150
+}
+u32 legofdmbw205gmpo {
+ srom 9-10 0x154
+}
+u32 legofdmbw20ul5gmpo {
+ srom 9-10 0x158
+}
+u32 legofdmbw205ghpo {
+ srom 9-10 0x15C
+}
+u32 legofdmbw20ul5ghpo {
+ srom 9-10 0x160
+}
+
+# mac addr override for the standard CIS LAN_NID
+u8[6] macaddr {
+ sfmt macaddr
+ srom 3 u8 0x4B, u8 0x4A, u8 0x4D, u8 0x4C, u8 0x4F, u8 0x4E
+ srom 4 u8 0x4D, u8 0x4C, u8 0x4F, u8 0x4E, u8 0x51, u8 0x50
+ srom 5-7 u8 0x53, u8 0x52, u8 0x55, u8 0x54, u8 0x57, u8 0x56
+ srom 8-10 u8 0x8D, u8 0x8C, u8 0x8F, u8 0x8E, u8 0x91, u8 0x90
+ srom >= 11 u8 0x91, u8 0x90, u8 0x93, u8 0x92, u8 0x95, u8 0x94
+}
+
+# 4 bytes each
+# mcs 0-7 power-offset. LSB nibble: m0, MSB nibble: m7
+# mcsbw202gpo mcsbw20ul2gpo mcsbw402gpo
+#
+u32 mcsbw202gpo {
+ srom 9-10 0x164
+ srom >= 11 0x154
+}
+u32 mcsbw20ul2gpo {
+ srom 9-10 0x168
+}
+u32 mcsbw402gpo {
+ srom 9-10 0x16C
+ srom >= 11 0x158
+}
+
+# 4 bytes each
+# 5G high subband mcs 0-7 power-offset.
+# LSB nibble: m0, MSB nibble: m7
+# mcsbw205ghpo mcsbw20ul5ghpo mcsbw405ghpo
+#
+u32 mcsbw205ghpo {
+ srom 9-10 0x188
+ srom >= 11 0x180
+}
+u32 mcsbw20ul5ghpo {
+ srom 9-10 0x18C
+}
+u32 mcsbw405ghpo {
+ srom 9-10 0x190
+ srom >= 11 0x184
+}
+
+# 4 bytes each
+# 5G low subband mcs 0-7 power-offset.
+# LSB nibble: m0, MSB nibble: m7
+# mcsbw205glpo mcsbw20ul5glpo mcsbw405glpo
+#
+u32 mcsbw205glpo {
+ srom 9-10 0x170
+ srom >= 11 0x160
+}
+u32 mcsbw20ul5glpo {
+ srom 9-10 0x174
+}
+u32 mcsbw405glpo {
+ srom 9-10 0x178
+ srom >= 11 0x164
+}
+
+# 4 bytes each
+# 5G mid subband mcs 0-7 power-offset.
+# LSB nibble: m0, MSB nibble: m7
+# mcsbw205gmpo mcsbw20ul5gmpo mcsbw405gmpo
+#
+u32 mcsbw205gmpo {
+ srom 9-10 0x17C
+ srom >= 11 0x170
+}
+u32 mcsbw20ul5gmpo {
+ srom 9-10 0x180
+}
+u32 mcsbw405gmpo {
+ srom 9-10 0x184
+ srom >= 11 0x174
+}
+
+# 2 bytes total
+# mcs-32 power offset for each band/subband.
+# LSB nibble: 2G band, MSB nibble:
+# mcs322ghpo, mcs325gmpo, mcs325glpo, mcs322gpo
+#
+u16 mcs32po {
+ srom 9-10 0x194
+}
+
+u8 measpower {
+ srom 8-10 0xB4 (&0xFE, >>1)
+ srom >= 11 0xB0 (&0xFE, >>1)
+}
+u8 measpower1 {
+ srom 8-10 0xBF (&0x7F)
+ srom >= 11 0xBB (&0x7F)
+}
+u8 measpower2 {
+ srom 8-10 u16 0xBE (&0x3F80, >>7)
+ srom >= 11 u16 0xBA (&0x3F80, >>7)
+}
+u16 rawtempsense {
+ srom 8-10 0xB4 (&0x1FF)
+ srom >= 11 0xB0 (&0x1FF)
+}
+
+u8 noiselvl2ga0 {
+ sfmt decimal
+ srom 8-10 0x1AB (&0x1F)
+ srom >= 11 0x1BD (&0x1F)
+}
+u8 noiselvl2ga1 {
+ sfmt decimal
+ srom 8-10 u16 0x1AA (&0x3E0, >>5)
+ srom >= 11 u16 0x1BC (&0x3E0, >>5)
+}
+u8 noiselvl2ga2 {
+ sfmt decimal
+ srom 8-10 0x1AA (&0x7C, >>2)
+ srom >= 11 0x1BC (&0x7C, >>2)
+}
+u8[4] noiselvl5ga0 {
+ sfmt decimal
+ srom >= 11 u8 0x1BF (&0x1F), u8 0x1C1 (&0x1F), u8 0x1C3 (&0x1F), u8 0x1C5 (&0x1F)
+}
+u8[4] noiselvl5ga1 {
+ sfmt decimal
+ srom >= 11 u16[4] 0x1BE (&0x3E0, >>5)
+}
+u8[4] noiselvl5ga2 {
+ sfmt decimal
+ srom >= 11 u8 0x1BE (&0x7C, >>2), u8 0x1C0 (&0x7C, >>2), u8 0x1C2 (&0x7C, >>2), u8 0x1C4 (&0x7C, >>2)
+}
+
+# paparambwver
+u8 paparambwver {
+ sfmt decimal
+ srom >= 11 0x190 (&0xF0, >>4)
+}
+
+# PA parameters: 8 (sromrev == 1)
+# or 9 (sromrev > 1) bytes
+#
+u16 pa0b0 {
+ sfmt decimal
+ srom 1-3 0x5E
+ srom 8-10 0xC2
+}
+u16 pa0b1 {
+ sfmt decimal
+ srom 1-3 0x60
+ srom 8-10 0xC4
+}
+u16 pa0b2 {
+ sfmt decimal
+ srom 1-3 0x62
+ srom 8-10 0xC6
+}
+u8 pa0itssit {
+ sfmt decimal
+ srom 1-3 0x71
+ srom 8-10 0xC0
+}
+u8 pa0maxpwr {
+ sfmt decimal
+ srom 1-3 0x69
+ srom 8-10 0xC1
+}
+u8 opo {
+ srom 2-3 0x79
+ srom 8-10 0x143
+}
+
+# 5G PA params
+u16 pa1b0 {
+ sfmt decimal
+ srom 1-3 0x6A
+ srom 8-10 0xCC
+}
+u16 pa1b1 {
+ sfmt decimal
+ srom 1-3 0x6C
+ srom 8-10 0xCE
+}
+u16 pa1b2 {
+ sfmt decimal
+ srom 1-3 0x6E
+ srom 8-10 0xD0
+}
+u16 pa1lob0 {
+ sfmt decimal
+ srom 2-3 0x3C
+ srom 8-10 0xD2
+}
+u16 pa1lob1 {
+ sfmt decimal
+ srom 2-3 0x3E
+ srom 8-10 0xD4
+}
+u16 pa1lob2 {
+ sfmt decimal
+ srom 2-3 0x40
+ srom 8-10 0xD6
+}
+u16 pa1hib0 {
+ sfmt decimal
+ srom 2-3 0x42
+ srom 8-10 0xD8
+}
+u16 pa1hib1 {
+ sfmt decimal
+ srom 2-3 0x44
+ srom 8-10 0xDA
+}
+u16 pa1hib2 {
+ sfmt decimal
+ srom 2-3 0x46
+ srom 8-10 0xDC
+}
+u8 pa1itssit {
+ sfmt decimal
+ srom 1-3 0x70
+ srom 8-10 0xC8
+}
+u8 pa1maxpwr {
+ sfmt decimal
+ srom 1-3 0x68
+ srom 8-10 0xC9
+}
+u8 pa1lomaxpwr {
+ sfmt decimal
+ srom 2-3 0x3A
+ srom 8-10 0xCA
+}
+u8 pa1himaxpwr {
+ sfmt decimal
+ srom 2-3 0x3B
+ srom 8-10 0xCB
+}
+
+u16 pdoffset40ma0 {
+ srom >= 11 0xCA
+}
+u16 pdoffset40ma1 {
+ srom >= 11 0xCC
+}
+u16 pdoffset40ma2 {
+ srom >= 11 0xCE
+}
+u16 pdoffset80ma0 {
+ srom >= 11 0xD0
+}
+u16 pdoffset80ma1 {
+ srom >= 11 0xD2
+}
+u16 pdoffset80ma2 {
+ srom >= 11 0xD4
+}
+
+u8 pdoffset2g40ma0 {
+ srom >= 11 0xC9 (&0xF)
+}
+u8 pdoffset2g40ma1 {
+ srom >= 11 0xC9 (&0xF0, >>4)
+}
+u8 pdoffset2g40ma2 {
+ srom >= 11 0xC8 (&0xF)
+}
+u8 pdoffset2g40mvalid {
+ srom >= 11 0xC8 (&0x80, >>7)
+}
+
+# 40Mhz channel 2g/5g power offset
+u16 bw40po {
+ srom 4-7 0x18E
+ srom 8 0x196
+}
+
+# 40Mhz channel dup 2g/5g power offset
+u16 bwduppo {
+ srom 4-7 0x190
+ srom 8 0x198
+}
+
+# cck2g/ofdm2g/ofdm5g power offset
+u16 cck2gpo {
+ srom 4-7 0x138
+ srom 8 0x140
+}
+u32 ofdm2gpo {
+ srom 4-7 0x13A
+ srom 8 0x142
+}
+u32 ofdm5gpo {
+ srom 4-7 0x13E
+ srom 8 0x146
+}
+u32 ofdm5glpo {
+ srom 4-7 0x142
+ srom 8 0x14A
+}
+u32 ofdm5ghpo {
+ srom 4-7 0x146
+ srom 8 0x14E
+}
+
+# cdd2g/5g power offset
+u16 cddpo {
+ srom 4-7 0x18A
+ srom 8 0x192
+}
+
+# mcs2g power offset
+u16 mcs2gpo0 {
+ srom 4-7 0x14A
+ srom 8 0x152
+}
+u16 mcs2gpo1 {
+ srom 4-7 0x14C
+ srom 8 0x154
+}
+u16 mcs2gpo2 {
+ srom 4-7 0x14E
+ srom 8 0x156
+}
+u16 mcs2gpo3 {
+ srom 4-7 0x150
+ srom 8 0x158
+}
+u16 mcs2gpo4 {
+ srom 4-7 0x152
+ srom 8 0x15A
+}
+u16 mcs2gpo5 {
+ srom 4-7 0x154
+ srom 8 0x15C
+}
+u16 mcs2gpo6 {
+ srom 4-7 0x156
+ srom 8 0x15E
+}
+u16 mcs2gpo7 {
+ srom 4-7 0x158
+ srom 8 0x160
+}
+
+# mcs5g low-high band power offset
+u16 mcs5glpo0 {
+ srom 4-7 0x16A
+ srom 8 0x172
+}
+u16 mcs5glpo1 {
+ srom 4-7 0x16C
+ srom 8 0x174
+}
+u16 mcs5glpo2 {
+ srom 4-7 0x16E
+ srom 8 0x176
+}
+u16 mcs5glpo3 {
+ srom 4-7 0x170
+ srom 8 0x178
+}
+u16 mcs5glpo4 {
+ srom 4-7 0x172
+ srom 8 0x17A
+}
+u16 mcs5glpo5 {
+ srom 4-7 0x174
+ srom 8 0x17C
+}
+u16 mcs5glpo6 {
+ srom 4-7 0x176
+ srom 8 0x17E
+}
+u16 mcs5glpo7 {
+ srom 4-7 0x178
+ srom 8 0x180
+}
+u16 mcs5ghpo0 {
+ srom 4-7 0x17A
+ srom 8 0x182
+}
+u16 mcs5ghpo1 {
+ srom 4-7 0x17C
+ srom 8 0x184
+}
+u16 mcs5ghpo2 {
+ srom 4-7 0x17E
+ srom 8 0x186
+}
+u16 mcs5ghpo3 {
+ srom 4-7 0x180
+ srom 8 0x188
+}
+u16 mcs5ghpo4 {
+ srom 4-7 0x182
+ srom 8 0x18A
+}
+u16 mcs5ghpo5 {
+ srom 4-7 0x184
+ srom 8 0x18C
+}
+u16 mcs5ghpo6 {
+ srom 4-7 0x186
+ srom 8 0x18E
+}
+u16 mcs5ghpo7 {
+ srom 4-7 0x188
+ srom 8 0x190
+}
+
+# mcs5g mid band power offset
+u16 mcs5gpo0 {
+ srom 4-7 0x15A
+ srom 8 0x162
+}
+u16 mcs5gpo1 {
+ srom 4-7 0x15C
+ srom 8 0x164
+}
+u16 mcs5gpo2 {
+ srom 4-7 0x15E
+ srom 8 0x166
+}
+u16 mcs5gpo3 {
+ srom 4-7 0x160
+ srom 8 0x168
+}
+u16 mcs5gpo4 {
+ srom 4-7 0x162
+ srom 8 0x16A
+}
+u16 mcs5gpo5 {
+ srom 4-7 0x164
+ srom 8 0x16C
+}
+u16 mcs5gpo6 {
+ srom 4-7 0x166
+ srom 8 0x16E
+}
+u16 mcs5gpo7 {
+ srom 4-7 0x168
+ srom 8 0x170
+}
+
+# stbc2g/5g power offset
+u16 stbcpo {
+ srom 4-7 0x18C
+ srom 8 0x194
+}
+
+u8 regrev {
+ srom 3 0x78
+ srom 4 0x55
+ srom 5-7 0x47
+ srom 8-10 0x95
+ srom >= 11 0x99
+}
+
+# 4328 2G RSSI mid pt sel & board switch arch,
+# 2 bytes, rev 3.
+#
+u8 rssismf2g {
+ srom 3 0x51 (&0xF)
+ srom 8-10 0xA5 (&0xF)
+}
+u8 rssismc2g {
+ srom 3 0x51 (&0xF0, >>4)
+ srom 8-10 0xA5 (&0xF0, >>4)
+}
+u8 rssisav2g {
+ srom 3 0x50 (&0x7)
+ srom 8-10 0xA4 (&0x7)
+}
+u8 bxa2g {
+ srom 3 0x50 (&0x18, >>3)
+ srom 8-10 0xA4 (&0x18, >>3)
+}
+
+# 4328 5G RSSI mid pt sel & board switch arch,
+# 2 bytes, rev 3.
+#
+u8 rssismf5g {
+ srom 3 0x53 (&0xF)
+ srom 8-10 0xA7 (&0xF)
+}
+u8 rssismc5g {
+ srom 3 0x53 (&0xF0, >>4)
+ srom 8-10 0xA7 (&0xF0, >>4)
+}
+u8 rssisav5g {
+ srom 3 0x52 (&0x7)
+ srom 8-10 0xA6 (&0x7)
+}
+u8 bxa5g {
+ srom 3 0x52 (&0x18, >>3)
+ srom 8-10 0xA6 (&0x18, >>3)
+}
+
+u8 rxgainerr2ga0 {
+ srom 8-10 0x19B (&0x3F)
+ srom >= 11 0x1C7 (&0x3F)
+}
+u8 rxgainerr2ga1 {
+ srom 8-10 u16 0x19A (&0x7C0, >>6)
+ srom >= 11 u16 0x1C6 (&0x7C0, >>6)
+}
+u8 rxgainerr2ga2 {
+ srom 8-10 0x19A (&0xF8, >>3)
+ srom >= 11 0x1C6 (&0xF8, >>3)
+}
+u8[4] rxgainerr5ga0 {
+ srom >= 11 u8 0x1C9 (&0x3F), u8 0x1CB (&0x3F), u8 0x1CD (&0x3F), u8 0x1CF (&0x3F)
+}
+u8[4] rxgainerr5ga1 {
+ srom >= 11 u16[4] 0x1C8 (&0x7C0, >>6)
+}
+u8[4] rxgainerr5ga2 {
+ srom >= 11 u8 0x1C8 (&0xF8, >>3), u8 0x1CA (&0xF8, >>3), u8 0x1CC (&0xF8, >>3), u8 0x1CE (&0xF8, >>3)
+}
+u8 rxgainerr5gha0 {
+ srom 8-10 0x1A1 (&0x3F)
+}
+u8 rxgainerr5gha1 {
+ srom 8-10 u16 0x1A0 (&0x7C0, >>6)
+}
+u8 rxgainerr5gha2 {
+ srom 8-10 0x1A0 (&0xF8, >>3)
+}
+u8 rxgainerr5gla0 {
+ srom 8-10 0x19D (&0x3F)
+}
+u8 rxgainerr5gla1 {
+ srom 8-10 u16 0x19C (&0x7C0, >>6)
+}
+u8 rxgainerr5gla2 {
+ srom 8-10 0x19C (&0xF8, >>3)
+}
+u8 rxgainerr5gma0 {
+ srom 8-10 0x19F (&0x3F)
+}
+u8 rxgainerr5gma1 {
+ srom 8-10 u16 0x19E (&0x7C0, >>6)
+}
+u8 rxgainerr5gma2 {
+ srom 8-10 0x19E (&0xF8, >>3)
+}
+u8 rxgainerr5gua0 {
+ srom 8-10 0x1A3 (&0x3F)
+}
+u8 rxgainerr5gua1 {
+ srom 8-10 u16 0x1A2 (&0x7C0, >>6)
+}
+u8 rxgainerr5gua2 {
+ srom 8-10 0x1A2 (&0xF8, >>3)
+}
+
+# 4328 2G RX power offset
+i8 rxpo2g {
+ sfmt decimal
+ srom 3 0x5B
+ srom 8-10 0xAD
+}
+
+# 4328 5G RX power offset
+i8 rxpo5g {
+ sfmt decimal
+ srom 3 0x5A
+ srom 8-10 0xAC
+}
+
+u16 subband5gver {
+ srom 8-10 u8 0x1A5 (&0x7)
+ srom >= 11 0xD6
+}
+
+# 2 bytes
+# byte1 tempthresh
+# byte2 period(msb 4 bits) | hysterisis(lsb 4 bits)
+#
+u8 tempthresh {
+ srom 8-10 0xB2
+ srom >= 11 0xAE
+}
+u8 temps_period {
+ sfmt decimal
+ srom 8-10 0xBC (&0xF)
+ srom >= 11 0xB8 (&0xF)
+}
+u8 temps_hysteresis {
+ sfmt decimal
+ srom 8-10 0xBC (&0xF0, >>4)
+ srom >= 11 0xB8 (&0xF0, >>4)
+}
+u8 tempoffset {
+ sfmt decimal
+ srom 8-10 0xB3
+ srom >= 11 0xAF
+}
+u8 tempsense_slope {
+ srom 8-10 0xB7
+ srom >= 11 0xB3
+}
+u8 tempcorrx {
+ srom 8-10 0xB6 (&0xFC, >>2)
+ srom >= 11 0xB2 (&0xFC, >>2)
+}
+u8 tempsense_option {
+ srom 8-10 0xB6 (&0x3)
+ srom >= 11 0xB2 (&0x3)
+}
+u8 phycal_tempdelta {
+ sfmt decimal
+ srom 8-10 0xBD
+ srom >= 11 0xB9
+}
+
+# 4328 2G TR isolation, 1 byte
+u8 tri2g {
+ srom 3 0x55
+ srom 8-10 0xA9
+}
+
+# 4328 5G TR isolation, 3 bytes
+u8 tri5gl {
+ srom 3 0x57
+ srom 8-10 0xAB
+}
+u8 tri5g {
+ srom 3 0x54
+ srom 8-10 0xA8
+}
+u8 tri5gh {
+ srom 3 0x56
+ srom 8-10 0xAA
+}
+
+# phy txbf rpcalvars
+u16 rpcal2g {
+ srom >= 11 0x16C
+}
+u16 rpcal5gb0 {
+ srom >= 11 0x16E
+}
+u16 rpcal5gb1 {
+ srom >= 11 0x17C
+}
+u16 rpcal5gb2 {
+ srom >= 11 0x17E
+}
+u16 rpcal5gb3 {
+ srom >= 11 0x18C
+}
+
+# Crystal frequency in kilohertz
+u32 xtalfreq {
+ sfmt decimal
+ srom >= 11 u16 0xB4
+}
+
+# N-PHY tx power workaround
+u8 txpid2ga0 {
+ srom 4-7 0x63
+}
+u8 txpid2ga1 {
+ srom 4-7 0x62
+}
+u8 txpid2ga2 {
+ srom 4-7 0x65
+}
+u8 txpid2ga3 {
+ srom 4-7 0x64
+}
+u8 txpid5ga0 {
+ srom 4-7 0x67
+}
+u8 txpid5ga1 {
+ srom 4-7 0x66
+}
+u8 txpid5ga2 {
+ srom 4-7 0x69
+}
+u8 txpid5ga3 {
+ srom 4-7 0x68
+}
+u8 txpid5gha0 {
+ srom 4-7 0x6F
+}
+u8 txpid5gha1 {
+ srom 4-7 0x6E
+}
+u8 txpid5gha2 {
+ srom 4-7 0x71
+}
+u8 txpid5gha3 {
+ srom 4-7 0x70
+}
+u8 txpid5gla0 {
+ srom 4-7 0x6B
+}
+u8 txpid5gla1 {
+ srom 4-7 0x6A
+}
+u8 txpid5gla2 {
+ srom 4-7 0x6D
+}
+u8 txpid5gla3 {
+ srom 4-7 0x6C
+}
+
+u16 cckPwrOffset {
+ srom 10 0x1B4
+}
+u8[6] et1macaddr {
+ sfmt macaddr
+ srom 0-2 u8 0x55, u8 0x54, u8 0x57, u8 0x56, u8 0x59, u8 0x58
+}
+u8 eu_edthresh2g {
+ srom 8 0x1A9
+ srom 9 0x199
+ srom 10 0x199
+ srom 11 0x1D1
+}
+u8 eu_edthresh5g {
+ srom 8 0x1A8
+ srom 9 0x198
+ srom 10 0x198
+ srom 11 0x1D0
+}
+u8 freqoffset_corr {
+ srom 8-10 0xB9 (&0xF)
+}
+u8 hw_iqcal_en {
+ srom 8-10 0xB9 (&0x20, >>5)
+}
+u8[6] il0macaddr {
+ sfmt macaddr
+ srom 0-2 u8 0x49, u8 0x48, u8 0x51, u8 0x50, u8 0x53, u8 0x52
+}
+u8 iqcal_swp_dis {
+ srom 8-10 0xB9 (&0x10, >>4)
+}
+
+u8 noisecaloffset {
+ srom 8-9 0x1B5
+}
+u8 noisecaloffset5g {
+ srom 8-9 0x1B4
+}
+u8 noiselvl5gha0 {
+ srom 8-10 0x1B1 (&0x1F)
+}
+u8 noiselvl5gha1 {
+ srom 8-10 u16 0x1B0 (&0x3E0, >>5)
+}
+u8 noiselvl5gha2 {
+ srom 8-10 0x1B0 (&0x7C, >>2)
+}
+u8 noiselvl5gla0 {
+ srom 8-10 0x1AD (&0x1F)
+}
+u8 noiselvl5gla1 {
+ srom 8-10 u16 0x1AC (&0x3E0, >>5)
+}
+u8 noiselvl5gla2 {
+ srom 8-10 0x1AC (&0x7C, >>2)
+}
+u8 noiselvl5gma0 {
+ srom 8-10 0x1AF (&0x1F)
+}
+u8 noiselvl5gma1 {
+ srom 8-10 u16 0x1AE (&0x3E0, >>5)
+}
+u8 noiselvl5gma2 {
+ srom 8-10 0x1AE (&0x7C, >>2)
+}
+u8 noiselvl5gua0 {
+ srom 8-10 0x1B3 (&0x1F)
+}
+u8 noiselvl5gua1 {
+ srom 8-10 u16 0x1B2 (&0x3E0, >>5)
+}
+u8 noiselvl5gua2 {
+ srom 8-10 0x1B2 (&0x7C, >>2)
+}
+
+u8 pcieingress_war {
+ srom 8-10 0x1A7 (&0xF)
+}
+
+u8 pdoffsetcckma0 {
+ srom >= 11 0x18F (&0xF)
+}
+u8 pdoffsetcckma1 {
+ srom >= 11 0x18F (&0xF0, >>4)
+}
+u8 pdoffsetcckma2 {
+ srom >= 11 0x18E (&0xF)
+}
+
+u8 sar2g {
+ srom 9-10 0x1A9
+ srom >= 11 0x1BB
+}
+u8 sar5g {
+ srom 9-10 0x1A8
+ srom >= 11 0x1BA
+}
+
+u16 subvid {
+ srom >= 2 0x6
+}
+
+u32[5] swctrlmap_2g {
+ srom 10 u32[4] 0x1B8, u16 0x1C8
+}
+
+u16 tssifloor2g {
+ srom >= 11 0xBE (&0x3FF)
+}
+u16[4] tssifloor5g {
+ srom >= 11 0xC0 (&0x3FF)
+}
+
+u8 txidxcap2g {
+ srom >= 11 u16 0x1A8 (&0xFF0, >>4)
+}
+u8 txidxcap5g {
+ srom >= 11 u16 0x1AC (&0xFF0, >>4)
+}
+
+#
+# Any variables defined within a `struct` block will be interpreted relative to
+# the provided array of SPROM base addresses; this is used to define
+# a common layout defined at the given base addresses.
+#
+# To produce SPROM variable names matching those used in the Broadcom HND
+# ASCII 'key=value\0' NVRAM, the index number of the variable's
+# struct instance will be appended (e.g., given a variable of noiselvl5ga, the
+# generated variable instances will be named noiselvl5ga0, noiselvl5ga1,
+# noiselvl5ga2, noiselvl5ga3 ...)
+#
+
+# PHY chain[0-4] parameters
+struct phy_chains[] {
+ srom 4-7 [0x080, 0x0AE, 0x0DC, 0x10A]
+ srom 8-10 [0x0C0, 0x0E0, 0x100, 0x120]
+ srom >= 11 [0x0D8, 0x100, 0x128]
+
+ # AC-PHY PA parameters
+ u8[4] maxp5ga {
+ srom 4-7 u8 0xB
+ srom 8-10 u8 0x9
+ srom >= 11 u8 0xD, u8 0xC, u8 0xF, u8 0xE
+ }
+ u16[3] pa2ga {
+ srom >= 11 0x2
+ }
+ u8 maxp2ga {
+ srom 4-7 0x1
+ srom 8-10 0x1
+ srom >= 11 0x1
+ }
+ u16[12] pa5ga {
+ srom >= 11 0x10
+ }
+
+ # AC-PHY rxgains
+ u8 rxgains5ghtrelnabypa {
+ srom >= 11 0x8 (&0x80, >>7)
+ }
+ u8 rxgains5ghelnagaina {
+ srom >= 11 0x8 (&0x7)
+ }
+ u8 rxgains5gelnagaina {
+ srom >= 11 0xA (&0x7)
+ }
+ u8 rxgains5gmtrelnabypa {
+ srom >= 11 0x9 (&0x80, >>7)
+ }
+ u8 rxgains2gtrelnabypa {
+ srom >= 11 0xB (&0x80, >>7)
+ }
+ u8 rxgains5gmtrisoa {
+ srom >= 11 0x9 (&0x78, >>3)
+ }
+ u8 rxgains5gmelnagaina {
+ srom >= 11 0x9 (&0x7)
+ }
+ u8 rxgains2gelnagaina {
+ srom >= 11 0xB (&0x7)
+ }
+ u8 rxgains5gtrisoa {
+ srom >= 11 0xA (&0x78, >>3)
+ }
+ u8 rxgains5gtrelnabypa {
+ srom >= 11 0xA (&0x80, >>7)
+ }
+ u8 rxgains2gtrisoa {
+ srom >= 11 0xB (&0x78, >>3)
+ }
+ u8 rxgains5ghtrisoa {
+ srom >= 11 0x8 (&0x78, >>3)
+ }
+
+ # 11n PA parameters
+ u16 pa5gw2a {
+ srom 4-7 0x12
+ srom 8-10 0x10
+ }
+ u16 pa5ghw1a {
+ srom 4-7 0x20
+ srom 8-10 0x1A
+ }
+ u16 pa5glw3a {
+ srom 4-7 0x1C
+ }
+ u16 pa5glw1a {
+ srom 4-7 0x18
+ srom 8-10 0x14
+ }
+ u16 pa5gw1a {
+ srom 4-7 0x10
+ srom 8-10 0xE
+ }
+ u16 pa5glw0a {
+ srom 4-7 0x16
+ srom 8-10 0x12
+ }
+ u16 pa5gw3a {
+ srom 4-7 0x14
+ }
+ u16 pa5glw2a {
+ srom 4-7 0x1A
+ srom 8-10 0x16
+ }
+ u16 pa5ghw3a {
+ srom 4-7 0x24
+ }
+ u16 pa5gw0a {
+ srom 4-7 0xE
+ srom 8-10 0xC
+ }
+ u8 maxp5gha {
+ srom 4-7 0xD
+ srom 8-10 0xB
+ }
+ u16 pa5ghw2a {
+ srom 4-7 0x22
+ srom 8-10 0x1C
+ }
+ u16 pa5ghw0a {
+ srom 4-7 0x1E
+ srom 8-10 0x18
+ }
+ u16 pa2gw3a {
+ srom 4-7 0x8
+ }
+ u16 pa2gw2a {
+ srom 4-7 0x6
+ srom 8-10 0x6
+ }
+ u16 pa2gw1a {
+ srom 4-7 0x4
+ srom 8-10 0x4
+ }
+ u16 pa2gw0a {
+ srom 4-7 0x2
+ srom 8-10 0x2
+ }
+ u8 maxp5gla {
+ srom 4-7 0xC
+ srom 8-10 0xA
+ }
+ u8 itt5ga {
+ srom 4-7 0xA
+ srom 8-10 0x8
+ }
+ u8 itt2ga {
+ srom 4-7 0x0
+ srom 8-10 0x0
+ }
+}
Index: head/sys/dev/bhnd/nvram/nvram_subr.c
===================================================================
--- head/sys/dev/bhnd/nvram/nvram_subr.c
+++ head/sys/dev/bhnd/nvram/nvram_subr.c
@@ -0,0 +1,149 @@
+/*-
+ * Copyright (c) 2016 Landon Fuller <landon@landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+
+#include "bhnd_nvram_map_data.h"
+
+/*
+ * CRC-8 lookup table used to checksum SPROM and NVRAM data via
+ * bhnd_nvram_crc8().
+ *
+ * Generated with following parameters:
+ * polynomial: CRC-8 (x^8 + x^7 + x^6 + x^4 + x^2 + 1)
+ * reflected bits: false
+ * reversed: true
+ */
+const uint8_t bhnd_nvram_crc8_tab[] = {
+ 0x00, 0xf7, 0xb9, 0x4e, 0x25, 0xd2, 0x9c, 0x6b, 0x4a, 0xbd, 0xf3,
+ 0x04, 0x6f, 0x98, 0xd6, 0x21, 0x94, 0x63, 0x2d, 0xda, 0xb1, 0x46,
+ 0x08, 0xff, 0xde, 0x29, 0x67, 0x90, 0xfb, 0x0c, 0x42, 0xb5, 0x7f,
+ 0x88, 0xc6, 0x31, 0x5a, 0xad, 0xe3, 0x14, 0x35, 0xc2, 0x8c, 0x7b,
+ 0x10, 0xe7, 0xa9, 0x5e, 0xeb, 0x1c, 0x52, 0xa5, 0xce, 0x39, 0x77,
+ 0x80, 0xa1, 0x56, 0x18, 0xef, 0x84, 0x73, 0x3d, 0xca, 0xfe, 0x09,
+ 0x47, 0xb0, 0xdb, 0x2c, 0x62, 0x95, 0xb4, 0x43, 0x0d, 0xfa, 0x91,
+ 0x66, 0x28, 0xdf, 0x6a, 0x9d, 0xd3, 0x24, 0x4f, 0xb8, 0xf6, 0x01,
+ 0x20, 0xd7, 0x99, 0x6e, 0x05, 0xf2, 0xbc, 0x4b, 0x81, 0x76, 0x38,
+ 0xcf, 0xa4, 0x53, 0x1d, 0xea, 0xcb, 0x3c, 0x72, 0x85, 0xee, 0x19,
+ 0x57, 0xa0, 0x15, 0xe2, 0xac, 0x5b, 0x30, 0xc7, 0x89, 0x7e, 0x5f,
+ 0xa8, 0xe6, 0x11, 0x7a, 0x8d, 0xc3, 0x34, 0xab, 0x5c, 0x12, 0xe5,
+ 0x8e, 0x79, 0x37, 0xc0, 0xe1, 0x16, 0x58, 0xaf, 0xc4, 0x33, 0x7d,
+ 0x8a, 0x3f, 0xc8, 0x86, 0x71, 0x1a, 0xed, 0xa3, 0x54, 0x75, 0x82,
+ 0xcc, 0x3b, 0x50, 0xa7, 0xe9, 0x1e, 0xd4, 0x23, 0x6d, 0x9a, 0xf1,
+ 0x06, 0x48, 0xbf, 0x9e, 0x69, 0x27, 0xd0, 0xbb, 0x4c, 0x02, 0xf5,
+ 0x40, 0xb7, 0xf9, 0x0e, 0x65, 0x92, 0xdc, 0x2b, 0x0a, 0xfd, 0xb3,
+ 0x44, 0x2f, 0xd8, 0x96, 0x61, 0x55, 0xa2, 0xec, 0x1b, 0x70, 0x87,
+ 0xc9, 0x3e, 0x1f, 0xe8, 0xa6, 0x51, 0x3a, 0xcd, 0x83, 0x74, 0xc1,
+ 0x36, 0x78, 0x8f, 0xe4, 0x13, 0x5d, 0xaa, 0x8b, 0x7c, 0x32, 0xc5,
+ 0xae, 0x59, 0x17, 0xe0, 0x2a, 0xdd, 0x93, 0x64, 0x0f, 0xf8, 0xb6,
+ 0x41, 0x60, 0x97, 0xd9, 0x2e, 0x45, 0xb2, 0xfc, 0x0b, 0xbe, 0x49,
+ 0x07, 0xf0, 0x9b, 0x6c, 0x22, 0xd5, 0xf4, 0x03, 0x4d, 0xba, 0xd1,
+ 0x26, 0x68, 0x9f
+};
+
+
+/**
+ * Return the size of type @p dt.
+ *
+ * @param dt NVRAM data type.
+ * @result the byte width of @p dt.
+ */
+size_t
+bhnd_nvram_type_width(bhnd_nvram_dt dt)
+{
+ switch (dt) {
+ case BHND_NVRAM_DT_INT8:
+ case BHND_NVRAM_DT_UINT8:
+ case BHND_NVRAM_DT_CHAR:
+ return (sizeof(uint8_t));
+
+ case BHND_NVRAM_DT_INT16:
+ case BHND_NVRAM_DT_UINT16:
+ return (sizeof(uint16_t));
+
+ case BHND_NVRAM_DT_INT32:
+ case BHND_NVRAM_DT_UINT32:
+ return (sizeof(uint32_t));
+ }
+
+ /* Quiesce gcc4.2 */
+ panic("bhnd nvram data type %u unknown", dt);
+}
+
+
+/**
+ * Return the variable definition for @p varname, if any.
+ *
+ * @param varname variable name
+ *
+ * @retval bhnd_nvram_var If a valid definition for @p varname is found.
+ * @retval NULL If no definition for @p varname is found.
+ */
+const struct bhnd_nvram_var *
+bhnd_nvram_var_defn(const char *varname)
+{
+ size_t min, mid, max;
+ int order;
+
+ /*
+ * Locate the requested variable using a binary search.
+ *
+ * The variable table is guaranteed to be sorted in lexicographical
+ * order (using the 'C' locale for collation rules)
+ */
+ min = 0;
+ mid = 0;
+ max = nitems(bhnd_nvram_vars) - 1;
+
+ while (max >= min) {
+ /* Select midpoint */
+ mid = (min + max) / 2;
+
+ /* Determine which side of the partition to search */
+ order = strcmp(bhnd_nvram_vars[mid].name, varname);
+ if (order < 0) {
+ /* Search upper partition */
+ min = mid + 1;
+ } else if (order > 0) {
+ /* Search lower partition */
+ max = mid - 1;
+ } else if (order == 0) {
+ /* Match found */
+ return (&bhnd_nvram_vars[mid]);
+ }
+ }
+
+ /* Not found */
+ return (NULL);
+}
Index: head/sys/dev/bhnd/nvram/nvramvar.h
===================================================================
--- head/sys/dev/bhnd/nvram/nvramvar.h
+++ head/sys/dev/bhnd/nvram/nvramvar.h
@@ -0,0 +1,128 @@
+/*-
+ * Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ * redistribution must be conditioned upon including a substantially
+ * similar Disclaimer requirement for further binary redistribution.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _BHND_NVRAM_BHND_NVRAMVAR_H_
+#define _BHND_NVRAM_BHND_NVRAMVAR_H_
+
+/** NVRAM Primitive data types */
+typedef enum {
+ BHND_NVRAM_DT_UINT8 = 0, /**< unsigned 8-bit integer */
+ BHND_NVRAM_DT_UINT16 = 1, /**< unsigned 16-bit integer */
+ BHND_NVRAM_DT_UINT32 = 2, /**< unsigned 32-bit integer */
+ BHND_NVRAM_DT_INT8 = 3, /**< signed 8-bit integer */
+ BHND_NVRAM_DT_INT16 = 4, /**< signed 16-bit integer */
+ BHND_NVRAM_DT_INT32 = 5, /**< signed 32-bit integer */
+ BHND_NVRAM_DT_CHAR = 6, /**< ASCII char */
+} bhnd_nvram_dt;
+
+/** NVRAM data type string representations */
+typedef enum {
+ BHND_NVRAM_VFMT_HEX = 1, /**< hex format */
+ BHND_NVRAM_VFMT_DEC = 2, /**< decimal format */
+ BHND_NVRAM_VFMT_MACADDR = 3, /**< mac address (canonical form, hex octets,
+ separated with ':') */
+ BHND_NVRAM_VFMT_LEDDC = 4, /**< LED PWM duty-cycle (2 bytes -- on/off) */
+ BHND_NVRAM_VFMT_CCODE = 5 /**< count code format (2-3 ASCII chars, or hex string) */
+} bhnd_nvram_fmt;
+
+/** NVRAM variable flags */
+enum {
+ BHND_NVRAM_VF_ARRAY = (1<<0), /**< variable is an array */
+ BHND_NVRAM_VF_MFGINT = (1<<1), /**< mfg-internal variable; should not be externally visible */
+ BHND_NVRAM_VF_IGNALL1 = (1<<2) /**< hide variable if its value has all bits set. */
+};
+
+#define BHND_SPROMREV_MAX UINT8_MAX /**< maximum supported SPROM revision */
+
+/** SPROM revision compatibility declaration */
+struct bhnd_sprom_compat {
+ uint8_t first; /**< first compatible SPROM revision */
+ uint8_t last; /**< last compatible SPROM revision, or BHND_SPROMREV_MAX */
+};
+
+/** SPROM value descriptor */
+struct bhnd_sprom_offset {
+ uint16_t offset; /**< byte offset within SPROM */
+ bool cont:1; /**< value should be bitwise OR'd with the
+ * previous offset descriptor */
+ bhnd_nvram_dt type:7; /**< data type */
+ int8_t shift; /**< shift to be applied to the value */
+ uint32_t mask; /**< mask to be applied to the value(s) */
+};
+
+/** SPROM-specific variable definition */
+struct bhnd_sprom_var {
+ struct bhnd_sprom_compat compat; /**< sprom compatibility declaration */
+ const struct bhnd_sprom_offset *offsets; /**< offset descriptors */
+ size_t num_offsets; /**< number of offset descriptors */
+};
+
+/** NVRAM variable definition */
+struct bhnd_nvram_var {
+ const char *name; /**< variable name */
+ bhnd_nvram_dt type; /**< base data type */
+ bhnd_nvram_fmt fmt; /**< string format */
+ uint32_t flags; /**< BHND_NVRAM_VF_* flags */
+
+ const struct bhnd_sprom_var *sprom_descs; /**< SPROM-specific variable descriptors */
+ size_t num_sp_descs; /**< number of sprom descriptors */
+};
+
+size_t bhnd_nvram_type_width(bhnd_nvram_dt dt);
+const struct bhnd_nvram_var *bhnd_nvram_var_defn(const char *varname);
+
+/** Initial bhnd_nvram_crc8 value */
+#define BHND_NVRAM_CRC8_INITIAL 0xFF
+
+/** Valid CRC-8 checksum */
+#define BHND_NVRAM_CRC8_VALID 0x9F
+
+extern const uint8_t bhnd_nvram_crc8_tab[];
+
+/**
+ * Calculate CRC-8 over @p buf.
+ *
+ * @param buf input buffer
+ * @param size buffer size
+ * @param crc last computed crc, or BHND_NVRAM_CRC8_INITIAL
+ */
+static inline uint8_t
+bhnd_nvram_crc8(const void *buf, size_t size, uint8_t crc)
+{
+ const uint8_t *p = (const uint8_t *)buf;
+ while (size--)
+ crc = bhnd_nvram_crc8_tab[(crc ^ *p++)];
+
+ return (crc);
+}
+
+
+#endif /* _BHND_NVRAM_BHND_NVRAMVAR_H_ */
\ No newline at end of file
Index: head/sys/dev/bhnd/tools/nvram_map_gen.awk
===================================================================
--- head/sys/dev/bhnd/tools/nvram_map_gen.awk
+++ head/sys/dev/bhnd/tools/nvram_map_gen.awk
@@ -0,0 +1,1162 @@
+#!/usr/bin/awk -f
+
+#-
+# Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer,
+# without modification.
+# 2. Redistributions in binary form must reproduce at minimum a disclaimer
+# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+# redistribution must be conditioned upon including a substantially
+# similar Disclaimer requirement for further binary redistribution.
+#
+# NO WARRANTY
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGES.
+#
+# $FreeBSD$
+
+BEGIN {
+ RS="\n"
+
+ depth = 0
+ symbols[depth,"_file"] = FILENAME
+ num_output_vars = 0
+ OUTPUT_FILE = null
+
+ # Seed rand()
+ srand()
+
+ # Output type
+ OUT_T = null
+ OUT_T_HEADER = "HEADER"
+ OUT_T_DATA = "DATA"
+
+ # Enable debug output
+ DEBUG = 0
+
+ # Maximum revision
+ REV_MAX = 255
+
+ # Parse arguments
+ if (ARGC < 2)
+ usage()
+
+ for (i = 1; i < ARGC; i++) {
+ if (ARGV[i] == "--debug") {
+ DEBUG = 1
+ } else if (ARGV[i] == "-d" && OUT_T == null) {
+ OUT_T = OUT_T_DATA
+ } else if (ARGV[i] == "-h" && OUT_T == null) {
+ OUT_T = OUT_T_HEADER
+ } else if (ARGV[i] == "-o") {
+ i++
+ if (i >= ARGC)
+ usage()
+
+ OUTPUT_FILE = ARGV[i]
+ } else if (ARGV[i] == "--") {
+ i++
+ break
+ } else if (ARGV[i] !~ /^-/) {
+ FILENAME = ARGV[i]
+ } else {
+ print "unknown option " ARGV[i]
+ usage()
+ }
+ }
+
+ ARGC=2
+
+ if (OUT_T == null) {
+ print("error: one of -d or -h required")
+ usage()
+ }
+
+ if (FILENAME == null) {
+ print("error: no input file specified")
+ usage()
+ }
+
+ if (OUTPUT_FILE == "-") {
+ OUTPUT_FILE = "/dev/stdout"
+ } else if (OUTPUT_FILE == null) {
+ _bi = split(FILENAME, _paths, "/")
+ OUTPUT_FILE = _paths[_bi]
+
+ if (OUTPUT_FILE !~ /^bhnd_/)
+ OUTPUT_FILE = "bhnd_" OUTPUT_FILE
+
+ if (OUT_T == OUT_T_HEADER)
+ OUTPUT_FILE = OUTPUT_FILE ".h"
+ else
+ OUTPUT_FILE = OUTPUT_FILE "_data.h"
+ }
+
+ # Format Constants
+ FMT["hex"] = "BHND_NVRAM_VFMT_HEX"
+ FMT["decimal"] = "BHND_NVRAM_VFMT_DEC"
+ FMT["ccode"] = "BHND_NVRAM_VFMT_CCODE"
+ FMT["macaddr"] = "BHND_NVRAM_VFMT_MACADDR"
+ FMT["led_dc"] = "BHND_NVRAM_VFMT_LEDDC"
+
+ # Data Type Constants
+ DTYPE["u8"] = "BHND_NVRAM_DT_UINT8"
+ DTYPE["u16"] = "BHND_NVRAM_DT_UINT16"
+ DTYPE["u32"] = "BHND_NVRAM_DT_UINT32"
+ DTYPE["i8"] = "BHND_NVRAM_DT_INT8"
+ DTYPE["i16"] = "BHND_NVRAM_DT_INT16"
+ DTYPE["i32"] = "BHND_NVRAM_DT_INT32"
+ DTYPE["char"] = "BHND_NVRAM_DT_CHAR"
+
+ # Default masking for standard types
+ TMASK["u8"] = "0x000000FF"
+ TMASK["u16"] = "0x0000FFFF"
+ TMASK["u32"] = "0xFFFFFFFF"
+ TMASK["i8"] = TMASK["u8"]
+ TMASK["i16"] = TMASK["u16"]
+ TMASK["i32"] = TMASK["u32"]
+ TMASK["char"] = TMASK["u8"]
+
+ # Byte sizes for standard types
+ TSIZE["u8"] = "1"
+ TSIZE["u16"] = "2"
+ TSIZE["u32"] = "4"
+ TSIZE["i8"] = TSIZE["u8"]
+ TSIZE["i16"] = TSIZE["u8"]
+ TSIZE["i32"] = TSIZE["u8"]
+ TSIZE["char"] = "1"
+
+ # Common Regexs
+ INT_REGEX = "^(0|[1-9][0-9]*),?$"
+ HEX_REGEX = "^0x[A-Fa-f0-9]+,?$"
+
+ ARRAY_REGEX = "\\[(0|[1-9][0-9]*)\\]"
+ TYPES_REGEX = "^(((u|i)(8|16|32))|char)("ARRAY_REGEX")?,?$"
+
+ IDENT_REGEX = "^[A-Za-z_][A-Za-z0-9_]*,?$"
+ SROM_OFF_REGEX = "("TYPES_REGEX"|"HEX_REGEX")"
+
+ # Parser states types
+ ST_STRUCT_BLOCK = "struct" # struct block
+ ST_VAR_BLOCK = "var" # variable block
+ ST_SROM_DEFN = "srom" # srom offset defn
+ ST_NONE = "NONE" # default state
+
+ # Property types
+ PROP_T_SFMT = "sfmt"
+ PROP_T_ALL1 = "all1"
+
+ # Internal variables used for parser state
+ # tracking
+ STATE_TYPE = "_state_type"
+ STATE_IDENT = "_state_block_name"
+ STATE_LINENO = "_state_first_line"
+ STATE_ISBLOCK = "_state_is_block"
+
+ # Common array keys
+ DEF_LINE = "def_line"
+ NUM_REVS = "num_revs"
+ REV = "rev"
+
+ # Revision array keys
+ REV_START = "rev_start"
+ REV_END = "rev_end"
+ REV_DESC = "rev_decl"
+ REV_NUM_OFFS = "num_offs"
+
+ # Offset array keys
+ OFF = "off"
+ OFF_NUM_SEGS = "off_num_segs"
+ OFF_SEG = "off_seg"
+
+ # Segment array keys
+ SEG_ADDR = "seg_addr"
+ SEG_COUNT = "seg_count"
+ SEG_TYPE = "seg_type"
+ SEG_MASK = "seg_mask"
+ SEG_SHIFT = "seg_shift"
+
+ # Variable array keys
+ VAR_NAME = "v_name"
+ VAR_TYPE = "v_type"
+ VAR_BASE_TYPE = "v_base_type"
+ VAR_FMT = "v_fmt"
+ VAR_STRUCT = "v_parent_struct"
+ VAR_PRIVATE = "v_private"
+ VAR_ARRAY = "v_array"
+ VAR_IGNALL1 = "v_ignall1"
+}
+
+# return the flag definition for variable `v`
+function gen_var_flags (v)
+{
+ _num_flags = 0;
+ if (vars[v,VAR_ARRAY])
+ _flags[_num_flags++] = "BHND_NVRAM_VF_ARRAY"
+
+ if (vars[v,VAR_PRIVATE])
+ _flags[_num_flags++] = "BHND_NVRAM_VF_MFGINT"
+
+ if (vars[v,VAR_IGNALL1])
+ _flags[_num_flags++] = "BHND_NVRAM_VF_IGNALL1"
+
+ if (_num_flags == 0)
+ _flags[_num_flags++] = "0"
+
+ return (join(_flags, "|", _num_flags))
+}
+
+# emit the bhnd_sprom_offsets for a given variable revision key
+function emit_var_sprom_offsets (v, revk)
+{
+ emit(sprintf("{{%u, %u}, (struct bhnd_sprom_offset[]) {\n",
+ vars[revk,REV_START],
+ vars[revk,REV_END]))
+ output_depth++
+
+ num_offs = vars[revk,REV_NUM_OFFS]
+ num_offs_written = 0
+ elem_count = 0
+ for (offset = 0; offset < num_offs; offset++) {
+ offk = subkey(revk, OFF, offset"")
+ num_segs = vars[offk,OFF_NUM_SEGS]
+
+ for (seg = 0; seg < num_segs; seg++) {
+ segk = subkey(offk, OFF_SEG, seg"")
+
+ for (seg_n = 0; seg_n < vars[segk,SEG_COUNT]; seg_n++) {
+ seg_addr = vars[segk,SEG_ADDR]
+ seg_addr += TSIZE[vars[segk,SEG_TYPE]] * seg_n
+
+ emit(sprintf("{%s, %s, %s, %s, %s},\n",
+ seg_addr,
+ (seg > 0) ? "true" : "false",
+ DTYPE[vars[segk,SEG_TYPE]],
+ vars[segk,SEG_SHIFT],
+ vars[segk,SEG_MASK]))
+
+ num_offs_written++
+ }
+ }
+ }
+
+ output_depth--
+ emit("}, " num_offs_written "},\n")
+}
+
+# emit the bhnd_nvram_var definition for variable name `v`
+function emit_var_defn (v)
+{
+ emit(sprintf("{\"%s\", %s, %s, %s, (struct bhnd_sprom_var[]) {\n",
+ v suffix,
+ DTYPE[vars[v,VAR_BASE_TYPE]],
+ FMT[vars[v,VAR_FMT]],
+ gen_var_flags(v)))
+ output_depth++
+
+ for (rev = 0; rev < vars[v,NUM_REVS]; rev++) {
+ revk = subkey(v, REV, rev"")
+ emit_var_sprom_offsets(v, revk)
+ }
+
+ output_depth--
+ emit("}, " vars[v,NUM_REVS] "},\n")
+}
+
+# emit a header name #define for variable `v`
+function emit_var_namedef (v)
+{
+ emit("#define\tBHND_NVAR_" toupper(v) "\t\"" v "\"\n")
+}
+
+# generate a set of var offset definitions for struct variable `st_vid`
+function gen_struct_var_offsets (vid, revk, st_vid, st_revk, base_addr)
+{
+ # Copy all offsets to the new variable
+ for (offset = 0; offset < vars[v,REV_NUM_OFFS]; offset++) {
+ st_offk = subkey(st_revk, OFF, offset"")
+ offk = subkey(revk, OFF, offset"")
+
+ # Copy all segments to the new variable, applying base
+ # address adjustment
+ num_segs = vars[st_offk,OFF_NUM_SEGS]
+ vars[offk,OFF_NUM_SEGS] = num_segs
+
+ for (seg = 0; seg < num_segs; seg++) {
+ st_segk = subkey(st_offk, OFF_SEG, seg"")
+ segk = subkey(offk, OFF_SEG, seg"")
+
+ vars[segk,SEG_ADDR] = vars[st_segk,SEG_ADDR] + \
+ base_addr""
+ vars[segk,SEG_COUNT] = vars[st_segk,SEG_COUNT]
+ vars[segk,SEG_TYPE] = vars[st_segk,SEG_TYPE]
+ vars[segk,SEG_MASK] = vars[st_segk,SEG_MASK]
+ vars[segk,SEG_SHIFT] = vars[st_segk,SEG_SHIFT]
+ }
+ }
+}
+
+# generate a complete set of variable definitions for struct variable `st_vid`.
+function gen_struct_vars (st_vid)
+{
+ st = vars[st_vid,VAR_STRUCT]
+ st_max_off = 0
+
+ # determine the total number of variables to generate
+ for (st_rev = 0; st_rev < structs[st,NUM_REVS]; st_rev++) {
+ srevk = subkey(st, REV, st_rev"")
+ for (off = 0; off < structs[srevk,REV_NUM_OFFS]; off++) {
+ if (off > st_max_off)
+ st_max_off = off
+ }
+ }
+
+ # generate variable records for each defined struct offset
+ for (off = 0; off < st_max_off; off++) {
+ # Construct basic variable definition
+ v = st_vid off""
+ vars[v,VAR_TYPE] = vars[st_vid,VAR_TYPE]
+ vars[v,VAR_BASE_TYPE] = vars[st_vid,VAR_BASE_TYPE]
+ vars[v,VAR_FMT] = vars[st_vid,VAR_FMT]
+ vars[v,VAR_PRIVATE] = vars[st_vid,VAR_PRIVATE]
+ vars[v,VAR_ARRAY] = vars[st_vid,VAR_ARRAY]
+ vars[v,VAR_IGNALL1] = vars[st_vid,VAR_IGNALL1]
+ vars[v,NUM_REVS] = 0
+
+ # Add to output variable list
+ output_vars[num_output_vars++] = v
+
+ # Construct revision / offset entries
+ for (srev = 0; srev < structs[st,NUM_REVS]; srev++) {
+ # Struct revision key
+ st_revk = subkey(st, REV, srev"")
+
+ # Skip offsets not defined for this revision
+ if (off > structs[st_revk,REV_NUM_OFFS])
+ continue
+
+ # Strut offset key and associated base address */
+ offk = subkey(st_revk, OFF, off"")
+ base_addr = structs[offk,SEG_ADDR]
+
+ for (vrev = 0; vrev < vars[st_vid,NUM_REVS]; vrev++) {
+ st_var_revk = subkey(st_vid, REV, vrev"")
+ v_start = vars[st_var_revk,REV_START]
+ v_end = vars[st_var_revk,REV_END]
+ s_start = structs[st_revk,REV_START]
+ s_end = structs[st_revk,REV_END]
+
+ # We don't support computing the union
+ # of partially overlapping ranges
+ if ((v_start < s_start && v_end >= s_start) ||
+ (v_start <= s_end && v_end > s_end))
+ {
+ errorx("partially overlapping " \
+ "revision ranges are not supported")
+ }
+
+ # skip variables revs that are not within
+ # the struct offset's compatibility range
+ if (v_start < s_start || v_start > s_end ||
+ v_end < s_start || v_end > s_end)
+ continue
+
+ # Generate the new revision record
+ rev = vars[v,NUM_REVS] ""
+ revk = subkey(v, REV, rev)
+ vars[v,NUM_REVS]++
+
+ vars[revk,DEF_LINE] = vars[st_revk,DEF_LINE]
+ vars[revk,REV_START] = v_start
+ vars[revk,REV_END] = v_end
+ vars[revk,REV_NUM_OFFS] = \
+ vars[st_var_revk,REV_NUM_OFFS]
+
+ gen_struct_var_offsets(v, revk, st_vid, st_revk,
+ base_addr)
+ }
+ }
+ }
+}
+
+
+END {
+ # Skip completion handling if exiting from an error
+ if (_EARLY_EXIT)
+ exit 1
+
+ # Check for complete block closure
+ if (depth > 0) {
+ block_start = g(STATE_LINENO)
+ errorx("missing '}' for block opened on line " block_start "")
+ }
+
+ # Generate concrete variable definitions for all struct variables
+ for (v in var_names) {
+ if (vars[v,VAR_STRUCT] != null) {
+ gen_struct_vars(v)
+ } else {
+ output_vars[num_output_vars++] = v
+ }
+ }
+
+ # Apply lexicographical sorting. To support more effecient table
+ # searching, we guarantee a stable sort order (using C collation).
+ sort(output_vars)
+
+ # Truncate output file and write common header
+ printf("") > OUTPUT_FILE
+ emit("/*\n")
+ emit(" * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.\n")
+ emit(" *\n")
+ emit(" * generated from nvram map: " FILENAME "\n")
+ emit(" */\n")
+ emit("\n")
+
+ # Emit all variable definitions
+ if (OUT_T == OUT_T_DATA) {
+ emit("#include <dev/bhnd/nvram/nvramvar.h>\n")
+ emit("static const struct bhnd_nvram_var bhnd_nvram_vars[] = "\
+ "{\n")
+ output_depth++
+ for (i = 0; i < num_output_vars; i++)
+ emit_var_defn(output_vars[i])
+ output_depth--
+ emit("};\n")
+ } else if (OUT_T == OUT_T_HEADER) {
+ for (i = 0; i < num_output_vars; i++)
+ emit_var_namedef(output_vars[i])
+ }
+
+ printf("%u variable records written to %s\n", num_output_vars,
+ OUTPUT_FILE) >> "/dev/stderr"
+}
+
+
+#
+# Print usage
+#
+function usage ()
+{
+ print "usage: bhnd_nvram_map.awk <input map> [-hd] [-o output file]"
+ _EARLY_EXIT = 1
+ exit 1
+}
+
+#
+# Join all array elements with the given separator
+#
+function join (array, sep, count)
+{
+ if (count == 0)
+ return ("")
+
+ _result = array[0]
+ for (_ji = 1; _ji < count; _ji++)
+ _result = _result sep array[_ji]
+
+ return (_result)
+}
+
+#
+# Sort a contiguous integer-indexed array, using standard awk comparison
+# operators over its values.
+#
+function sort (array) {
+ # determine array size
+ _sort_alen = 0
+
+ for (_ssort_key in array)
+ _sort_alen++
+
+ if (_sort_alen <= 1)
+ return
+
+ # perform sort
+ _qsort(array, 0, _sort_alen-1)
+}
+
+function _qsort (array, first, last)
+{
+ if (first >= last)
+ return
+
+ # select pivot element
+ _qpivot = int(first + int((last-first+1) * rand()))
+ _qleft = first
+ _qright = last
+
+ _qpivot_val = array[_qpivot]
+
+ # partition
+ while (_qleft <= _qright) {
+ while (array[_qleft] < _qpivot_val)
+ _qleft++
+
+ while (array[_qright] > _qpivot_val)
+ _qright--
+
+ # swap
+ if (_qleft <= _qright) {
+ _qleft_val = array[_qleft]
+ _qright_val = array[_qright]
+
+ array[_qleft] = _qright_val
+ array[_qright] = _qleft_val
+
+ _qleft++
+ _qright--
+ }
+ }
+
+ # sort the partitions
+ _qsort(array, first, _qright)
+ _qsort(array, _qleft, last)
+}
+
+#
+# Print msg to output file, without indentation
+#
+function emit_ni (msg)
+{
+ printf("%s", msg) >> OUTPUT_FILE
+}
+
+#
+# Print msg to output file, indented for the current `output_depth`
+#
+function emit (msg)
+{
+ for (_ind = 0; _ind < output_depth; _ind++)
+ emit_ni("\t")
+
+ emit_ni(msg)
+}
+
+#
+# Print a warning to stderr
+#
+function warn (msg)
+{
+ print "warning:", msg, "at", FILENAME, "line", NR > "/dev/stderr"
+}
+
+#
+# Print a compiler error to stderr
+#
+function error (msg)
+{
+ errorx(msg " at " FILENAME " line " NR ":\n\t" $0)
+}
+
+#
+# Print an error message without including the source line information
+#
+function errorx (msg)
+{
+ print "error:", msg > "/dev/stderr"
+ _EARLY_EXIT=1
+ exit 1
+}
+
+#
+# Print a debug output message
+#
+function debug (msg)
+{
+ if (!DEBUG)
+ return
+ for (_di = 0; _di < depth; _di++)
+ printf("\t") > "/dev/stderr"
+ print msg > "/dev/stderr"
+}
+
+#
+# Return an array key composed of the given (parent, selector, child)
+# tuple.
+# The child argument is optional and may be omitted.
+#
+function subkey (parent, selector, child)
+{
+ if (child != null)
+ return (parent SUBSEP selector SUBSEP child)
+ else
+ return (parent SUBSEP selector)
+}
+
+#
+# Advance to the next non-comment input record
+#
+function next_line ()
+{
+ do {
+ _result = getline
+ } while (_result > 0 && $0 ~ /^[ \t]*#.*/) # skip comment lines
+ return (_result)
+}
+
+#
+# Advance to the next input record and verify that it matches @p regex
+#
+function getline_matching (regex)
+{
+ _result = next_line()
+ if (_result <= 0)
+ return (_result)
+
+ if ($0 ~ regex)
+ return (1)
+
+ return (-1)
+}
+
+#
+# Shift the current fields left by `n`.
+#
+# If all fields are consumed and the optional do_getline argument is true,
+# read the next line.
+#
+function shiftf (n, do_getline)
+{
+ if (n > NF) error("shift past end of line")
+ for (_si = 1; _si <= NF-n; _si++) {
+ $(_si) = $(_si+n)
+ }
+ NF = NF - n
+
+ if (NF == 0 && do_getline)
+ next_line()
+}
+
+#
+# Parse a revision descriptor from the current line.
+#
+function parse_revdesc (result)
+{
+ _rstart = 0
+ _rend = 0
+
+ if ($2 ~ "[0-9]*-[0-9*]") {
+ split($2, _revrange, "[ \t]*-[ \t]*")
+ _rstart = _revrange[1]
+ _rend = _revrange[2]
+ } else if ($2 ~ "(>|>=|<|<=)" && $3 ~ "[1-9][0-9]*") {
+ if ($2 == ">") {
+ _rstart = int($3)+1
+ _rend = REV_MAX
+ } else if ($2 == ">=") {
+ _rstart = int($3)
+ _rend = REV_MAX
+ } else if ($2 == "<" && int($3) > 0) {
+ _rstart = 0
+ _rend = int($3)-1
+ } else if ($2 == "<=") {
+ _rstart = 0
+ _rend = int($3)-1
+ } else {
+ error("invalid revision descriptor")
+ }
+ } else if ($2 ~ "[1-9][0-9]*") {
+ _rstart = int($2)
+ _rend = int($2)
+ } else {
+ error("invalid revision descriptor")
+ }
+
+ result[REV_START] = _rstart
+ result[REV_END] = _rend
+}
+
+#
+# Push a new parser state.
+#
+# The name may be null, in which case the STATE_IDENT variable will not be
+# defined in this scope
+#
+function push_state (type, name, block) {
+ depth++
+ push(STATE_LINENO, NR)
+ if (name != null)
+ push(STATE_IDENT, name)
+ push(STATE_TYPE, type)
+ push(STATE_ISBLOCK, block)
+}
+
+#
+# Pop the top of the parser state stack.
+#
+function pop_state () {
+ # drop all symbols defined at this depth
+ for (s in symbols) {
+ if (s ~ "^"depth"[^0-9]")
+ delete symbols[s]
+ }
+ depth--
+}
+
+#
+# Find opening brace and push a new parser state for a brace-delimited block.
+#
+# The name may be null, in which case the STATE_IDENT variable will not be
+# defined in this scope
+#
+function open_block (type, name)
+{
+ if ($0 ~ "{" || getline_matching("^[ \t]*{") > 0) {
+ push_state(type, name, 1)
+ sub("^[^{]+{", "", $0)
+ return
+ }
+
+ error("found '"$1 "' instead of expected '{' for '" name "'")
+}
+
+#
+# Find closing brace and pop parser states until the first
+# brace-delimited block is discarded.
+#
+function close_block ()
+{
+ if ($0 !~ "}")
+ error("internal error - no closing brace")
+
+ # pop states until we exit the first enclosing block
+ do {
+ _closed_block = g(STATE_ISBLOCK)
+ pop_state()
+ } while (!_closed_block)
+
+ # strip everything prior to the block closure
+ sub("^[^}]*}", "", $0)
+}
+
+# Internal symbol table lookup function. Returns the symbol depth if
+# name is found at or above scope; if scope is null, it defauls to 0
+function _find_sym (name, scope)
+{
+ if (scope == null)
+ scope = 0;
+
+ for (i = scope; i < depth; i++) {
+ if ((depth-i,name) in symbols)
+ return (depth-i)
+ }
+
+ return (-1)
+}
+
+#
+# Look up a variable in the symbol table with `name` and return its value.
+#
+# If `scope` is not null, the variable search will start at the provided
+# scope level -- 0 is the current scope, 1 is the parent's scope, etc.
+#
+function g (name, scope)
+{
+ _g_depth = _find_sym(name, scope)
+ if (_g_depth < 0)
+ error("'" name "' is undefined")
+
+ return (symbols[_g_depth,name])
+}
+
+function is_defined (name, scope)
+{
+ return (_find_sym(name, scope) >= 0)
+}
+
+# Define a new variable in the symbol table's current scope,
+# with the given value
+function push (name, value)
+{
+ symbols[depth,name] = value
+}
+
+# Set an existing variable's value in the symbol table; if not yet defined,
+# will trigger an error
+function set (name, value, scope)
+{
+ for (i = 0; i < depth; i++) {
+ if ((depth-i,name) in symbols) {
+ symbols[depth-i,name] = value
+ return
+ }
+ }
+ # No existing value, cannot define
+ error("'" name "' is undefined")
+}
+
+# Evaluates to true if immediately within a block scope of the given type
+function in_state (type)
+{
+ if (!is_defined(STATE_TYPE))
+ return (type == ST_NONE)
+
+ return (type == g(STATE_TYPE))
+}
+
+# Evaluates to true if within an immediate or non-immediate block scope of the
+# given type
+function in_nested_state (type)
+{
+ for (i = 0; i < depth; i++) {
+ if ((depth-i,STATE_TYPE) in symbols) {
+ if (symbols[depth-i,STATE_TYPE] == type)
+ return (1)
+ }
+ }
+ return (0)
+}
+
+# Evaluates to true if definitions of the given type are permitted within
+# the current scope
+function allow_def (type)
+{
+ if (type == ST_VAR_BLOCK) {
+ return (in_state(ST_NONE) || in_state(ST_STRUCT_BLOCK))
+ } else if (type == ST_STRUCT_BLOCK) {
+ return (in_state(ST_NONE))
+ } else if (type == ST_SROM_DEFN) {
+ return (in_state(ST_VAR_BLOCK) || in_state(ST_STRUCT_BLOCK))
+ }
+
+ error("unknown type '" type "'")
+}
+
+# struct definition
+$1 == ST_STRUCT_BLOCK && allow_def($1) {
+ name = $2
+
+ # Remove array[] specifier
+ if (sub(/\[\]$/, "", name) == 0)
+ error("expected '" name "[]', not '" name "'")
+
+ if (name !~ IDENT_REGEX || name ~ TYPES_REGEX)
+ error("invalid identifier '" name "'")
+
+ # Add top-level struct entry
+ if ((name,DEF_LINE) in structs)
+ error("struct identifier '" name "' previously defined on " \
+ "line " structs[name,DEF_LINE])
+ structs[name,DEF_LINE] = NR
+ structs[name,NUM_REVS] = 0
+
+ # Open the block
+ debug("struct " name " {")
+ open_block(ST_STRUCT_BLOCK, name)
+}
+
+# struct srom descriptor
+$1 == ST_SROM_DEFN && allow_def(ST_SROM_DEFN) && in_state(ST_STRUCT_BLOCK) {
+ sid = g(STATE_IDENT)
+
+ # parse revision descriptor
+ rev_desc[REV_START] = 0
+ parse_revdesc(rev_desc)
+
+ # assign revision id
+ rev = structs[sid,NUM_REVS] ""
+ revk = subkey(sid, REV, rev)
+ structs[sid,NUM_REVS]++
+
+ # init basic revision state
+ structs[revk,REV_START] = rev_desc[REV_START]
+ structs[revk,REV_END] = rev_desc[REV_END]
+
+ if (match($0, "\\[[^]]*\\]") <= 0)
+ error("expected base address array")
+
+ addrs_str = substr($0, RSTART+1, RLENGTH-2)
+ num_offs = split(addrs_str, addrs, ",[ \t]*")
+ structs[revk, REV_NUM_OFFS] = num_offs
+ for (i = 1; i <= num_offs; i++) {
+ offk = subkey(revk, OFF, (i-1) "")
+
+ if (addrs[i] !~ HEX_REGEX)
+ error("invalid base address '" addrs[i] "'")
+
+ structs[offk,SEG_ADDR] = addrs[i]
+ }
+
+ debug("struct_srom " structs[revk,REV_START] "... [" addrs_str "]")
+ next
+}
+
+# close any previous srom revision descriptor
+$1 == ST_SROM_DEFN && in_state(ST_SROM_DEFN) {
+ pop_state()
+}
+
+# open a new srom revision descriptor
+$1 == ST_SROM_DEFN && allow_def(ST_SROM_DEFN) {
+ # parse revision descriptor
+ parse_revdesc(rev_desc)
+
+ # assign revision id
+ vid = g(STATE_IDENT)
+ rev = vars[vid,NUM_REVS] ""
+ revk = subkey(vid, REV, rev)
+ vars[vid,NUM_REVS]++
+
+ # vend scoped rev/revk variables for use in the
+ # revision offset block
+ push("rev_id", rev)
+ push("rev_key", revk)
+
+ # init basic revision state
+ vars[revk,DEF_LINE] = NR
+ vars[revk,REV_START] = rev_desc[REV_START]
+ vars[revk,REV_END] = rev_desc[REV_END]
+ vars[revk,REV_NUM_OFFS] = 0
+
+ debug("srom " rev_desc[REV_START] "-" rev_desc[REV_END] " {")
+ push_state(ST_SROM_DEFN, null, 0)
+
+ # seek to the first offset definition
+ do {
+ shiftf(1)
+ } while ($1 !~ SROM_OFF_REGEX && NF > 0)
+}
+
+#
+# Extract and return the array length from the given type string.
+# Returns -1 if the type is not an array.
+#
+function type_array_len (type)
+{
+ # extract byte count[] and width
+ if (match(type, ARRAY_REGEX"$") > 0) {
+ return (substr(type, RSTART+1, RLENGTH-2))
+ } else {
+ return (-1)
+ }
+}
+
+#
+# Parse an offset declaration from the current line.
+#
+function parse_offset_segment (revk, offk)
+{
+ vid = g(STATE_IDENT)
+
+ # use explicit type if specified, otherwise use the variable's
+ # common type
+ if ($1 !~ HEX_REGEX) {
+ type = $1
+ if (type !~ TYPES_REGEX)
+ error("unknown field type '" type "'")
+
+ shiftf(1)
+ } else {
+ type = vars[vid,VAR_TYPE]
+ }
+
+ # read offset value
+ offset = $1
+ if (offset !~ HEX_REGEX)
+ error("invalid offset value '" offset "'")
+
+ # extract byte count[], base type, and width
+ if (match(type, ARRAY_REGEX"$") > 0) {
+ count = int(substr(type, RSTART+1, RLENGTH-2))
+ type = substr(type, 1, RSTART-1)
+ } else {
+ count = 1
+ }
+ width = TSIZE[type]
+
+ # seek to attributes or end of the offset expr
+ sub("^[^,(|){}]+", "", $0)
+
+ # parse attributes
+ mask=TMASK[type]
+ shift=0
+
+ if ($1 ~ "^\\(") {
+ # extract attribute list
+ if (match($0, "\\([^|\(\)]*\\)") <= 0)
+ error("expected attribute list")
+ attr_str = substr($0, RSTART+1, RLENGTH-2)
+
+ # drop from input line
+ $0 = substr($0, RSTART+RLENGTH, length($0) - RSTART+RLENGTH)
+
+ # parse attributes
+ num_attr = split(attr_str, attrs, ",[ \t]*")
+ for (i = 1; i <= num_attr; i++) {
+ attr = attrs[i]
+ if (sub("^&[ \t]*", "", attr) > 0) {
+ mask = attr
+ } else if (sub("^<<[ \t]*", "", attr) > 0) {
+ shift = "-"attr
+ } else if (sub("^>>[ \t]*", "", attr) > 0) {
+ shift = attr
+ } else {
+ error("unknown attribute '" attr "'")
+ }
+ }
+ }
+
+ # assign segment id
+ seg = vars[offk,OFF_NUM_SEGS] ""
+ segk = subkey(offk, OFF_SEG, seg)
+ vars[offk,OFF_NUM_SEGS]++
+
+ vars[segk,SEG_ADDR] = offset + (width * _oi)
+ vars[segk,SEG_COUNT] = count
+ vars[segk,SEG_TYPE] = type
+ vars[segk,SEG_MASK] = mask
+ vars[segk,SEG_SHIFT] = shift
+
+ debug("{"vars[segk,SEG_ADDR]", "type", "mask", "shift"}" \
+ _comma)
+}
+
+# revision offset definition
+$1 ~ SROM_OFF_REGEX && in_state(ST_SROM_DEFN) {
+ vid = g(STATE_IDENT)
+
+ # fetch rev id/key defined by our parent block
+ rev = g("rev_id")
+ revk = g("rev_key")
+
+ # parse all offsets
+ do {
+ # assign offset id
+ off = vars[revk,REV_NUM_OFFS] ""
+ offk = subkey(revk, OFF, off)
+ vars[revk,REV_NUM_OFFS]++
+
+ # initialize segment count
+ vars[offk,DEF_LINE] = NR
+ vars[offk,OFF_NUM_SEGS] = 0
+
+ debug("[")
+ # parse all segments
+ do {
+ parse_offset_segment(revk, offk)
+ _more_seg = ($1 == "|")
+ if (_more_seg)
+ shiftf(1, 1)
+ } while (_more_seg)
+ debug("],")
+ _more_vals = ($1 == ",")
+ if (_more_vals)
+ shiftf(1, 1)
+ } while (_more_vals)
+}
+
+# variable definition
+(($1 == "private" && $2 ~ TYPES_REGEX) || $1 ~ TYPES_REGEX) &&
+ allow_def(ST_VAR_BLOCK) \
+{
+ # check for 'private' flag
+ if ($1 == "private") {
+ private = 1
+ shiftf(1)
+ } else {
+ private = 0
+ }
+
+ type = $1
+ name = $2
+ array = 0
+ debug(type " " name " {")
+
+ # Check for and remove any array[] specifier
+ base_type = type
+ if (sub(ARRAY_REGEX"$", "", base_type) > 0)
+ array = 1
+
+ # verify type
+ if (!base_type in DTYPE)
+ error("unknown type '" $1 "'")
+
+ # Add top-level variable entry
+ if (name in var_names)
+ error("variable identifier '" name "' previously defined on " \
+ "line " vars[name,DEF_LINE])
+
+ var_names[name] = 0
+ vars[name,VAR_NAME] = name
+ vars[name,DEF_LINE] = NR
+ vars[name,VAR_TYPE] = type
+ vars[name,VAR_BASE_TYPE] = base_type
+ vars[name,NUM_REVS] = 0
+ vars[name,VAR_PRIVATE] = private
+ vars[name,VAR_ARRAY] = array
+ vars[name,VAR_FMT] = "hex" # default if not specified
+
+ open_block(ST_VAR_BLOCK, name)
+
+ debug("type=" DTYPE[base_type])
+
+ if (in_nested_state(ST_STRUCT_BLOCK)) {
+ # Fetch the enclosing struct's name
+ sid = g(STATE_IDENT, 1)
+
+ # Mark as a struct-based variable
+ vars[name,VAR_STRUCT] = sid
+ }
+}
+
+# variable parameters
+$1 ~ IDENT_REGEX && $2 ~ IDENT_REGEX && in_state(ST_VAR_BLOCK) {
+ vid = g(STATE_IDENT)
+ if ($1 == PROP_T_SFMT) {
+ if (!$2 in FMT)
+ error("invalid fmt '" $2 "'")
+
+ vars[vid,VAR_FMT] = $2
+ debug($1 "=" FMT[$2])
+ } else if ($1 == PROP_T_ALL1 && $2 == "ignore") {
+ vars[vid,VAR_IGNALL1] = 1
+ } else {
+ error("unknown parameter " $1)
+ }
+ next
+}
+
+# Skip comments and blank lines
+/^[ \t]*#/ || /^$/ {
+ next
+}
+
+# Close blocks
+/}/ && !in_state(ST_NONE) {
+ while (!in_state(ST_NONE) && $0 ~ "}") {
+ close_block();
+ debug("}")
+ }
+ next
+}
+
+# Report unbalanced '}'
+/}/ && in_state(ST_NONE) {
+ error("extra '}'")
+}
+
+# Invalid variable type
+$1 && allow_def(ST_VAR_BLOCK) {
+ error("unknown type '" $1 "'")
+}
+
+# Generic parse failure
+{
+ error("unrecognized statement")
+}
Index: head/sys/dev/bhnd/tools/nvram_map_gen.sh
===================================================================
--- head/sys/dev/bhnd/tools/nvram_map_gen.sh
+++ head/sys/dev/bhnd/tools/nvram_map_gen.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# Use C locale to ensure AWK string comparisons always produce
+# a stable sort order.
+
+# $FreeBSD$
+
+BHND_TOOLDIR="$(dirname $0)/"
+
+LC_ALL=C; export LC_ALL
+
+"$BHND_TOOLDIR/nvram_map_gen.awk" $@
Index: head/sys/dev/bwn/bwn_mac.c
===================================================================
--- head/sys/dev/bwn/bwn_mac.c
+++ head/sys/dev/bwn/bwn_mac.c
@@ -42,6 +42,8 @@
#include <dev/bhnd/bhnd.h>
#include <dev/bhnd/bhnd_ids.h>
+#include "bhnd_nvram_map.h"
+
static const struct resource_spec bwn_rspec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
{ -1, -1, 0 }
@@ -97,6 +99,14 @@
r = sc->res[0];
device_printf(dev, "got rid=%d res=%p\n", sc->rspec[0].rid, r);
+ uint8_t macaddr[6];
+ error = bhnd_nvram_getvar(dev, BHND_NVAR_MACADDR, macaddr,
+ sizeof(macaddr));
+ if (error)
+ return (error);
+
+ device_printf(dev, "got macaddr %6D\n", macaddr, ":");
+
return (0);
}
Index: head/sys/modules/bhnd/Makefile
===================================================================
--- head/sys/modules/bhnd/Makefile
+++ head/sys/modules/bhnd/Makefile
@@ -1,10 +1,16 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../dev/bhnd
+.PATH: ${.CURDIR}/../../dev/bhnd/nvram
KMOD= bhnd
SRCS= bhnd.c bhnd_subr.c \
- bhnd_bus_if.c bhnd_bus_if.h bhnd_nvram_if.h
+ bhnd_sprom.c nvram_subr.c \
+ bhnd_nvram_map.h bhnd_nvram_map_data.h
+
+SRCS+= bhnd_bus_if.c bhnd_bus_if.h \
+ bhnd_chipc_if.c bhnd_chipc_if.h \
+ bhnd_nvram_if.c bhnd_nvram_if.h
SRCS+= device_if.h bus_if.h
@@ -13,7 +19,6 @@
bhndb \
bhndb_pci \
cores \
- nvram \
siba \
siba_bhndb
Index: head/sys/modules/bhnd/bhndb/Makefile
===================================================================
--- head/sys/modules/bhnd/bhndb/Makefile
+++ head/sys/modules/bhnd/bhndb/Makefile
@@ -5,8 +5,10 @@
KMOD= bhndb
SRCS= bhndb.c bhndb_subr.c bhndb_hwdata.c \
bhndb_bus_if.c bhndb_bus_if.h \
- bhndb_if.c bhndb_if.h \
- bhnd_bus_if.h
+ bhndb_if.c bhndb_if.h
+SRCS+= bhnd_bus_if.h \
+ bhnd_chipc_if.h \
+ bhnd_nvram_if.h
SRCS+= device_if.h bus_if.h pci_if.h
Index: head/sys/modules/bhnd/bhndb_pci/Makefile
===================================================================
--- head/sys/modules/bhnd/bhndb_pci/Makefile
+++ head/sys/modules/bhnd/bhndb_pci/Makefile
@@ -3,8 +3,10 @@
.PATH: ${.CURDIR}/../../../dev/bhnd/bhndb
KMOD= bhndb_pci
-SRCS= bhndb_pci.c bhndb_pci_hwdata.c
+SRCS= bhndb_pci.c bhndb_pci_hwdata.c \
+ bhndb_pci_sprom.c
SRCS+= bhnd_bus_if.h bhndb_bus_if.h bhndb_if.h
+SRCS+= bhnd_nvram_if.h
SRCS+= device_if.h bus_if.h pci_if.h
Index: head/sys/modules/bhnd/cores/bhnd_chipc/Makefile
===================================================================
--- head/sys/modules/bhnd/cores/bhnd_chipc/Makefile
+++ head/sys/modules/bhnd/cores/bhnd_chipc/Makefile
@@ -3,8 +3,8 @@
.PATH: ${.CURDIR}/../../../../dev/bhnd/cores/chipc
KMOD= bhnd_chipc
-SRCS= chipc.c \
- bhnd_chipc_if.c bhnd_chipc_if.h
-SRCS+= device_if.h bus_if.h bhnd_bus_if.h
+SRCS= chipc.c
+SRCS+= device_if.h bus_if.h bhnd_bus_if.h \
+ bhnd_chipc_if.h bhnd_nvram_if.h
.include <bsd.kmod.mk>
Index: head/sys/modules/bhnd/nvram/Makefile
===================================================================
--- head/sys/modules/bhnd/nvram/Makefile
+++ head/sys/modules/bhnd/nvram/Makefile
@@ -1,10 +0,0 @@
-# $FreeBSD$
-
-.PATH: ${.CURDIR}/../../../dev/bhnd/nvram
-
-KMOD= bhnd_nvram
-SRCS= bhnd_nvram_if.c bhnd_nvram_if.h bhnd_bus_if.h
-
-SRCS+= device_if.h bus_if.h
-
-.include <bsd.kmod.mk>
Index: head/sys/modules/bwn_pci/Makefile
===================================================================
--- head/sys/modules/bwn_pci/Makefile
+++ head/sys/modules/bwn_pci/Makefile
@@ -4,8 +4,8 @@
KMOD= if_bwn_pci
SRCS= if_bwn_pci.c bwn_mac.c
+SRCS+= bhnd_bus_if.h bhndb_bus_if.h \
+ bhndb_if.h bhnd_nvram_map.h
SRCS+= device_if.h bus_if.h pci_if.h \
- bhnd_bus_if.h bhndb_bus_if.h \
- bhndb_if.h
.include <bsd.kmod.mk>

File Metadata

Mime Type
text/plain
Expires
Fri, Dec 12, 9:15 AM (6 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26893024
Default Alt Text
D6196.diff (179 KB)

Event Timeline