]> git.pld-linux.org Git - packages/kernel.git/blame - kernel-bcm43xx-patch_2.6.18.1_for_PCI-E.patch
- try to fix ppc builds for external modules (untested yet)
[packages/kernel.git] / kernel-bcm43xx-patch_2.6.18.1_for_PCI-E.patch
CommitLineData
7bc63040 1Index: 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 225Index: 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
279Index: 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);
This page took 0.100929 seconds and 4 git commands to generate.