diff options
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r-- | drivers/net/wireless/b43/main.c | 678 |
1 files changed, 510 insertions, 168 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index eb4159686985..73fbf0358f96 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -113,6 +113,17 @@ static int b43_modparam_pio = B43_PIO_DEFAULT; | |||
113 | module_param_named(pio, b43_modparam_pio, int, 0644); | 113 | module_param_named(pio, b43_modparam_pio, int, 0644); |
114 | MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); | 114 | MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); |
115 | 115 | ||
116 | #ifdef CONFIG_B43_BCMA | ||
117 | static const struct bcma_device_id b43_bcma_tbl[] = { | ||
118 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS), | ||
119 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS), | ||
120 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS), | ||
121 | BCMA_CORETABLE_END | ||
122 | }; | ||
123 | MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl); | ||
124 | #endif | ||
125 | |||
126 | #ifdef CONFIG_B43_SSB | ||
116 | static const struct ssb_device_id b43_ssb_tbl[] = { | 127 | static const struct ssb_device_id b43_ssb_tbl[] = { |
117 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), | 128 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), |
118 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6), | 129 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6), |
@@ -126,8 +137,8 @@ static const struct ssb_device_id b43_ssb_tbl[] = { | |||
126 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16), | 137 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16), |
127 | SSB_DEVTABLE_END | 138 | SSB_DEVTABLE_END |
128 | }; | 139 | }; |
129 | |||
130 | MODULE_DEVICE_TABLE(ssb, b43_ssb_tbl); | 140 | MODULE_DEVICE_TABLE(ssb, b43_ssb_tbl); |
141 | #endif | ||
131 | 142 | ||
132 | /* Channel and ratetables are shared for all devices. | 143 | /* Channel and ratetables are shared for all devices. |
133 | * They can't be const, because ieee80211 puts some precalculated | 144 | * They can't be const, because ieee80211 puts some precalculated |
@@ -548,7 +559,7 @@ void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) | |||
548 | { | 559 | { |
549 | u32 low, high; | 560 | u32 low, high; |
550 | 561 | ||
551 | B43_WARN_ON(dev->sdev->id.revision < 3); | 562 | B43_WARN_ON(dev->dev->core_rev < 3); |
552 | 563 | ||
553 | /* The hardware guarantees us an atomic read, if we | 564 | /* The hardware guarantees us an atomic read, if we |
554 | * read the low register first. */ | 565 | * read the low register first. */ |
@@ -586,7 +597,7 @@ static void b43_tsf_write_locked(struct b43_wldev *dev, u64 tsf) | |||
586 | { | 597 | { |
587 | u32 low, high; | 598 | u32 low, high; |
588 | 599 | ||
589 | B43_WARN_ON(dev->sdev->id.revision < 3); | 600 | B43_WARN_ON(dev->dev->core_rev < 3); |
590 | 601 | ||
591 | low = tsf; | 602 | low = tsf; |
592 | high = (tsf >> 32); | 603 | high = (tsf >> 32); |
@@ -714,7 +725,7 @@ void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on) | |||
714 | b43_ram_write(dev, i * 4, buffer[i]); | 725 | b43_ram_write(dev, i * 4, buffer[i]); |
715 | 726 | ||
716 | b43_write16(dev, 0x0568, 0x0000); | 727 | b43_write16(dev, 0x0568, 0x0000); |
717 | if (dev->sdev->id.revision < 11) | 728 | if (dev->dev->core_rev < 11) |
718 | b43_write16(dev, 0x07C0, 0x0000); | 729 | b43_write16(dev, 0x07C0, 0x0000); |
719 | else | 730 | else |
720 | b43_write16(dev, 0x07C0, 0x0100); | 731 | b43_write16(dev, 0x07C0, 0x0100); |
@@ -1132,7 +1143,7 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) | |||
1132 | b43_write32(dev, B43_MMIO_MACCTL, macctl); | 1143 | b43_write32(dev, B43_MMIO_MACCTL, macctl); |
1133 | /* Commit write */ | 1144 | /* Commit write */ |
1134 | b43_read32(dev, B43_MMIO_MACCTL); | 1145 | b43_read32(dev, B43_MMIO_MACCTL); |
1135 | if (awake && dev->sdev->id.revision >= 5) { | 1146 | if (awake && dev->dev->core_rev >= 5) { |
1136 | /* Wait for the microcode to wake up. */ | 1147 | /* Wait for the microcode to wake up. */ |
1137 | for (i = 0; i < 100; i++) { | 1148 | for (i = 0; i < 100; i++) { |
1138 | ucstat = b43_shm_read16(dev, B43_SHM_SHARED, | 1149 | ucstat = b43_shm_read16(dev, B43_SHM_SHARED, |
@@ -1144,35 +1155,85 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) | |||
1144 | } | 1155 | } |
1145 | } | 1156 | } |
1146 | 1157 | ||
1147 | static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, u32 flags) | 1158 | #ifdef CONFIG_B43_BCMA |
1159 | static void b43_bcma_phy_reset(struct b43_wldev *dev) | ||
1160 | { | ||
1161 | u32 flags; | ||
1162 | |||
1163 | /* Put PHY into reset */ | ||
1164 | flags = bcma_aread32(dev->dev->bdev, BCMA_IOCTL); | ||
1165 | flags |= B43_BCMA_IOCTL_PHY_RESET; | ||
1166 | flags |= B43_BCMA_IOCTL_PHY_BW_20MHZ; /* Make 20 MHz def */ | ||
1167 | bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags); | ||
1168 | udelay(2); | ||
1169 | |||
1170 | /* Take PHY out of reset */ | ||
1171 | flags = bcma_aread32(dev->dev->bdev, BCMA_IOCTL); | ||
1172 | flags &= ~B43_BCMA_IOCTL_PHY_RESET; | ||
1173 | flags |= BCMA_IOCTL_FGC; | ||
1174 | bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags); | ||
1175 | udelay(1); | ||
1176 | |||
1177 | /* Do not force clock anymore */ | ||
1178 | flags = bcma_aread32(dev->dev->bdev, BCMA_IOCTL); | ||
1179 | flags &= ~BCMA_IOCTL_FGC; | ||
1180 | bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags); | ||
1181 | udelay(1); | ||
1182 | } | ||
1183 | |||
1184 | static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode) | ||
1185 | { | ||
1186 | b43_device_enable(dev, B43_BCMA_IOCTL_PHY_CLKEN); | ||
1187 | bcma_core_set_clockmode(dev->dev->bdev, BCMA_CLKMODE_FAST); | ||
1188 | b43_bcma_phy_reset(dev); | ||
1189 | bcma_core_pll_ctl(dev->dev->bdev, 0x300, 0x3000000, true); | ||
1190 | } | ||
1191 | #endif | ||
1192 | |||
1193 | static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, bool gmode) | ||
1148 | { | 1194 | { |
1195 | struct ssb_device *sdev = dev->dev->sdev; | ||
1149 | u32 tmslow; | 1196 | u32 tmslow; |
1197 | u32 flags = 0; | ||
1150 | 1198 | ||
1199 | if (gmode) | ||
1200 | flags |= B43_TMSLOW_GMODE; | ||
1151 | flags |= B43_TMSLOW_PHYCLKEN; | 1201 | flags |= B43_TMSLOW_PHYCLKEN; |
1152 | flags |= B43_TMSLOW_PHYRESET; | 1202 | flags |= B43_TMSLOW_PHYRESET; |
1153 | if (dev->phy.type == B43_PHYTYPE_N) | 1203 | if (dev->phy.type == B43_PHYTYPE_N) |
1154 | flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */ | 1204 | flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */ |
1155 | ssb_device_enable(dev->sdev, flags); | 1205 | b43_device_enable(dev, flags); |
1156 | msleep(2); /* Wait for the PLL to turn on. */ | 1206 | msleep(2); /* Wait for the PLL to turn on. */ |
1157 | 1207 | ||
1158 | /* Now take the PHY out of Reset again */ | 1208 | /* Now take the PHY out of Reset again */ |
1159 | tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); | 1209 | tmslow = ssb_read32(sdev, SSB_TMSLOW); |
1160 | tmslow |= SSB_TMSLOW_FGC; | 1210 | tmslow |= SSB_TMSLOW_FGC; |
1161 | tmslow &= ~B43_TMSLOW_PHYRESET; | 1211 | tmslow &= ~B43_TMSLOW_PHYRESET; |
1162 | ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); | 1212 | ssb_write32(sdev, SSB_TMSLOW, tmslow); |
1163 | ssb_read32(dev->sdev, SSB_TMSLOW); /* flush */ | 1213 | ssb_read32(sdev, SSB_TMSLOW); /* flush */ |
1164 | msleep(1); | 1214 | msleep(1); |
1165 | tmslow &= ~SSB_TMSLOW_FGC; | 1215 | tmslow &= ~SSB_TMSLOW_FGC; |
1166 | ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); | 1216 | ssb_write32(sdev, SSB_TMSLOW, tmslow); |
1167 | ssb_read32(dev->sdev, SSB_TMSLOW); /* flush */ | 1217 | ssb_read32(sdev, SSB_TMSLOW); /* flush */ |
1168 | msleep(1); | 1218 | msleep(1); |
1169 | } | 1219 | } |
1170 | 1220 | ||
1171 | void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) | 1221 | void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode) |
1172 | { | 1222 | { |
1173 | u32 macctl; | 1223 | u32 macctl; |
1174 | 1224 | ||
1175 | b43_ssb_wireless_core_reset(dev, flags); | 1225 | switch (dev->dev->bus_type) { |
1226 | #ifdef CONFIG_B43_BCMA | ||
1227 | case B43_BUS_BCMA: | ||
1228 | b43_bcma_wireless_core_reset(dev, gmode); | ||
1229 | break; | ||
1230 | #endif | ||
1231 | #ifdef CONFIG_B43_SSB | ||
1232 | case B43_BUS_SSB: | ||
1233 | b43_ssb_wireless_core_reset(dev, gmode); | ||
1234 | break; | ||
1235 | #endif | ||
1236 | } | ||
1176 | 1237 | ||
1177 | /* Turn Analog ON, but only if we already know the PHY-type. | 1238 | /* Turn Analog ON, but only if we already know the PHY-type. |
1178 | * This protects against very early setup where we don't know the | 1239 | * This protects against very early setup where we don't know the |
@@ -1183,7 +1244,7 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) | |||
1183 | 1244 | ||
1184 | macctl = b43_read32(dev, B43_MMIO_MACCTL); | 1245 | macctl = b43_read32(dev, B43_MMIO_MACCTL); |
1185 | macctl &= ~B43_MACCTL_GMODE; | 1246 | macctl &= ~B43_MACCTL_GMODE; |
1186 | if (flags & B43_TMSLOW_GMODE) | 1247 | if (gmode) |
1187 | macctl |= B43_MACCTL_GMODE; | 1248 | macctl |= B43_MACCTL_GMODE; |
1188 | macctl |= B43_MACCTL_IHR_ENABLED; | 1249 | macctl |= B43_MACCTL_IHR_ENABLED; |
1189 | b43_write32(dev, B43_MMIO_MACCTL, macctl); | 1250 | b43_write32(dev, B43_MMIO_MACCTL, macctl); |
@@ -1221,7 +1282,7 @@ static void drain_txstatus_queue(struct b43_wldev *dev) | |||
1221 | { | 1282 | { |
1222 | u32 dummy; | 1283 | u32 dummy; |
1223 | 1284 | ||
1224 | if (dev->sdev->id.revision < 5) | 1285 | if (dev->dev->core_rev < 5) |
1225 | return; | 1286 | return; |
1226 | /* Read all entries from the microcode TXstatus FIFO | 1287 | /* Read all entries from the microcode TXstatus FIFO |
1227 | * and throw them away. | 1288 | * and throw them away. |
@@ -1427,9 +1488,9 @@ u8 b43_ieee80211_antenna_sanitize(struct b43_wldev *dev, | |||
1427 | 1488 | ||
1428 | /* Get the mask of available antennas. */ | 1489 | /* Get the mask of available antennas. */ |
1429 | if (dev->phy.gmode) | 1490 | if (dev->phy.gmode) |
1430 | antenna_mask = dev->sdev->bus->sprom.ant_available_bg; | 1491 | antenna_mask = dev->dev->bus_sprom->ant_available_bg; |
1431 | else | 1492 | else |
1432 | antenna_mask = dev->sdev->bus->sprom.ant_available_a; | 1493 | antenna_mask = dev->dev->bus_sprom->ant_available_a; |
1433 | 1494 | ||
1434 | if (!(antenna_mask & (1 << (antenna_nr - 1)))) { | 1495 | if (!(antenna_mask & (1 << (antenna_nr - 1)))) { |
1435 | /* This antenna is not available. Fall back to default. */ | 1496 | /* This antenna is not available. Fall back to default. */ |
@@ -1644,7 +1705,7 @@ static void b43_beacon_update_trigger_work(struct work_struct *work) | |||
1644 | mutex_lock(&wl->mutex); | 1705 | mutex_lock(&wl->mutex); |
1645 | dev = wl->current_dev; | 1706 | dev = wl->current_dev; |
1646 | if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { | 1707 | if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { |
1647 | if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { | 1708 | if (b43_bus_host_is_sdio(dev->dev)) { |
1648 | /* wl->mutex is enough. */ | 1709 | /* wl->mutex is enough. */ |
1649 | b43_do_beacon_update_trigger_work(dev); | 1710 | b43_do_beacon_update_trigger_work(dev); |
1650 | mmiowb(); | 1711 | mmiowb(); |
@@ -1689,7 +1750,7 @@ static void b43_update_templates(struct b43_wl *wl) | |||
1689 | static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) | 1750 | static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) |
1690 | { | 1751 | { |
1691 | b43_time_lock(dev); | 1752 | b43_time_lock(dev); |
1692 | if (dev->sdev->id.revision >= 3) { | 1753 | if (dev->dev->core_rev >= 3) { |
1693 | b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16)); | 1754 | b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16)); |
1694 | b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10)); | 1755 | b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10)); |
1695 | } else { | 1756 | } else { |
@@ -1923,7 +1984,7 @@ static irqreturn_t b43_do_interrupt(struct b43_wldev *dev) | |||
1923 | return IRQ_NONE; | 1984 | return IRQ_NONE; |
1924 | reason &= dev->irq_mask; | 1985 | reason &= dev->irq_mask; |
1925 | if (!reason) | 1986 | if (!reason) |
1926 | return IRQ_HANDLED; | 1987 | return IRQ_NONE; |
1927 | 1988 | ||
1928 | dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) | 1989 | dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) |
1929 | & 0x0001DC00; | 1990 | & 0x0001DC00; |
@@ -2063,7 +2124,7 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx, | |||
2063 | B43_WARN_ON(1); | 2124 | B43_WARN_ON(1); |
2064 | return -ENOSYS; | 2125 | return -ENOSYS; |
2065 | } | 2126 | } |
2066 | err = request_firmware(&blob, ctx->fwname, ctx->dev->sdev->dev); | 2127 | err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev); |
2067 | if (err == -ENOENT) { | 2128 | if (err == -ENOENT) { |
2068 | snprintf(ctx->errors[ctx->req_type], | 2129 | snprintf(ctx->errors[ctx->req_type], |
2069 | sizeof(ctx->errors[ctx->req_type]), | 2130 | sizeof(ctx->errors[ctx->req_type]), |
@@ -2113,26 +2174,48 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) | |||
2113 | { | 2174 | { |
2114 | struct b43_wldev *dev = ctx->dev; | 2175 | struct b43_wldev *dev = ctx->dev; |
2115 | struct b43_firmware *fw = &ctx->dev->fw; | 2176 | struct b43_firmware *fw = &ctx->dev->fw; |
2116 | const u8 rev = ctx->dev->sdev->id.revision; | 2177 | const u8 rev = ctx->dev->dev->core_rev; |
2117 | const char *filename; | 2178 | const char *filename; |
2118 | u32 tmshigh; | 2179 | u32 tmshigh; |
2119 | int err; | 2180 | int err; |
2120 | 2181 | ||
2182 | /* Files for HT and LCN were found by trying one by one */ | ||
2183 | |||
2121 | /* Get microcode */ | 2184 | /* Get microcode */ |
2122 | if ((rev >= 5) && (rev <= 10)) | 2185 | if ((rev >= 5) && (rev <= 10)) { |
2123 | filename = "ucode5"; | 2186 | filename = "ucode5"; |
2124 | else if ((rev >= 11) && (rev <= 12)) | 2187 | } else if ((rev >= 11) && (rev <= 12)) { |
2125 | filename = "ucode11"; | 2188 | filename = "ucode11"; |
2126 | else if (rev == 13) | 2189 | } else if (rev == 13) { |
2127 | filename = "ucode13"; | 2190 | filename = "ucode13"; |
2128 | else if (rev == 14) | 2191 | } else if (rev == 14) { |
2129 | filename = "ucode14"; | 2192 | filename = "ucode14"; |
2130 | else if (rev == 15) | 2193 | } else if (rev == 15) { |
2131 | filename = "ucode15"; | 2194 | filename = "ucode15"; |
2132 | else if ((rev >= 16) && (rev <= 20)) | 2195 | } else { |
2133 | filename = "ucode16_mimo"; | 2196 | switch (dev->phy.type) { |
2134 | else | 2197 | case B43_PHYTYPE_N: |
2135 | goto err_no_ucode; | 2198 | if (rev >= 16) |
2199 | filename = "ucode16_mimo"; | ||
2200 | else | ||
2201 | goto err_no_ucode; | ||
2202 | break; | ||
2203 | case B43_PHYTYPE_HT: | ||
2204 | if (rev == 29) | ||
2205 | filename = "ucode29_mimo"; | ||
2206 | else | ||
2207 | goto err_no_ucode; | ||
2208 | break; | ||
2209 | case B43_PHYTYPE_LCN: | ||
2210 | if (rev == 24) | ||
2211 | filename = "ucode24_mimo"; | ||
2212 | else | ||
2213 | goto err_no_ucode; | ||
2214 | break; | ||
2215 | default: | ||
2216 | goto err_no_ucode; | ||
2217 | } | ||
2218 | } | ||
2136 | err = b43_do_request_fw(ctx, filename, &fw->ucode); | 2219 | err = b43_do_request_fw(ctx, filename, &fw->ucode); |
2137 | if (err) | 2220 | if (err) |
2138 | goto err_load; | 2221 | goto err_load; |
@@ -2157,7 +2240,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) | |||
2157 | switch (dev->phy.type) { | 2240 | switch (dev->phy.type) { |
2158 | case B43_PHYTYPE_A: | 2241 | case B43_PHYTYPE_A: |
2159 | if ((rev >= 5) && (rev <= 10)) { | 2242 | if ((rev >= 5) && (rev <= 10)) { |
2160 | tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); | 2243 | tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); |
2161 | if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) | 2244 | if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) |
2162 | filename = "a0g1initvals5"; | 2245 | filename = "a0g1initvals5"; |
2163 | else | 2246 | else |
@@ -2191,6 +2274,18 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) | |||
2191 | else | 2274 | else |
2192 | goto err_no_initvals; | 2275 | goto err_no_initvals; |
2193 | break; | 2276 | break; |
2277 | case B43_PHYTYPE_HT: | ||
2278 | if (rev == 29) | ||
2279 | filename = "ht0initvals29"; | ||
2280 | else | ||
2281 | goto err_no_initvals; | ||
2282 | break; | ||
2283 | case B43_PHYTYPE_LCN: | ||
2284 | if (rev == 24) | ||
2285 | filename = "lcn0initvals24"; | ||
2286 | else | ||
2287 | goto err_no_initvals; | ||
2288 | break; | ||
2194 | default: | 2289 | default: |
2195 | goto err_no_initvals; | 2290 | goto err_no_initvals; |
2196 | } | 2291 | } |
@@ -2202,7 +2297,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) | |||
2202 | switch (dev->phy.type) { | 2297 | switch (dev->phy.type) { |
2203 | case B43_PHYTYPE_A: | 2298 | case B43_PHYTYPE_A: |
2204 | if ((rev >= 5) && (rev <= 10)) { | 2299 | if ((rev >= 5) && (rev <= 10)) { |
2205 | tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); | 2300 | tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); |
2206 | if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) | 2301 | if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) |
2207 | filename = "a0g1bsinitvals5"; | 2302 | filename = "a0g1bsinitvals5"; |
2208 | else | 2303 | else |
@@ -2238,6 +2333,18 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) | |||
2238 | else | 2333 | else |
2239 | goto err_no_initvals; | 2334 | goto err_no_initvals; |
2240 | break; | 2335 | break; |
2336 | case B43_PHYTYPE_HT: | ||
2337 | if (rev == 29) | ||
2338 | filename = "ht0bsinitvals29"; | ||
2339 | else | ||
2340 | goto err_no_initvals; | ||
2341 | break; | ||
2342 | case B43_PHYTYPE_LCN: | ||
2343 | if (rev == 24) | ||
2344 | filename = "lcn0bsinitvals24"; | ||
2345 | else | ||
2346 | goto err_no_initvals; | ||
2347 | break; | ||
2241 | default: | 2348 | default: |
2242 | goto err_no_initvals; | 2349 | goto err_no_initvals; |
2243 | } | 2350 | } |
@@ -2448,7 +2555,7 @@ static int b43_upload_microcode(struct b43_wldev *dev) | |||
2448 | 2555 | ||
2449 | snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u", | 2556 | snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u", |
2450 | dev->fw.rev, dev->fw.patch); | 2557 | dev->fw.rev, dev->fw.patch); |
2451 | wiphy->hw_version = dev->sdev->id.coreid; | 2558 | wiphy->hw_version = dev->dev->core_id; |
2452 | 2559 | ||
2453 | if (b43_is_old_txhdr_format(dev)) { | 2560 | if (b43_is_old_txhdr_format(dev)) { |
2454 | /* We're over the deadline, but we keep support for old fw | 2561 | /* We're over the deadline, but we keep support for old fw |
@@ -2566,7 +2673,7 @@ out: | |||
2566 | */ | 2673 | */ |
2567 | static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev) | 2674 | static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev) |
2568 | { | 2675 | { |
2569 | struct ssb_bus *bus = dev->sdev->bus; | 2676 | struct ssb_bus *bus = dev->dev->sdev->bus; |
2570 | 2677 | ||
2571 | #ifdef CONFIG_SSB_DRIVER_PCICORE | 2678 | #ifdef CONFIG_SSB_DRIVER_PCICORE |
2572 | return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev); | 2679 | return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev); |
@@ -2588,7 +2695,7 @@ static int b43_gpio_init(struct b43_wldev *dev) | |||
2588 | 2695 | ||
2589 | mask = 0x0000001F; | 2696 | mask = 0x0000001F; |
2590 | set = 0x0000000F; | 2697 | set = 0x0000000F; |
2591 | if (dev->sdev->bus->chip_id == 0x4301) { | 2698 | if (dev->dev->chip_id == 0x4301) { |
2592 | mask |= 0x0060; | 2699 | mask |= 0x0060; |
2593 | set |= 0x0060; | 2700 | set |= 0x0060; |
2594 | } | 2701 | } |
@@ -2599,21 +2706,34 @@ static int b43_gpio_init(struct b43_wldev *dev) | |||
2599 | mask |= 0x0180; | 2706 | mask |= 0x0180; |
2600 | set |= 0x0180; | 2707 | set |= 0x0180; |
2601 | } | 2708 | } |
2602 | if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) { | 2709 | if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) { |
2603 | b43_write16(dev, B43_MMIO_GPIO_MASK, | 2710 | b43_write16(dev, B43_MMIO_GPIO_MASK, |
2604 | b43_read16(dev, B43_MMIO_GPIO_MASK) | 2711 | b43_read16(dev, B43_MMIO_GPIO_MASK) |
2605 | | 0x0200); | 2712 | | 0x0200); |
2606 | mask |= 0x0200; | 2713 | mask |= 0x0200; |
2607 | set |= 0x0200; | 2714 | set |= 0x0200; |
2608 | } | 2715 | } |
2609 | if (dev->sdev->id.revision >= 2) | 2716 | if (dev->dev->core_rev >= 2) |
2610 | mask |= 0x0010; /* FIXME: This is redundant. */ | 2717 | mask |= 0x0010; /* FIXME: This is redundant. */ |
2611 | 2718 | ||
2612 | gpiodev = b43_ssb_gpio_dev(dev); | 2719 | switch (dev->dev->bus_type) { |
2613 | if (gpiodev) | 2720 | #ifdef CONFIG_B43_BCMA |
2614 | ssb_write32(gpiodev, B43_GPIO_CONTROL, | 2721 | case B43_BUS_BCMA: |
2615 | (ssb_read32(gpiodev, B43_GPIO_CONTROL) | 2722 | bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL, |
2616 | & mask) | set); | 2723 | (bcma_cc_read32(&dev->dev->bdev->bus->drv_cc, |
2724 | BCMA_CC_GPIOCTL) & mask) | set); | ||
2725 | break; | ||
2726 | #endif | ||
2727 | #ifdef CONFIG_B43_SSB | ||
2728 | case B43_BUS_SSB: | ||
2729 | gpiodev = b43_ssb_gpio_dev(dev); | ||
2730 | if (gpiodev) | ||
2731 | ssb_write32(gpiodev, B43_GPIO_CONTROL, | ||
2732 | (ssb_read32(gpiodev, B43_GPIO_CONTROL) | ||
2733 | & mask) | set); | ||
2734 | break; | ||
2735 | #endif | ||
2736 | } | ||
2617 | 2737 | ||
2618 | return 0; | 2738 | return 0; |
2619 | } | 2739 | } |
@@ -2623,9 +2743,21 @@ static void b43_gpio_cleanup(struct b43_wldev *dev) | |||
2623 | { | 2743 | { |
2624 | struct ssb_device *gpiodev; | 2744 | struct ssb_device *gpiodev; |
2625 | 2745 | ||
2626 | gpiodev = b43_ssb_gpio_dev(dev); | 2746 | switch (dev->dev->bus_type) { |
2627 | if (gpiodev) | 2747 | #ifdef CONFIG_B43_BCMA |
2628 | ssb_write32(gpiodev, B43_GPIO_CONTROL, 0); | 2748 | case B43_BUS_BCMA: |
2749 | bcma_cc_write32(&dev->dev->bdev->bus->drv_cc, BCMA_CC_GPIOCTL, | ||
2750 | 0); | ||
2751 | break; | ||
2752 | #endif | ||
2753 | #ifdef CONFIG_B43_SSB | ||
2754 | case B43_BUS_SSB: | ||
2755 | gpiodev = b43_ssb_gpio_dev(dev); | ||
2756 | if (gpiodev) | ||
2757 | ssb_write32(gpiodev, B43_GPIO_CONTROL, 0); | ||
2758 | break; | ||
2759 | #endif | ||
2760 | } | ||
2629 | } | 2761 | } |
2630 | 2762 | ||
2631 | /* http://bcm-specs.sipsolutions.net/EnableMac */ | 2763 | /* http://bcm-specs.sipsolutions.net/EnableMac */ |
@@ -2697,12 +2829,30 @@ out: | |||
2697 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */ | 2829 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */ |
2698 | void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on) | 2830 | void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on) |
2699 | { | 2831 | { |
2700 | u32 tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); | 2832 | u32 tmp; |
2701 | if (on) | 2833 | |
2702 | tmslow |= B43_TMSLOW_MACPHYCLKEN; | 2834 | switch (dev->dev->bus_type) { |
2703 | else | 2835 | #ifdef CONFIG_B43_BCMA |
2704 | tmslow &= ~B43_TMSLOW_MACPHYCLKEN; | 2836 | case B43_BUS_BCMA: |
2705 | ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); | 2837 | tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL); |
2838 | if (on) | ||
2839 | tmp |= B43_BCMA_IOCTL_MACPHYCLKEN; | ||
2840 | else | ||
2841 | tmp &= ~B43_BCMA_IOCTL_MACPHYCLKEN; | ||
2842 | bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp); | ||
2843 | break; | ||
2844 | #endif | ||
2845 | #ifdef CONFIG_B43_SSB | ||
2846 | case B43_BUS_SSB: | ||
2847 | tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); | ||
2848 | if (on) | ||
2849 | tmp |= B43_TMSLOW_MACPHYCLKEN; | ||
2850 | else | ||
2851 | tmp &= ~B43_TMSLOW_MACPHYCLKEN; | ||
2852 | ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); | ||
2853 | break; | ||
2854 | #endif | ||
2855 | } | ||
2706 | } | 2856 | } |
2707 | 2857 | ||
2708 | static void b43_adjust_opmode(struct b43_wldev *dev) | 2858 | static void b43_adjust_opmode(struct b43_wldev *dev) |
@@ -2741,15 +2891,15 @@ static void b43_adjust_opmode(struct b43_wldev *dev) | |||
2741 | /* Workaround: On old hardware the HW-MAC-address-filter | 2891 | /* Workaround: On old hardware the HW-MAC-address-filter |
2742 | * doesn't work properly, so always run promisc in filter | 2892 | * doesn't work properly, so always run promisc in filter |
2743 | * it in software. */ | 2893 | * it in software. */ |
2744 | if (dev->sdev->id.revision <= 4) | 2894 | if (dev->dev->core_rev <= 4) |
2745 | ctl |= B43_MACCTL_PROMISC; | 2895 | ctl |= B43_MACCTL_PROMISC; |
2746 | 2896 | ||
2747 | b43_write32(dev, B43_MMIO_MACCTL, ctl); | 2897 | b43_write32(dev, B43_MMIO_MACCTL, ctl); |
2748 | 2898 | ||
2749 | cfp_pretbtt = 2; | 2899 | cfp_pretbtt = 2; |
2750 | if ((ctl & B43_MACCTL_INFRA) && !(ctl & B43_MACCTL_AP)) { | 2900 | if ((ctl & B43_MACCTL_INFRA) && !(ctl & B43_MACCTL_AP)) { |
2751 | if (dev->sdev->bus->chip_id == 0x4306 && | 2901 | if (dev->dev->chip_id == 0x4306 && |
2752 | dev->sdev->bus->chip_rev == 3) | 2902 | dev->dev->chip_rev == 3) |
2753 | cfp_pretbtt = 100; | 2903 | cfp_pretbtt = 100; |
2754 | else | 2904 | else |
2755 | cfp_pretbtt = 50; | 2905 | cfp_pretbtt = 50; |
@@ -2907,7 +3057,7 @@ static int b43_chip_init(struct b43_wldev *dev) | |||
2907 | b43_write16(dev, 0x005E, value16); | 3057 | b43_write16(dev, 0x005E, value16); |
2908 | } | 3058 | } |
2909 | b43_write32(dev, 0x0100, 0x01000000); | 3059 | b43_write32(dev, 0x0100, 0x01000000); |
2910 | if (dev->sdev->id.revision < 5) | 3060 | if (dev->dev->core_rev < 5) |
2911 | b43_write32(dev, 0x010C, 0x01000000); | 3061 | b43_write32(dev, 0x010C, 0x01000000); |
2912 | 3062 | ||
2913 | b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) | 3063 | b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) |
@@ -2922,7 +3072,7 @@ static int b43_chip_init(struct b43_wldev *dev) | |||
2922 | /* Initially set the wireless operation mode. */ | 3072 | /* Initially set the wireless operation mode. */ |
2923 | b43_adjust_opmode(dev); | 3073 | b43_adjust_opmode(dev); |
2924 | 3074 | ||
2925 | if (dev->sdev->id.revision < 3) { | 3075 | if (dev->dev->core_rev < 3) { |
2926 | b43_write16(dev, 0x060E, 0x0000); | 3076 | b43_write16(dev, 0x060E, 0x0000); |
2927 | b43_write16(dev, 0x0610, 0x8000); | 3077 | b43_write16(dev, 0x0610, 0x8000); |
2928 | b43_write16(dev, 0x0604, 0x0000); | 3078 | b43_write16(dev, 0x0604, 0x0000); |
@@ -2941,8 +3091,20 @@ static int b43_chip_init(struct b43_wldev *dev) | |||
2941 | 3091 | ||
2942 | b43_mac_phy_clock_set(dev, true); | 3092 | b43_mac_phy_clock_set(dev, true); |
2943 | 3093 | ||
2944 | b43_write16(dev, B43_MMIO_POWERUP_DELAY, | 3094 | switch (dev->dev->bus_type) { |
2945 | dev->sdev->bus->chipco.fast_pwrup_delay); | 3095 | #ifdef CONFIG_B43_BCMA |
3096 | case B43_BUS_BCMA: | ||
3097 | /* FIXME: 0xE74 is quite common, but should be read from CC */ | ||
3098 | b43_write16(dev, B43_MMIO_POWERUP_DELAY, 0xE74); | ||
3099 | break; | ||
3100 | #endif | ||
3101 | #ifdef CONFIG_B43_SSB | ||
3102 | case B43_BUS_SSB: | ||
3103 | b43_write16(dev, B43_MMIO_POWERUP_DELAY, | ||
3104 | dev->dev->sdev->bus->chipco.fast_pwrup_delay); | ||
3105 | break; | ||
3106 | #endif | ||
3107 | } | ||
2946 | 3108 | ||
2947 | err = 0; | 3109 | err = 0; |
2948 | b43dbg(dev->wl, "Chip initialized\n"); | 3110 | b43dbg(dev->wl, "Chip initialized\n"); |
@@ -3105,7 +3267,7 @@ static int b43_validate_chipaccess(struct b43_wldev *dev) | |||
3105 | b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0); | 3267 | b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0); |
3106 | b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4); | 3268 | b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4); |
3107 | 3269 | ||
3108 | if ((dev->sdev->id.revision >= 3) && (dev->sdev->id.revision <= 10)) { | 3270 | if ((dev->dev->core_rev >= 3) && (dev->dev->core_rev <= 10)) { |
3109 | /* The 32bit register shadows the two 16bit registers | 3271 | /* The 32bit register shadows the two 16bit registers |
3110 | * with update sideeffects. Validate this. */ | 3272 | * with update sideeffects. Validate this. */ |
3111 | b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA); | 3273 | b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA); |
@@ -3458,21 +3620,33 @@ static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf) | |||
3458 | 3620 | ||
3459 | static void b43_put_phy_into_reset(struct b43_wldev *dev) | 3621 | static void b43_put_phy_into_reset(struct b43_wldev *dev) |
3460 | { | 3622 | { |
3461 | struct ssb_device *sdev = dev->sdev; | 3623 | u32 tmp; |
3462 | u32 tmslow; | ||
3463 | 3624 | ||
3464 | tmslow = ssb_read32(sdev, SSB_TMSLOW); | 3625 | switch (dev->dev->bus_type) { |
3465 | tmslow &= ~B43_TMSLOW_GMODE; | 3626 | #ifdef CONFIG_B43_BCMA |
3466 | tmslow |= B43_TMSLOW_PHYRESET; | 3627 | case B43_BUS_BCMA: |
3467 | tmslow |= SSB_TMSLOW_FGC; | 3628 | b43err(dev->wl, |
3468 | ssb_write32(sdev, SSB_TMSLOW, tmslow); | 3629 | "Putting PHY into reset not supported on BCMA\n"); |
3469 | msleep(1); | 3630 | break; |
3631 | #endif | ||
3632 | #ifdef CONFIG_B43_SSB | ||
3633 | case B43_BUS_SSB: | ||
3634 | tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); | ||
3635 | tmp &= ~B43_TMSLOW_GMODE; | ||
3636 | tmp |= B43_TMSLOW_PHYRESET; | ||
3637 | tmp |= SSB_TMSLOW_FGC; | ||
3638 | ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); | ||
3639 | msleep(1); | ||
3640 | |||
3641 | tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW); | ||
3642 | tmp &= ~SSB_TMSLOW_FGC; | ||
3643 | tmp |= B43_TMSLOW_PHYRESET; | ||
3644 | ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp); | ||
3645 | msleep(1); | ||
3470 | 3646 | ||
3471 | tmslow = ssb_read32(sdev, SSB_TMSLOW); | 3647 | break; |
3472 | tmslow &= ~SSB_TMSLOW_FGC; | 3648 | #endif |
3473 | tmslow |= B43_TMSLOW_PHYRESET; | 3649 | } |
3474 | ssb_write32(sdev, SSB_TMSLOW, tmslow); | ||
3475 | msleep(1); | ||
3476 | } | 3650 | } |
3477 | 3651 | ||
3478 | static const char *band_to_string(enum ieee80211_band band) | 3652 | static const char *band_to_string(enum ieee80211_band band) |
@@ -3954,7 +4128,7 @@ redo: | |||
3954 | 4128 | ||
3955 | /* Disable interrupts on the device. */ | 4129 | /* Disable interrupts on the device. */ |
3956 | b43_set_status(dev, B43_STAT_INITIALIZED); | 4130 | b43_set_status(dev, B43_STAT_INITIALIZED); |
3957 | if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { | 4131 | if (b43_bus_host_is_sdio(dev->dev)) { |
3958 | /* wl->mutex is locked. That is enough. */ | 4132 | /* wl->mutex is locked. That is enough. */ |
3959 | b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); | 4133 | b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); |
3960 | b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */ | 4134 | b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */ |
@@ -3967,11 +4141,11 @@ redo: | |||
3967 | /* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */ | 4141 | /* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */ |
3968 | orig_dev = dev; | 4142 | orig_dev = dev; |
3969 | mutex_unlock(&wl->mutex); | 4143 | mutex_unlock(&wl->mutex); |
3970 | if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { | 4144 | if (b43_bus_host_is_sdio(dev->dev)) { |
3971 | b43_sdio_free_irq(dev); | 4145 | b43_sdio_free_irq(dev); |
3972 | } else { | 4146 | } else { |
3973 | synchronize_irq(dev->sdev->irq); | 4147 | synchronize_irq(dev->dev->irq); |
3974 | free_irq(dev->sdev->irq, dev); | 4148 | free_irq(dev->dev->irq, dev); |
3975 | } | 4149 | } |
3976 | mutex_lock(&wl->mutex); | 4150 | mutex_lock(&wl->mutex); |
3977 | dev = wl->current_dev; | 4151 | dev = wl->current_dev; |
@@ -4004,19 +4178,19 @@ static int b43_wireless_core_start(struct b43_wldev *dev) | |||
4004 | B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED); | 4178 | B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED); |
4005 | 4179 | ||
4006 | drain_txstatus_queue(dev); | 4180 | drain_txstatus_queue(dev); |
4007 | if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { | 4181 | if (b43_bus_host_is_sdio(dev->dev)) { |
4008 | err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler); | 4182 | err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler); |
4009 | if (err) { | 4183 | if (err) { |
4010 | b43err(dev->wl, "Cannot request SDIO IRQ\n"); | 4184 | b43err(dev->wl, "Cannot request SDIO IRQ\n"); |
4011 | goto out; | 4185 | goto out; |
4012 | } | 4186 | } |
4013 | } else { | 4187 | } else { |
4014 | err = request_threaded_irq(dev->sdev->irq, b43_interrupt_handler, | 4188 | err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler, |
4015 | b43_interrupt_thread_handler, | 4189 | b43_interrupt_thread_handler, |
4016 | IRQF_SHARED, KBUILD_MODNAME, dev); | 4190 | IRQF_SHARED, KBUILD_MODNAME, dev); |
4017 | if (err) { | 4191 | if (err) { |
4018 | b43err(dev->wl, "Cannot request IRQ-%d\n", | 4192 | b43err(dev->wl, "Cannot request IRQ-%d\n", |
4019 | dev->sdev->irq); | 4193 | dev->dev->irq); |
4020 | goto out; | 4194 | goto out; |
4021 | } | 4195 | } |
4022 | } | 4196 | } |
@@ -4083,9 +4257,21 @@ static int b43_phy_versioning(struct b43_wldev *dev) | |||
4083 | unsupported = 1; | 4257 | unsupported = 1; |
4084 | break; | 4258 | break; |
4085 | #endif | 4259 | #endif |
4260 | #ifdef CONFIG_B43_PHY_HT | ||
4261 | case B43_PHYTYPE_HT: | ||
4262 | if (phy_rev > 1) | ||
4263 | unsupported = 1; | ||
4264 | break; | ||
4265 | #endif | ||
4266 | #ifdef CONFIG_B43_PHY_LCN | ||
4267 | case B43_PHYTYPE_LCN: | ||
4268 | if (phy_rev > 1) | ||
4269 | unsupported = 1; | ||
4270 | break; | ||
4271 | #endif | ||
4086 | default: | 4272 | default: |
4087 | unsupported = 1; | 4273 | unsupported = 1; |
4088 | }; | 4274 | } |
4089 | if (unsupported) { | 4275 | if (unsupported) { |
4090 | b43err(dev->wl, "FOUND UNSUPPORTED PHY " | 4276 | b43err(dev->wl, "FOUND UNSUPPORTED PHY " |
4091 | "(Analog %u, Type %u, Revision %u)\n", | 4277 | "(Analog %u, Type %u, Revision %u)\n", |
@@ -4096,22 +4282,42 @@ static int b43_phy_versioning(struct b43_wldev *dev) | |||
4096 | analog_type, phy_type, phy_rev); | 4282 | analog_type, phy_type, phy_rev); |
4097 | 4283 | ||
4098 | /* Get RADIO versioning */ | 4284 | /* Get RADIO versioning */ |
4099 | if (dev->sdev->bus->chip_id == 0x4317) { | 4285 | if (dev->dev->core_rev >= 24) { |
4100 | if (dev->sdev->bus->chip_rev == 0) | 4286 | u16 radio24[3]; |
4101 | tmp = 0x3205017F; | 4287 | |
4102 | else if (dev->sdev->bus->chip_rev == 1) | 4288 | for (tmp = 0; tmp < 3; tmp++) { |
4103 | tmp = 0x4205017F; | 4289 | b43_write16(dev, B43_MMIO_RADIO24_CONTROL, tmp); |
4104 | else | 4290 | radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA); |
4105 | tmp = 0x5205017F; | 4291 | } |
4292 | |||
4293 | /* Broadcom uses "id" for our "ver" and has separated "ver" */ | ||
4294 | /* radio_ver = (radio24[0] & 0xF0) >> 4; */ | ||
4295 | |||
4296 | radio_manuf = 0x17F; | ||
4297 | radio_ver = (radio24[2] << 8) | radio24[1]; | ||
4298 | radio_rev = (radio24[0] & 0xF); | ||
4106 | } else { | 4299 | } else { |
4107 | b43_write16(dev, B43_MMIO_RADIO_CONTROL, B43_RADIOCTL_ID); | 4300 | if (dev->dev->chip_id == 0x4317) { |
4108 | tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); | 4301 | if (dev->dev->chip_rev == 0) |
4109 | b43_write16(dev, B43_MMIO_RADIO_CONTROL, B43_RADIOCTL_ID); | 4302 | tmp = 0x3205017F; |
4110 | tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) << 16; | 4303 | else if (dev->dev->chip_rev == 1) |
4111 | } | 4304 | tmp = 0x4205017F; |
4112 | radio_manuf = (tmp & 0x00000FFF); | 4305 | else |
4113 | radio_ver = (tmp & 0x0FFFF000) >> 12; | 4306 | tmp = 0x5205017F; |
4114 | radio_rev = (tmp & 0xF0000000) >> 28; | 4307 | } else { |
4308 | b43_write16(dev, B43_MMIO_RADIO_CONTROL, | ||
4309 | B43_RADIOCTL_ID); | ||
4310 | tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW); | ||
4311 | b43_write16(dev, B43_MMIO_RADIO_CONTROL, | ||
4312 | B43_RADIOCTL_ID); | ||
4313 | tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH) | ||
4314 | << 16; | ||
4315 | } | ||
4316 | radio_manuf = (tmp & 0x00000FFF); | ||
4317 | radio_ver = (tmp & 0x0FFFF000) >> 12; | ||
4318 | radio_rev = (tmp & 0xF0000000) >> 28; | ||
4319 | } | ||
4320 | |||
4115 | if (radio_manuf != 0x17F /* Broadcom */) | 4321 | if (radio_manuf != 0x17F /* Broadcom */) |
4116 | unsupported = 1; | 4322 | unsupported = 1; |
4117 | switch (phy_type) { | 4323 | switch (phy_type) { |
@@ -4139,6 +4345,14 @@ static int b43_phy_versioning(struct b43_wldev *dev) | |||
4139 | if (radio_ver != 0x2062 && radio_ver != 0x2063) | 4345 | if (radio_ver != 0x2062 && radio_ver != 0x2063) |
4140 | unsupported = 1; | 4346 | unsupported = 1; |
4141 | break; | 4347 | break; |
4348 | case B43_PHYTYPE_HT: | ||
4349 | if (radio_ver != 0x2059) | ||
4350 | unsupported = 1; | ||
4351 | break; | ||
4352 | case B43_PHYTYPE_LCN: | ||
4353 | if (radio_ver != 0x2064) | ||
4354 | unsupported = 1; | ||
4355 | break; | ||
4142 | default: | 4356 | default: |
4143 | B43_WARN_ON(1); | 4357 | B43_WARN_ON(1); |
4144 | } | 4358 | } |
@@ -4204,7 +4418,7 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev) | |||
4204 | 4418 | ||
4205 | static void b43_bluetooth_coext_enable(struct b43_wldev *dev) | 4419 | static void b43_bluetooth_coext_enable(struct b43_wldev *dev) |
4206 | { | 4420 | { |
4207 | struct ssb_sprom *sprom = &dev->sdev->bus->sprom; | 4421 | struct ssb_sprom *sprom = dev->dev->bus_sprom; |
4208 | u64 hf; | 4422 | u64 hf; |
4209 | 4423 | ||
4210 | if (!modparam_btcoex) | 4424 | if (!modparam_btcoex) |
@@ -4231,16 +4445,21 @@ static void b43_bluetooth_coext_disable(struct b43_wldev *dev) | |||
4231 | 4445 | ||
4232 | static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev) | 4446 | static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev) |
4233 | { | 4447 | { |
4234 | struct ssb_bus *bus = dev->sdev->bus; | 4448 | struct ssb_bus *bus; |
4235 | u32 tmp; | 4449 | u32 tmp; |
4236 | 4450 | ||
4451 | if (dev->dev->bus_type != B43_BUS_SSB) | ||
4452 | return; | ||
4453 | |||
4454 | bus = dev->dev->sdev->bus; | ||
4455 | |||
4237 | if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) || | 4456 | if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) || |
4238 | (bus->chip_id == 0x4312)) { | 4457 | (bus->chip_id == 0x4312)) { |
4239 | tmp = ssb_read32(dev->sdev, SSB_IMCFGLO); | 4458 | tmp = ssb_read32(dev->dev->sdev, SSB_IMCFGLO); |
4240 | tmp &= ~SSB_IMCFGLO_REQTO; | 4459 | tmp &= ~SSB_IMCFGLO_REQTO; |
4241 | tmp &= ~SSB_IMCFGLO_SERTO; | 4460 | tmp &= ~SSB_IMCFGLO_SERTO; |
4242 | tmp |= 0x3; | 4461 | tmp |= 0x3; |
4243 | ssb_write32(dev->sdev, SSB_IMCFGLO, tmp); | 4462 | ssb_write32(dev->dev->sdev, SSB_IMCFGLO, tmp); |
4244 | ssb_commit_settings(bus); | 4463 | ssb_commit_settings(bus); |
4245 | } | 4464 | } |
4246 | } | 4465 | } |
@@ -4310,36 +4529,45 @@ static void b43_wireless_core_exit(struct b43_wldev *dev) | |||
4310 | dev->wl->current_beacon = NULL; | 4529 | dev->wl->current_beacon = NULL; |
4311 | } | 4530 | } |
4312 | 4531 | ||
4313 | ssb_device_disable(dev->sdev, 0); | 4532 | b43_device_disable(dev, 0); |
4314 | ssb_bus_may_powerdown(dev->sdev->bus); | 4533 | b43_bus_may_powerdown(dev); |
4315 | } | 4534 | } |
4316 | 4535 | ||
4317 | /* Initialize a wireless core */ | 4536 | /* Initialize a wireless core */ |
4318 | static int b43_wireless_core_init(struct b43_wldev *dev) | 4537 | static int b43_wireless_core_init(struct b43_wldev *dev) |
4319 | { | 4538 | { |
4320 | struct ssb_bus *bus = dev->sdev->bus; | 4539 | struct ssb_sprom *sprom = dev->dev->bus_sprom; |
4321 | struct ssb_sprom *sprom = &bus->sprom; | ||
4322 | struct b43_phy *phy = &dev->phy; | 4540 | struct b43_phy *phy = &dev->phy; |
4323 | int err; | 4541 | int err; |
4324 | u64 hf; | 4542 | u64 hf; |
4325 | u32 tmp; | ||
4326 | 4543 | ||
4327 | B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT); | 4544 | B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT); |
4328 | 4545 | ||
4329 | err = ssb_bus_powerup(bus, 0); | 4546 | err = b43_bus_powerup(dev, 0); |
4330 | if (err) | 4547 | if (err) |
4331 | goto out; | 4548 | goto out; |
4332 | if (!ssb_device_is_enabled(dev->sdev)) { | 4549 | if (!b43_device_is_enabled(dev)) |
4333 | tmp = phy->gmode ? B43_TMSLOW_GMODE : 0; | 4550 | b43_wireless_core_reset(dev, phy->gmode); |
4334 | b43_wireless_core_reset(dev, tmp); | ||
4335 | } | ||
4336 | 4551 | ||
4337 | /* Reset all data structures. */ | 4552 | /* Reset all data structures. */ |
4338 | setup_struct_wldev_for_init(dev); | 4553 | setup_struct_wldev_for_init(dev); |
4339 | phy->ops->prepare_structs(dev); | 4554 | phy->ops->prepare_structs(dev); |
4340 | 4555 | ||
4341 | /* Enable IRQ routing to this device. */ | 4556 | /* Enable IRQ routing to this device. */ |
4342 | ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->sdev); | 4557 | switch (dev->dev->bus_type) { |
4558 | #ifdef CONFIG_B43_BCMA | ||
4559 | case B43_BUS_BCMA: | ||
4560 | bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci, | ||
4561 | dev->dev->bdev, true); | ||
4562 | break; | ||
4563 | #endif | ||
4564 | #ifdef CONFIG_B43_SSB | ||
4565 | case B43_BUS_SSB: | ||
4566 | ssb_pcicore_dev_irqvecs_enable(&dev->dev->sdev->bus->pcicore, | ||
4567 | dev->dev->sdev); | ||
4568 | break; | ||
4569 | #endif | ||
4570 | } | ||
4343 | 4571 | ||
4344 | b43_imcfglo_timeouts_workaround(dev); | 4572 | b43_imcfglo_timeouts_workaround(dev); |
4345 | b43_bluetooth_coext_disable(dev); | 4573 | b43_bluetooth_coext_disable(dev); |
@@ -4352,7 +4580,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | |||
4352 | if (err) | 4580 | if (err) |
4353 | goto err_busdown; | 4581 | goto err_busdown; |
4354 | b43_shm_write16(dev, B43_SHM_SHARED, | 4582 | b43_shm_write16(dev, B43_SHM_SHARED, |
4355 | B43_SHM_SH_WLCOREREV, dev->sdev->id.revision); | 4583 | B43_SHM_SH_WLCOREREV, dev->dev->core_rev); |
4356 | hf = b43_hf_read(dev); | 4584 | hf = b43_hf_read(dev); |
4357 | if (phy->type == B43_PHYTYPE_G) { | 4585 | if (phy->type == B43_PHYTYPE_G) { |
4358 | hf |= B43_HF_SYMW; | 4586 | hf |= B43_HF_SYMW; |
@@ -4370,8 +4598,9 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | |||
4370 | if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW) | 4598 | if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW) |
4371 | hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */ | 4599 | hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */ |
4372 | #ifdef CONFIG_SSB_DRIVER_PCICORE | 4600 | #ifdef CONFIG_SSB_DRIVER_PCICORE |
4373 | if ((bus->bustype == SSB_BUSTYPE_PCI) && | 4601 | if (dev->dev->bus_type == B43_BUS_SSB && |
4374 | (bus->pcicore.dev->id.revision <= 10)) | 4602 | dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI && |
4603 | dev->dev->sdev->bus->pcicore.dev->id.revision <= 10) | ||
4375 | hf |= B43_HF_PCISCW; /* PCI slow clock workaround. */ | 4604 | hf |= B43_HF_PCISCW; /* PCI slow clock workaround. */ |
4376 | #endif | 4605 | #endif |
4377 | hf &= ~B43_HF_SKCFPUP; | 4606 | hf &= ~B43_HF_SKCFPUP; |
@@ -4399,8 +4628,8 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | |||
4399 | /* Maximum Contention Window */ | 4628 | /* Maximum Contention Window */ |
4400 | b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); | 4629 | b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); |
4401 | 4630 | ||
4402 | if ((dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA) || | 4631 | if (b43_bus_host_is_pcmcia(dev->dev) || |
4403 | (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) || | 4632 | b43_bus_host_is_sdio(dev->dev) || |
4404 | dev->use_pio) { | 4633 | dev->use_pio) { |
4405 | dev->__using_pio_transfers = 1; | 4634 | dev->__using_pio_transfers = 1; |
4406 | err = b43_pio_init(dev); | 4635 | err = b43_pio_init(dev); |
@@ -4414,7 +4643,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | |||
4414 | b43_set_synth_pu_delay(dev, 1); | 4643 | b43_set_synth_pu_delay(dev, 1); |
4415 | b43_bluetooth_coext_enable(dev); | 4644 | b43_bluetooth_coext_enable(dev); |
4416 | 4645 | ||
4417 | ssb_bus_powerup(bus, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)); | 4646 | b43_bus_powerup(dev, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)); |
4418 | b43_upload_card_macaddress(dev); | 4647 | b43_upload_card_macaddress(dev); |
4419 | b43_security_init(dev); | 4648 | b43_security_init(dev); |
4420 | 4649 | ||
@@ -4431,7 +4660,7 @@ out: | |||
4431 | err_chip_exit: | 4660 | err_chip_exit: |
4432 | b43_chip_exit(dev); | 4661 | b43_chip_exit(dev); |
4433 | err_busdown: | 4662 | err_busdown: |
4434 | ssb_bus_may_powerdown(bus); | 4663 | b43_bus_may_powerdown(dev); |
4435 | B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT); | 4664 | B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT); |
4436 | return err; | 4665 | return err; |
4437 | } | 4666 | } |
@@ -4737,11 +4966,10 @@ static void b43_wireless_core_detach(struct b43_wldev *dev) | |||
4737 | static int b43_wireless_core_attach(struct b43_wldev *dev) | 4966 | static int b43_wireless_core_attach(struct b43_wldev *dev) |
4738 | { | 4967 | { |
4739 | struct b43_wl *wl = dev->wl; | 4968 | struct b43_wl *wl = dev->wl; |
4740 | struct ssb_bus *bus = dev->sdev->bus; | 4969 | struct pci_dev *pdev = NULL; |
4741 | struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL; | ||
4742 | int err; | 4970 | int err; |
4743 | bool have_2ghz_phy = 0, have_5ghz_phy = 0; | ||
4744 | u32 tmp; | 4971 | u32 tmp; |
4972 | bool have_2ghz_phy = 0, have_5ghz_phy = 0; | ||
4745 | 4973 | ||
4746 | /* Do NOT do any device initialization here. | 4974 | /* Do NOT do any device initialization here. |
4747 | * Do it in wireless_core_init() instead. | 4975 | * Do it in wireless_core_init() instead. |
@@ -4750,25 +4978,42 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
4750 | * that in core_init(), too. | 4978 | * that in core_init(), too. |
4751 | */ | 4979 | */ |
4752 | 4980 | ||
4753 | err = ssb_bus_powerup(bus, 0); | 4981 | #ifdef CONFIG_B43_SSB |
4982 | if (dev->dev->bus_type == B43_BUS_SSB && | ||
4983 | dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI) | ||
4984 | pdev = dev->dev->sdev->bus->host_pci; | ||
4985 | #endif | ||
4986 | |||
4987 | err = b43_bus_powerup(dev, 0); | ||
4754 | if (err) { | 4988 | if (err) { |
4755 | b43err(wl, "Bus powerup failed\n"); | 4989 | b43err(wl, "Bus powerup failed\n"); |
4756 | goto out; | 4990 | goto out; |
4757 | } | 4991 | } |
4758 | /* Get the PHY type. */ | ||
4759 | if (dev->sdev->id.revision >= 5) { | ||
4760 | u32 tmshigh; | ||
4761 | 4992 | ||
4762 | tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); | 4993 | /* Get the PHY type. */ |
4763 | have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY); | 4994 | switch (dev->dev->bus_type) { |
4764 | have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY); | 4995 | #ifdef CONFIG_B43_BCMA |
4765 | } else | 4996 | case B43_BUS_BCMA: |
4766 | B43_WARN_ON(1); | 4997 | tmp = bcma_aread32(dev->dev->bdev, BCMA_IOST); |
4998 | have_2ghz_phy = !!(tmp & B43_BCMA_IOST_2G_PHY); | ||
4999 | have_5ghz_phy = !!(tmp & B43_BCMA_IOST_5G_PHY); | ||
5000 | break; | ||
5001 | #endif | ||
5002 | #ifdef CONFIG_B43_SSB | ||
5003 | case B43_BUS_SSB: | ||
5004 | if (dev->dev->core_rev >= 5) { | ||
5005 | tmp = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); | ||
5006 | have_2ghz_phy = !!(tmp & B43_TMSHIGH_HAVE_2GHZ_PHY); | ||
5007 | have_5ghz_phy = !!(tmp & B43_TMSHIGH_HAVE_5GHZ_PHY); | ||
5008 | } else | ||
5009 | B43_WARN_ON(1); | ||
5010 | break; | ||
5011 | #endif | ||
5012 | } | ||
4767 | 5013 | ||
4768 | dev->phy.gmode = have_2ghz_phy; | 5014 | dev->phy.gmode = have_2ghz_phy; |
4769 | dev->phy.radio_on = 1; | 5015 | dev->phy.radio_on = 1; |
4770 | tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; | 5016 | b43_wireless_core_reset(dev, dev->phy.gmode); |
4771 | b43_wireless_core_reset(dev, tmp); | ||
4772 | 5017 | ||
4773 | err = b43_phy_versioning(dev); | 5018 | err = b43_phy_versioning(dev); |
4774 | if (err) | 5019 | if (err) |
@@ -4790,6 +5035,8 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
4790 | #endif | 5035 | #endif |
4791 | case B43_PHYTYPE_G: | 5036 | case B43_PHYTYPE_G: |
4792 | case B43_PHYTYPE_N: | 5037 | case B43_PHYTYPE_N: |
5038 | case B43_PHYTYPE_HT: | ||
5039 | case B43_PHYTYPE_LCN: | ||
4793 | have_2ghz_phy = 1; | 5040 | have_2ghz_phy = 1; |
4794 | break; | 5041 | break; |
4795 | default: | 5042 | default: |
@@ -4816,8 +5063,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
4816 | goto err_powerdown; | 5063 | goto err_powerdown; |
4817 | 5064 | ||
4818 | dev->phy.gmode = have_2ghz_phy; | 5065 | dev->phy.gmode = have_2ghz_phy; |
4819 | tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; | 5066 | b43_wireless_core_reset(dev, dev->phy.gmode); |
4820 | b43_wireless_core_reset(dev, tmp); | ||
4821 | 5067 | ||
4822 | err = b43_validate_chipaccess(dev); | 5068 | err = b43_validate_chipaccess(dev); |
4823 | if (err) | 5069 | if (err) |
@@ -4832,8 +5078,8 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
4832 | INIT_WORK(&dev->restart_work, b43_chip_reset); | 5078 | INIT_WORK(&dev->restart_work, b43_chip_reset); |
4833 | 5079 | ||
4834 | dev->phy.ops->switch_analog(dev, 0); | 5080 | dev->phy.ops->switch_analog(dev, 0); |
4835 | ssb_device_disable(dev->sdev, 0); | 5081 | b43_device_disable(dev, 0); |
4836 | ssb_bus_may_powerdown(bus); | 5082 | b43_bus_may_powerdown(dev); |
4837 | 5083 | ||
4838 | out: | 5084 | out: |
4839 | return err; | 5085 | return err; |
@@ -4841,11 +5087,11 @@ out: | |||
4841 | err_phy_free: | 5087 | err_phy_free: |
4842 | b43_phy_free(dev); | 5088 | b43_phy_free(dev); |
4843 | err_powerdown: | 5089 | err_powerdown: |
4844 | ssb_bus_may_powerdown(bus); | 5090 | b43_bus_may_powerdown(dev); |
4845 | return err; | 5091 | return err; |
4846 | } | 5092 | } |
4847 | 5093 | ||
4848 | static void b43_one_core_detach(struct ssb_device *dev) | 5094 | static void b43_one_core_detach(struct b43_bus_dev *dev) |
4849 | { | 5095 | { |
4850 | struct b43_wldev *wldev; | 5096 | struct b43_wldev *wldev; |
4851 | struct b43_wl *wl; | 5097 | struct b43_wl *wl; |
@@ -4853,17 +5099,17 @@ static void b43_one_core_detach(struct ssb_device *dev) | |||
4853 | /* Do not cancel ieee80211-workqueue based work here. | 5099 | /* Do not cancel ieee80211-workqueue based work here. |
4854 | * See comment in b43_remove(). */ | 5100 | * See comment in b43_remove(). */ |
4855 | 5101 | ||
4856 | wldev = ssb_get_drvdata(dev); | 5102 | wldev = b43_bus_get_wldev(dev); |
4857 | wl = wldev->wl; | 5103 | wl = wldev->wl; |
4858 | b43_debugfs_remove_device(wldev); | 5104 | b43_debugfs_remove_device(wldev); |
4859 | b43_wireless_core_detach(wldev); | 5105 | b43_wireless_core_detach(wldev); |
4860 | list_del(&wldev->list); | 5106 | list_del(&wldev->list); |
4861 | wl->nr_devs--; | 5107 | wl->nr_devs--; |
4862 | ssb_set_drvdata(dev, NULL); | 5108 | b43_bus_set_wldev(dev, NULL); |
4863 | kfree(wldev); | 5109 | kfree(wldev); |
4864 | } | 5110 | } |
4865 | 5111 | ||
4866 | static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) | 5112 | static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl) |
4867 | { | 5113 | { |
4868 | struct b43_wldev *wldev; | 5114 | struct b43_wldev *wldev; |
4869 | int err = -ENOMEM; | 5115 | int err = -ENOMEM; |
@@ -4873,7 +5119,7 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) | |||
4873 | goto out; | 5119 | goto out; |
4874 | 5120 | ||
4875 | wldev->use_pio = b43_modparam_pio; | 5121 | wldev->use_pio = b43_modparam_pio; |
4876 | wldev->sdev = dev; | 5122 | wldev->dev = dev; |
4877 | wldev->wl = wl; | 5123 | wldev->wl = wl; |
4878 | b43_set_status(wldev, B43_STAT_UNINIT); | 5124 | b43_set_status(wldev, B43_STAT_UNINIT); |
4879 | wldev->bad_frames_preempt = modparam_bad_frames_preempt; | 5125 | wldev->bad_frames_preempt = modparam_bad_frames_preempt; |
@@ -4885,7 +5131,7 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) | |||
4885 | 5131 | ||
4886 | list_add(&wldev->list, &wl->devlist); | 5132 | list_add(&wldev->list, &wl->devlist); |
4887 | wl->nr_devs++; | 5133 | wl->nr_devs++; |
4888 | ssb_set_drvdata(dev, wldev); | 5134 | b43_bus_set_wldev(dev, wldev); |
4889 | b43_debugfs_add_device(wldev); | 5135 | b43_debugfs_add_device(wldev); |
4890 | 5136 | ||
4891 | out: | 5137 | out: |
@@ -4926,19 +5172,20 @@ static void b43_sprom_fixup(struct ssb_bus *bus) | |||
4926 | } | 5172 | } |
4927 | } | 5173 | } |
4928 | 5174 | ||
4929 | static void b43_wireless_exit(struct ssb_device *dev, struct b43_wl *wl) | 5175 | static void b43_wireless_exit(struct b43_bus_dev *dev, struct b43_wl *wl) |
4930 | { | 5176 | { |
4931 | struct ieee80211_hw *hw = wl->hw; | 5177 | struct ieee80211_hw *hw = wl->hw; |
4932 | 5178 | ||
4933 | ssb_set_devtypedata(dev, NULL); | 5179 | ssb_set_devtypedata(dev->sdev, NULL); |
4934 | ieee80211_free_hw(hw); | 5180 | ieee80211_free_hw(hw); |
4935 | } | 5181 | } |
4936 | 5182 | ||
4937 | static struct b43_wl *b43_wireless_init(struct ssb_device *dev) | 5183 | static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev) |
4938 | { | 5184 | { |
4939 | struct ssb_sprom *sprom = &dev->bus->sprom; | 5185 | struct ssb_sprom *sprom = dev->bus_sprom; |
4940 | struct ieee80211_hw *hw; | 5186 | struct ieee80211_hw *hw; |
4941 | struct b43_wl *wl; | 5187 | struct b43_wl *wl; |
5188 | char chip_name[6]; | ||
4942 | 5189 | ||
4943 | hw = ieee80211_alloc_hw(sizeof(*wl), &b43_hw_ops); | 5190 | hw = ieee80211_alloc_hw(sizeof(*wl), &b43_hw_ops); |
4944 | if (!hw) { | 5191 | if (!hw) { |
@@ -4977,29 +5224,105 @@ static struct b43_wl *b43_wireless_init(struct ssb_device *dev) | |||
4977 | INIT_WORK(&wl->tx_work, b43_tx_work); | 5224 | INIT_WORK(&wl->tx_work, b43_tx_work); |
4978 | skb_queue_head_init(&wl->tx_queue); | 5225 | skb_queue_head_init(&wl->tx_queue); |
4979 | 5226 | ||
4980 | b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n", | 5227 | snprintf(chip_name, ARRAY_SIZE(chip_name), |
4981 | dev->bus->chip_id, dev->id.revision); | 5228 | (dev->chip_id > 0x9999) ? "%d" : "%04X", dev->chip_id); |
5229 | b43info(wl, "Broadcom %s WLAN found (core revision %u)\n", chip_name, | ||
5230 | dev->core_rev); | ||
4982 | return wl; | 5231 | return wl; |
4983 | } | 5232 | } |
4984 | 5233 | ||
4985 | static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id) | 5234 | #ifdef CONFIG_B43_BCMA |
5235 | static int b43_bcma_probe(struct bcma_device *core) | ||
4986 | { | 5236 | { |
5237 | struct b43_bus_dev *dev; | ||
5238 | struct b43_wl *wl; | ||
5239 | int err; | ||
5240 | |||
5241 | dev = b43_bus_dev_bcma_init(core); | ||
5242 | if (!dev) | ||
5243 | return -ENODEV; | ||
5244 | |||
5245 | wl = b43_wireless_init(dev); | ||
5246 | if (IS_ERR(wl)) { | ||
5247 | err = PTR_ERR(wl); | ||
5248 | goto bcma_out; | ||
5249 | } | ||
5250 | |||
5251 | err = b43_one_core_attach(dev, wl); | ||
5252 | if (err) | ||
5253 | goto bcma_err_wireless_exit; | ||
5254 | |||
5255 | err = ieee80211_register_hw(wl->hw); | ||
5256 | if (err) | ||
5257 | goto bcma_err_one_core_detach; | ||
5258 | b43_leds_register(wl->current_dev); | ||
5259 | |||
5260 | bcma_out: | ||
5261 | return err; | ||
5262 | |||
5263 | bcma_err_one_core_detach: | ||
5264 | b43_one_core_detach(dev); | ||
5265 | bcma_err_wireless_exit: | ||
5266 | ieee80211_free_hw(wl->hw); | ||
5267 | return err; | ||
5268 | } | ||
5269 | |||
5270 | static void b43_bcma_remove(struct bcma_device *core) | ||
5271 | { | ||
5272 | struct b43_wldev *wldev = bcma_get_drvdata(core); | ||
5273 | struct b43_wl *wl = wldev->wl; | ||
5274 | |||
5275 | /* We must cancel any work here before unregistering from ieee80211, | ||
5276 | * as the ieee80211 unreg will destroy the workqueue. */ | ||
5277 | cancel_work_sync(&wldev->restart_work); | ||
5278 | |||
5279 | /* Restore the queues count before unregistering, because firmware detect | ||
5280 | * might have modified it. Restoring is important, so the networking | ||
5281 | * stack can properly free resources. */ | ||
5282 | wl->hw->queues = wl->mac80211_initially_registered_queues; | ||
5283 | b43_leds_stop(wldev); | ||
5284 | ieee80211_unregister_hw(wl->hw); | ||
5285 | |||
5286 | b43_one_core_detach(wldev->dev); | ||
5287 | |||
5288 | b43_leds_unregister(wl); | ||
5289 | |||
5290 | ieee80211_free_hw(wl->hw); | ||
5291 | } | ||
5292 | |||
5293 | static struct bcma_driver b43_bcma_driver = { | ||
5294 | .name = KBUILD_MODNAME, | ||
5295 | .id_table = b43_bcma_tbl, | ||
5296 | .probe = b43_bcma_probe, | ||
5297 | .remove = b43_bcma_remove, | ||
5298 | }; | ||
5299 | #endif | ||
5300 | |||
5301 | #ifdef CONFIG_B43_SSB | ||
5302 | static | ||
5303 | int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) | ||
5304 | { | ||
5305 | struct b43_bus_dev *dev; | ||
4987 | struct b43_wl *wl; | 5306 | struct b43_wl *wl; |
4988 | int err; | 5307 | int err; |
4989 | int first = 0; | 5308 | int first = 0; |
4990 | 5309 | ||
4991 | wl = ssb_get_devtypedata(dev); | 5310 | dev = b43_bus_dev_ssb_init(sdev); |
5311 | if (!dev) | ||
5312 | return -ENOMEM; | ||
5313 | |||
5314 | wl = ssb_get_devtypedata(sdev); | ||
4992 | if (!wl) { | 5315 | if (!wl) { |
4993 | /* Probing the first core. Must setup common struct b43_wl */ | 5316 | /* Probing the first core. Must setup common struct b43_wl */ |
4994 | first = 1; | 5317 | first = 1; |
4995 | b43_sprom_fixup(dev->bus); | 5318 | b43_sprom_fixup(sdev->bus); |
4996 | wl = b43_wireless_init(dev); | 5319 | wl = b43_wireless_init(dev); |
4997 | if (IS_ERR(wl)) { | 5320 | if (IS_ERR(wl)) { |
4998 | err = PTR_ERR(wl); | 5321 | err = PTR_ERR(wl); |
4999 | goto out; | 5322 | goto out; |
5000 | } | 5323 | } |
5001 | ssb_set_devtypedata(dev, wl); | 5324 | ssb_set_devtypedata(sdev, wl); |
5002 | B43_WARN_ON(ssb_get_devtypedata(dev) != wl); | 5325 | B43_WARN_ON(ssb_get_devtypedata(sdev) != wl); |
5003 | } | 5326 | } |
5004 | err = b43_one_core_attach(dev, wl); | 5327 | err = b43_one_core_attach(dev, wl); |
5005 | if (err) | 5328 | if (err) |
@@ -5023,10 +5346,10 @@ static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id) | |||
5023 | return err; | 5346 | return err; |
5024 | } | 5347 | } |
5025 | 5348 | ||
5026 | static void b43_ssb_remove(struct ssb_device *dev) | 5349 | static void b43_ssb_remove(struct ssb_device *sdev) |
5027 | { | 5350 | { |
5028 | struct b43_wl *wl = ssb_get_devtypedata(dev); | 5351 | struct b43_wl *wl = ssb_get_devtypedata(sdev); |
5029 | struct b43_wldev *wldev = ssb_get_drvdata(dev); | 5352 | struct b43_wldev *wldev = ssb_get_drvdata(sdev); |
5030 | 5353 | ||
5031 | /* We must cancel any work here before unregistering from ieee80211, | 5354 | /* We must cancel any work here before unregistering from ieee80211, |
5032 | * as the ieee80211 unreg will destroy the workqueue. */ | 5355 | * as the ieee80211 unreg will destroy the workqueue. */ |
@@ -5042,17 +5365,25 @@ static void b43_ssb_remove(struct ssb_device *dev) | |||
5042 | ieee80211_unregister_hw(wl->hw); | 5365 | ieee80211_unregister_hw(wl->hw); |
5043 | } | 5366 | } |
5044 | 5367 | ||
5045 | b43_one_core_detach(dev); | 5368 | b43_one_core_detach(wldev->dev); |
5046 | 5369 | ||
5047 | if (list_empty(&wl->devlist)) { | 5370 | if (list_empty(&wl->devlist)) { |
5048 | b43_leds_unregister(wl); | 5371 | b43_leds_unregister(wl); |
5049 | /* Last core on the chip unregistered. | 5372 | /* Last core on the chip unregistered. |
5050 | * We can destroy common struct b43_wl. | 5373 | * We can destroy common struct b43_wl. |
5051 | */ | 5374 | */ |
5052 | b43_wireless_exit(dev, wl); | 5375 | b43_wireless_exit(wldev->dev, wl); |
5053 | } | 5376 | } |
5054 | } | 5377 | } |
5055 | 5378 | ||
5379 | static struct ssb_driver b43_ssb_driver = { | ||
5380 | .name = KBUILD_MODNAME, | ||
5381 | .id_table = b43_ssb_tbl, | ||
5382 | .probe = b43_ssb_probe, | ||
5383 | .remove = b43_ssb_remove, | ||
5384 | }; | ||
5385 | #endif /* CONFIG_B43_SSB */ | ||
5386 | |||
5056 | /* Perform a hardware reset. This can be called from any context. */ | 5387 | /* Perform a hardware reset. This can be called from any context. */ |
5057 | void b43_controller_restart(struct b43_wldev *dev, const char *reason) | 5388 | void b43_controller_restart(struct b43_wldev *dev, const char *reason) |
5058 | { | 5389 | { |
@@ -5063,13 +5394,6 @@ void b43_controller_restart(struct b43_wldev *dev, const char *reason) | |||
5063 | ieee80211_queue_work(dev->wl->hw, &dev->restart_work); | 5394 | ieee80211_queue_work(dev->wl->hw, &dev->restart_work); |
5064 | } | 5395 | } |
5065 | 5396 | ||
5066 | static struct ssb_driver b43_ssb_driver = { | ||
5067 | .name = KBUILD_MODNAME, | ||
5068 | .id_table = b43_ssb_tbl, | ||
5069 | .probe = b43_ssb_probe, | ||
5070 | .remove = b43_ssb_remove, | ||
5071 | }; | ||
5072 | |||
5073 | static void b43_print_driverinfo(void) | 5397 | static void b43_print_driverinfo(void) |
5074 | { | 5398 | { |
5075 | const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", | 5399 | const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "", |
@@ -5108,14 +5432,27 @@ static int __init b43_init(void) | |||
5108 | err = b43_sdio_init(); | 5432 | err = b43_sdio_init(); |
5109 | if (err) | 5433 | if (err) |
5110 | goto err_pcmcia_exit; | 5434 | goto err_pcmcia_exit; |
5111 | err = ssb_driver_register(&b43_ssb_driver); | 5435 | #ifdef CONFIG_B43_BCMA |
5436 | err = bcma_driver_register(&b43_bcma_driver); | ||
5112 | if (err) | 5437 | if (err) |
5113 | goto err_sdio_exit; | 5438 | goto err_sdio_exit; |
5439 | #endif | ||
5440 | #ifdef CONFIG_B43_SSB | ||
5441 | err = ssb_driver_register(&b43_ssb_driver); | ||
5442 | if (err) | ||
5443 | goto err_bcma_driver_exit; | ||
5444 | #endif | ||
5114 | b43_print_driverinfo(); | 5445 | b43_print_driverinfo(); |
5115 | 5446 | ||
5116 | return err; | 5447 | return err; |
5117 | 5448 | ||
5449 | #ifdef CONFIG_B43_SSB | ||
5450 | err_bcma_driver_exit: | ||
5451 | #endif | ||
5452 | #ifdef CONFIG_B43_BCMA | ||
5453 | bcma_driver_unregister(&b43_bcma_driver); | ||
5118 | err_sdio_exit: | 5454 | err_sdio_exit: |
5455 | #endif | ||
5119 | b43_sdio_exit(); | 5456 | b43_sdio_exit(); |
5120 | err_pcmcia_exit: | 5457 | err_pcmcia_exit: |
5121 | b43_pcmcia_exit(); | 5458 | b43_pcmcia_exit(); |
@@ -5126,7 +5463,12 @@ err_dfs_exit: | |||
5126 | 5463 | ||
5127 | static void __exit b43_exit(void) | 5464 | static void __exit b43_exit(void) |
5128 | { | 5465 | { |
5466 | #ifdef CONFIG_B43_SSB | ||
5129 | ssb_driver_unregister(&b43_ssb_driver); | 5467 | ssb_driver_unregister(&b43_ssb_driver); |
5468 | #endif | ||
5469 | #ifdef CONFIG_B43_BCMA | ||
5470 | bcma_driver_unregister(&b43_bcma_driver); | ||
5471 | #endif | ||
5130 | b43_sdio_exit(); | 5472 | b43_sdio_exit(); |
5131 | b43_pcmcia_exit(); | 5473 | b43_pcmcia_exit(); |
5132 | b43_debugfs_exit(); | 5474 | b43_debugfs_exit(); |