diff options
author | Stefano Brivio <stefano.brivio@polimi.it> | 2006-10-16 00:18:11 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-12-02 00:11:58 -0500 |
commit | f3d1fca3eb05cf6ff3879a385a15d24fbf556c57 (patch) | |
tree | f8625cb837369a8ee7755f4d0639a9abe36fd860 | |
parent | 995cdaa45b1faf8f4472e4b4c6027dc685ae1b54 (diff) |
[PATCH] bcm43xx: add PCI-E code
The current bcm43xx driver does not contain code to handle PCI-E interfaces
such as the BCM4311 and BCM4312. This patch, originally written by Stefano
Brivio adds the necessary code to enable these interfaces.
Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx.h | 29 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_main.c | 143 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_power.c | 28 |
3 files changed, 156 insertions, 44 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h index 5f43d7f42af1..94dfb92fab5c 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx.h | |||
@@ -159,6 +159,7 @@ | |||
159 | 159 | ||
160 | /* Chipcommon registers. */ | 160 | /* Chipcommon registers. */ |
161 | #define BCM43xx_CHIPCOMMON_CAPABILITIES 0x04 | 161 | #define BCM43xx_CHIPCOMMON_CAPABILITIES 0x04 |
162 | #define BCM43xx_CHIPCOMMON_CTL 0x28 | ||
162 | #define BCM43xx_CHIPCOMMON_PLLONDELAY 0xB0 | 163 | #define BCM43xx_CHIPCOMMON_PLLONDELAY 0xB0 |
163 | #define BCM43xx_CHIPCOMMON_FREFSELDELAY 0xB4 | 164 | #define BCM43xx_CHIPCOMMON_FREFSELDELAY 0xB4 |
164 | #define BCM43xx_CHIPCOMMON_SLOWCLKCTL 0xB8 | 165 | #define BCM43xx_CHIPCOMMON_SLOWCLKCTL 0xB8 |
@@ -172,6 +173,33 @@ | |||
172 | /* SBTOPCI2 values. */ | 173 | /* SBTOPCI2 values. */ |
173 | #define BCM43xx_SBTOPCI2_PREFETCH 0x4 | 174 | #define BCM43xx_SBTOPCI2_PREFETCH 0x4 |
174 | #define BCM43xx_SBTOPCI2_BURST 0x8 | 175 | #define BCM43xx_SBTOPCI2_BURST 0x8 |
176 | #define BCM43xx_SBTOPCI2_MEMREAD_MULTI 0x20 | ||
177 | |||
178 | /* PCI-E core registers. */ | ||
179 | #define BCM43xx_PCIECORE_REG_ADDR 0x0130 | ||
180 | #define BCM43xx_PCIECORE_REG_DATA 0x0134 | ||
181 | #define BCM43xx_PCIECORE_MDIO_CTL 0x0128 | ||
182 | #define BCM43xx_PCIECORE_MDIO_DATA 0x012C | ||
183 | |||
184 | /* PCI-E registers. */ | ||
185 | #define BCM43xx_PCIE_TLP_WORKAROUND 0x0004 | ||
186 | #define BCM43xx_PCIE_DLLP_LINKCTL 0x0100 | ||
187 | |||
188 | /* PCI-E MDIO bits. */ | ||
189 | #define BCM43xx_PCIE_MDIO_ST 0x40000000 | ||
190 | #define BCM43xx_PCIE_MDIO_WT 0x10000000 | ||
191 | #define BCM43xx_PCIE_MDIO_DEV 22 | ||
192 | #define BCM43xx_PCIE_MDIO_REG 18 | ||
193 | #define BCM43xx_PCIE_MDIO_TA 0x00020000 | ||
194 | #define BCM43xx_PCIE_MDIO_TC 0x0100 | ||
195 | |||
196 | /* MDIO devices. */ | ||
197 | #define BCM43xx_MDIO_SERDES_RX 0x1F | ||
198 | |||
199 | /* SERDES RX registers. */ | ||
200 | #define BCM43xx_SERDES_RXTIMER 0x2 | ||
201 | #define BCM43xx_SERDES_CDR 0x6 | ||
202 | #define BCM43xx_SERDES_CDR_BW 0x7 | ||
175 | 203 | ||
176 | /* Chipcommon capabilities. */ | 204 | /* Chipcommon capabilities. */ |
177 | #define BCM43xx_CAPABILITIES_PCTL 0x00040000 | 205 | #define BCM43xx_CAPABILITIES_PCTL 0x00040000 |
@@ -221,6 +249,7 @@ | |||
221 | #define BCM43xx_COREID_USB20_HOST 0x819 | 249 | #define BCM43xx_COREID_USB20_HOST 0x819 |
222 | #define BCM43xx_COREID_USB20_DEV 0x81a | 250 | #define BCM43xx_COREID_USB20_DEV 0x81a |
223 | #define BCM43xx_COREID_SDIO_HOST 0x81b | 251 | #define BCM43xx_COREID_SDIO_HOST 0x81b |
252 | #define BCM43xx_COREID_PCIE 0x820 | ||
224 | 253 | ||
225 | /* Core Information Registers */ | 254 | /* Core Information Registers */ |
226 | #define BCM43xx_CIR_BASE 0xf00 | 255 | #define BCM43xx_CIR_BASE 0xf00 |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 2ffc0d5b54ee..c6bd86889f1b 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |||
@@ -130,6 +130,10 @@ MODULE_PARM_DESC(fwpostfix, "Postfix for .fw files. Useful for debugging."); | |||
130 | { PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 130 | { PCI_VENDOR_ID_BROADCOM, 0x4301, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
131 | /* Broadcom 4307 802.11b */ | 131 | /* Broadcom 4307 802.11b */ |
132 | { PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 132 | { PCI_VENDOR_ID_BROADCOM, 0x4307, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
133 | /* Broadcom 4311 802.11(a)/b/g */ | ||
134 | { PCI_VENDOR_ID_BROADCOM, 0x4311, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | ||
135 | /* Broadcom 4312 802.11a/b/g */ | ||
136 | { PCI_VENDOR_ID_BROADCOM, 0x4312, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | ||
133 | /* Broadcom 4318 802.11b/g */ | 137 | /* Broadcom 4318 802.11b/g */ |
134 | { PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, | 138 | { PCI_VENDOR_ID_BROADCOM, 0x4318, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, |
135 | /* Broadcom 4319 802.11a/b/g */ | 139 | /* Broadcom 4319 802.11a/b/g */ |
@@ -2600,8 +2604,9 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm) | |||
2600 | /* fetch sb_id_hi from core information registers */ | 2604 | /* fetch sb_id_hi from core information registers */ |
2601 | sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI); | 2605 | sb_id_hi = bcm43xx_read32(bcm, BCM43xx_CIR_SB_ID_HI); |
2602 | 2606 | ||
2603 | core_id = (sb_id_hi & 0xFFF0) >> 4; | 2607 | core_id = (sb_id_hi & 0x8FF0) >> 4; |
2604 | core_rev = (sb_id_hi & 0xF); | 2608 | core_rev = (sb_id_hi & 0x7000) >> 8; |
2609 | core_rev |= (sb_id_hi & 0xF); | ||
2605 | core_vendor = (sb_id_hi & 0xFFFF0000) >> 16; | 2610 | core_vendor = (sb_id_hi & 0xFFFF0000) >> 16; |
2606 | 2611 | ||
2607 | /* if present, chipcommon is always core 0; read the chipid from it */ | 2612 | /* if present, chipcommon is always core 0; read the chipid from it */ |
@@ -2711,6 +2716,7 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm) | |||
2711 | core = NULL; | 2716 | core = NULL; |
2712 | switch (core_id) { | 2717 | switch (core_id) { |
2713 | case BCM43xx_COREID_PCI: | 2718 | case BCM43xx_COREID_PCI: |
2719 | case BCM43xx_COREID_PCIE: | ||
2714 | core = &bcm->core_pci; | 2720 | core = &bcm->core_pci; |
2715 | if (core->available) { | 2721 | if (core->available) { |
2716 | printk(KERN_WARNING PFX "Multiple PCI cores found.\n"); | 2722 | printk(KERN_WARNING PFX "Multiple PCI cores found.\n"); |
@@ -2749,12 +2755,12 @@ static int bcm43xx_probe_cores(struct bcm43xx_private *bcm) | |||
2749 | case 6: | 2755 | case 6: |
2750 | case 7: | 2756 | case 7: |
2751 | case 9: | 2757 | case 9: |
2758 | case 10: | ||
2752 | break; | 2759 | break; |
2753 | default: | 2760 | default: |
2754 | printk(KERN_ERR PFX "Error: Unsupported 80211 core revision %u\n", | 2761 | printk(KERN_WARNING PFX |
2762 | "Unsupported 80211 core revision %u\n", | ||
2755 | core_rev); | 2763 | core_rev); |
2756 | err = -ENODEV; | ||
2757 | goto out; | ||
2758 | } | 2764 | } |
2759 | bcm->nr_80211_available++; | 2765 | bcm->nr_80211_available++; |
2760 | core->priv = ext_80211; | 2766 | core->priv = ext_80211; |
@@ -2868,16 +2874,11 @@ static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm, | |||
2868 | u32 sbimconfiglow; | 2874 | u32 sbimconfiglow; |
2869 | u8 limit; | 2875 | u8 limit; |
2870 | 2876 | ||
2871 | if (bcm->chip_rev < 5) { | 2877 | if (bcm->core_pci.rev <= 5 && bcm->core_pci.id != BCM43xx_COREID_PCIE) { |
2872 | sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW); | 2878 | sbimconfiglow = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW); |
2873 | sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK; | 2879 | sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK; |
2874 | sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK; | 2880 | sbimconfiglow &= ~ BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK; |
2875 | if (bcm->bustype == BCM43xx_BUSTYPE_PCI) | 2881 | sbimconfiglow |= 0x32; |
2876 | sbimconfiglow |= 0x32; | ||
2877 | else if (bcm->bustype == BCM43xx_BUSTYPE_SB) | ||
2878 | sbimconfiglow |= 0x53; | ||
2879 | else | ||
2880 | assert(0); | ||
2881 | bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow); | 2882 | bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, sbimconfiglow); |
2882 | } | 2883 | } |
2883 | 2884 | ||
@@ -3004,22 +3005,64 @@ static void bcm43xx_pcicore_broadcast_value(struct bcm43xx_private *bcm, | |||
3004 | 3005 | ||
3005 | static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm) | 3006 | static int bcm43xx_pcicore_commit_settings(struct bcm43xx_private *bcm) |
3006 | { | 3007 | { |
3007 | int err; | 3008 | int err = 0; |
3008 | struct bcm43xx_coreinfo *old_core; | ||
3009 | 3009 | ||
3010 | old_core = bcm->current_core; | 3010 | bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); |
3011 | err = bcm43xx_switch_core(bcm, &bcm->core_pci); | ||
3012 | if (err) | ||
3013 | goto out; | ||
3014 | 3011 | ||
3015 | bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000); | 3012 | if (bcm->core_chipcommon.available) { |
3013 | err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); | ||
3014 | if (err) | ||
3015 | goto out; | ||
3016 | |||
3017 | bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000); | ||
3018 | |||
3019 | /* this function is always called when a PCI core is mapped */ | ||
3020 | err = bcm43xx_switch_core(bcm, &bcm->core_pci); | ||
3021 | if (err) | ||
3022 | goto out; | ||
3023 | } else | ||
3024 | bcm43xx_pcicore_broadcast_value(bcm, 0xfd8, 0x00000000); | ||
3025 | |||
3026 | bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate); | ||
3016 | 3027 | ||
3017 | bcm43xx_switch_core(bcm, old_core); | ||
3018 | assert(err == 0); | ||
3019 | out: | 3028 | out: |
3020 | return err; | 3029 | return err; |
3021 | } | 3030 | } |
3022 | 3031 | ||
3032 | static u32 bcm43xx_pcie_reg_read(struct bcm43xx_private *bcm, u32 address) | ||
3033 | { | ||
3034 | bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address); | ||
3035 | return bcm43xx_read32(bcm, BCM43xx_PCIECORE_REG_DATA); | ||
3036 | } | ||
3037 | |||
3038 | static void bcm43xx_pcie_reg_write(struct bcm43xx_private *bcm, u32 address, | ||
3039 | u32 data) | ||
3040 | { | ||
3041 | bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_ADDR, address); | ||
3042 | bcm43xx_write32(bcm, BCM43xx_PCIECORE_REG_DATA, data); | ||
3043 | } | ||
3044 | |||
3045 | static void bcm43xx_pcie_mdio_write(struct bcm43xx_private *bcm, u8 dev, u8 reg, | ||
3046 | u16 data) | ||
3047 | { | ||
3048 | int i; | ||
3049 | |||
3050 | bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0x0082); | ||
3051 | bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_DATA, BCM43xx_PCIE_MDIO_ST | | ||
3052 | BCM43xx_PCIE_MDIO_WT | (dev << BCM43xx_PCIE_MDIO_DEV) | | ||
3053 | (reg << BCM43xx_PCIE_MDIO_REG) | BCM43xx_PCIE_MDIO_TA | | ||
3054 | data); | ||
3055 | udelay(10); | ||
3056 | |||
3057 | for (i = 0; i < 10; i++) { | ||
3058 | if (bcm43xx_read32(bcm, BCM43xx_PCIECORE_MDIO_CTL) & | ||
3059 | BCM43xx_PCIE_MDIO_TC) | ||
3060 | break; | ||
3061 | msleep(1); | ||
3062 | } | ||
3063 | bcm43xx_write32(bcm, BCM43xx_PCIECORE_MDIO_CTL, 0); | ||
3064 | } | ||
3065 | |||
3023 | /* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable. | 3066 | /* Make an I/O Core usable. "core_mask" is the bitmask of the cores to enable. |
3024 | * To enable core 0, pass a core_mask of 1<<0 | 3067 | * To enable core 0, pass a core_mask of 1<<0 |
3025 | */ | 3068 | */ |
@@ -3039,7 +3082,8 @@ static int bcm43xx_setup_backplane_pci_connection(struct bcm43xx_private *bcm, | |||
3039 | if (err) | 3082 | if (err) |
3040 | goto out; | 3083 | goto out; |
3041 | 3084 | ||
3042 | if (bcm->core_pci.rev < 6) { | 3085 | if (bcm->current_core->rev < 6 || |
3086 | bcm->current_core->id == BCM43xx_COREID_PCI) { | ||
3043 | value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC); | 3087 | value = bcm43xx_read32(bcm, BCM43xx_CIR_SBINTVEC); |
3044 | value |= (1 << backplane_flag_nr); | 3088 | value |= (1 << backplane_flag_nr); |
3045 | bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value); | 3089 | bcm43xx_write32(bcm, BCM43xx_CIR_SBINTVEC, value); |
@@ -3057,21 +3101,46 @@ static int bcm43xx_setup_backplane_pci_connection(struct bcm43xx_private *bcm, | |||
3057 | } | 3101 | } |
3058 | } | 3102 | } |
3059 | 3103 | ||
3060 | value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2); | 3104 | if (bcm->current_core->id == BCM43xx_COREID_PCI) { |
3061 | value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST; | 3105 | value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2); |
3062 | bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value); | 3106 | value |= BCM43xx_SBTOPCI2_PREFETCH | BCM43xx_SBTOPCI2_BURST; |
3063 | 3107 | bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value); | |
3064 | if (bcm->core_pci.rev < 5) { | 3108 | |
3065 | value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW); | 3109 | if (bcm->current_core->rev < 5) { |
3066 | value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT) | 3110 | value = bcm43xx_read32(bcm, BCM43xx_CIR_SBIMCONFIGLOW); |
3067 | & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK; | 3111 | value |= (2 << BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_SHIFT) |
3068 | value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT) | 3112 | & BCM43xx_SBIMCONFIGLOW_SERVICE_TOUT_MASK; |
3069 | & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK; | 3113 | value |= (3 << BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_SHIFT) |
3070 | bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value); | 3114 | & BCM43xx_SBIMCONFIGLOW_REQUEST_TOUT_MASK; |
3071 | err = bcm43xx_pcicore_commit_settings(bcm); | 3115 | bcm43xx_write32(bcm, BCM43xx_CIR_SBIMCONFIGLOW, value); |
3072 | assert(err == 0); | 3116 | err = bcm43xx_pcicore_commit_settings(bcm); |
3117 | assert(err == 0); | ||
3118 | } else if (bcm->current_core->rev >= 11) { | ||
3119 | value = bcm43xx_read32(bcm, BCM43xx_PCICORE_SBTOPCI2); | ||
3120 | value |= BCM43xx_SBTOPCI2_MEMREAD_MULTI; | ||
3121 | bcm43xx_write32(bcm, BCM43xx_PCICORE_SBTOPCI2, value); | ||
3122 | } | ||
3123 | } else { | ||
3124 | if (bcm->current_core->rev == 0 || bcm->current_core->rev == 1) { | ||
3125 | value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_TLP_WORKAROUND); | ||
3126 | value |= 0x8; | ||
3127 | bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_TLP_WORKAROUND, | ||
3128 | value); | ||
3129 | } | ||
3130 | if (bcm->current_core->rev == 0) { | ||
3131 | bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX, | ||
3132 | BCM43xx_SERDES_RXTIMER, 0x8128); | ||
3133 | bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX, | ||
3134 | BCM43xx_SERDES_CDR, 0x0100); | ||
3135 | bcm43xx_pcie_mdio_write(bcm, BCM43xx_MDIO_SERDES_RX, | ||
3136 | BCM43xx_SERDES_CDR_BW, 0x1466); | ||
3137 | } else if (bcm->current_core->rev == 1) { | ||
3138 | value = bcm43xx_pcie_reg_read(bcm, BCM43xx_PCIE_DLLP_LINKCTL); | ||
3139 | value |= 0x40; | ||
3140 | bcm43xx_pcie_reg_write(bcm, BCM43xx_PCIE_DLLP_LINKCTL, | ||
3141 | value); | ||
3142 | } | ||
3073 | } | 3143 | } |
3074 | |||
3075 | out_switch_back: | 3144 | out_switch_back: |
3076 | err = bcm43xx_switch_core(bcm, old_core); | 3145 | err = bcm43xx_switch_core(bcm, old_core); |
3077 | out: | 3146 | out: |
@@ -3676,7 +3745,7 @@ static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm) | |||
3676 | bcm->ieee->freq_band = IEEE80211_24GHZ_BAND; | 3745 | bcm->ieee->freq_band = IEEE80211_24GHZ_BAND; |
3677 | break; | 3746 | break; |
3678 | case BCM43xx_PHYTYPE_G: | 3747 | case BCM43xx_PHYTYPE_G: |
3679 | if (phy_rev > 7) | 3748 | if (phy_rev > 8) |
3680 | phy_rev_ok = 0; | 3749 | phy_rev_ok = 0; |
3681 | bcm->ieee->modulation = IEEE80211_OFDM_MODULATION | | 3750 | bcm->ieee->modulation = IEEE80211_OFDM_MODULATION | |
3682 | IEEE80211_CCK_MODULATION; | 3751 | IEEE80211_CCK_MODULATION; |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_power.c b/drivers/net/wireless/bcm43xx/bcm43xx_power.c index 6569da3a7a39..7e774f410953 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_power.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_power.c | |||
@@ -153,8 +153,6 @@ int bcm43xx_pctl_init(struct bcm43xx_private *bcm) | |||
153 | int err, maxfreq; | 153 | int err, maxfreq; |
154 | struct bcm43xx_coreinfo *old_core; | 154 | struct bcm43xx_coreinfo *old_core; |
155 | 155 | ||
156 | if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL)) | ||
157 | return 0; | ||
158 | old_core = bcm->current_core; | 156 | old_core = bcm->current_core; |
159 | err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); | 157 | err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); |
160 | if (err == -ENODEV) | 158 | if (err == -ENODEV) |
@@ -162,11 +160,27 @@ int bcm43xx_pctl_init(struct bcm43xx_private *bcm) | |||
162 | if (err) | 160 | if (err) |
163 | goto out; | 161 | goto out; |
164 | 162 | ||
165 | maxfreq = bcm43xx_pctl_clockfreqlimit(bcm, 1); | 163 | if (bcm->chip_id == 0x4321) { |
166 | bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY, | 164 | if (bcm->chip_rev == 0) |
167 | (maxfreq * 150 + 999999) / 1000000); | 165 | bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_CTL, 0x03A4); |
168 | bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_FREFSELDELAY, | 166 | if (bcm->chip_rev == 1) |
169 | (maxfreq * 15 + 999999) / 1000000); | 167 | bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_CTL, 0x00A4); |
168 | } | ||
169 | |||
170 | if (bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL) { | ||
171 | if (bcm->current_core->rev >= 10) { | ||
172 | /* Set Idle Power clock rate to 1Mhz */ | ||
173 | bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL, | ||
174 | (bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL) | ||
175 | & 0x0000FFFF) | 0x40000); | ||
176 | } else { | ||
177 | maxfreq = bcm43xx_pctl_clockfreqlimit(bcm, 1); | ||
178 | bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY, | ||
179 | (maxfreq * 150 + 999999) / 1000000); | ||
180 | bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_FREFSELDELAY, | ||
181 | (maxfreq * 15 + 999999) / 1000000); | ||
182 | } | ||
183 | } | ||
170 | 184 | ||
171 | err = bcm43xx_switch_core(bcm, old_core); | 185 | err = bcm43xx_switch_core(bcm, old_core); |
172 | assert(err == 0); | 186 | assert(err == 0); |