34 #include <linux/module.h>
35 #include <linux/if_arp.h>
39 #include <linux/sched.h>
42 #include <linux/slab.h>
44 #include <asm/unaligned.h>
66 #if defined(CONFIG_B43LEGACY_DMA) && defined(CONFIG_B43LEGACY_PIO)
67 static int modparam_pio;
70 #elif defined(CONFIG_B43LEGACY_DMA)
71 # define modparam_pio 0
72 #elif defined(CONFIG_B43LEGACY_PIO)
73 # define modparam_pio 1
76 static int modparam_bad_frames_preempt;
81 static char modparam_fwpostfix[16];
98 #define RATETAB_ENT(_rateid, _flags) \
100 .bitrate = B43legacy_RATE_TO_100KBPS(_rateid), \
101 .hw_value = (_rateid), \
122 #define b43legacy_b_ratetable (__b43legacy_ratetable + 0)
123 #define b43legacy_b_ratetable_size 4
124 #define b43legacy_g_ratetable (__b43legacy_ratetable + 0)
125 #define b43legacy_g_ratetable_size 12
127 #define CHANTAB_ENT(_chanid, _freq) \
129 .center_freq = (_freq), \
130 .hw_value = (_chanid), \
150 .channels = b43legacy_bg_chantable,
151 .n_channels =
ARRAY_SIZE(b43legacy_bg_chantable),
157 .channels = b43legacy_bg_chantable,
158 .n_channels =
ARRAY_SIZE(b43legacy_bg_chantable),
185 if (!b43legacy_ratelimit(wl))
194 (wl && wl->
hw) ? wiphy_name(wl->
hw->wiphy) :
"wlan", &vaf);
204 if (!b43legacy_ratelimit(wl))
213 (wl && wl->
hw) ? wiphy_name(wl->
hw->wiphy) :
"wlan", &vaf);
223 if (!b43legacy_ratelimit(wl))
232 (wl && wl->
hw) ? wiphy_name(wl->
hw->wiphy) :
"wlan", &vaf);
249 (wl && wl->
hw) ? wiphy_name(wl->
hw->wiphy) :
"wlan", &vaf);
292 if (offset & 0x0003) {
294 b43legacy_shm_control_word(dev, routing, offset >> 2);
295 ret = b43legacy_read16(dev,
298 b43legacy_shm_control_word(dev, routing,
306 b43legacy_shm_control_word(dev, routing, offset);
319 if (offset & 0x0003) {
321 b43legacy_shm_control_word(dev, routing, offset >> 2);
322 ret = b43legacy_read16(dev,
329 b43legacy_shm_control_word(dev, routing, offset);
341 if (offset & 0x0003) {
343 b43legacy_shm_control_word(dev, routing, offset >> 2);
345 b43legacy_write16(dev,
347 (value >> 16) & 0xffff);
349 b43legacy_shm_control_word(dev, routing,
358 b43legacy_shm_control_word(dev, routing, offset);
368 if (offset & 0x0003) {
370 b43legacy_shm_control_word(dev, routing, offset >> 2);
372 b43legacy_write16(dev,
379 b43legacy_shm_control_word(dev, routing, offset);
403 (value & 0x0000FFFF));
406 ((value & 0xFFFF0000) >> 16));
417 if (dev->
dev->id.revision >= 3) {
423 high = b43legacy_read32(dev,
425 low = b43legacy_read32(dev,
427 high2 = b43legacy_read32(dev,
453 }
while (v3 != test3 || v2 != test2 || v1 != test1);
492 if (dev->
dev->id.revision >= 3) {
493 u32 lo = (tsf & 0x00000000FFFFFFFFULL);
494 u32 hi = (tsf & 0xFFFFFFFF00000000ULL) >> 32;
504 u16 v0 = (tsf & 0x000000000000FFFFULL);
505 u16 v1 = (tsf & 0x00000000FFFF0000ULL) >> 16;
506 u16 v2 = (tsf & 0x0000FFFF00000000ULL) >> 32;
507 u16 v3 = (tsf & 0xFFFF000000000000ULL) >> 48;
523 b43legacy_time_lock(dev);
524 b43legacy_tsf_write_locked(dev, tsf);
525 b43legacy_time_unlock(dev);
552 static void b43legacy_write_mac_bssid_templates(
struct b43legacy_wldev *dev)
555 const u8 *mac = dev->
wl->mac_addr;
573 tmp = (
u32)(mac_bssid[i + 0]);
574 tmp |= (
u32)(mac_bssid[i + 1]) << 8;
575 tmp |= (
u32)(mac_bssid[i + 2]) << 16;
576 tmp |= (
u32)(mac_bssid[i + 3]) << 24;
577 b43legacy_ram_write(dev, 0x20 + i, tmp);
578 b43legacy_ram_write(dev, 0x78 + i, tmp);
579 b43legacy_ram_write(dev, 0x478 + i, tmp);
583 static void b43legacy_upload_card_macaddress(
struct b43legacy_wldev *dev)
585 b43legacy_write_mac_bssid_templates(dev);
596 b43legacy_write16(dev, 0x684, 510 + slot_time);
601 static void b43legacy_short_slot_timing_enable(
struct b43legacy_wldev *dev)
603 b43legacy_set_slot_time(dev, 9);
606 static void b43legacy_short_slot_timing_disable(
struct b43legacy_wldev *dev)
608 b43legacy_set_slot_time(dev, 20);
628 unsigned int max_loop;
642 buffer[0] = 0x000B846E;
649 for (i = 0; i < 5; i++)
650 b43legacy_ram_write(dev, i * 4, buffer[i]);
655 b43legacy_write16(dev, 0x0568, 0x0000);
656 b43legacy_write16(dev, 0x07C0, 0x0000);
657 b43legacy_write16(dev, 0x050C, 0x0000);
658 b43legacy_write16(dev, 0x0508, 0x0000);
659 b43legacy_write16(dev, 0x050A, 0x0000);
660 b43legacy_write16(dev, 0x054C, 0x0000);
661 b43legacy_write16(dev, 0x056A, 0x0014);
662 b43legacy_write16(dev, 0x0568, 0x0826);
663 b43legacy_write16(dev, 0x0500, 0x0000);
664 b43legacy_write16(dev, 0x0502, 0x0030);
668 for (i = 0x00; i < max_loop; i++) {
669 value = b43legacy_read16(dev, 0x050E);
674 for (i = 0x00; i < 0x0A; i++) {
675 value = b43legacy_read16(dev, 0x050E);
680 for (i = 0x00; i < 0x0A; i++) {
681 value = b43legacy_read16(dev, 0x0690);
682 if (!(value & 0x0100))
691 static void b43legacy_switch_analog(
struct b43legacy_wldev *dev,
int on)
719 b43legacy_switch_analog(dev, 1);
725 dev->
phy.gmode =
true;
727 dev->
phy.gmode =
false;
741 if (!(v0 & 0x00000001))
745 stat.cookie = (v0 >> 16);
746 stat.seq = (v1 & 0x0000FFFF);
747 stat.phy_stat = ((v1 & 0x00FF0000) >> 16);
748 tmp = (v0 & 0x0000FFFF);
749 stat.frame_count = ((tmp & 0xF000) >> 12);
750 stat.rts_count = ((tmp & 0x0F00) >> 8);
751 stat.supp_reason = ((tmp & 0x001C) >> 2);
752 stat.pm_indicated = !!(tmp & 0x0080);
753 stat.intermediate = !!(tmp & 0x0040);
754 stat.for_ampdu = !!(tmp & 0x0020);
755 stat.acked = !!(tmp & 0x0002);
765 if (dev->
dev->id.revision < 5)
772 if (!(dummy & 0x00000001))
792 (jssi & 0x0000FFFF));
794 (jssi & 0xFFFF0000) >> 16);
797 static void b43legacy_generate_noise_sample(
struct b43legacy_wldev *dev)
799 b43legacy_jssi_write(dev, 0x7F7F7F7F);
807 static void b43legacy_calculate_link_quality(
struct b43legacy_wldev *dev)
814 dev->
noisecalc.calculation_running =
true;
817 b43legacy_generate_noise_sample(dev);
833 goto drop_calculation;
835 if (noise[0] == 0x7F || noise[1] == 0x7F ||
836 noise[2] == 0x7F || noise[3] == 0x7F)
854 for (i = 0; i < 8; i++) {
855 for (j = 0; j < 4; j++)
864 tmp = (tmp / 128) & 0x1F;
876 dev->
noisecalc.calculation_running =
false;
880 b43legacy_generate_noise_sample(dev);
913 if (!(tmp & 0x00000008))
920 static void b43legacy_write_template_common(
struct b43legacy_wldev *dev,
927 struct b43legacy_plcp_hdr4 plcp;
931 b43legacy_ram_write(dev, ram_offset,
le32_to_cpu(plcp.data));
932 ram_offset +=
sizeof(
u32);
936 tmp = (
u32)(data[0]) << 16;
937 tmp |= (
u32)(data[1]) << 24;
938 b43legacy_ram_write(dev, ram_offset, tmp);
939 ram_offset +=
sizeof(
u32);
940 for (i = 2; i <
size; i +=
sizeof(
u32)) {
941 tmp = (
u32)(data[i + 0]);
943 tmp |= (
u32)(data[i + 1]) << 8;
945 tmp |= (
u32)(data[i + 2]) << 16;
947 tmp |= (
u32)(data[i + 3]) << 24;
948 b43legacy_ram_write(dev, ram_offset + i - 2, tmp);
951 size +
sizeof(
struct b43legacy_plcp_hdr6));
955 static u16 b43legacy_antenna_to_phyctl(
int antenna)
966 static void b43legacy_write_beacon_template(
struct b43legacy_wldev *dev,
971 unsigned int i,
len, variable_len;
974 bool tim_found =
false;
981 len =
min((
size_t)dev->
wl->current_beacon->len,
982 0x200 -
sizeof(
struct b43legacy_plcp_hdr6));
983 rate = ieee80211_get_tx_rate(dev->
wl->hw, info)->hw_value;
985 b43legacy_write_template_common(dev, (
const u8 *)bcn, len, ram_offset,
986 shm_size_offset, rate);
990 antenna = b43legacy_antenna_to_phyctl(antenna);
1004 ie = bcn->
u.beacon.variable;
1006 for (i = 0; i < variable_len - 2; ) {
1017 if (variable_len < ie_len + 2 + i)
1024 tim_position =
sizeof(
struct b43legacy_plcp_hdr6);
1029 dtim_period = ie[i + 3];
1041 "beacon template packet. AP or IBSS operation "
1042 "may be broken.\n");
1047 static void b43legacy_write_probe_resp_plcp(
struct b43legacy_wldev *dev,
1048 u16 shm_offset,
u16 size,
1051 struct b43legacy_plcp_hdr4 plcp;
1084 u16 src_size, elem_size, src_pos, dest_pos;
1089 src_size = dev->
wl->current_beacon->len;
1090 src_data = (
const u8 *)dev->
wl->current_beacon->data;
1095 u.beacon.variable));
1105 memcpy(dest_data, src_data, ie_start);
1107 dest_pos = ie_start;
1108 for ( ; src_pos < src_size - 2; src_pos += elem_size) {
1109 elem_size = src_data[src_pos + 1] + 2;
1110 if (src_data[src_pos] == 5) {
1114 memcpy(dest_data + dest_pos, src_data + src_pos, elem_size);
1115 dest_pos += elem_size;
1117 *dest_size = dest_pos;
1133 static void b43legacy_write_probe_resp_template(
struct b43legacy_wldev *dev,
1135 u16 shm_size_offset,
1138 const u8 *probe_resp_data;
1141 size = dev->
wl->current_beacon->len;
1142 probe_resp_data = b43legacy_generate_probe_resp(dev, &size, rate);
1149 b43legacy_write_probe_resp_plcp(dev, 0x31A, size,
1151 b43legacy_write_probe_resp_plcp(dev, 0x32C, size,
1153 b43legacy_write_probe_resp_plcp(dev, 0x33E, size,
1155 b43legacy_write_probe_resp_plcp(dev, 0x350, size,
1158 size =
min((
size_t)size,
1159 0x200 -
sizeof(
struct b43legacy_plcp_hdr6));
1160 b43legacy_write_template_common(dev, probe_resp_data,
1163 kfree(probe_resp_data);
1172 b43legacy_write_beacon_template(dev, 0x68, 0x18);
1175 b43legacy_write_probe_resp_template(dev, 0x268, 0x4A,
1176 &__b43legacy_ratetable[3]);
1186 b43legacy_write_beacon_template(dev, 0x468, 0x1A);
1193 u32 cmd, beacon0_valid, beacon1_valid;
1208 if (beacon0_valid && beacon1_valid) {
1218 b43legacy_upload_beacon0(dev);
1219 b43legacy_upload_beacon1(dev);
1224 if (!beacon0_valid) {
1225 b43legacy_upload_beacon0(dev);
1229 }
else if (!beacon1_valid) {
1230 b43legacy_upload_beacon1(dev);
1238 static void b43legacy_beacon_update_trigger_work(
struct work_struct *
work)
1249 handle_irq_beacon(dev);
1261 static void b43legacy_update_templates(
struct b43legacy_wl *wl)
1273 beacon = ieee80211_beacon_get(wl->
hw, wl->
vif);
1288 b43legacy_time_lock(dev);
1289 if (dev->
dev->id.revision >= 3) {
1291 (beacon_int << 16));
1293 (beacon_int << 10));
1295 b43legacy_write16(dev, 0x606, (beacon_int >> 6));
1296 b43legacy_write16(dev, 0x610, beacon_int);
1298 b43legacy_time_unlock(dev);
1299 b43legacydbg(dev->
wl,
"Set beacon interval to %u\n", beacon_int);
1311 u32 merged_dma_reason = 0;
1313 unsigned long flags;
1321 for (i = 0; i <
ARRAY_SIZE(dma_reason); i++) {
1323 merged_dma_reason |= dma_reason[
i];
1334 "restarting the controller\n");
1343 "0x%08X, 0x%08X, 0x%08X, "
1344 "0x%08X, 0x%08X, 0x%08X\n",
1345 dma_reason[0], dma_reason[1],
1346 dma_reason[2], dma_reason[3],
1347 dma_reason[4], dma_reason[5]);
1350 spin_unlock_irqrestore(&dev->
wl->irq_lock, flags);
1355 "0x%08X, 0x%08X, 0x%08X, "
1356 "0x%08X, 0x%08X, 0x%08X\n",
1357 dma_reason[0], dma_reason[1],
1358 dma_reason[2], dma_reason[3],
1359 dma_reason[4], dma_reason[5]);
1363 handle_irq_ucode_debug(dev);
1365 handle_irq_tbtt_indication(dev);
1367 handle_irq_atim_end(dev);
1369 handle_irq_beacon(dev);
1371 handle_irq_pmq(dev);
1375 handle_irq_noise(dev);
1379 if (b43legacy_using_pio(dev))
1386 if (dma_reason[3] & B43legacy_DMAIRQ_RX_DONE) {
1387 if (b43legacy_using_pio(dev))
1396 handle_irq_transmit_status(dev);
1400 spin_unlock_irqrestore(&dev->
wl->irq_lock, flags);
1404 u16 base,
int queueidx)
1412 dev->
dma_reason[queueidx] &= ~B43legacy_DMAIRQ_RX_DONE;
1417 if (b43legacy_using_pio(dev) &&
1418 (dev->
dev->id.revision < 3) &&
1452 spin_lock(&dev->
wl->irq_lock);
1458 if (reason == 0xffffffff)
1484 b43legacy_interrupt_ack(dev, reason);
1492 spin_unlock(&dev->
wl->irq_lock);
1506 dev->
fw.initvals_band =
NULL;
1509 static void b43legacy_print_fw_helptext(
struct b43legacy_wl *wl)
1511 b43legacyerr(wl,
"You must go to http://wireless.kernel.org/en/users/"
1512 "Drivers/b43#devicefirmware "
1513 "and download the correct firmware (version 3).\n");
1520 char path[
sizeof(modparam_fwpostfix) + 32];
1529 "b43legacy%s/%s.fw",
1530 modparam_fwpostfix, name);
1534 "or load failed.\n",
path);
1540 switch (hdr->
type) {
1562 static int b43legacy_one_core_attach(
struct ssb_device *dev,
1564 static void b43legacy_one_core_detach(
struct ssb_device *dev);
1566 static void b43legacy_request_firmware(
struct work_struct *work)
1572 const u8 rev = dev->
dev->id.revision;
1578 filename =
"ucode2";
1580 filename =
"ucode4";
1582 filename =
"ucode5";
1583 err = do_request_fw(dev, filename, &fw->
ucode);
1592 err = do_request_fw(dev, filename, &fw->
pcm);
1597 switch (dev->
phy.type) {
1600 if ((rev >= 5) && (rev <= 10))
1601 filename =
"b0g0initvals5";
1602 else if (rev == 2 || rev == 4)
1603 filename =
"b0g0initvals2";
1605 goto err_no_initvals;
1608 goto err_no_initvals;
1610 err = do_request_fw(dev, filename, &fw->
initvals);
1615 switch (dev->
phy.type) {
1618 if ((rev >= 5) && (rev <= 10))
1619 filename =
"b0g0bsinitvals5";
1622 else if (rev == 2 || rev == 4)
1625 goto err_no_initvals;
1628 goto err_no_initvals;
1636 goto err_one_core_detach;
1639 err_one_core_detach:
1640 b43legacy_one_core_detach(dev->
dev);
1644 b43legacy_print_fw_helptext(dev->
wl);
1649 b43legacyerr(dev->
wl,
"No Initial Values firmware file for PHY %u, "
1650 "core rev %u\n", dev->
phy.type, rev);
1654 b43legacy_release_firmware(dev);
1678 for (i = 0; i < 64; i++)
1680 for (i = 0; i < 4096; i += 2)
1684 data = (
__be32 *) (dev->
fw.ucode->data + hdr_len);
1686 b43legacy_shm_control_word(dev,
1690 for (i = 0; i < len; i++) {
1698 data = (
__be32 *) (dev->
fw.pcm->data + hdr_len);
1704 for (i = 0; i < len; i++) {
1729 b43legacy_print_fw_helptext(dev->
wl);
1734 if (signal_pending(
current)) {
1752 if (fwrev > 0x128) {
1754 " Only firmware from binary drivers version 3.x"
1755 " is supported. You must change your firmware"
1757 b43legacy_print_fw_helptext(dev->
wl);
1761 b43legacyinfo(dev->
wl,
"Loading firmware version 0x%X, patch level %u "
1762 "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", fwrev, fwpatch,
1763 (fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF,
1764 (fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F,
1767 dev->
fw.rev = fwrev;
1768 dev->
fw.patch = fwpatch;
1771 dev->
fw.rev, dev->
fw.patch);
1797 for (i = 0; i <
count; i++) {
1804 if (offset >= 0x1000)
1809 if (array_size <
sizeof(iv->data.
d32))
1811 array_size -=
sizeof(iv->data.
d32);
1814 b43legacy_write32(dev, offset, value);
1822 if (array_size <
sizeof(iv->data.
d16))
1824 array_size -=
sizeof(iv->data.
d16);
1827 b43legacy_write16(dev, offset, value);
1840 b43legacyerr(dev->
wl,
"Initial Values Firmware file-format error.\n");
1841 b43legacy_print_fw_helptext(dev->
wl);
1858 err = b43legacy_write_initvals(dev, ivals, count,
1868 err = b43legacy_write_initvals(dev, ivals, count,
1889 b43legacy_read32(dev,
1894 b43legacy_read16(dev,
1900 if (dev->
dev->bus->chip_id == 0x4301) {
1906 b43legacy_read16(dev,
1912 if (dev->
dev->id.revision >= 2)
1915 #ifdef CONFIG_SSB_DRIVER_PCICORE
1934 #ifdef CONFIG_SSB_DRIVER_PCICORE
1951 b43legacy_read32(dev,
1962 spin_lock_irq(&dev->
wl->irq_lock);
1965 spin_unlock_irq(&dev->
wl->irq_lock);
1982 spin_lock_irq(&dev->
wl->irq_lock);
1984 spin_unlock_irq(&dev->
wl->irq_lock);
1985 b43legacy_synchronize_irq(dev);
1989 b43legacy_read32(dev,
1993 for (i = 40;
i; i--) {
1994 tmp = b43legacy_read32(dev,
2041 if (dev->
dev->id.revision <= 4)
2049 if (dev->
dev->bus->chip_id == 0x4306 &&
2050 dev->
dev->bus->chip_rev == 3)
2055 b43legacy_write16(dev, 0x612, cfp_pretbtt);
2078 switch (dev->
phy.type) {
2100 static void b43legacy_mgmtframe_txantenna(
struct b43legacy_wldev *dev,
2147 b43legacy_gpio_cleanup(dev);
2159 u32 value32, macctl;
2169 err = b43legacy_upload_microcode(dev);
2173 err = b43legacy_gpio_init(dev);
2177 err = b43legacy_upload_initvals(dev);
2179 goto err_gpio_clean;
2182 b43legacy_write16(dev, 0x03E6, 0x0000);
2196 value16 = b43legacy_read16(dev, 0x005E);
2198 b43legacy_write16(dev, 0x005E, value16);
2200 b43legacy_write32(dev, 0x0100, 0x01000000);
2201 if (dev->
dev->id.revision < 5)
2202 b43legacy_write32(dev, 0x010C, 0x01000000);
2205 value32 &= ~B43legacy_MACCTL_INFRA;
2211 if (b43legacy_using_pio(dev)) {
2212 b43legacy_write32(dev, 0x0210, 0x00000100);
2213 b43legacy_write32(dev, 0x0230, 0x00000100);
2214 b43legacy_write32(dev, 0x0250, 0x00000100);
2215 b43legacy_write32(dev, 0x0270, 0x00000100);
2225 b43legacy_adjust_opmode(dev);
2227 if (dev->
dev->id.revision < 3) {
2228 b43legacy_write16(dev, 0x060E, 0x0000);
2229 b43legacy_write16(dev, 0x0610, 0x8000);
2230 b43legacy_write16(dev, 0x0604, 0x0000);
2231 b43legacy_write16(dev, 0x0606, 0x0200);
2233 b43legacy_write32(dev, 0x0188, 0x80000000);
2234 b43legacy_write32(dev, 0x018C, 0x02000000);
2249 dev->
dev->bus->chipco.fast_pwrup_delay);
2262 b43legacy_gpio_cleanup(dev);
2266 static void b43legacy_periodic_every120sec(
struct b43legacy_wldev *dev)
2278 static void b43legacy_periodic_every60sec(
struct b43legacy_wldev *dev)
2288 static void b43legacy_periodic_every30sec(
struct b43legacy_wldev *dev)
2291 b43legacy_calculate_link_quality(dev);
2294 static void b43legacy_periodic_every15sec(
struct b43legacy_wldev *dev)
2308 b43legacy_periodic_every120sec(dev);
2310 b43legacy_periodic_every60sec(dev);
2312 b43legacy_periodic_every30sec(dev);
2313 b43legacy_periodic_every15sec(dev);
2321 static void b43legacy_periodic_work_handler(
struct work_struct *work)
2326 unsigned long delay;
2335 do_periodic_work(dev);
2348 static void b43legacy_periodic_tasks_setup(
struct b43legacy_wldev *dev)
2399 if (dev->
dev->id.revision >= 5)
2405 #ifdef CONFIG_B43LEGACY_HWRNG
2406 static int b43legacy_rng_read(
struct hwrng *rng,
u32 *data)
2409 unsigned long flags;
2417 spin_unlock_irqrestore(&wl->
irq_lock, flags);
2419 return (
sizeof(
u16));
2423 static void b43legacy_rng_exit(
struct b43legacy_wl *wl)
2425 #ifdef CONFIG_B43LEGACY_HWRNG
2426 if (wl->rng_initialized)
2435 #ifdef CONFIG_B43LEGACY_HWRNG
2437 "%s_%s", KBUILD_MODNAME, wiphy_name(wl->
hw->wiphy));
2438 wl->rng.name = wl->rng_name;
2439 wl->rng.data_read = b43legacy_rng_read;
2440 wl->rng.priv = (
unsigned long)wl;
2441 wl->rng_initialized = 1;
2444 wl->rng_initialized = 0;
2446 "number generator (%d)\n", err);
2453 static void b43legacy_tx_work(
struct work_struct *work)
2470 while (skb_queue_len(&wl->
tx_queue[queue_num])) {
2472 if (b43legacy_using_pio(dev))
2514 static int b43legacy_op_conf_tx(
struct ieee80211_hw *hw,
2521 static int b43legacy_op_get_stats(
struct ieee80211_hw *hw,
2525 unsigned long flags;
2529 spin_unlock_irqrestore(&wl->
irq_lock, flags);
2534 static const char *phymode_to_string(
unsigned int phymode)
2547 static int find_wldev_for_phymode(
struct b43legacy_wl *wl,
2548 unsigned int phymode,
2555 if (d->
phy.possible_phymodes & phymode) {
2588 static int b43legacy_switch_phymode(
struct b43legacy_wl *wl,
2589 unsigned int new_mode)
2597 err = find_wldev_for_phymode(wl, new_mode, &up_dev, &gmode);
2599 b43legacyerr(wl,
"Could not find a device for %s-PHY mode\n",
2600 phymode_to_string(new_mode));
2608 phymode_to_string(new_mode));
2614 b43legacy_wireless_core_stop(down_dev);
2616 b43legacy_wireless_core_exit(down_dev);
2618 if (down_dev != up_dev)
2621 b43legacy_put_phy_into_reset(down_dev);
2624 up_dev->phy.gmode = gmode;
2626 err = b43legacy_wireless_core_init(up_dev);
2629 " for newly selected %s-PHY mode\n",
2630 phymode_to_string(new_mode));
2635 err = b43legacy_wireless_core_start(up_dev);
2638 "newly selected %s-PHY mode\n",
2639 phymode_to_string(new_mode));
2640 b43legacy_wireless_core_exit(up_dev);
2659 unsigned int short_retry,
2660 unsigned int long_retry)
2664 short_retry =
min(short_retry, (
unsigned int)0xF);
2665 long_retry =
min(long_retry, (
unsigned int)0xF);
2671 static int b43legacy_op_dev_config(
struct ieee80211_hw *hw,
2678 unsigned long flags;
2679 unsigned int new_phymode = 0xFFFF;
2690 b43legacy_set_retry_limits(dev,
2693 changed &= ~IEEE80211_CONF_CHANGE_RETRY_LIMITS;
2695 goto out_unlock_mutex;
2698 switch (conf->
channel->band) {
2708 err = b43legacy_switch_phymode(wl, new_phymode);
2710 goto out_unlock_mutex;
2717 spin_unlock_irqrestore(&wl->
irq_lock, flags);
2718 goto out_unlock_mutex;
2721 spin_unlock_irqrestore(&wl->
irq_lock, flags);
2722 b43legacy_synchronize_irq(dev);
2740 b43legacy_mgmtframe_txantenna(dev, antenna_tx);
2748 " button still turns the radio"
2749 " physically off. Press the"
2750 " button to turn it on.\n");
2761 spin_unlock_irqrestore(&wl->
irq_lock, flags);
2779 if (b43legacy_is_cck_rate(rate->
hw_value)) {
2793 if (b43legacy_is_cck_rate(rate->
hw_value)) {
2795 basic_offset &= 0xF;
2798 basic_offset &= 0xF;
2806 direct + 2 * basic_offset);
2809 basic + 2 * offset, rateptr);
2813 static void b43legacy_op_bss_info_changed(
struct ieee80211_hw *hw,
2820 unsigned long flags;
2832 spin_unlock_irqrestore(&wl->
irq_lock, flags);
2833 goto out_unlock_mutex;
2838 b43legacy_synchronize_irq(dev);
2850 b43legacy_update_templates(wl);
2852 if (changed & BSS_CHANGED_BSSID)
2853 b43legacy_write_mac_bssid_templates(dev);
2855 spin_unlock_irqrestore(&wl->
irq_lock, flags);
2862 b43legacy_set_beacon_int(dev, conf->
beacon_int);
2865 b43legacy_update_basic_rates(dev, conf->
basic_rates);
2869 b43legacy_short_slot_timing_enable(dev);
2871 b43legacy_short_slot_timing_disable(dev);
2880 spin_unlock_irqrestore(&wl->
irq_lock, flags);
2885 static void b43legacy_op_configure_filter(
struct ieee80211_hw *hw,
2886 unsigned int changed,
2887 unsigned int *fflags,
u64 multicast)
2891 unsigned long flags;
2918 b43legacy_adjust_opmode(dev);
2919 spin_unlock_irqrestore(&wl->
irq_lock, flags);
2926 unsigned long flags;
2938 spin_unlock_irqrestore(&wl->
irq_lock, flags);
2939 b43legacy_synchronize_irq(dev);
2952 while (skb_queue_len(&wl->
tx_queue[queue_num]))
2968 drain_txstatus_queue(dev);
2985 b43legacy_periodic_tasks_setup(dev);
3003 int unsupported = 0;
3013 if (phy_rev != 2 && phy_rev != 4
3014 && phy_rev != 6 && phy_rev != 7)
3026 "(Analog %u, Type %u, Revision %u)\n",
3027 analog_type, phy_type, phy_rev);
3030 b43legacydbg(dev->
wl,
"Found PHY: Analog %u, Type %u, Revision %u\n",
3031 analog_type, phy_type, phy_rev);
3035 if (dev->
dev->bus->chip_id == 0x4317) {
3036 if (dev->
dev->bus->chip_rev == 0)
3038 else if (dev->
dev->bus->chip_rev == 1)
3051 radio_manuf = (tmp & 0x00000FFF);
3052 radio_ver = (tmp & 0x0FFFF000) >> 12;
3053 radio_rev = (tmp & 0xF0000000) >> 28;
3056 if ((radio_ver & 0xFFF0) != 0x2050)
3060 if (radio_ver != 0x2050)
3068 "(Manuf 0x%X, Version 0x%X, Revision %u)\n",
3069 radio_manuf, radio_ver, radio_rev);
3073 " Revision %u\n", radio_manuf, radio_ver, radio_rev);
3080 phy->
analog = analog_type;
3081 phy->
type = phy_type;
3121 phy->
nrssi[i] = -1000;
3140 setup_struct_phy_for_init(dev, &dev->
phy);
3155 u16 pu_delay = 1050;
3159 if ((dev->
phy.radio_ver == 0x2050) && (dev->
phy.radio_rev == 8))
3160 pu_delay =
max(pu_delay, (
u16)2400);
3200 b43legacy_rng_exit(dev->
wl);
3203 b43legacy_chip_exit(dev);
3205 b43legacy_switch_analog(dev, 0);
3210 if (dev->
wl->current_beacon) {
3212 dev->
wl->current_beacon =
NULL;
3234 phy->
nrssi[i] = -1000;
3287 setup_struct_wldev_for_init(dev);
3291 goto err_kfree_lo_control;
3296 prepare_phy_data_for_init(dev);
3298 err = b43legacy_chip_init(dev);
3300 goto err_kfree_tssitbl;
3303 dev->
dev->id.revision);
3318 b43legacy_set_retry_limits(dev,
3334 b43legacy_rate_memory_init(dev);
3348 if (b43legacy_using_pio(dev))
3355 }
while (err == -
EAGAIN);
3359 b43legacy_set_synth_pu_delay(dev, 1);
3362 b43legacy_upload_card_macaddress(dev);
3363 b43legacy_security_init(dev);
3364 b43legacy_rng_init(wl);
3374 b43legacy_chip_exit(dev);
3378 err_kfree_lo_control:
3386 static int b43legacy_op_add_interface(
struct ieee80211_hw *hw,
3391 unsigned long flags;
3404 goto out_mutex_unlock;
3415 b43legacy_adjust_opmode(dev);
3416 b43legacy_set_pretbtt(dev);
3417 b43legacy_set_synth_pu_delay(dev, 0);
3418 b43legacy_upload_card_macaddress(dev);
3419 spin_unlock_irqrestore(&wl->
irq_lock, flags);
3428 static void b43legacy_op_remove_interface(
struct ieee80211_hw *hw,
3433 unsigned long flags;
3446 b43legacy_adjust_opmode(dev);
3448 b43legacy_upload_card_macaddress(dev);
3449 spin_unlock_irqrestore(&wl->
irq_lock, flags);
3475 err = b43legacy_wireless_core_init(dev);
3477 goto out_mutex_unlock;
3482 err = b43legacy_wireless_core_start(dev);
3485 b43legacy_wireless_core_exit(dev);
3486 goto out_mutex_unlock;
3507 b43legacy_wireless_core_stop(dev);
3508 b43legacy_wireless_core_exit(dev);
3513 static int b43legacy_op_beacon_set_tim(
struct ieee80211_hw *hw,
3517 unsigned long flags;
3520 b43legacy_update_templates(wl);
3521 spin_unlock_irqrestore(&wl->
irq_lock, flags);
3544 .tx = b43legacy_op_tx,
3545 .conf_tx = b43legacy_op_conf_tx,
3546 .add_interface = b43legacy_op_add_interface,
3547 .remove_interface = b43legacy_op_remove_interface,
3548 .config = b43legacy_op_dev_config,
3549 .bss_info_changed = b43legacy_op_bss_info_changed,
3550 .configure_filter = b43legacy_op_configure_filter,
3551 .get_stats = b43legacy_op_get_stats,
3552 .start = b43legacy_op_start,
3553 .stop = b43legacy_op_stop,
3554 .set_tim = b43legacy_op_beacon_set_tim,
3555 .get_survey = b43legacy_op_get_survey,
3562 static void b43legacy_chip_reset(
struct work_struct *work)
3575 b43legacy_wireless_core_stop(dev);
3577 b43legacy_wireless_core_exit(dev);
3581 err = b43legacy_wireless_core_init(dev);
3586 err = b43legacy_wireless_core_start(dev);
3588 b43legacy_wireless_core_exit(dev);
3612 &b43legacy_band_2GHz_BPHY;
3618 &b43legacy_band_2GHz_GPHY;
3625 static void b43legacy_wireless_core_detach(
struct b43legacy_wldev *dev)
3629 b43legacy_release_firmware(dev);
3632 static int b43legacy_wireless_core_attach(
struct b43legacy_wldev *dev)
3655 if (dev->
dev->id.revision >= 5) {
3662 }
else if (dev->
dev->id.revision == 4)
3667 dev->
phy.gmode = (have_gphy || have_bphy);
3668 dev->
phy.radio_on =
true;
3672 err = b43legacy_phy_versioning(dev);
3677 (pdev->
device != 0x4312 &&
3678 pdev->
device != 0x4319 &&
3679 pdev->
device != 0x4324)) {
3683 switch (dev->
phy.type) {
3694 dev->
phy.gmode = (have_gphy || have_bphy);
3698 err = b43legacy_validate_chipaccess(dev);
3701 err = b43legacy_setup_modes(dev, have_bphy, have_gphy);
3711 b43legacy_switch_analog(dev, 0);
3723 static void b43legacy_one_core_detach(
struct ssb_device *dev)
3731 wldev = ssb_get_drvdata(dev);
3734 b43legacy_wireless_core_detach(wldev);
3737 ssb_set_drvdata(dev,
NULL);
3741 static int b43legacy_one_core_attach(
struct ssb_device *dev,
3756 (
void (*)(
unsigned long))b43legacy_interrupt_tasklet,
3757 (
unsigned long)wldev);
3760 INIT_LIST_HEAD(&wldev->
list);
3762 err = b43legacy_wireless_core_attach(wldev);
3764 goto err_kfree_wldev;
3768 ssb_set_drvdata(dev, wldev);
3778 static void b43legacy_sprom_fixup(
struct ssb_bus *bus)
3783 bus->
sprom.board_rev > 0x40)
3787 static void b43legacy_wireless_exit(
struct ssb_device *dev,
3796 static int b43legacy_wireless_init(
struct ssb_device *dev)
3804 b43legacy_sprom_fixup(dev->
bus);
3815 hw->
wiphy->interface_modes =
3822 SET_IEEE80211_DEV(hw, dev->
dev);
3823 if (is_valid_ether_addr(sprom->
et1mac))
3824 SET_IEEE80211_PERM_ADDR(hw, sprom->
et1mac);
3826 SET_IEEE80211_PERM_ADDR(hw, sprom->
il0mac);
3829 wl = hw_to_b43legacy_wl(hw);
3830 memset(wl, 0,
sizeof(*wl));
3841 skb_queue_head_init(&wl->
tx_queue[queue_num]);
3846 b43legacyinfo(wl,
"Broadcom %04X WLAN found (core revision %u)\n",
3847 dev->
bus->chip_id, dev->
id.revision);
3853 static int b43legacy_probe(
struct ssb_device *dev,
3860 wl = ssb_get_devtypedata(dev);
3864 err = b43legacy_wireless_init(dev);
3867 wl = ssb_get_devtypedata(dev);
3870 err = b43legacy_one_core_attach(dev, wl);
3872 goto err_wireless_exit;
3883 b43legacy_wireless_exit(dev, wl);
3887 static void b43legacy_remove(
struct ssb_device *dev)
3898 if (!wldev->
fw.ucode)
3903 b43legacy_one_core_detach(dev);
3909 b43legacy_wireless_exit(dev, wl);
3935 b43legacy_wireless_core_stop(wldev);
3937 b43legacy_wireless_core_exit(wldev);
3955 err = b43legacy_wireless_core_init(wldev);
3962 err = b43legacy_wireless_core_start(wldev);
3964 b43legacy_wireless_core_exit(wldev);
3977 # define b43legacy_suspend NULL
3978 # define b43legacy_resume NULL
3981 static struct ssb_driver b43legacy_ssb_driver = {
3982 .name = KBUILD_MODNAME,
3983 .id_table = b43legacy_ssb_tbl,
3984 .probe = b43legacy_probe,
3985 .remove = b43legacy_remove,
3990 static void b43legacy_print_driverinfo(
void)
3992 const char *feat_pci =
"", *feat_leds =
"",
3993 *feat_pio =
"", *feat_dma =
"";
3995 #ifdef CONFIG_B43LEGACY_PCI_AUTOSELECT
3998 #ifdef CONFIG_B43LEGACY_LEDS
4001 #ifdef CONFIG_B43LEGACY_PIO
4004 #ifdef CONFIG_B43LEGACY_DMA
4008 "[ Features: %s%s%s%s ]\n",
4009 feat_pci, feat_leds, feat_pio, feat_dma);
4012 static int __init b43legacy_init(
void)
4022 b43legacy_print_driverinfo();
4031 static void __exit b43legacy_exit(
void)