20 #include <linux/slab.h>
21 #include <linux/pci.h>
28 #define SSB_VERBOSE_PCICORESWITCH_DEBUG 0
50 if (cur_core == coreidx)
69 #if SSB_VERBOSE_PCICORESWITCH_DEBUG
71 "Switching to %s core, index %d\n",
80 spin_unlock_irqrestore(&bus->
bar_lock, flags);
113 if (what & SSB_GPIO_XTAL) {
129 out &= ~SSB_GPIO_PLL;
147 out &= ~SSB_GPIO_XTAL;
165 printk(
KERN_ERR PFX "Error: ssb_pci_xtal() could not access PCI config space!\n");
171 #define SPOFF(offset) ((offset) / sizeof(u16))
173 #define SPEX16(_outvar, _offset, _mask, _shift) \
174 out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
175 #define SPEX32(_outvar, _offset, _mask, _shift) \
176 out->_outvar = ((((u32)in[SPOFF((_offset)+2)] << 16 | \
177 in[SPOFF(_offset)]) & (_mask)) >> (_shift))
178 #define SPEX(_outvar, _offset, _mask, _shift) \
179 SPEX16(_outvar, _offset, _mask, _shift)
181 #define SPEX_ARRAY8(_field, _offset, _mask, _shift) \
183 SPEX(_field[0], _offset + 0, _mask, _shift); \
184 SPEX(_field[1], _offset + 2, _mask, _shift); \
185 SPEX(_field[2], _offset + 4, _mask, _shift); \
186 SPEX(_field[3], _offset + 6, _mask, _shift); \
187 SPEX(_field[4], _offset + 8, _mask, _shift); \
188 SPEX(_field[5], _offset + 10, _mask, _shift); \
189 SPEX(_field[6], _offset + 12, _mask, _shift); \
190 SPEX(_field[7], _offset + 14, _mask, _shift); \
197 static const u8 t[] = {
198 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
199 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
200 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
201 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
202 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
203 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
204 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
205 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
206 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
207 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
208 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
209 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
210 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
211 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
212 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
213 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
214 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
215 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
216 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
217 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
218 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
219 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
220 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
221 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
222 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
223 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
224 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
225 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
226 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
227 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
228 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
229 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
231 return t[crc ^
data];
239 for (word = 0; word < size - 1; word++) {
240 crc = ssb_crc8(crc, sprom[word] & 0x00FF);
241 crc = ssb_crc8(crc, (sprom[word] & 0xFF00) >> 8);
243 crc = ssb_crc8(crc, sprom[size - 1] & 0x00FF);
249 static int sprom_check_crc(
const u16 *sprom,
size_t size)
255 crc = ssb_sprom_crc(sprom, size);
258 if (crc != expected_crc)
274 static int sprom_do_write(
struct ssb_bus *bus,
const u16 *sprom)
282 err = pci_read_config_dword(pdev,
SSB_SPROMCTL, &spromctl);
286 err = pci_write_config_dword(pdev,
SSB_SPROMCTL, spromctl);
291 for (i = 0; i <
size; i++) {
294 else if (i == size / 2)
296 else if (i == (size * 3) / 4)
304 err = pci_read_config_dword(pdev,
SSB_SPROMCTL, &spromctl);
308 err = pci_write_config_dword(pdev,
SSB_SPROMCTL, spromctl);
321 static s8 r123_extract_antgain(
u8 sprom_revision,
const u16 *
in,
328 gain = (v &
mask) >> shift;
331 if (sprom_revision == 1) {
336 gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2);
355 for (i = 0; i < 3; i++) {
356 v = in[
SPOFF(loc[0]) +
i];
360 for (i = 0; i < 3; i++) {
361 v = in[
SPOFF(loc[1]) +
i];
364 for (i = 0; i < 3; i++) {
365 v = in[
SPOFF(loc[2]) +
i];
416 static void sprom_extract_r458(
struct ssb_sprom *out,
const u16 *in)
455 static void sprom_extract_r45(
struct ssb_sprom *out,
const u16 *in)
466 for (i = 0; i < 3; i++) {
467 v = in[
SPOFF(il0mac_offset) +
i];
525 sprom_extract_r458(out, in);
530 static void sprom_extract_r8(
struct ssb_sprom *out,
const u16 *in)
534 u16 pwr_info_offset[] = {
542 for (i = 0; i < 3; i++) {
624 for (i = 0; i <
ARRAY_SIZE(pwr_info_offset); i++) {
625 o = pwr_info_offset[
i];
735 sprom_extract_r458(out, in);
743 memset(out, 0,
sizeof(*out));
745 out->
revision = in[size - 1] & 0x00FF;
750 if ((bus->
chip_id & 0xFF00) == 0x4400) {
762 sprom_extract_r123(out, in);
766 sprom_extract_r45(out, in);
769 sprom_extract_r8(out, in);
773 " revision %d detected. Will extract"
776 sprom_extract_r123(out, in);
787 static int ssb_pci_sprom_get(
struct ssb_bus *bus,
803 if (bus->
chipco.dev->id.revision >= 31)
805 else if (bus->
chip_id == 0x4312 &&
806 (bus->
chipco.status & 0x03) == 2)
819 sprom_do_read(bus, buf);
829 sprom_do_read(bus, buf);
839 " fallback SPROM failed (err %d)\n",
843 " revision %d provided by"
849 " SPROM CRC (corrupt SPROM)\n");
852 err = sprom_extract(bus, sprom, buf, bus->
sprom_size);
859 static void ssb_pci_get_boardinfo(
struct ssb_bus *bus,
871 err = ssb_pci_sprom_get(bus, &iv->
sprom);
874 ssb_pci_get_boardinfo(bus, &iv->
boardinfo);
880 #ifdef CONFIG_SSB_DEBUG
881 static int ssb_pci_assert_buspower(
struct ssb_bus *bus)
883 if (
likely(bus->powered_up))
887 "while accessing PCI MMIO space\n");
888 if (bus->power_warn_count <= 10) {
889 bus->power_warn_count++;
896 static inline int ssb_pci_assert_buspower(
struct ssb_bus *bus)
906 if (
unlikely(ssb_pci_assert_buspower(bus)))
919 if (
unlikely(ssb_pci_assert_buspower(bus)))
932 if (
unlikely(ssb_pci_assert_buspower(bus)))
941 #ifdef CONFIG_SSB_BLOCKIO
948 if (
unlikely(ssb_pci_assert_buspower(bus)))
972 memset(buffer, 0xFF, count);
980 if (
unlikely(ssb_pci_assert_buspower(bus)))
993 if (
unlikely(ssb_pci_assert_buspower(bus)))
1006 if (
unlikely(ssb_pci_assert_buspower(bus)))
1015 #ifdef CONFIG_SSB_BLOCKIO
1016 static void ssb_pci_block_write(
struct ssb_device *dev,
const void *buffer,
1017 size_t count,
u16 offset,
u8 reg_width)
1022 if (
unlikely(ssb_pci_assert_buspower(bus)))
1028 switch (reg_width) {
1048 .read8 = ssb_pci_read8,
1049 .read16 = ssb_pci_read16,
1050 .read32 = ssb_pci_read32,
1051 .write8 = ssb_pci_write8,
1052 .write16 = ssb_pci_write16,
1053 .write32 = ssb_pci_write32,
1054 #ifdef CONFIG_SSB_BLOCKIO
1055 .block_read = ssb_pci_block_read,
1056 .block_write = ssb_pci_block_write,
1074 static ssize_t ssb_pci_attr_sprom_store(
struct device *pcidev,
1076 const char *buf,
size_t count)
1086 sprom_check_crc, sprom_do_write);
1090 ssb_pci_attr_sprom_show,
1091 ssb_pci_attr_sprom_store);