14 #include <linux/pci.h>
17 #include <linux/slab.h>
42 if (get_fallback_sprom)
44 get_fallback_sprom = sprom_callback;
49 static int bcma_fill_sprom_with_fallback(
struct bcma_bus *
bus,
54 if (!get_fallback_sprom) {
59 err = get_fallback_sprom(bus, out);
63 bcma_debug(bus,
"Using SPROM revision %d provided by platform.\n",
67 bcma_warn(bus,
"Using fallback SPROM failed (err %d)\n", err);
79 sprom[i] = bcma_read16(bus->
drv_cc.core,
90 static const u8 t[] = {
91 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
92 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
93 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
94 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
95 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
96 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
97 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
98 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
99 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
100 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
101 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
102 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
103 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
104 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
105 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
106 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
107 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
108 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
109 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
110 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
111 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
112 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
113 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
114 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
115 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
116 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
117 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
118 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
119 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
120 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
121 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
122 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
124 return t[crc ^
data];
127 static u8 bcma_sprom_crc(
const u16 *sprom)
132 for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) {
133 crc = bcma_crc8(crc, sprom[word] & 0x00FF);
134 crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
136 crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF);
142 static int bcma_sprom_check_crc(
const u16 *sprom)
148 crc = bcma_sprom_crc(sprom);
151 if (crc != expected_crc)
157 static int bcma_sprom_valid(
const u16 *sprom)
162 err = bcma_sprom_check_crc(sprom);
167 if (revision != 8 && revision != 9) {
168 pr_err(
"Unsupported SPROM revision: %d\n", revision);
179 #define SPOFF(offset) ((offset) / sizeof(u16))
181 #define SPEX(_field, _offset, _mask, _shift) \
182 bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift))
184 #define SPEX32(_field, _offset, _mask, _shift) \
185 bus->sprom._field = ((((u32)sprom[SPOFF((_offset)+2)] << 16 | \
186 sprom[SPOFF(_offset)]) & (_mask)) >> (_shift))
188 #define SPEX_ARRAY8(_field, _offset, _mask, _shift) \
190 SPEX(_field[0], _offset + 0, _mask, _shift); \
191 SPEX(_field[1], _offset + 2, _mask, _shift); \
192 SPEX(_field[2], _offset + 4, _mask, _shift); \
193 SPEX(_field[3], _offset + 6, _mask, _shift); \
194 SPEX(_field[4], _offset + 8, _mask, _shift); \
195 SPEX(_field[5], _offset + 10, _mask, _shift); \
196 SPEX(_field[6], _offset + 12, _mask, _shift); \
197 SPEX(_field[7], _offset + 14, _mask, _shift); \
200 static void bcma_sprom_extract_r8(
struct bcma_bus *bus,
const u16 *sprom)
204 u16 pwr_info_offset[] = {
211 bus->
sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
214 for (i = 0; i < 3; i++) {
266 for (i = 0; i <
ARRAY_SIZE(pwr_info_offset); i++) {
267 o = pwr_info_offset[
i];
453 static bool bcma_sprom_ext_available(
struct bcma_bus *bus)
459 if (bus->
drv_cc.core->id.rev >= 31) {
463 srom_control = bcma_read32(bus->
drv_cc.core,
483 return chip_status & present_mask;
489 static bool bcma_sprom_onchip_available(
struct bcma_bus *bus)
534 static int bcma_sprom_onchip_offset(
struct bcma_bus *bus)
557 if (!bcma_sprom_ext_available(bus)) {
565 sprom_onchip = bcma_sprom_onchip_available(bus);
568 offset = bcma_sprom_onchip_offset(bus);
570 if (!offset || !sprom_onchip) {
576 err = bcma_fill_sprom_with_fallback(bus, &bus->
sprom);
581 sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4,
sizeof(
u16),
590 bcma_debug(bus,
"SPROM offset 0x%x\n", offset);
591 bcma_sprom_read(bus, offset, sprom);
597 err = bcma_sprom_valid(sprom);
601 bcma_sprom_extract_r8(bus, sprom);