The SPROM is uint16 based and all reads and writes to the SPROM should be done in 16 bit transactions. The SPROM is accessed through the MMIO starting at offset 0x1000, offsets given here are byte offsets from the beginning of the SPROM (So il0macaddr is at MMIO offset 0x1000 + 0x48). Unprogrammed values default to 0xFFFF. You should always read these values as 16-bit integers to get the correct byte ordering.
SPROM Layouts
Check which SPROM Layout applies by checking the SPROM Revision (Offset 0x7E).
Revision 1 SPROM
Offset |
Usage |
Notes |
0x04 |
Subsytem product ID for PCI |
|
0x06 |
Subsystem vendor ID for PCI |
|
0x08 |
Product ID for PCI |
|
0x48 |
Start of Named Parameter Area |
|
0x48-0x4C |
il0macaddr - MAC address for 802.11b/g |
|
0x4E-0x52 |
et0macaddr - MAC address for ethernet |
See b44 Driver |
0x54-0x58 |
et1macaddr - MAC address for 802.11a |
|
|
Ethernet PHY settings: one or two singles or a dual (encoded bitwise) |
See b44 Driver |
0x5A |
bits 4-0: et0phyaddr - MII Address for enet0 |
0x1F if not present |
bits 9-5: et1phyaddr - MII Address for enet1 |
0x1F if not present |
|
bit 14: et0mdcport - MDIO for enet0 |
|
|
bit 15: et1mdcport - MDIO for enet1 |
|
|
|
Board revision, Antennas 0/1, Country Code |
|
0x5C |
bits 7-0: Board Revision |
|
bits 11-8: Country Code |
See locales |
|
bits 13-12: Bitfield of antennas available for A PHY |
|
|
bits 15-14: Bitfield of antennas available for B/G PHY |
|
|
0x5E |
pa0b0 |
|
0x60 |
pa0b1 |
|
0x62 |
pa0b2 |
|
0x64 |
GPIO 0 and 1 |
See GPIO below |
0x66 |
GPIO 2 and 3 |
See GPIO below |
|
PA Max Power |
Units: 4*dBm (dBm in Q5.2) |
0x68 |
bits 7-0: A PHY Max Power |
|
bits 15-8: B/G PHY Max Power |
|
|
0x6A |
pa1b0 |
|
0x6C |
pa1b1 |
|
0x6E |
pa1b2 |
|
|
Idle TSSI Target |
|
0x70 |
bits 7-0: A PHY |
|
bits 15-8: B/G PHY |
|
|
0x72 |
Low 16 bits of boardflags |
If unset (0xFFFF) use 0 |
|
Antenna Gain |
If unset, use 2 dBm, all values are in dBm |
0x74 |
bits 7-0: A PHY |
|
bits 15-8: B/G PHY |
|
|
0x76 - 0x7C |
OEM String |
8 Characters (SROM Rev 1 only) |
|
SPROM Checksum and Revision |
|
0x7E |
bits 7-0: SPROM Revision |
|
bits 15-8: SPROM CRC8 |
|
Revision 2 SPROM
Same as Revision 1 unless specified here
Offset |
Usage |
Notes |
0x38 |
High 16 bits of boardflags |
|
|
A PHY Max Power |
|
0x3A |
bits 7-0: Max Power High |
|
bits 15-8: Max Power Low |
|
|
0x3C |
pa1lob0: A PHY PA Low Settings |
|
0x3E |
pa1lob1: A PHY PA Low Settings |
|
0x40 |
pa1lob2: A PHY PA Low Settings |
|
0x42 |
pa1hib0: A PHY PA High Settings |
|
0x44 |
pa1hib1: A PHY PA High Settings |
|
0x46 |
pa1hib2: A PHY PA High Settings |
|
|
opo: OFDM Power Offset from CCK Level |
|
0x78 |
bits 7-0: OFDM Power Offset from CCK Level |
|
bits 15-8: Unused |
|
|
0x7C |
Country Code |
2 Characters, 0 if unset |
Revision 3 SPROM
Same as Revision 2 unless specified here
Offset |
Usage |
Notes |
0x2C-0x2E |
ofdmapo: A PHY OFDM Mid Power Offset |
BE 32 bit |
0x30-0x32 |
ofdmalpo: A PHY OFDM Low Power Offset |
BE 32 bit |
0x34-0x36 |
ofdmahpo: A PHY OFDM Low Power Offset |
BE 32 bit |
|
GPIO LED Powersave Duty Cycle |
BE 32 bit |
0x42-0x44 |
bits 31-24: On Count |
|
bits 23-16: Unused |
|
|
bits 15-8: Off Count |
|
|
bits 7-0: Unused |
|
|
|
cckpo - CCK Power Offset |
|
0x78 |
bits 3-0: CCK Rate 1M Power Offset |
|
bits 7-4: CCK Rate 2M Power Offset |
|
|
bits 11-8: CCK Rate 5.5M Power Offset |
|
|
bits 15-12: CCK Rate 11M Power Offset |
|
|
0x7A-0x7C |
ofdmgpo - G PHY OFDM Power Offset |
BE 32 bit |
GPIO
If the value in the SPROM isn't 0 or 0xFFFF, the pin should be configured. GPIO pins 0 and 2 are stored in bits 7-0 of offsets 0x64 and 0x66 respectively. GPIO pins 1 and 3 are stored in bits 15-8 of offsets 0x64 and 0x66 respectively.
Calculating the CRC
The CRC value is a crc8 calculated over the first 127 bytes (that's all excluding the crc8 byte) in the SPROM (which is the crc8 byte) after byte-reversing each 16 bit word. The starting value for the crc8 is 0xFF and the final value is XOR'ed with 0xFF, the polynomial is x8+x7+x6+x4+x2+1.
Writing to the SPROM
In order to write to the SPROM, or the PCI config space SPROM Control register (pci config space 0x88) with 0x10 (WRITE ENABLE) and wait 500 msecs, then write each 16-bit word the the correct offset in the MMIO space delaying 20 msecs after each write. Then turn off the write enable bit again and again wait 500 msecs.