Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F139371459
D6196.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
179 KB
Referenced Files
None
Subscribers
None
D6196.diff
View Options
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, ®) == 0)
+ if (pci_find_cap(sc->parent, PCIY_EXPRESS, ®) == 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
Details
Attached
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)
Attached To
Mode
D6196: Initial bhnd(4) SPROM/NVRAM support.
Attached
Detach File
Event Timeline
Log In to Comment