bmips: add B43 SPROM PCI fixups
[openwrt/openwrt.git] / target / linux / bmips / files / arch / mips / bmips / b43-sprom.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * B43 Fallback SPROM Driver
4 *
5 * Copyright (C) 2020 Álvaro Fernández Rojas <noltari@gmail.com>
6 * Copyright (C) 2014 Jonas Gorski <jonas.gorski@gmail.com>
7 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
8 * Copyright (C) 2008 Florian Fainelli <f.fainelli@gmail.com>
9 */
10
11 #include <linux/bcma/bcma.h>
12 #include <linux/etherdevice.h>
13 #include <linux/init.h>
14 #include <linux/kernel.h>
15 #include <linux/mtd/mtd.h>
16 #include <linux/of_net.h>
17 #include <linux/of_platform.h>
18 #include <linux/ssb/ssb.h>
19
20 enum b43_sprom_type {
21 B43_SPROM_SSB,
22 B43_SPROM_BCMA,
23 B43_SPROM_NUM
24 };
25
26 struct b43_sprom_raw {
27 u16 *map;
28 size_t size;
29 u8 type;
30 };
31
32 struct b43_sprom {
33 struct device *dev;
34 struct ssb_sprom sprom;
35 u32 pci_bus;
36 u32 pci_dev;
37 u8 mac[ETH_ALEN];
38 int devid_override;
39 };
40
41 static struct b43_sprom b43_sprom;
42
43 #if defined (CONFIG_SSB_PCIHOST)
44 static u16 bcm4306_sprom_map[] = {
45 0x4001, 0x0000, 0x0453, 0x14e4, 0x4320, 0x8000, 0x0002, 0x0002,
46 0x1000, 0x1800, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff,
47 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
48 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff,
49 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff,
50 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x3034, 0x14d4,
51 0xfa91, 0xfe60, 0xffff, 0xffff, 0x004c, 0xffff, 0xffff, 0xffff,
52 0x003e, 0x0a49, 0xff02, 0x0000, 0xff10, 0xffff, 0xffff, 0x0002,
53 };
54
55 struct b43_sprom_raw bcm4306_sprom = {
56 .map = bcm4306_sprom_map,
57 .size = ARRAY_SIZE(bcm4306_sprom_map),
58 .type = B43_SPROM_SSB,
59 };
60
61 static u16 bcm4318_sprom_map[] = {
62 0x2001, 0x0000, 0x0449, 0x14e4, 0x4318, 0x8000, 0x0002, 0x0000,
63 0x1000, 0x1800, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff,
64 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
65 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0xffff, 0xffff, 0xffff,
66 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0x0000, 0xffff,
67 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x3046, 0x15a7,
68 0xfab0, 0xfe97, 0xffff, 0xffff, 0x0048, 0xffff, 0xffff, 0xffff,
69 0x003e, 0xea49, 0xff02, 0x0000, 0xff08, 0xffff, 0xffff, 0x0002,
70 };
71
72 struct b43_sprom_raw bcm4318_sprom = {
73 .map = bcm4318_sprom_map,
74 .size = ARRAY_SIZE(bcm4318_sprom_map),
75 .type = B43_SPROM_SSB,
76 };
77
78 static u16 bcm4321_sprom_map[] = {
79 0x3001, 0x0000, 0x046c, 0x14e4, 0x4328, 0x8000, 0x0002, 0x0000,
80 0x1000, 0x1800, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff,
81 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
82 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
83 0x5372, 0x0032, 0x4a01, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
84 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0x0303, 0x0202,
85 0xffff, 0x2728, 0x5b5b, 0x222b, 0x5b5b, 0x1927, 0x5b5b, 0x1e36,
86 0x5b5b, 0x303c, 0x3030, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
87 0x3e4c, 0x0000, 0x0000, 0x0000, 0x0000, 0x7838, 0x3a34, 0x0000,
88 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
89 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0x3e4c,
90 0x0000, 0x0000, 0x0000, 0x0000, 0x7838, 0x3a34, 0x0000, 0x0000,
91 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
92 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
93 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
94 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
95 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
96 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
97 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
98 0xffff, 0xffff, 0xffff, 0xffff, 0x0008, 0x0000, 0x0000, 0x0000,
99 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
100 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
101 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
102 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
103 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
104 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
105 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
106 0xffff, 0xffff, 0xffff, 0x0004,
107 };
108
109 struct b43_sprom_raw bcm4321_sprom = {
110 .map = bcm4321_sprom_map,
111 .size = ARRAY_SIZE(bcm4321_sprom_map),
112 .type = B43_SPROM_SSB,
113 };
114
115 static u16 bcm4322_sprom_map[] = {
116 0x3001, 0x0000, 0x04bc, 0x14e4, 0x432c, 0x8000, 0x0002, 0x0000,
117 0x1730, 0x1800, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff,
118 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
119 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
120 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
121 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
122 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
123 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
124 0x5372, 0x1209, 0x0200, 0x0000, 0x0400, 0x0000, 0x0000, 0x0000,
125 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0x0303, 0x0202,
126 0xffff, 0x0033, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0301,
127 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
128 0x2048, 0xfe9a, 0x1571, 0xfabd, 0xffff, 0xffff, 0xffff, 0xffff,
129 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
130 0x2048, 0xfeb9, 0x159f, 0xfadd, 0xffff, 0xffff, 0xffff, 0xffff,
131 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
132 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
133 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
134 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
135 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
136 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
137 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
138 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
139 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
140 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
141 0x0000, 0x0000, 0x0000, 0x3333, 0x5555, 0xffff, 0xffff, 0xffff,
142 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
143 0xffff, 0xffff, 0xffff, 0x0008,
144 };
145
146 struct b43_sprom_raw bcm4322_sprom = {
147 .map = bcm4322_sprom_map,
148 .size = ARRAY_SIZE(bcm4322_sprom_map),
149 .type = B43_SPROM_SSB,
150 };
151
152 static u16 bcm43222_sprom_map[] = {
153 0x2001, 0x0000, 0x04d4, 0x14e4, 0x4351, 0x8000, 0x0002, 0x0000,
154 0x1730, 0x1800, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff,
155 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
156 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
157 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
158 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
159 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
160 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
161 0x5372, 0x2305, 0x0200, 0x0000, 0x2400, 0x0000, 0x0000, 0x0000,
162 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0x0303, 0x0202,
163 0xffff, 0x0033, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0325,
164 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
165 0x204c, 0xfea6, 0x1717, 0xfa6d, 0xffff, 0xffff, 0xffff, 0xffff,
166 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
167 0x204c, 0xfeb8, 0x167c, 0xfa9e, 0xffff, 0xffff, 0xffff, 0xffff,
168 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
169 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
170 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
171 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
172 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
173 0x0000, 0x3333, 0x3333, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
174 0x0000, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333, 0x3333,
175 0x3333, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
176 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
177 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
178 0x0000, 0x0000, 0x0000, 0x0004, 0x0000, 0xffff, 0xffff, 0xffff,
179 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
180 0xffff, 0xffff, 0xffff, 0x0008,
181 };
182
183 struct b43_sprom_raw bcm43222_sprom = {
184 .map = bcm43222_sprom_map,
185 .size = ARRAY_SIZE(bcm43222_sprom_map),
186 .type = B43_SPROM_SSB,
187 };
188 #endif /* CONFIG_SSB_PCIHOST */
189
190 #if defined(CONFIG_BCMA_HOST_PCI)
191 static u16 bcm4313_sprom_map[] = {
192 0x2801, 0x0000, 0x0510, 0x14e4, 0x0078, 0xedbe, 0x0000, 0x2bc4,
193 0x2a64, 0x2964, 0x2c64, 0x3ce7, 0x46ff, 0x47ff, 0x0c00, 0x0820,
194 0x0030, 0x1002, 0x9f28, 0x5d44, 0x8080, 0x1d8f, 0x0032, 0x0100,
195 0xdf00, 0x71f5, 0x8400, 0x0083, 0x8500, 0x2010, 0x0001, 0x0000,
196 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
197 0x0000, 0x0000, 0x1008, 0x0305, 0x0000, 0x0000, 0x0000, 0x0000,
198 0x4727, 0x8000, 0x0002, 0x0000, 0x1f30, 0x1800, 0x0000, 0x0000,
199 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
200 0x5372, 0x1215, 0x2a00, 0x0800, 0x0800, 0x0000, 0x0000, 0x0000,
201 0x0000, 0x0000, 0x0003, 0xffff, 0x88ff, 0xffff, 0x0003, 0x0202,
202 0xffff, 0x0011, 0x007a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0201,
203 0x0000, 0x7800, 0x7c0a, 0x0398, 0x0008, 0x0000, 0x0000, 0x0000,
204 0x0044, 0x1684, 0xfd0d, 0xff35, 0x0000, 0x0000, 0x0000, 0x0000,
205 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
206 0x0048, 0xfed2, 0x15d9, 0xfac6, 0x0000, 0x0000, 0x0000, 0x0000,
207 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
208 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
209 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
210 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
211 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
212 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
213 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
214 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
215 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
216 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
217 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
218 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
219 0x0000, 0x0000, 0x0000, 0x0008,
220 };
221
222 struct b43_sprom_raw bcm4313_sprom = {
223 .map = bcm4313_sprom_map,
224 .size = ARRAY_SIZE(bcm4313_sprom_map),
225 .type = B43_SPROM_BCMA,
226 };
227
228 static u16 bcm4331_sprom_map[] = {
229 0x2801, 0x0000, 0x0525, 0x14e4, 0x0078, 0xedbe, 0x0000, 0x2bc4,
230 0x2a64, 0x2964, 0x2c64, 0x3ce7, 0x46ff, 0x47ff, 0x0c00, 0x0820,
231 0x0030, 0x1002, 0x9f28, 0x5d44, 0x8080, 0x1d8f, 0x0032, 0x0100,
232 0xdf00, 0x71f5, 0x8400, 0x0083, 0x8500, 0x2010, 0x0001, 0xffff,
233 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
234 0xffff, 0xffff, 0x1010, 0x0005, 0xffff, 0xffff, 0xffff, 0xffff,
235 0x4331, 0x8000, 0x0002, 0x0000, 0x1f30, 0x1800, 0x0000, 0x0000,
236 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
237 0x5372, 0x1104, 0x0200, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
238 0x0000, 0x0000, 0x0000, 0xffff, 0x88ff, 0xffff, 0x0707, 0x0202,
239 0xff02, 0x0077, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0325,
240 0x0325, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
241 0x2048, 0xfe56, 0x16f2, 0xfa44, 0x3e3c, 0x3c3c, 0xfe77, 0x1657,
242 0xfa75, 0xffff, 0xffff, 0xffff, 0xfe76, 0x15da, 0xfa85, 0x0000,
243 0x2048, 0xfe5c, 0x16b5, 0xfa56, 0x3e3c, 0x3c3c, 0xfe7c, 0x169d,
244 0xfa6b, 0xffff, 0xffff, 0xffff, 0xfe7a, 0x1597, 0xfa97, 0x0000,
245 0x2048, 0xfe68, 0x1734, 0xfa46, 0x3e3c, 0x3c3c, 0xfe7f, 0x15e4,
246 0xfa94, 0xffff, 0xffff, 0xffff, 0xfe7d, 0x1582, 0xfa9f, 0x0000,
247 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
248 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
249 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
250 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
251 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
252 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
253 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
254 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff,
255 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
256 0xffff, 0xffff, 0xffff, 0x0009,
257 };
258
259 struct b43_sprom_raw bcm4331_sprom = {
260 .map = bcm4331_sprom_map,
261 .size = ARRAY_SIZE(bcm4331_sprom_map),
262 .type = B43_SPROM_BCMA,
263 };
264
265 static u16 bcm43131_sprom_map[] = {
266 0x2801, 0x0000, 0x05f7, 0x14e4, 0x0070, 0xedbe, 0x1c00, 0x2bc4,
267 0x2a64, 0x2964, 0x2c64, 0x3ce7, 0x46ff, 0x47ff, 0x0c00, 0x0820,
268 0x0030, 0x1002, 0x9f28, 0x5d44, 0x8080, 0x1d8f, 0x0032, 0x0100,
269 0xdf00, 0x71f5, 0x8400, 0x0083, 0x8500, 0x2010, 0x0001, 0x0000,
270 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
271 0x0000, 0x0000, 0x1008, 0x0305, 0x0000, 0x0000, 0x0000, 0x0000,
272 0x43aa, 0x8000, 0x0002, 0x0000, 0x1f30, 0x1800, 0x0000, 0x0000,
273 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
274 0x5372, 0x1280, 0x0200, 0x0000, 0x8800, 0x0000, 0x0000, 0x0000,
275 0x0000, 0x0000, 0x0003, 0xffff, 0x88ff, 0xffff, 0x0002, 0x0202,
276 0xffff, 0x0022, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0415,
277 0x0000, 0x7800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
278 0x204c, 0xfe96, 0x192c, 0xfa15, 0x0000, 0x0000, 0x0000, 0x0000,
279 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
280 0x204c, 0xfe91, 0x1950, 0xfa0a, 0x0000, 0x0000, 0x0000, 0x0000,
281 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
282 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
283 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
284 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
285 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
286 0x0000, 0x4444, 0x4444, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
287 0x0000, 0x4444, 0x4444, 0x4444, 0x4444, 0x6666, 0x6666, 0x6666,
288 0x6666, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
289 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
290 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
291 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff,
292 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
293 0xffff, 0xffff, 0xffff, 0x0008,
294 };
295
296 struct b43_sprom_raw bcm43131_sprom = {
297 .map = bcm43131_sprom_map,
298 .size = ARRAY_SIZE(bcm43131_sprom_map),
299 .type = B43_SPROM_BCMA,
300 };
301
302 static u16 bcm43217_sprom_map[] = {
303 0x2801, 0x0000, 0x05e9, 0x14e4, 0x0070, 0xedbe, 0x0000, 0x2bc4,
304 0x2a64, 0x2964, 0x2c64, 0x3ce7, 0x46ff, 0x47ff, 0x0c00, 0x0820,
305 0x0030, 0x1002, 0x9f28, 0x5d44, 0x8080, 0x1d8f, 0x0032, 0x0100,
306 0xdf00, 0x71f5, 0x8400, 0x0083, 0x8500, 0x2010, 0x0001, 0x0000,
307 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
308 0x0000, 0x0000, 0x1008, 0x0305, 0x0000, 0x0000, 0x0000, 0x0000,
309 0x43a9, 0x8000, 0x0002, 0x0000, 0x1f30, 0x1800, 0x0000, 0x0000,
310 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
311 0x5372, 0x1252, 0x0200, 0x0000, 0x9800, 0x0000, 0x0000, 0x0000,
312 0x0000, 0x0000, 0x0003, 0xffff, 0x88ff, 0xffff, 0x0003, 0x0202,
313 0xffff, 0x0033, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0415,
314 0x0000, 0x7800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
315 0x204c, 0xfe96, 0x192c, 0xfa15, 0x0000, 0x0000, 0x0000, 0x0000,
316 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
317 0x204c, 0xfe91, 0x1950, 0xfa0a, 0x0000, 0x0000, 0x0000, 0x0000,
318 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
319 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
320 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
321 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
322 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
323 0x0000, 0x4444, 0x4444, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
324 0x0000, 0x4444, 0x4444, 0x4444, 0x4444, 0x6666, 0x6666, 0x6666,
325 0x6666, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
326 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
327 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
328 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff,
329 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
330 0xffff, 0xffff, 0xffff, 0x7a08,
331 };
332
333 struct b43_sprom_raw bcm43217_sprom = {
334 .map = bcm43217_sprom_map,
335 .size = ARRAY_SIZE(bcm43217_sprom_map),
336 .type = B43_SPROM_BCMA,
337 };
338
339 static u16 bcm43225_sprom_map[] = {
340 0x2801, 0x0000, 0x04da, 0x14e4, 0x0078, 0xedbe, 0x0000, 0x2bc4,
341 0x2a64, 0x2964, 0x2c64, 0x3ce7, 0x46ff, 0x47ff, 0x0c00, 0x0820,
342 0x0030, 0x1002, 0x9f28, 0x5d44, 0x8080, 0x1d8f, 0x0032, 0x0100,
343 0xdf00, 0x71f5, 0x8400, 0x0083, 0x8500, 0x2010, 0x0001, 0xffff,
344 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
345 0xffff, 0xffff, 0x1008, 0x0005, 0xffff, 0xffff, 0xffff, 0xffff,
346 0x4357, 0x8000, 0x0002, 0x0000, 0x1f30, 0x1800, 0x0000, 0x0000,
347 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
348 0x5372, 0x1200, 0x0200, 0x0000, 0x1000, 0x0000, 0x0000, 0x0000,
349 0x0000, 0x0000, 0x0000, 0x88ff, 0xffff, 0xffff, 0x0303, 0x0202,
350 0xffff, 0x0033, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0325,
351 0xffff, 0x7800, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
352 0x204e, 0xfead, 0x1611, 0xfa9a, 0xffff, 0xffff, 0xffff, 0xffff,
353 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
354 0x204e, 0xfec1, 0x1674, 0xfab2, 0xffff, 0xffff, 0xffff, 0xffff,
355 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
356 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
357 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
358 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
359 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
360 0x0000, 0x5555, 0x5555, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
361 0x0000, 0x5555, 0x7555, 0x5555, 0x7555, 0x5555, 0x7555, 0x5555,
362 0x7555, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
363 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
364 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
365 0x0000, 0x0000, 0x0000, 0x0002, 0x0000, 0xffff, 0xffff, 0xffff,
366 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
367 0xffff, 0xffff, 0xffff, 0x0008,
368 };
369
370 struct b43_sprom_raw bcm43225_sprom = {
371 .map = bcm43225_sprom_map,
372 .size = ARRAY_SIZE(bcm43225_sprom_map),
373 .type = B43_SPROM_BCMA,
374 };
375
376 static u16 bcm43227_sprom_map[] = {
377 0x2801, 0x0000, 0x0543, 0x14e4, 0x0070, 0xedbe, 0x0000, 0x2bc4,
378 0x2a64, 0x2964, 0x2c64, 0x3ce7, 0x46ff, 0x47ff, 0x0c00, 0x0820,
379 0x0030, 0x1002, 0x9f28, 0x5d44, 0x8080, 0x1d8f, 0x0032, 0x0100,
380 0xdf00, 0x71f5, 0x8400, 0x0083, 0x8500, 0x2010, 0x0001, 0x0000,
381 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
382 0x0000, 0x0000, 0x1008, 0x0305, 0x0000, 0x0000, 0x0000, 0x0000,
383 0x4358, 0x8000, 0x0002, 0x0000, 0x1f30, 0x1800, 0x0000, 0x0000,
384 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
385 0x5372, 0x1402, 0x0200, 0x0000, 0x0800, 0x0000, 0x0000, 0x0000,
386 0x0000, 0x0000, 0x0003, 0xffff, 0x88ff, 0xffff, 0x0003, 0x0202,
387 0xffff, 0x0033, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0415,
388 0x0000, 0x7800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
389 0x204c, 0xff36, 0x16d2, 0xfaae, 0x0000, 0x0000, 0x0000, 0x0000,
390 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
391 0x204c, 0xfeca, 0x159b, 0xfa80, 0x0000, 0x0000, 0x0000, 0x0000,
392 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
393 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
394 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
395 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
396 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
397 0x0000, 0x4444, 0x4444, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
398 0x0000, 0x4444, 0x4444, 0x4444, 0x4444, 0x6666, 0x6666, 0x6666,
399 0x6666, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
400 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
401 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
402 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff,
403 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
404 0xffff, 0xffff, 0xffff, 0x0008,
405 };
406
407 struct b43_sprom_raw bcm43227_sprom = {
408 .map = bcm43227_sprom_map,
409 .size = ARRAY_SIZE(bcm43227_sprom_map),
410 .type = B43_SPROM_BCMA,
411 };
412
413 static u16 bcm43228_sprom_map[] = {
414 0x2801, 0x0000, 0x0011, 0x1028, 0x0070, 0xedbe, 0x0000, 0x2bc4,
415 0x2a64, 0x2964, 0x2c64, 0x3ce7, 0x46ff, 0x47ff, 0x0c00, 0x0820,
416 0x0030, 0x1002, 0x9f28, 0x5d44, 0x8080, 0x1d8f, 0x0032, 0x0100,
417 0xdf00, 0x71f5, 0x8400, 0x0083, 0x8500, 0x2010, 0x0001, 0x0000,
418 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
419 0x0000, 0x0000, 0x1008, 0x0305, 0x0000, 0x0000, 0x0000, 0x0000,
420 0x4359, 0x8000, 0x0002, 0x0000, 0x1f30, 0x1800, 0x0000, 0x0000,
421 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
422 0x5372, 0x1203, 0x0200, 0x0000, 0x0800, 0x0000, 0x0000, 0x0000,
423 0x0000, 0x0000, 0x0003, 0xffff, 0x88ff, 0xffff, 0x0303, 0x0202,
424 0xffff, 0x0033, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0215,
425 0x0215, 0x7800, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
426 0x204c, 0xff73, 0x1762, 0xfaa4, 0x3e34, 0x3434, 0xfea1, 0x154c,
427 0xfad0, 0xfea1, 0x144c, 0xfafb, 0xfe7b, 0x13fe, 0xfafc, 0x0000,
428 0x204c, 0xff41, 0x16a3, 0xfa8f, 0x3e34, 0x3434, 0xfe97, 0x1446,
429 0xfb05, 0xfe97, 0x1346, 0xfb32, 0xfeb9, 0x1516, 0xfaee, 0x0000,
430 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
431 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
432 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
433 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
434 0x0000, 0x4444, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
435 0x0000, 0x4444, 0x4444, 0x4444, 0x4444, 0x8888, 0x8888, 0x8888,
436 0x8888, 0x0000, 0x0000, 0x0000, 0x0000, 0x3333, 0x3333, 0x3333,
437 0x3333, 0x0000, 0x0000, 0x0000, 0x0000, 0x3333, 0x3333, 0x3333,
438 0x3333, 0x0000, 0x0000, 0x0000, 0x0000, 0x3333, 0x3333, 0x3333,
439 0x3333, 0x0000, 0x0000, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff,
440 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff,
441 0xffff, 0xffff, 0xffff, 0xf008,
442 };
443
444 struct b43_sprom_raw bcm43228_sprom = {
445 .map = bcm43228_sprom_map,
446 .size = ARRAY_SIZE(bcm43228_sprom_map),
447 .type = B43_SPROM_BCMA,
448 };
449 #endif /* CONFIG_BCMA_HOST_PCI */
450
451 /* Get the word-offset for a SSB_SPROM_XXX define. */
452 #define SPOFF(offset) ((offset) / sizeof(u16))
453 /* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */
454 #define SPEX16(_outvar, _offset, _mask, _shift) \
455 out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
456 #define SPEX32(_outvar, _offset, _mask, _shift) \
457 out->_outvar = ((((u32)in[SPOFF((_offset)+2)] << 16 | \
458 in[SPOFF(_offset)]) & (_mask)) >> (_shift))
459 #define SPEX(_outvar, _offset, _mask, _shift) \
460 SPEX16(_outvar, _offset, _mask, _shift)
461
462 #define SPEX_ARRAY8(_field, _offset, _mask, _shift) \
463 do { \
464 SPEX(_field[0], _offset + 0, _mask, _shift); \
465 SPEX(_field[1], _offset + 2, _mask, _shift); \
466 SPEX(_field[2], _offset + 4, _mask, _shift); \
467 SPEX(_field[3], _offset + 6, _mask, _shift); \
468 SPEX(_field[4], _offset + 8, _mask, _shift); \
469 SPEX(_field[5], _offset + 10, _mask, _shift); \
470 SPEX(_field[6], _offset + 12, _mask, _shift); \
471 SPEX(_field[7], _offset + 14, _mask, _shift); \
472 } while (0)
473
474
475 static s8 sprom_extract_antgain(u8 sprom_revision, const u16 *in, u16 offset,
476 u16 mask, u16 shift)
477 {
478 u16 v;
479 u8 gain;
480
481 v = in[SPOFF(offset)];
482 gain = (v & mask) >> shift;
483 if (gain == 0xFF)
484 gain = 2; /* If unset use 2dBm */
485 if (sprom_revision == 1) {
486 /* Convert to Q5.2 */
487 gain <<= 2;
488 } else {
489 /* Q5.2 Fractional part is stored in 0xC0 */
490 gain = ((gain & 0xC0) >> 6) | ((gain & 0x3F) << 2);
491 }
492
493 return (s8)gain;
494 }
495
496 static void sprom_extract_r23(struct ssb_sprom *out, const u16 *in)
497 {
498 SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
499 SPEX(opo, SSB_SPROM2_OPO, SSB_SPROM2_OPO_VALUE, 0);
500 SPEX(pa1lob0, SSB_SPROM2_PA1LOB0, 0xFFFF, 0);
501 SPEX(pa1lob1, SSB_SPROM2_PA1LOB1, 0xFFFF, 0);
502 SPEX(pa1lob2, SSB_SPROM2_PA1LOB2, 0xFFFF, 0);
503 SPEX(pa1hib0, SSB_SPROM2_PA1HIB0, 0xFFFF, 0);
504 SPEX(pa1hib1, SSB_SPROM2_PA1HIB1, 0xFFFF, 0);
505 SPEX(pa1hib2, SSB_SPROM2_PA1HIB2, 0xFFFF, 0);
506 SPEX(maxpwr_ah, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_HI, 0);
507 SPEX(maxpwr_al, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_LO,
508 SSB_SPROM2_MAXP_A_LO_SHIFT);
509 }
510
511 static void sprom_extract_r123(struct ssb_sprom *out, const u16 *in)
512 {
513 u16 loc[3];
514
515 if (out->revision == 3) /* rev 3 moved MAC */
516 loc[0] = SSB_SPROM3_IL0MAC;
517 else {
518 loc[0] = SSB_SPROM1_IL0MAC;
519 loc[1] = SSB_SPROM1_ET0MAC;
520 loc[2] = SSB_SPROM1_ET1MAC;
521 }
522
523 SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0);
524 SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A,
525 SSB_SPROM1_ETHPHY_ET1A_SHIFT);
526 SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
527 SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
528 SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
529 SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0);
530 if (out->revision == 1)
531 SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
532 SSB_SPROM1_BINF_CCODE_SHIFT);
533 SPEX(ant_available_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA,
534 SSB_SPROM1_BINF_ANTA_SHIFT);
535 SPEX(ant_available_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG,
536 SSB_SPROM1_BINF_ANTBG_SHIFT);
537 SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0);
538 SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0);
539 SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0);
540 SPEX(pa1b0, SSB_SPROM1_PA1B0, 0xFFFF, 0);
541 SPEX(pa1b1, SSB_SPROM1_PA1B1, 0xFFFF, 0);
542 SPEX(pa1b2, SSB_SPROM1_PA1B2, 0xFFFF, 0);
543 SPEX(gpio0, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P0, 0);
544 SPEX(gpio1, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P1,
545 SSB_SPROM1_GPIOA_P1_SHIFT);
546 SPEX(gpio2, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P2, 0);
547 SPEX(gpio3, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P3,
548 SSB_SPROM1_GPIOB_P3_SHIFT);
549 SPEX(maxpwr_a, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_A,
550 SSB_SPROM1_MAXPWR_A_SHIFT);
551 SPEX(maxpwr_bg, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_BG, 0);
552 SPEX(itssi_a, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_A,
553 SSB_SPROM1_ITSSI_A_SHIFT);
554 SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0);
555 SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
556
557 SPEX(alpha2[0], SSB_SPROM1_CCODE, 0xff00, 8);
558 SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0);
559
560 /* Extract the antenna gain values. */
561 out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in,
562 SSB_SPROM1_AGAIN,
563 SSB_SPROM1_AGAIN_BG,
564 SSB_SPROM1_AGAIN_BG_SHIFT);
565 out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in,
566 SSB_SPROM1_AGAIN,
567 SSB_SPROM1_AGAIN_A,
568 SSB_SPROM1_AGAIN_A_SHIFT);
569 if (out->revision >= 2)
570 sprom_extract_r23(out, in);
571 }
572
573 /* Revs 4 5 and 8 have partially shared layout */
574 static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in)
575 {
576 SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01,
577 SSB_SPROM4_TXPID2G0, SSB_SPROM4_TXPID2G0_SHIFT);
578 SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01,
579 SSB_SPROM4_TXPID2G1, SSB_SPROM4_TXPID2G1_SHIFT);
580 SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23,
581 SSB_SPROM4_TXPID2G2, SSB_SPROM4_TXPID2G2_SHIFT);
582 SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23,
583 SSB_SPROM4_TXPID2G3, SSB_SPROM4_TXPID2G3_SHIFT);
584
585 SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01,
586 SSB_SPROM4_TXPID5GL0, SSB_SPROM4_TXPID5GL0_SHIFT);
587 SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01,
588 SSB_SPROM4_TXPID5GL1, SSB_SPROM4_TXPID5GL1_SHIFT);
589 SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23,
590 SSB_SPROM4_TXPID5GL2, SSB_SPROM4_TXPID5GL2_SHIFT);
591 SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23,
592 SSB_SPROM4_TXPID5GL3, SSB_SPROM4_TXPID5GL3_SHIFT);
593
594 SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01,
595 SSB_SPROM4_TXPID5G0, SSB_SPROM4_TXPID5G0_SHIFT);
596 SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01,
597 SSB_SPROM4_TXPID5G1, SSB_SPROM4_TXPID5G1_SHIFT);
598 SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23,
599 SSB_SPROM4_TXPID5G2, SSB_SPROM4_TXPID5G2_SHIFT);
600 SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23,
601 SSB_SPROM4_TXPID5G3, SSB_SPROM4_TXPID5G3_SHIFT);
602
603 SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01,
604 SSB_SPROM4_TXPID5GH0, SSB_SPROM4_TXPID5GH0_SHIFT);
605 SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01,
606 SSB_SPROM4_TXPID5GH1, SSB_SPROM4_TXPID5GH1_SHIFT);
607 SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23,
608 SSB_SPROM4_TXPID5GH2, SSB_SPROM4_TXPID5GH2_SHIFT);
609 SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23,
610 SSB_SPROM4_TXPID5GH3, SSB_SPROM4_TXPID5GH3_SHIFT);
611 }
612
613 static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
614 {
615 static const u16 pwr_info_offset[] = {
616 SSB_SPROM4_PWR_INFO_CORE0, SSB_SPROM4_PWR_INFO_CORE1,
617 SSB_SPROM4_PWR_INFO_CORE2, SSB_SPROM4_PWR_INFO_CORE3
618 };
619 int i;
620
621 BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
622 ARRAY_SIZE(out->core_pwr_info));
623
624 SPEX(et0phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET0A, 0);
625 SPEX(et1phyaddr, SSB_SPROM4_ETHPHY, SSB_SPROM4_ETHPHY_ET1A,
626 SSB_SPROM4_ETHPHY_ET1A_SHIFT);
627 SPEX(board_rev, SSB_SPROM4_BOARDREV, 0xFFFF, 0);
628 SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0);
629 if (out->revision == 4) {
630 SPEX(alpha2[0], SSB_SPROM4_CCODE, 0xff00, 8);
631 SPEX(alpha2[1], SSB_SPROM4_CCODE, 0x00ff, 0);
632 SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
633 SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0);
634 SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0);
635 SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0);
636 } else {
637 SPEX(alpha2[0], SSB_SPROM5_CCODE, 0xff00, 8);
638 SPEX(alpha2[1], SSB_SPROM5_CCODE, 0x00ff, 0);
639 SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0);
640 SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0);
641 SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0);
642 SPEX(boardflags2_hi, SSB_SPROM5_BFL2HI, 0xFFFF, 0);
643 }
644 SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A,
645 SSB_SPROM4_ANTAVAIL_A_SHIFT);
646 SPEX(ant_available_bg, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_BG,
647 SSB_SPROM4_ANTAVAIL_BG_SHIFT);
648 SPEX(maxpwr_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_MAXP_BG_MASK, 0);
649 SPEX(itssi_bg, SSB_SPROM4_MAXP_BG, SSB_SPROM4_ITSSI_BG,
650 SSB_SPROM4_ITSSI_BG_SHIFT);
651 SPEX(maxpwr_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_MAXP_A_MASK, 0);
652 SPEX(itssi_a, SSB_SPROM4_MAXP_A, SSB_SPROM4_ITSSI_A,
653 SSB_SPROM4_ITSSI_A_SHIFT);
654 if (out->revision == 4) {
655 SPEX(gpio0, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P0, 0);
656 SPEX(gpio1, SSB_SPROM4_GPIOA, SSB_SPROM4_GPIOA_P1,
657 SSB_SPROM4_GPIOA_P1_SHIFT);
658 SPEX(gpio2, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P2, 0);
659 SPEX(gpio3, SSB_SPROM4_GPIOB, SSB_SPROM4_GPIOB_P3,
660 SSB_SPROM4_GPIOB_P3_SHIFT);
661 } else {
662 SPEX(gpio0, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P0, 0);
663 SPEX(gpio1, SSB_SPROM5_GPIOA, SSB_SPROM5_GPIOA_P1,
664 SSB_SPROM5_GPIOA_P1_SHIFT);
665 SPEX(gpio2, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P2, 0);
666 SPEX(gpio3, SSB_SPROM5_GPIOB, SSB_SPROM5_GPIOB_P3,
667 SSB_SPROM5_GPIOB_P3_SHIFT);
668 }
669
670 /* Extract the antenna gain values. */
671 out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in,
672 SSB_SPROM4_AGAIN01,
673 SSB_SPROM4_AGAIN0,
674 SSB_SPROM4_AGAIN0_SHIFT);
675 out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in,
676 SSB_SPROM4_AGAIN01,
677 SSB_SPROM4_AGAIN1,
678 SSB_SPROM4_AGAIN1_SHIFT);
679 out->antenna_gain.a2 = sprom_extract_antgain(out->revision, in,
680 SSB_SPROM4_AGAIN23,
681 SSB_SPROM4_AGAIN2,
682 SSB_SPROM4_AGAIN2_SHIFT);
683 out->antenna_gain.a3 = sprom_extract_antgain(out->revision, in,
684 SSB_SPROM4_AGAIN23,
685 SSB_SPROM4_AGAIN3,
686 SSB_SPROM4_AGAIN3_SHIFT);
687
688 /* Extract cores power info info */
689 for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
690 u16 o = pwr_info_offset[i];
691
692 SPEX(core_pwr_info[i].itssi_2g, o + SSB_SPROM4_2G_MAXP_ITSSI,
693 SSB_SPROM4_2G_ITSSI, SSB_SPROM4_2G_ITSSI_SHIFT);
694 SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SPROM4_2G_MAXP_ITSSI,
695 SSB_SPROM4_2G_MAXP, 0);
696
697 SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SPROM4_2G_PA_0, ~0, 0);
698 SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SPROM4_2G_PA_1, ~0, 0);
699 SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SPROM4_2G_PA_2, ~0, 0);
700 SPEX(core_pwr_info[i].pa_2g[3], o + SSB_SPROM4_2G_PA_3, ~0, 0);
701
702 SPEX(core_pwr_info[i].itssi_5g, o + SSB_SPROM4_5G_MAXP_ITSSI,
703 SSB_SPROM4_5G_ITSSI, SSB_SPROM4_5G_ITSSI_SHIFT);
704 SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SPROM4_5G_MAXP_ITSSI,
705 SSB_SPROM4_5G_MAXP, 0);
706 SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM4_5GHL_MAXP,
707 SSB_SPROM4_5GH_MAXP, 0);
708 SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM4_5GHL_MAXP,
709 SSB_SPROM4_5GL_MAXP, SSB_SPROM4_5GL_MAXP_SHIFT);
710
711 SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SPROM4_5GL_PA_0, ~0, 0);
712 SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SPROM4_5GL_PA_1, ~0, 0);
713 SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SPROM4_5GL_PA_2, ~0, 0);
714 SPEX(core_pwr_info[i].pa_5gl[3], o + SSB_SPROM4_5GL_PA_3, ~0, 0);
715 SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SPROM4_5G_PA_0, ~0, 0);
716 SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SPROM4_5G_PA_1, ~0, 0);
717 SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SPROM4_5G_PA_2, ~0, 0);
718 SPEX(core_pwr_info[i].pa_5g[3], o + SSB_SPROM4_5G_PA_3, ~0, 0);
719 SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SPROM4_5GH_PA_0, ~0, 0);
720 SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SPROM4_5GH_PA_1, ~0, 0);
721 SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SPROM4_5GH_PA_2, ~0, 0);
722 SPEX(core_pwr_info[i].pa_5gh[3], o + SSB_SPROM4_5GH_PA_3, ~0, 0);
723 }
724
725 sprom_extract_r458(out, in);
726
727 /* TODO - get remaining rev 4 stuff needed */
728 }
729
730 static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
731 {
732 int i;
733 u16 o;
734 static const u16 pwr_info_offset[] = {
735 SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
736 SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
737 };
738 BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
739 ARRAY_SIZE(out->core_pwr_info));
740
741 SPEX(board_rev, SSB_SPROM8_BOARDREV, 0xFFFF, 0);
742 SPEX(board_type, SSB_SPROM1_SPID, 0xFFFF, 0);
743 SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
744 SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
745 SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
746 SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0);
747 SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0);
748 SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, 0xFFFF, 0);
749 SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
750 SSB_SPROM8_ANTAVAIL_A_SHIFT);
751 SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
752 SSB_SPROM8_ANTAVAIL_BG_SHIFT);
753 SPEX(maxpwr_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_MAXP_BG_MASK, 0);
754 SPEX(itssi_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_ITSSI_BG,
755 SSB_SPROM8_ITSSI_BG_SHIFT);
756 SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
757 SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
758 SSB_SPROM8_ITSSI_A_SHIFT);
759 SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0);
760 SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK,
761 SSB_SPROM8_MAXP_AL_SHIFT);
762 SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
763 SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
764 SSB_SPROM8_GPIOA_P1_SHIFT);
765 SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
766 SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
767 SSB_SPROM8_GPIOB_P3_SHIFT);
768 SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0);
769 SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G,
770 SSB_SPROM8_TRI5G_SHIFT);
771 SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0);
772 SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH,
773 SSB_SPROM8_TRI5GH_SHIFT);
774 SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G, 0);
775 SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G,
776 SSB_SPROM8_RXPO5G_SHIFT);
777 SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0);
778 SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G,
779 SSB_SPROM8_RSSISMC2G_SHIFT);
780 SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G,
781 SSB_SPROM8_RSSISAV2G_SHIFT);
782 SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G,
783 SSB_SPROM8_BXA2G_SHIFT);
784 SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0);
785 SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G,
786 SSB_SPROM8_RSSISMC5G_SHIFT);
787 SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G,
788 SSB_SPROM8_RSSISAV5G_SHIFT);
789 SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G,
790 SSB_SPROM8_BXA5G_SHIFT);
791 SPEX(pa0b0, SSB_SPROM8_PA0B0, 0xFFFF, 0);
792 SPEX(pa0b1, SSB_SPROM8_PA0B1, 0xFFFF, 0);
793 SPEX(pa0b2, SSB_SPROM8_PA0B2, 0xFFFF, 0);
794 SPEX(pa1b0, SSB_SPROM8_PA1B0, 0xFFFF, 0);
795 SPEX(pa1b1, SSB_SPROM8_PA1B1, 0xFFFF, 0);
796 SPEX(pa1b2, SSB_SPROM8_PA1B2, 0xFFFF, 0);
797 SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, 0xFFFF, 0);
798 SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, 0xFFFF, 0);
799 SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, 0xFFFF, 0);
800 SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, 0xFFFF, 0);
801 SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, 0xFFFF, 0);
802 SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, 0xFFFF, 0);
803 SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, 0xFFFF, 0);
804 SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, 0xFFFFFFFF, 0);
805 SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, 0xFFFFFFFF, 0);
806 SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, 0xFFFFFFFF, 0);
807 SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
808
809 /* Extract the antenna gain values. */
810 out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in,
811 SSB_SPROM8_AGAIN01,
812 SSB_SPROM8_AGAIN0,
813 SSB_SPROM8_AGAIN0_SHIFT);
814 out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in,
815 SSB_SPROM8_AGAIN01,
816 SSB_SPROM8_AGAIN1,
817 SSB_SPROM8_AGAIN1_SHIFT);
818 out->antenna_gain.a2 = sprom_extract_antgain(out->revision, in,
819 SSB_SPROM8_AGAIN23,
820 SSB_SPROM8_AGAIN2,
821 SSB_SPROM8_AGAIN2_SHIFT);
822 out->antenna_gain.a3 = sprom_extract_antgain(out->revision, in,
823 SSB_SPROM8_AGAIN23,
824 SSB_SPROM8_AGAIN3,
825 SSB_SPROM8_AGAIN3_SHIFT);
826
827 /* Extract cores power info info */
828 for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
829 o = pwr_info_offset[i];
830 SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
831 SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
832 SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
833 SSB_SPROM8_2G_MAXP, 0);
834
835 SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
836 SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
837 SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
838
839 SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
840 SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
841 SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
842 SSB_SPROM8_5G_MAXP, 0);
843 SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
844 SSB_SPROM8_5GH_MAXP, 0);
845 SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
846 SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
847
848 SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
849 SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
850 SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
851 SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
852 SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
853 SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
854 SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
855 SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
856 SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
857 }
858
859 /* Extract FEM info */
860 SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G,
861 SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT);
862 SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G,
863 SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
864 SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G,
865 SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT);
866 SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G,
867 SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT);
868 SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G,
869 SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT);
870
871 SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G,
872 SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT);
873 SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G,
874 SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
875 SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G,
876 SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT);
877 SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G,
878 SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT);
879 SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G,
880 SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT);
881
882 SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
883 SSB_SPROM8_LEDDC_ON_SHIFT);
884 SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF,
885 SSB_SPROM8_LEDDC_OFF_SHIFT);
886
887 SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN,
888 SSB_SPROM8_TXRXC_TXCHAIN_SHIFT);
889 SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN,
890 SSB_SPROM8_TXRXC_RXCHAIN_SHIFT);
891 SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH,
892 SSB_SPROM8_TXRXC_SWITCH_SHIFT);
893
894 SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0);
895
896 SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0);
897 SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0);
898 SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0);
899 SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0);
900
901 SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP,
902 SSB_SPROM8_RAWTS_RAWTEMP_SHIFT);
903 SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER,
904 SSB_SPROM8_RAWTS_MEASPOWER_SHIFT);
905 SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX,
906 SSB_SPROM8_OPT_CORRX_TEMP_SLOPE,
907 SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT);
908 SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX,
909 SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT);
910 SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX,
911 SSB_SPROM8_OPT_CORRX_TEMP_OPTION,
912 SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT);
913 SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP,
914 SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR,
915 SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT);
916 SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP,
917 SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP,
918 SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT);
919 SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL,
920 SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT);
921
922 SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0);
923 SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0);
924 SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0);
925 SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0);
926
927 SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH,
928 SSB_SPROM8_THERMAL_TRESH_SHIFT);
929 SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET,
930 SSB_SPROM8_THERMAL_OFFSET_SHIFT);
931 SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA,
932 SSB_SPROM8_TEMPDELTA_PHYCAL,
933 SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT);
934 SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD,
935 SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT);
936 SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA,
937 SSB_SPROM8_TEMPDELTA_HYSTERESIS,
938 SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT);
939 sprom_extract_r458(out, in);
940
941 /* TODO - get remaining rev 8 stuff needed */
942 }
943
944 static int sprom_extract(struct ssb_sprom *out, const u16 *in, u16 size)
945 {
946 memset(out, 0, sizeof(*out));
947
948 out->revision = in[size - 1] & 0x00FF;
949 memset(out->et0mac, 0xFF, 6); /* preset et0 and et1 mac */
950 memset(out->et1mac, 0xFF, 6);
951
952 switch (out->revision) {
953 case 1:
954 case 2:
955 case 3:
956 sprom_extract_r123(out, in);
957 break;
958 case 4:
959 case 5:
960 sprom_extract_r45(out, in);
961 break;
962 case 8:
963 sprom_extract_r8(out, in);
964 break;
965 default:
966 pr_warn("Unsupported SPROM revision %d detected. Will extract v1\n",
967 out->revision);
968 out->revision = 1;
969 sprom_extract_r123(out, in);
970 }
971
972 if (out->boardflags_lo == 0xFFFF)
973 out->boardflags_lo = 0; /* per specs */
974 if (out->boardflags_hi == 0xFFFF)
975 out->boardflags_hi = 0; /* per specs */
976
977 return 0;
978 }
979
980 static void b43_sprom_fixup(struct b43_sprom *priv, u16 *sprom)
981 {
982 struct device_node *node = priv->dev->of_node;
983 u32 fixups, off, val;
984 int i = 0;
985
986 if (!of_get_property(node, "brcm,sprom-fixups", &fixups))
987 return;
988
989 fixups /= sizeof(u32);
990
991 dev_info(priv->dev, "patching SPROM with %u fixups...\n", fixups >> 1);
992
993 while (i < fixups) {
994 if (of_property_read_u32_index(node, "brcm,sprom-fixups",
995 i++, &off)) {
996 dev_err(priv->dev, "error reading fixup[%u] offset\n",
997 i - 1);
998 return;
999 }
1000
1001 if (of_property_read_u32_index(node, "brcm,sprom-fixups",
1002 i++, &val)) {
1003 dev_err(priv->dev, "error reading fixup[%u] value\n",
1004 i - 1);
1005 return;
1006 }
1007
1008 dev_dbg(priv->dev, "fixup[%d]=0x%04x\n", off, val);
1009
1010 sprom[off] = val;
1011 }
1012 }
1013
1014 int sprom_override_devid(struct b43_sprom *priv, struct ssb_sprom *out,
1015 const u16 *in)
1016 {
1017 const struct b43_sprom_raw *raw = of_device_get_match_data(priv->dev);
1018
1019 if (raw->type == B43_SPROM_SSB) {
1020 SPEX(dev_id, SSB_SPROM1_PID, 0xFFFF, 0);
1021 return !!out->dev_id;
1022 } else if (raw->type == B43_SPROM_BCMA) {
1023 SPEX(dev_id, 0x0060, 0xFFFF, 0);
1024 return !!out->dev_id;
1025 }
1026
1027 return 0;
1028 }
1029
1030 static void b43_sprom_set(struct b43_sprom *priv)
1031 {
1032 const struct b43_sprom_raw *raw = of_device_get_match_data(priv->dev);
1033 struct ssb_sprom *sprom = &priv->sprom;
1034
1035 if (raw) {
1036 u16 template_sprom[220];
1037
1038 memcpy(template_sprom, raw->map, raw->size * sizeof(u16));
1039 b43_sprom_fixup(priv, template_sprom);
1040 sprom_extract(sprom, template_sprom, raw->size);
1041
1042 priv->devid_override = sprom_override_devid(priv, sprom,
1043 template_sprom);
1044 } else {
1045 sprom->revision = 0x02;
1046 sprom->board_rev = 0x0017;
1047 sprom->country_code = 0x00;
1048 sprom->ant_available_bg = 0x03;
1049 sprom->pa0b0 = 0x15ae;
1050 sprom->pa0b1 = 0xfa85;
1051 sprom->pa0b2 = 0xfe8d;
1052 sprom->pa1b0 = 0xffff;
1053 sprom->pa1b1 = 0xffff;
1054 sprom->pa1b2 = 0xffff;
1055 sprom->gpio0 = 0xff;
1056 sprom->gpio1 = 0xff;
1057 sprom->gpio2 = 0xff;
1058 sprom->gpio3 = 0xff;
1059 sprom->maxpwr_bg = 0x4c;
1060 sprom->itssi_bg = 0x00;
1061 sprom->boardflags_lo = 0x2848;
1062 sprom->boardflags_hi = 0x0000;
1063 priv->devid_override = 0;
1064 }
1065 }
1066
1067 #if defined(CONFIG_SSB_PCIHOST)
1068 int b43_get_fallback_ssb_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
1069 {
1070 struct b43_sprom *priv = &b43_sprom;
1071
1072 if (bus->bustype == SSB_BUSTYPE_PCI) {
1073 if (bus->host_pci->bus->number != priv->pci_bus ||
1074 PCI_SLOT(bus->host_pci->devfn) != priv->pci_dev)
1075 pr_warn("ssb_fallback_sprom: pci bus/device num "
1076 "mismatch: expected %i/%i, but got %i/%i\n",
1077 priv->pci_bus, priv->pci_dev,
1078 bus->host_pci->bus->number,
1079 PCI_SLOT(bus->host_pci->devfn));
1080 if (priv->devid_override)
1081 bus->host_pci->device = priv->sprom.dev_id;
1082 memcpy(out, &priv->sprom, sizeof(struct ssb_sprom));
1083 return 0;
1084 } else {
1085 pr_err("%s: unable to fill SPROM for given bustype.\n",
1086 __func__);
1087 return -EINVAL;
1088 }
1089 }
1090 #endif /* CONFIG_SSB_PCIHOST */
1091
1092 #if defined(CONFIG_BCMA_HOST_PCI)
1093 int b43_get_fallback_bcma_sprom(struct bcma_bus *bus, struct ssb_sprom *out)
1094 {
1095 struct b43_sprom *priv = &b43_sprom;
1096
1097 if (bus->hosttype == BCMA_HOSTTYPE_PCI) {
1098 if (bus->host_pci->bus->number != priv->pci_bus ||
1099 PCI_SLOT(bus->host_pci->devfn) != priv->pci_dev)
1100 pr_warn("bcma_fallback_sprom: pci bus/device num "
1101 "mismatch: expected %i/%i, but got %i/%i\n",
1102 priv->pci_bus, priv->pci_dev,
1103 bus->host_pci->bus->number,
1104 PCI_SLOT(bus->host_pci->devfn));
1105 if (priv->devid_override)
1106 bus->host_pci->device = priv->sprom.dev_id;
1107 memcpy(out, &priv->sprom, sizeof(struct ssb_sprom));
1108 return 0;
1109 } else {
1110 pr_err("%s: unable to fill SPROM for given bustype.\n",
1111 __func__);
1112 return -EINVAL;
1113 }
1114 }
1115 #endif /* CONFIG_BCMA_HOST_PCI */
1116
1117 static int b43_sprom_probe(struct platform_device *pdev)
1118 {
1119 struct device *dev = &pdev->dev;
1120 struct device_node *node = dev->of_node;
1121 struct b43_sprom *priv = &b43_sprom;
1122 const void *mac;
1123 int ret;
1124
1125 priv->dev = dev;
1126
1127 b43_sprom_set(priv);
1128
1129 of_property_read_u32(node, "pci-bus", &priv->pci_bus);
1130 of_property_read_u32(node, "pci-dev", &priv->pci_dev);
1131
1132 mac = of_get_mac_address(node);
1133 if (!IS_ERR_OR_NULL(mac)) {
1134 memcpy(priv->mac, mac, ETH_ALEN);
1135 dev_info(dev, "mtd mac %pM\n", priv->mac);
1136 } else {
1137 random_ether_addr(priv->mac);
1138 dev_info(dev, "random mac %pM\n", priv->mac);
1139 }
1140
1141 memcpy(priv->sprom.il0mac, priv->mac, ETH_ALEN);
1142 memcpy(priv->sprom.et0mac, priv->mac, ETH_ALEN);
1143 memcpy(priv->sprom.et1mac, priv->mac, ETH_ALEN);
1144
1145 #if defined(CONFIG_SSB_PCIHOST)
1146 ret = ssb_arch_register_fallback_sprom(&b43_get_fallback_ssb_sprom);
1147 if (ret)
1148 return ret;
1149 #endif /* CONFIG_SSB_PCIHOST */
1150
1151 #if defined(CONFIG_BCMA_HOST_PCI)
1152 ret = bcma_arch_register_fallback_sprom(b43_get_fallback_bcma_sprom);
1153 if (ret)
1154 return ret;
1155 #endif /* CONFIG_BCMA_HOST_PCI */
1156
1157 return 0;
1158 }
1159
1160 static const struct of_device_id b43_sprom_of_match[] = {
1161 { .compatible = "brcm,bcm43xx-sprom", .data = NULL },
1162 #if defined (CONFIG_SSB_PCIHOST)
1163 { .compatible = "brcm,bcm4306-sprom", .data = &bcm4306_sprom, },
1164 { .compatible = "brcm,bcm4321-sprom", .data = &bcm4321_sprom, },
1165 { .compatible = "brcm,bcm4322-sprom", .data = &bcm4322_sprom, },
1166 { .compatible = "brcm,bcm43222-sprom", .data = &bcm43222_sprom, },
1167 #endif /* CONFIG_BCMA_HOST_PCI */
1168 #if defined(CONFIG_BCMA_HOST_PCI)
1169 { .compatible = "brcm,bcm4313-sprom", .data = &bcm4313_sprom, },
1170 { .compatible = "brcm,bcm4331-sprom", .data = &bcm4331_sprom, },
1171 { .compatible = "brcm,bcm43131-sprom", .data = &bcm43131_sprom, },
1172 { .compatible = "brcm,bcm43217-sprom", .data = &bcm43217_sprom, },
1173 { .compatible = "brcm,bcm43225-sprom", .data = &bcm43225_sprom, },
1174 { .compatible = "brcm,bcm43227-sprom", .data = &bcm43227_sprom, },
1175 { .compatible = "brcm,bcm43228-sprom", .data = &bcm43228_sprom, },
1176 #endif /* CONFIG_BCMA_HOST_PCI */
1177 { /* sentinel */ }
1178 };
1179
1180 static struct platform_driver b43_sprom_driver = {
1181 .probe = b43_sprom_probe,
1182 .driver = {
1183 .name = "b43-sprom",
1184 .of_match_table = b43_sprom_of_match,
1185 },
1186 };
1187
1188 int __init b43_sprom_init(void)
1189 {
1190 int ret = platform_driver_register(&b43_sprom_driver);
1191 if (ret)
1192 pr_err("b43-sprom: Error registering platform driver!\n");
1193 return ret;
1194 }
1195 late_initcall(b43_sprom_init);