]>
Commit | Line | Data |
---|---|---|
7bc63040 | 1 | Index: linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_main.c |
2 | =================================================================== | |
3 | --- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |
4 | +++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |
5 | @@ -130,6 +130,10 @@ MODULE_PARM_DESC(fwpostfix, "Postfix for | |
6 | { PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | |
7 | /* Broadcom 4307 802.11b */ | |
8 | { PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | |
9 | + /* Broadcom 4311 802.11(a)/b/g */ | |
10 | + { PCI_VENDOR_ID_BROADCOM, 0x4311, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | |
11 | + /* Broadcom 4312 802.11a/b/g */ | |
12 | + { PCI_VENDOR_ID_BROADCOM, 0x4312, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | |
13 | /* Broadcom 4318 802.11b/g */ | |
14 | { PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | |
15 | /* Broadcom 4319 802.11a/b/g */ | |
16 | @@ -2582,8 +2586,9 @@ static int bcm43xx_probe_cores(struct bc | |
17 | /* fetch sb_id_hi from core information registers */ | |
18 | sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI); | |
19 | ||
20 | - core_id = (sb_id_hi & 0xFFF0) >> 4; | |
21 | - core_rev = (sb_id_hi & 0xF); | |
22 | + core_id = (sb_id_hi & 0x8FF0) >> 4; | |
23 | + core_rev = (sb_id_hi & 0x7000) >> 8; | |
24 | + core_rev |= (sb_id_hi & 0xF); | |
25 | core_vendor = (sb_id_hi & 0xFFFF0000) >> 16; | |
26 | ||
27 | /* if present, chipcommon is always core 0; read the chipid from it */ | |
28 | @@ -2693,6 +2698,7 @@ static int bcm43xx_probe_cores(struct bc | |
29 | core = NULL; | |
30 | switch (core_id) { | |
31 | case BCM43xx_COREID_PCI: | |
32 | + case BCM43xx_COREID_PCIE: | |
33 | core = &bcm->core_pci; | |
34 | if (core->available) { | |
35 | printk(KERN_WARNING PFX "Multiple PCI cores found.\n"); | |
36 | @@ -2731,12 +2737,12 @@ static int bcm43xx_probe_cores(struct bc | |
37 | case 6: | |
38 | case 7: | |
39 | case 9: | |
40 | + case 10: | |
41 | break; | |
42 | default: | |
43 | - printk(KERN_ERR PFX "Error: Unsupported 80211 core revision %u\n", | |
44 | + printk(KERN_WARNING PFX | |
45 | + "Unsupported 80211 core revision %u\n", | |
46 | core_rev); | |
47 | - err = -ENODEV; | |
48 | - goto out; | |
49 | } | |
50 | bcm->nr_80211_available++; | |
51 | core->priv = ext_80211; | |
52 | @@ -2850,16 +2856,11 @@ static int bcm43xx_wireless_core_init(st | |
53 | u32 sbimconfiglow; | |
54 | u8 limit; | |
55 | ||
56 | - if (bcm->chip_rev < 5) { | |
57 | + if (bcm->core_pci.rev <= 5 && bcm->core_pci.id != BCM43xx_COREID_PCIE) { | |
58 | sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW); | |
59 | sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK; | |
60 | sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK; | |
61 | - if (bcm->bustype == BCM43xx_BUSTYPE_PCI) | |
62 | - sbimconfiglow |= 0x32; | |
63 | - else if (bcm->bustype == BCM43xx_BUSTYPE_SB) | |
64 | - sbimconfiglow |= 0x53; | |
65 | - else | |
66 | - assert(0); | |
67 | + sbimconfiglow |= 0x32; | |
68 | bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow); | |
69 | } | |
70 | ||
7bc63040 | 71 | @@ -2983,22 +2987,64 @@ static void bcm43xx_pcicore_broadcast_va |
72 | ||
73 | static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm) | |
74 | { | |
75 | - int err; | |
76 | - struct bcm43xx_coreinfo *old_core; | |
77 | + int err = 0; | |
78 | ||
79 | - old_core = bcm->current_core; | |
80 | - err = bcm43xx_switch_core(bcm, &bcm->core_pci); | |
81 | - if (err) | |
82 | - goto out; | |
83 | + bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); | |
84 | ||
85 | - bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000); | |
86 | + if (bcm->core_chipcommon.available) { | |
87 | + err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); | |
88 | + if (err) | |
89 | + goto out; | |
90 | + | |
91 | + bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000); | |
92 | + | |
93 | + /* this function is always called when a PCI core is mapped */ | |
94 | + err = bcm43xx_switch_core(bcm, &bcm->core_pci); | |
95 | + if (err) | |
96 | + goto out; | |
97 | + } else | |
98 | + bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000); | |
99 | + | |
100 | + bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); | |
101 | ||
102 | - bcm43xx_switch_core(bcm, old_core); | |
103 | - assert(err == 0); | |
104 | out: | |
105 | return err; | |
106 | } | |
107 | ||
108 | +static u32 bcm43xx_pcie_reg_read(struct bcm43xx_private *bcm, u32 address) | |
109 | +{ | |
110 | + bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address); | |
111 | + return bcm43xx_read32(bcm, BCM43xx_PCIECORE_REG_DATA); | |
112 | +} | |
113 | + | |
114 | +static void bcm43xx_pcie_reg_write(struct bcm43xx_private *bcm, u32 address, | |
115 | + u32 data) | |
116 | +{ | |
117 | + bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address); | |
118 | + bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_DATA, data); | |
119 | +} | |
120 | + | |
121 | +static void bcm43xx_pcie_mdio_write(struct bcm43xx_private *bcm, u8 dev, u8 reg, | |
122 | + u16 data) | |
123 | +{ | |
124 | + int i; | |
125 | + | |
126 | + bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0x0082); | |
127 | + bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_DATA, BCM43xx_PCIE_MDIO_ST | | |
128 | + BCM43xx_PCIE_MDIO_WT | (dev << BCM43xx_PCIE_MDIO_DEV) | | |
129 | + (reg << BCM43xx_PCIE_MDIO_REG) | BCM43xx_PCIE_MDIO_TA | | |
130 | + data); | |
131 | + udelay(10); | |
132 | + | |
133 | + for (i = 0; i < 10; i++) { | |
134 | + if (bcm43xx_read32(bcm, BCM43xx_PCIECORE_MDIO_CTL) & | |
135 | + BCM43xx_PCIE_MDIO_TC) | |
136 | + break; | |
137 | + msleep(1); | |
138 | + } | |
139 | + bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0); | |
140 | +} | |
141 | + | |
142 | /* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable. | |
143 | * To enable core 0, pass a core_mask of 1<<0 | |
144 | */ | |
145 | @@ -3018,7 +3064,8 @@ static int bcm43xx_setup_backplane_pci_c | |
146 | if (err) | |
147 | goto out; | |
148 | ||
149 | - if (bcm->core_pci.rev < 6) { | |
150 | + if (bcm->current_core->rev < 6 || | |
151 | + bcm->current_core->id == BCM43xx_COREID_PCI) { | |
152 | value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC); | |
153 | value |= (1 << backplane_flag_nr); | |
154 | bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value); | |
155 | @@ -3036,21 +3083,46 @@ static int bcm43xx_setup_backplane_pci_c | |
156 | } | |
157 | } | |
158 | ||
159 | - value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2); | |
160 | - value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST; | |
161 | - bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value); | |
162 | - | |
163 | - if (bcm->core_pci.rev < 5) { | |
164 | - value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW); | |
165 | - value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT) | |
166 | - & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK; | |
167 | - value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT) | |
168 | - & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK; | |
169 | - bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value); | |
170 | - err = bcm43xx_pcicore_commit_settings(bcm); | |
171 | - assert(err == 0); | |
172 | + if (bcm->current_core->id == BCM43xx_COREID_PCI) { | |
173 | + value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2); | |
174 | + value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST; | |
175 | + bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value); | |
176 | + | |
177 | + if (bcm->current_core->rev < 5) { | |
178 | + value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW); | |
179 | + value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT) | |
180 | + & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK; | |
181 | + value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT) | |
182 | + & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK; | |
183 | + bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value); | |
184 | + err = bcm43xx_pcicore_commit_settings(bcm); | |
185 | + assert(err == 0); | |
186 | + } else if (bcm->current_core->rev >= 11) { | |
187 | + value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2); | |
188 | + value |= BCM43xx_SBTOPCI2_MEMREAD_MULTI; | |
189 | + bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value); | |
190 | + } | |
191 | + } else { | |
192 | + if (bcm->current_core->rev == 0 || bcm->current_core->rev == 1) { | |
193 | + value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_TLP_WORKAROUND); | |
194 | + value |= 0x8; | |
195 | + bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_TLP_WORKAROUND, | |
196 | + value); | |
197 | + } | |
198 | + if (bcm->current_core->rev == 0) { | |
199 | + bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX, | |
200 | + BCM43xx_SERDES_RXTIMER, 0x8128); | |
201 | + bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX, | |
202 | + BCM43xx_SERDES_CDR, 0x0100); | |
203 | + bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX, | |
204 | + BCM43xx_SERDES_CDR_BW, 0x1466); | |
205 | + } else if (bcm->current_core->rev == 1) { | |
206 | + value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_DLLP_LINKCTL); | |
207 | + value |= 0x40; | |
208 | + bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_DLLP_LINKCTL, | |
209 | + value); | |
210 | + } | |
211 | } | |
212 | - | |
213 | out_switch_back: | |
214 | err = bcm43xx_switch_core(bcm, old_core); | |
215 | out: | |
216 | @@ -3635,7 +3707,7 @@ static int bcm43xx_read_phyinfo(struct b | |
217 | bcm->ieee->freq_band = IEEE80211_24GHZ_BAND; | |
218 | break; | |
219 | case BCM43xx_PHYTYPE_G: | |
220 | - if (phy_rev > 7) | |
221 | + if (phy_rev > 8) | |
222 | phy_rev_ok = 0; | |
223 | bcm->ieee->modulation = IEEE80211_OFDM_MODULATION | | |
224 | IEEE80211_CCK_MODULATION; | |
7bc63040 | 225 | Index: linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx.h |
226 | =================================================================== | |
227 | --- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx.h | |
228 | +++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx.h | |
229 | @@ -159,6 +159,7 @@ | |
230 | ||
231 | /* Chipcommon registers. */ | |
232 | #define BCM43xx_CHIPCOMMON_CAPABILITIES 0x04 | |
233 | +#define BCM43xx_CHIPCOMMON_CTL 0x28 | |
234 | #define BCM43xx_CHIPCOMMON_PLLONDELAY 0xB0 | |
235 | #define BCM43xx_CHIPCOMMON_FREFSELDELAY 0xB4 | |
236 | #define BCM43xx_CHIPCOMMON_SLOWCLKCTL 0xB8 | |
237 | @@ -172,6 +173,33 @@ | |
238 | /* SBTOPCI2 values. */ | |
239 | #define BCM43xx_SBTOPCI2_PREFETCH 0x4 | |
240 | #define BCM43xx_SBTOPCI2_BURST 0x8 | |
241 | +#define BCM43xx_SBTOPCI2_MEMREAD_MULTI 0x20 | |
242 | + | |
243 | +/* PCI-E core registers. */ | |
244 | +#define BCM43xx_PCIECORE_REG_ADDR 0x0130 | |
245 | +#define BCM43xx_PCIECORE_REG_DATA 0x0134 | |
246 | +#define BCM43xx_PCIECORE_MDIO_CTL 0x0128 | |
247 | +#define BCM43xx_PCIECORE_MDIO_DATA 0x012C | |
248 | + | |
249 | +/* PCI-E registers. */ | |
250 | +#define BCM43xx_PCIE_TLP_WORKAROUND 0x0004 | |
251 | +#define BCM43xx_PCIE_DLLP_LINKCTL 0x0100 | |
252 | + | |
253 | +/* PCI-E MDIO bits. */ | |
254 | +#define BCM43xx_PCIE_MDIO_ST 0x40000000 | |
255 | +#define BCM43xx_PCIE_MDIO_WT 0x10000000 | |
256 | +#define BCM43xx_PCIE_MDIO_DEV 22 | |
257 | +#define BCM43xx_PCIE_MDIO_REG 18 | |
258 | +#define BCM43xx_PCIE_MDIO_TA 0x00020000 | |
259 | +#define BCM43xx_PCIE_MDIO_TC 0x0100 | |
260 | + | |
261 | +/* MDIO devices. */ | |
262 | +#define BCM43xx_MDIO_SERDES_RX 0x1F | |
263 | + | |
264 | +/* SERDES RX registers. */ | |
265 | +#define BCM43xx_SERDES_RXTIMER 0x2 | |
266 | +#define BCM43xx_SERDES_CDR 0x6 | |
267 | +#define BCM43xx_SERDES_CDR_BW 0x7 | |
268 | ||
269 | /* Chipcommon capabilities. */ | |
270 | #define BCM43xx_CAPABILITIES_PCTL 0x00040000 | |
271 | @@ -221,6 +249,7 @@ | |
272 | #define BCM43xx_COREID_USB20_HOST 0x819 | |
273 | #define BCM43xx_COREID_USB20_DEV 0x81a | |
274 | #define BCM43xx_COREID_SDIO_HOST 0x81b | |
275 | +#define BCM43xx_COREID_PCIE 0x820 | |
276 | ||
277 | /* Core Information Registers */ | |
278 | #define BCM43xx_CIR_BASE 0xf00 | |
279 | Index: linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_power.c | |
280 | =================================================================== | |
281 | --- linux-2.6.18.orig/drivers/net/wireless/bcm43xx/bcm43xx_power.c | |
282 | +++ linux-2.6.18/drivers/net/wireless/bcm43xx/bcm43xx_power.c | |
283 | @@ -153,8 +153,6 @@ int bcm43xx_pctl_init(struct bcm43xx_pri | |
284 | int err, maxfreq; | |
285 | struct bcm43xx_coreinfo *old_core; | |
286 | ||
287 | - if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL)) | |
288 | - return 0; | |
289 | old_core = bcm->current_core; | |
290 | err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); | |
291 | if (err == -ENODEV) | |
292 | @@ -162,11 +160,27 @@ int bcm43xx_pctl_init(struct bcm43xx_pri | |
293 | if (err) | |
294 | goto out; | |
295 | ||
296 | - maxfreq = bcm43xx_pctl_clockfreqlimit(bcm, 1); | |
297 | - bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY, | |
298 | - (maxfreq * 150 + 999999) / 1000000); | |
299 | - bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_FREFSELDELAY, | |
300 | - (maxfreq * 15 + 999999) / 1000000); | |
301 | + if (bcm->chip_id == 0x4321) { | |
302 | + if (bcm->chip_rev == 0) | |
303 | + bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_CTL, 0x03A4); | |
304 | + if (bcm->chip_rev == 1) | |
305 | + bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_CTL, 0x00A4); | |
306 | + } | |
307 | + | |
308 | + if (bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL) { | |
309 | + if (bcm->current_core->rev >= 10) { | |
310 | + /* Set Idle Power clock rate to 1Mhz */ | |
311 | + bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL, | |
312 | + (bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL) | |
313 | + & 0x0000FFFF) | 0x40000); | |
314 | + } else { | |
315 | + maxfreq = bcm43xx_pctl_clockfreqlimit(bcm, 1); | |
316 | + bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY, | |
317 | + (maxfreq * 150 + 999999) / 1000000); | |
318 | + bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_FREFSELDELAY, | |
319 | + (maxfreq * 15 + 999999) / 1000000); | |
320 | + } | |
321 | + } | |
322 | ||
323 | err = bcm43xx_switch_core(bcm, old_core); | |
324 | assert(err == 0); |