- 根目录:
- drivers
- net
- wireless
- b43
- main.c
C++程序
|
5657行
|
146.26 KB
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/firmware.h>
#include <linux/workqueue.h>
#include <linux/skbuff.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <asm/unaligned.h>
#include "b43.h"
#include "main.h"
#include "debugfs.h"
#include "phy_common.h"
#include "phy_g.h"
#include "phy_n.h"
#include "dma.h"
#include "pio.h"
#include "sysfs.h"
#include "xmit.h"
#include "lo.h"
#include "pcmcia.h"
#include "sdio.h"
#include <linux/mmc/sdio_func.h>
MODULE_DESCRIPTION("Broadcom B43 wireless driver");
MODULE_AUTHOR("Martin Langer");
MODULE_AUTHOR("Stefano Brivio");
MODULE_AUTHOR("Michael Buesch");
MODULE_AUTHOR("Gábor Stefanik");
MODULE_AUTHOR("Rafał Miłecki");
MODULE_LICENSE("GPL");
MODULE_FIRMWARE("b43/ucode11.fw");
MODULE_FIRMWARE("b43/ucode13.fw");
MODULE_FIRMWARE("b43/ucode14.fw");
MODULE_FIRMWARE("b43/ucode15.fw");
MODULE_FIRMWARE("b43/ucode16_mimo.fw");
MODULE_FIRMWARE("b43/ucode5.fw");
MODULE_FIRMWARE("b43/ucode9.fw");
static int modparam_bad_frames_preempt;
module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
MODULE_PARM_DESC(bad_frames_preempt,
"enable(1) / disable(0) Bad Frames Preemption");
static char modparam_fwpostfix[16];
module_param_string(fwpostfix, modparam_fwpostfix, 16, 0444);
MODULE_PARM_DESC(fwpostfix, "Postfix for the .fw files to load.");
static int modparam_hwpctl;
module_param_named(hwpctl, modparam_hwpctl, int, 0444);
MODULE_PARM_DESC(hwpctl, "Enable hardware-side power control (default off)");
static int modparam_nohwcrypt;
module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
static int modparam_hwtkip;
module_param_named(hwtkip, modparam_hwtkip, int, 0444);
MODULE_PARM_DESC(hwtkip, "Enable hardware tkip.");
static int modparam_qos = 1;
module_param_named(qos, modparam_qos, int, 0444);
MODULE_PARM_DESC(qos, "Enable QOS support (default on)");
static int modparam_btcoex = 1;
module_param_named(btcoex, modparam_btcoex, int, 0444);
MODULE_PARM_DESC(btcoex, "Enable Bluetooth coexistence (default on)");
int b43_modparam_verbose = B43_VERBOSITY_DEFAULT;
module_param_named(verbose, b43_modparam_verbose, int, 0644);
MODULE_PARM_DESC(verbose, "Log message verbosity: 0=error, 1=warn, 2=info(default), 3=debug");
static int b43_modparam_pio = 0;
module_param_named(pio, b43_modparam_pio, int, 0644);
MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
static int modparam_allhwsupport = !IS_ENABLED(CONFIG_BRCMSMAC);
module_param_named(allhwsupport, modparam_allhwsupport, int, 0444);
MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if overlaps with the brcmsmac driver)");
#ifdef CONFIG_B43_BCMA
static const struct bcma_device_id b43_bcma_tbl[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),
BCMA_CORETABLE_END
};
MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl);
#endif
#ifdef CONFIG_B43_SSB
static const struct ssb_device_id b43_ssb_tbl[] = {
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 7),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 11),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 12),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 15),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16),
SSB_DEVTABLE_END
};
MODULE_DEVICE_TABLE(ssb, b43_ssb_tbl);
#endif
#define RATETAB_ENT(_rateid, _flags) \
{ \
.bitrate = B43_RATE_TO_BASE100KBPS(_rateid), \
.hw_value = (_rateid), \
.flags = (_flags), \
}
static struct ieee80211_rate __b43_ratetable[] = {
RATETAB_ENT(B43_CCK_RATE_1MB, 0),
RATETAB_ENT(B43_CCK_RATE_2MB, IEEE80211_RATE_SHORT_PREAMBLE),
RATETAB_ENT(B43_CCK_RATE_5MB, IEEE80211_RATE_SHORT_PREAMBLE),
RATETAB_ENT(B43_CCK_RATE_11MB, IEEE80211_RATE_SHORT_PREAMBLE),
RATETAB_ENT(B43_OFDM_RATE_6MB, 0),
RATETAB_ENT(B43_OFDM_RATE_9MB, 0),
RATETAB_ENT(B43_OFDM_RATE_12MB, 0),
RATETAB_ENT(B43_OFDM_RATE_18MB, 0),
RATETAB_ENT(B43_OFDM_RATE_24MB, 0),
RATETAB_ENT(B43_OFDM_RATE_36MB, 0),
RATETAB_ENT(B43_OFDM_RATE_48MB, 0),
RATETAB_ENT(B43_OFDM_RATE_54MB, 0),
};
#define b43_a_ratetable (__b43_ratetable + 4)
#define b43_a_ratetable_size 8
#define b43_b_ratetable (__b43_ratetable + 0)
#define b43_b_ratetable_size 4
#define b43_g_ratetable (__b43_ratetable + 0)
#define b43_g_ratetable_size 12
#define CHAN4G(_channel, _freq, _flags) { \
.band = IEEE80211_BAND_2GHZ, \
.center_freq = (_freq), \
.hw_value = (_channel), \
.flags = (_flags), \
.max_antenna_gain = 0, \
.max_power = 30, \
}
static struct ieee80211_channel b43_2ghz_chantable[] = {
CHAN4G(1, 2412, 0),
CHAN4G(2, 2417, 0),
CHAN4G(3, 2422, 0),
CHAN4G(4, 2427, 0),
CHAN4G(5, 2432, 0),
CHAN4G(6, 2437, 0),
CHAN4G(7, 2442, 0),
CHAN4G(8, 2447, 0),
CHAN4G(9, 2452, 0),
CHAN4G(10, 2457, 0),
CHAN4G(11, 2462, 0),
CHAN4G(12, 2467, 0),
CHAN4G(13, 2472, 0),
CHAN4G(14, 2484, 0),
};
#undef CHAN4G
#define CHAN5G(_channel, _flags) { \
.band = IEEE80211_BAND_5GHZ, \
.center_freq = 5000 + (5 * (_channel)), \
.hw_value = (_channel), \
.flags = (_flags), \
.max_antenna_gain = 0, \
.max_power = 30, \
}
static struct ieee80211_channel b43_5ghz_nphy_chantable[] = {
CHAN5G(32, 0), CHAN5G(34, 0),
CHAN5G(36, 0), CHAN5G(38, 0),
CHAN5G(40, 0), CHAN5G(42, 0),
CHAN5G(44, 0), CHAN5G(46, 0),
CHAN5G(48, 0), CHAN5G(50, 0),
CHAN5G(52, 0), CHAN5G(54, 0),
CHAN5G(56, 0), CHAN5G(58, 0),
CHAN5G(60, 0), CHAN5G(62, 0),
CHAN5G(64, 0), CHAN5G(66, 0),
CHAN5G(68, 0), CHAN5G(70, 0),
CHAN5G(72, 0), CHAN5G(74, 0),
CHAN5G(76, 0), CHAN5G(78, 0),
CHAN5G(80, 0), CHAN5G(82, 0),
CHAN5G(84, 0), CHAN5G(86, 0),
CHAN5G(88, 0), CHAN5G(90, 0),
CHAN5G(92, 0), CHAN5G(94, 0),
CHAN5G(96, 0), CHAN5G(98, 0),
CHAN5G(100, 0), CHAN5G(102, 0),
CHAN5G(104, 0), CHAN5G(106, 0),
CHAN5G(108, 0), CHAN5G(110, 0),
CHAN5G(112, 0), CHAN5G(114, 0),
CHAN5G(116, 0), CHAN5G(118, 0),
CHAN5G(120, 0), CHAN5G(122, 0),
CHAN5G(124, 0), CHAN5G(126, 0),
CHAN5G(128, 0), CHAN5G(130, 0),
CHAN5G(132, 0), CHAN5G(134, 0),
CHAN5G(136, 0), CHAN5G(138, 0),
CHAN5G(140, 0), CHAN5G(142, 0),
CHAN5G(144, 0), CHAN5G(145, 0),
CHAN5G(146, 0), CHAN5G(147, 0),
CHAN5G(148, 0), CHAN5G(149, 0),
CHAN5G(150, 0), CHAN5G(151, 0),
CHAN5G(152, 0), CHAN5G(153, 0),
CHAN5G(154, 0), CHAN5G(155, 0),
CHAN5G(156, 0), CHAN5G(157, 0),
CHAN5G(158, 0), CHAN5G(159, 0),
CHAN5G(160, 0), CHAN5G(161, 0),
CHAN5G(162, 0), CHAN5G(163, 0),
CHAN5G(164, 0), CHAN5G(165, 0),
CHAN5G(166, 0), CHAN5G(168, 0),
CHAN5G(170, 0), CHAN5G(172, 0),
CHAN5G(174, 0), CHAN5G(176, 0),
CHAN5G(178, 0), CHAN5G(180, 0),
CHAN5G(182, 0), CHAN5G(184, 0),
CHAN5G(186, 0), CHAN5G(188, 0),
CHAN5G(190, 0), CHAN5G(192, 0),
CHAN5G(194, 0), CHAN5G(196, 0),
CHAN5G(198, 0), CHAN5G(200, 0),
CHAN5G(202, 0), CHAN5G(204, 0),
CHAN5G(206, 0), CHAN5G(208, 0),
CHAN5G(210, 0), CHAN5G(212, 0),
CHAN5G(214, 0), CHAN5G(216, 0),
CHAN5G(218, 0), CHAN5G(220, 0),
CHAN5G(222, 0), CHAN5G(224, 0),
CHAN5G(226, 0), CHAN5G(228, 0),
};
static struct ieee80211_channel b43_5ghz_aphy_chantable[] = {
CHAN5G(34, 0), CHAN5G(36, 0),
CHAN5G(38, 0), CHAN5G(40, 0),
CHAN5G(42, 0), CHAN5G(44, 0),
CHAN5G(46, 0), CHAN5G(48, 0),
CHAN5G(52, 0), CHAN5G(56, 0),
CHAN5G(60, 0), CHAN5G(64, 0),
CHAN5G(100, 0), CHAN5G(104, 0),
CHAN5G(108, 0), CHAN5G(112, 0),
CHAN5G(116, 0), CHAN5G(120, 0),
CHAN5G(124, 0), CHAN5G(128, 0),
CHAN5G(132, 0), CHAN5G(136, 0),
CHAN5G(140, 0), CHAN5G(149, 0),
CHAN5G(153, 0), CHAN5G(157, 0),
CHAN5G(161, 0), CHAN5G(165, 0),
CHAN5G(184, 0), CHAN5G(188, 0),
CHAN5G(192, 0), CHAN5G(196, 0),
CHAN5G(200, 0), CHAN5G(204, 0),
CHAN5G(208, 0), CHAN5G(212, 0),
CHAN5G(216, 0),
};
#undef CHAN5G
static struct ieee80211_supported_band b43_band_5GHz_nphy = {
.band = IEEE80211_BAND_5GHZ,
.channels = b43_5ghz_nphy_chantable,
.n_channels = ARRAY_SIZE(b43_5ghz_nphy_chantable),
.bitrates = b43_a_ratetable,
.n_bitrates = b43_a_ratetable_size,
};
static struct ieee80211_supported_band b43_band_5GHz_aphy = {
.band = IEEE80211_BAND_5GHZ,
.channels = b43_5ghz_aphy_chantable,
.n_channels = ARRAY_SIZE(b43_5ghz_aphy_chantable),
.bitrates = b43_a_ratetable,
.n_bitrates = b43_a_ratetable_size,
};
static struct ieee80211_supported_band b43_band_2GHz = {
.band = IEEE80211_BAND_2GHZ,
.channels = b43_2ghz_chantable,
.n_channels = ARRAY_SIZE(b43_2ghz_chantable),
.bitrates = b43_g_ratetable,
.n_bitrates = b43_g_ratetable_size,
};
static void b43_wireless_core_exit(struct b43_wldev *dev);
static int b43_wireless_core_init(struct b43_wldev *dev);
static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
static int b43_wireless_core_start(struct b43_wldev *dev);
static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *conf,
u32 changed);
static int b43_ratelimit(struct b43_wl *wl)
{
if (!wl || !wl->current_dev)
return 1;
if (b43_status(wl->current_dev) < B43_STAT_STARTED)
return 1;
return net_ratelimit();
}
void b43info(struct b43_wl *wl, const char *fmt, ...)
{
struct va_format vaf;
va_list args;
if (b43_modparam_verbose < B43_VERBOSITY_INFO)
return;
if (!b43_ratelimit(wl))
return;
va_start(args, fmt);
vaf.fmt = fmt;
vaf.va = &args;
printk(KERN_INFO "b43-%s: %pV",
(wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
va_end(args);
}
void b43err(struct b43_wl *wl, const char *fmt, ...)
{
struct va_format vaf;
va_list args;
if (b43_modparam_verbose < B43_VERBOSITY_ERROR)
return;
if (!b43_ratelimit(wl))
return;
va_start(args, fmt);
vaf.fmt = fmt;
vaf.va = &args;
printk(KERN_ERR "b43-%s ERROR: %pV",
(wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
va_end(args);
}
void b43warn(struct b43_wl *wl, const char *fmt, ...)
{
struct va_format vaf;
va_list args;
if (b43_modparam_verbose < B43_VERBOSITY_WARN)
return;
if (!b43_ratelimit(wl))
return;
va_start(args, fmt);
vaf.fmt = fmt;
vaf.va = &args;
printk(KERN_WARNING "b43-%s warning: %pV",
(wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
va_end(args);
}
void b43dbg(struct b43_wl *wl, const char *fmt, ...)
{
struct va_format vaf;
va_list args;
if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
return;
va_start(args, fmt);
vaf.fmt = fmt;
vaf.va = &args;
printk(KERN_DEBUG "b43-%s debug: %pV",
(wl && wl->hw) ? wiphy_name(wl->hw->wiphy) : "wlan", &vaf);
va_end(args);
}
static void b43_ram_write(struct b43_wldev *dev, u16 offset, u32 val)
{
u32 macctl;
B43_WARN_ON(offset % 4 != 0);
macctl = b43_read32(dev, B43_MMIO_MACCTL);
if (macctl & B43_MACCTL_BE)
val = swab32(val);
b43_write32(dev, B43_MMIO_RAM_CONTROL, offset);
mmiowb();
b43_write32(dev, B43_MMIO_RAM_DATA, val);
}
static inline void b43_shm_control_word(struct b43_wldev *dev,
u16 routing, u16 offset)
{
u32 control;
control = routing;
control <<= 16;
control |= offset;
b43_write32(dev, B43_MMIO_SHM_CONTROL, control);
}
u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
{
u32 ret;
if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) {
b43_shm_control_word(dev, routing, offset >> 2);
ret = b43_read16(dev, B43_MMIO_SHM_DATA_UNALIGNED);
b43_shm_control_word(dev, routing, (offset >> 2) + 1);
ret |= ((u32)b43_read16(dev, B43_MMIO_SHM_DATA)) << 16;
goto out;
}
offset >>= 2;
}
b43_shm_control_word(dev, routing, offset);
ret = b43_read32(dev, B43_MMIO_SHM_DATA);
out:
return ret;
}
u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset)
{
u16 ret;
if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) {
b43_shm_control_word(dev, routing, offset >> 2);
ret = b43_read16(dev, B43_MMIO_SHM_DATA_UNALIGNED);
goto out;
}
offset >>= 2;
}
b43_shm_control_word(dev, routing, offset);
ret = b43_read16(dev, B43_MMIO_SHM_DATA);
out:
return ret;
}
void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
{
if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) {
b43_shm_control_word(dev, routing, offset >> 2);
b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED,
value & 0xFFFF);
b43_shm_control_word(dev, routing, (offset >> 2) + 1);
b43_write16(dev, B43_MMIO_SHM_DATA,
(value >> 16) & 0xFFFF);
return;
}
offset >>= 2;
}
b43_shm_control_word(dev, routing, offset);
b43_write32(dev, B43_MMIO_SHM_DATA, value);
}
void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
{
if (routing == B43_SHM_SHARED) {
B43_WARN_ON(offset & 0x0001);
if (offset & 0x0003) {
b43_shm_control_word(dev, routing, offset >> 2);
b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, value);
return;
}
offset >>= 2;
}
b43_shm_control_word(dev, routing, offset);
b43_write16(dev, B43_MMIO_SHM_DATA, value);
}
u64 b43_hf_read(struct b43_wldev *dev)
{
u64 ret;
ret = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTF3);
ret <<= 16;
ret |= b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTF2);
ret <<= 16;
ret |= b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTF1);
return ret;
}
void b43_hf_write(struct b43_wldev *dev, u64 value)
{
u16 lo, mi, hi;
lo = (value & 0x00000000FFFFULL);
mi = (value & 0x0000FFFF0000ULL) >> 16;
hi = (value & 0xFFFF00000000ULL) >> 32;
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTF1, lo);
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTF2, mi);
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTF3, hi);
}
static u16 b43_fwcapa_read(struct b43_wldev *dev)
{
B43_WARN_ON(!dev->fw.opensource);
return b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_FWCAPA);
}
void b43_tsf_read(struct b43_wldev *dev, u64 *tsf)
{
u32 low, high;
B43_WARN_ON(dev->dev->core_rev < 3);
low = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_LOW);
high = b43_read32(dev, B43_MMIO_REV3PLUS_TSF_HIGH);
*tsf = high;
*tsf <<= 32;
*tsf |= low;
}
static void b43_time_lock(struct b43_wldev *dev)
{
b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_TBTTHOLD);
b43_read32(dev, B43_MMIO_MACCTL);
}
static void b43_time_unlock(struct b43_wldev *dev)
{
b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_TBTTHOLD, 0);
b43_read32(dev, B43_MMIO_MACCTL);
}
static void b43_tsf_write_locked(struct b43_wldev *dev, u64 tsf)
{
u32 low, high;
B43_WARN_ON(dev->dev->core_rev < 3);
low = tsf;
high = (tsf >> 32);
b43_write32(dev, B43_MMIO_REV3PLUS_TSF_LOW, low);
mmiowb();
b43_write32(dev, B43_MMIO_REV3PLUS_TSF_HIGH, high);
mmiowb();
}
void b43_tsf_write(struct b43_wldev *dev, u64 tsf)
{
b43_time_lock(dev);
b43_tsf_write_locked(dev, tsf);
b43_time_unlock(dev);
}
static
void b43_macfilter_set(struct b43_wldev *dev, u16 offset, const u8 *mac)
{
static const u8 zero_addr[ETH_ALEN] = { 0 };
u16 data;
if (!mac)
mac = zero_addr;
offset |= 0x0020;
b43_write16(dev, B43_MMIO_MACFILTER_CONTROL, offset);
data = mac[0];
data |= mac[1] << 8;
b43_write16(dev, B43_MMIO_MACFILTER_DATA, data);
data = mac[2];
data |= mac[3] << 8;
b43_write16(dev, B43_MMIO_MACFILTER_DATA, data);
data = mac[4];
data |= mac[5] << 8;
b43_write16(dev, B43_MMIO_MACFILTER_DATA, data);
}
static void b43_write_mac_bssid_templates(struct b43_wldev *dev)
{
const u8 *mac;
const u8 *bssid;
u8 mac_bssid[ETH_ALEN * 2];
int i;
u32 tmp;
bssid = dev->wl->bssid;
mac = dev->wl->mac_addr;
b43_macfilter_set(dev, B43_MACFILTER_BSSID, bssid);
memcpy(mac_bssid, mac, ETH_ALEN);
memcpy(mac_bssid + ETH_ALEN, bssid, ETH_ALEN);
for (i = 0; i < ARRAY_SIZE(mac_bssid); i += sizeof(u32)) {
tmp = (u32) (mac_bssid[i + 0]);
tmp |= (u32) (mac_bssid[i + 1]) << 8;
tmp |= (u32) (mac_bssid[i + 2]) << 16;
tmp |= (u32) (mac_bssid[i + 3]) << 24;
b43_ram_write(dev, 0x20 + i, tmp);
}
}
static void b43_upload_card_macaddress(struct b43_wldev *dev)
{
b43_write_mac_bssid_templates(dev);
b43_macfilter_set(dev, B43_MACFILTER_SELF, dev->wl->mac_addr);
}
static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time)
{
if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
return;
b43_write16(dev, B43_MMIO_IFSSLOT, 510 + slot_time);
}
static void b43_short_slot_timing_enable(struct b43_wldev *dev)
{
b43_set_slot_time(dev, 9);
}
static void b43_short_slot_timing_disable(struct b43_wldev *dev)
{
b43_set_slot_time(dev, 20);
}
void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on)
{
struct b43_phy *phy = &dev->phy;
unsigned int i, max_loop;
u16 value;
u32 buffer[5] = {
0x00000000,
0x00D40000,
0x00000000,
0x01000000,
0x00000000,
};
if (ofdm) {
max_loop = 0x1E;
buffer[0] = 0x000201CC;
} else {
max_loop = 0xFA;
buffer[0] = 0x000B846E;
}
for (i = 0; i < 5; i++)
b43_ram_write(dev, i * 4, buffer[i]);
b43_write16(dev, B43_MMIO_XMTSEL, 0x0000);
if (dev->dev->core_rev < 11)
b43_write16(dev, B43_MMIO_WEPCTL, 0x0000);
else
b43_write16(dev, B43_MMIO_WEPCTL, 0x0100);
value = (ofdm ? 0x41 : 0x40);
b43_write16(dev, B43_MMIO_TXE0_PHYCTL, value);
if (phy->type == B43_PHYTYPE_N || phy->type == B43_PHYTYPE_LP ||
phy->type == B43_PHYTYPE_LCN)
b43_write16(dev, B43_MMIO_TXE0_PHYCTL1, 0x1A02);
b43_write16(dev, B43_MMIO_TXE0_WM_0, 0x0000);
b43_write16(dev, B43_MMIO_TXE0_WM_1, 0x0000);
b43_write16(dev, B43_MMIO_XMTTPLATETXPTR, 0x0000);
b43_write16(dev, B43_MMIO_XMTTXCNT, 0x0014);
b43_write16(dev, B43_MMIO_XMTSEL, 0x0826);
b43_write16(dev, B43_MMIO_TXE0_CTL, 0x0000);
if (!pa_on && phy->type == B43_PHYTYPE_N)
;
switch (phy->type) {
case B43_PHYTYPE_N:
case B43_PHYTYPE_LCN:
b43_write16(dev, B43_MMIO_TXE0_AUX, 0x00D0);
break;
case B43_PHYTYPE_LP:
b43_write16(dev, B43_MMIO_TXE0_AUX, 0x0050);
break;
default:
b43_write16(dev, B43_MMIO_TXE0_AUX, 0x0030);
}
b43_read16(dev, B43_MMIO_TXE0_AUX);
if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5)
b43_radio_write16(dev, 0x0051, 0x0017);
for (i = 0x00; i < max_loop; i++) {
value = b43_read16(dev, B43_MMIO_TXE0_STATUS);
if (value & 0x0080)
break;
udelay(10);
}
for (i = 0x00; i < 0x0A; i++) {
value = b43_read16(dev, B43_MMIO_TXE0_STATUS);
if (value & 0x0400)
break;
udelay(10);
}
for (i = 0x00; i < 0x19; i++) {
value = b43_read16(dev, B43_MMIO_IFSSTAT);
if (!(value & 0x0100))
break;
udelay(10);
}
if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5)
b43_radio_write16(dev, 0x0051, 0x0037);
}
static void key_write(struct b43_wldev *dev,
u8 index, u8 algorithm, const u8 *key)
{
unsigned int i;
u32 offset;
u16 value;
u16 kidx;
kidx = b43_kidx_to_fw(dev, index);
value = ((kidx << 4) | algorithm);
b43_shm_write16(dev, B43_SHM_SHARED,
B43_SHM_SH_KEYIDXBLOCK + (kidx * 2), value);
offset = dev->ktp + (index * B43_SEC_KEYSIZE);
for (i = 0; i < B43_SEC_KEYSIZE; i += 2) {
value = key[i];
value |= (u16) (key[i + 1]) << 8;
b43_shm_write16(dev, B43_SHM_SHARED, offset + i, value);
}
}
static void keymac_write(struct b43_wldev *dev, u8 index, const u8 *addr)
{
u32 addrtmp[2] = { 0, 0, };
u8 pairwise_keys_start = B43_NR_GROUP_KEYS * 2;
if (b43_new_kidx_api(dev))
pairwise_keys_start = B43_NR_GROUP_KEYS;
B43_WARN_ON(index < pairwise_keys_start);
index -= pairwise_keys_start;
B43_WARN_ON(index >= B43_NR_PAIRWISE_KEYS);
if (addr) {
addrtmp[0] = addr[0];
addrtmp[0] |= ((u32) (addr[1]) << 8);
addrtmp[0] |= ((u32) (addr[2]) << 16);
addrtmp[0] |= ((u32) (addr[3]) << 24);
addrtmp[1] = addr[4];
addrtmp[1] |= ((u32) (addr[5]) << 8);
}
b43_shm_write32(dev, B43_SHM_RCMTA,
(index * 2) + 0, addrtmp[0]);
b43_shm_write16(dev, B43_SHM_RCMTA,
(index * 2) + 1, addrtmp[1]);
}
static void rx_tkip_phase1_write(struct b43_wldev *dev, u8 index, u32 iv32,
u16 *phase1key)
{
unsigned int i;
u32 offset;
u8 pairwise_keys_start = B43_NR_GROUP_KEYS * 2;
if (!modparam_hwtkip)
return;
if (b43_new_kidx_api(dev))
pairwise_keys_start = B43_NR_GROUP_KEYS;
B43_WARN_ON(index < pairwise_keys_start);
index -= pairwise_keys_start;
B43_WARN_ON(index >= B43_NR_PAIRWISE_KEYS);
if (b43_debug(dev, B43_DBG_KEYS)) {
b43dbg(dev->wl, "rx_tkip_phase1_write : idx 0x%x, iv32 0x%x\n",
index, iv32);
}
offset = B43_SHM_SH_TKIPTSCTTAK + index * (10 + 4);
for (i = 0; i < 10; i += 2) {
b43_shm_write16(dev, B43_SHM_SHARED, offset + i,
phase1key ? phase1key[i / 2] : 0);
}
b43_shm_write16(dev, B43_SHM_SHARED, offset + i, iv32);
b43_shm_write16(dev, B43_SHM_SHARED, offset + i + 2, iv32 >> 16);
}
static void b43_op_update_tkip_key(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_key_conf *keyconf,
struct ieee80211_sta *sta,
u32 iv32, u16 *phase1key)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
int index = keyconf->hw_key_idx;
if (B43_WARN_ON(!modparam_hwtkip))
return;
B43_WARN_ON(!mutex_is_locked(&wl->mutex));
dev = wl->current_dev;
B43_WARN_ON(!dev || b43_status(dev) < B43_STAT_INITIALIZED);
keymac_write(dev, index, NULL);
rx_tkip_phase1_write(dev, index, iv32, phase1key);
if (WARN_ON(!sta))
return;
keymac_write(dev, index, sta->addr);
}
static void do_key_write(struct b43_wldev *dev,
u8 index, u8 algorithm,
const u8 *key, size_t key_len, const u8 *mac_addr)
{
u8 buf[B43_SEC_KEYSIZE] = { 0, };
u8 pairwise_keys_start = B43_NR_GROUP_KEYS * 2;
if (b43_new_kidx_api(dev))
pairwise_keys_start = B43_NR_GROUP_KEYS;
B43_WARN_ON(index >= ARRAY_SIZE(dev->key));
B43_WARN_ON(key_len > B43_SEC_KEYSIZE);
if (index >= pairwise_keys_start)
keymac_write(dev, index, NULL);
if (algorithm == B43_SEC_ALGO_TKIP) {
rx_tkip_phase1_write(dev, index, 0xffffffff, (u16*)buf);
} else if (index >= pairwise_keys_start)
rx_tkip_phase1_write(dev, index, 0, NULL);
if (key)
memcpy(buf, key, key_len);
key_write(dev, index, algorithm, buf);
if (index >= pairwise_keys_start)
keymac_write(dev, index, mac_addr);
dev->key[index].algorithm = algorithm;
}
static int b43_key_write(struct b43_wldev *dev,
int index, u8 algorithm,
const u8 *key, size_t key_len,
const u8 *mac_addr,
struct ieee80211_key_conf *keyconf)
{
int i;
int pairwise_keys_start;
if (algorithm == B43_SEC_ALGO_TKIP && key_len == 32)
key_len = 16;
if (key_len > B43_SEC_KEYSIZE)
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(dev->key); i++) {
B43_WARN_ON(dev->key[i].keyconf == keyconf);
}
if (index < 0) {
if (b43_new_kidx_api(dev))
pairwise_keys_start = B43_NR_GROUP_KEYS;
else
pairwise_keys_start = B43_NR_GROUP_KEYS * 2;
for (i = pairwise_keys_start;
i < pairwise_keys_start + B43_NR_PAIRWISE_KEYS;
i++) {
B43_WARN_ON(i >= ARRAY_SIZE(dev->key));
if (!dev->key[i].keyconf) {
index = i;
break;
}
}
if (index < 0) {
b43warn(dev->wl, "Out of hardware key memory\n");
return -ENOSPC;
}
} else
B43_WARN_ON(index > 3);
do_key_write(dev, index, algorithm, key, key_len, mac_addr);
if ((index <= 3) && !b43_new_kidx_api(dev)) {
B43_WARN_ON(mac_addr);
do_key_write(dev, index + 4, algorithm, key, key_len, NULL);
}
keyconf->hw_key_idx = index;
dev->key[index].keyconf = keyconf;
return 0;
}
static int b43_key_clear(struct b43_wldev *dev, int index)
{
if (B43_WARN_ON((index < 0) || (index >= ARRAY_SIZE(dev->key))))
return -EINVAL;
do_key_write(dev, index, B43_SEC_ALGO_NONE,
NULL, B43_SEC_KEYSIZE, NULL);
if ((index <= 3) && !b43_new_kidx_api(dev)) {
do_key_write(dev, index + 4, B43_SEC_ALGO_NONE,
NULL, B43_SEC_KEYSIZE, NULL);
}
dev->key[index].keyconf = NULL;
return 0;
}
static void b43_clear_keys(struct b43_wldev *dev)
{
int i, count;
if (b43_new_kidx_api(dev))
count = B43_NR_GROUP_KEYS + B43_NR_PAIRWISE_KEYS;
else
count = B43_NR_GROUP_KEYS * 2 + B43_NR_PAIRWISE_KEYS;
for (i = 0; i < count; i++)
b43_key_clear(dev, i);
}
static void b43_dump_keymemory(struct b43_wldev *dev)
{
unsigned int i, index, count, offset, pairwise_keys_start;
u8 mac[ETH_ALEN];
u16 algo;
u32 rcmta0;
u16 rcmta1;
u64 hf;
struct b43_key *key;
if (!b43_debug(dev, B43_DBG_KEYS))
return;
hf = b43_hf_read(dev);
b43dbg(dev->wl, "Hardware key memory dump: USEDEFKEYS=%u\n",
!!(hf & B43_HF_USEDEFKEYS));
if (b43_new_kidx_api(dev)) {
pairwise_keys_start = B43_NR_GROUP_KEYS;
count = B43_NR_GROUP_KEYS + B43_NR_PAIRWISE_KEYS;
} else {
pairwise_keys_start = B43_NR_GROUP_KEYS * 2;
count = B43_NR_GROUP_KEYS * 2 + B43_NR_PAIRWISE_KEYS;
}
for (index = 0; index < count; index++) {
key = &(dev->key[index]);
printk(KERN_DEBUG "Key slot %02u: %s",
index, (key->keyconf == NULL) ? " " : "*");
offset = dev->ktp + (index * B43_SEC_KEYSIZE);
for (i = 0; i < B43_SEC_KEYSIZE; i += 2) {
u16 tmp = b43_shm_read16(dev, B43_SHM_SHARED, offset + i);
printk("%02X%02X", (tmp & 0xFF), ((tmp >> 8) & 0xFF));
}
algo = b43_shm_read16(dev, B43_SHM_SHARED,
B43_SHM_SH_KEYIDXBLOCK + (index * 2));
printk(" Algo: %04X/%02X", algo, key->algorithm);
if (index >= pairwise_keys_start) {
if (key->algorithm == B43_SEC_ALGO_TKIP) {
printk(" TKIP: ");
offset = B43_SHM_SH_TKIPTSCTTAK + (index - 4) * (10 + 4);
for (i = 0; i < 14; i += 2) {
u16 tmp = b43_shm_read16(dev, B43_SHM_SHARED, offset + i);
printk("%02X%02X", (tmp & 0xFF), ((tmp >> 8) & 0xFF));
}
}
rcmta0 = b43_shm_read32(dev, B43_SHM_RCMTA,
((index - pairwise_keys_start) * 2) + 0);
rcmta1 = b43_shm_read16(dev, B43_SHM_RCMTA,
((index - pairwise_keys_start) * 2) + 1);
*((__le32 *)(&mac[0])) = cpu_to_le32(rcmta0);
*((__le16 *)(&mac[4])) = cpu_to_le16(rcmta1);
printk(" MAC: %pM", mac);
} else
printk(" DEFAULT KEY");
printk("\n");
}
}
void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags)
{
u32 macctl;
u16 ucstat;
bool hwps;
bool awake;
int i;
B43_WARN_ON((ps_flags & B43_PS_ENABLED) &&
(ps_flags & B43_PS_DISABLED));
B43_WARN_ON((ps_flags & B43_PS_AWAKE) && (ps_flags & B43_PS_ASLEEP));
if (ps_flags & B43_PS_ENABLED) {
hwps = true;
} else if (ps_flags & B43_PS_DISABLED) {
hwps = false;
} else {
}
if (ps_flags & B43_PS_AWAKE) {
awake = true;
} else if (ps_flags & B43_PS_ASLEEP) {
awake = false;
} else {
}
hwps = false;
awake = true;
macctl = b43_read32(dev, B43_MMIO_MACCTL);
if (hwps)
macctl |= B43_MACCTL_HWPS;
else
macctl &= ~B43_MACCTL_HWPS;
if (awake)
macctl |= B43_MACCTL_AWAKE;
else
macctl &= ~B43_MACCTL_AWAKE;
b43_write32(dev, B43_MMIO_MACCTL, macctl);
b43_read32(dev, B43_MMIO_MACCTL);
if (awake && dev->dev->core_rev >= 5) {
for (i = 0; i < 100; i++) {
ucstat = b43_shm_read16(dev, B43_SHM_SHARED,
B43_SHM_SH_UCODESTAT);
if (ucstat != B43_SHM_SH_UCODESTAT_SLEEP)
break;
udelay(10);
}
}
}
#ifdef CONFIG_B43_BCMA
static void b43_bcma_phy_reset(struct b43_wldev *dev)
{
u32 flags;
flags = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
flags |= B43_BCMA_IOCTL_PHY_RESET;
flags |= B43_BCMA_IOCTL_PHY_BW_20MHZ;
bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags);
udelay(2);
flags = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
flags &= ~B43_BCMA_IOCTL_PHY_RESET;
flags |= BCMA_IOCTL_FGC;
bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags);
udelay(1);
flags = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
flags &= ~BCMA_IOCTL_FGC;
bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags);
udelay(1);
}
static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode)
{
u32 req = B43_BCMA_CLKCTLST_80211_PLL_REQ |
B43_BCMA_CLKCTLST_PHY_PLL_REQ;
u32 status = B43_BCMA_CLKCTLST_80211_PLL_ST |
B43_BCMA_CLKCTLST_PHY_PLL_ST;
b43_device_enable(dev, B43_BCMA_IOCTL_PHY_CLKEN);
bcma_core_set_clockmode(dev->dev->bdev, BCMA_CLKMODE_FAST);
b43_bcma_phy_reset(dev);
bcma_core_pll_ctl(dev->dev->bdev, req, status, true);
}
#endif
static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, bool gmode)
{
struct ssb_device *sdev = dev->dev->sdev;
u32 tmslow;
u32 flags = 0;
if (gmode)
flags |= B43_TMSLOW_GMODE;
flags |= B43_TMSLOW_PHYCLKEN;
flags |= B43_TMSLOW_PHYRESET;
if (dev->phy.type == B43_PHYTYPE_N)
flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ;
b43_device_enable(dev, flags);
msleep(2);
tmslow = ssb_read32(sdev, SSB_TMSLOW);
tmslow |= SSB_TMSLOW_FGC;
tmslow &= ~B43_TMSLOW_PHYRESET;
ssb_write32(sdev, SSB_TMSLOW, tmslow);
ssb_read32(sdev, SSB_TMSLOW);
msleep(1);
tmslow &= ~SSB_TMSLOW_FGC;
ssb_write32(sdev, SSB_TMSLOW, tmslow);
ssb_read32(sdev, SSB_TMSLOW);
msleep(1);
}
void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode)
{
u32 macctl;
switch (dev->dev->bus_type) {
#ifdef CONFIG_B43_BCMA
case B43_BUS_BCMA:
b43_bcma_wireless_core_reset(dev, gmode);
break;
#endif
#ifdef CONFIG_B43_SSB
case B43_BUS_SSB:
b43_ssb_wireless_core_reset(dev, gmode);
break;
#endif
}
if (dev->phy.ops)
dev->phy.ops->switch_analog(dev, 1);
macctl = b43_read32(dev, B43_MMIO_MACCTL);
macctl &= ~B43_MACCTL_GMODE;
if (gmode)
macctl |= B43_MACCTL_GMODE;
macctl |= B43_MACCTL_IHR_ENABLED;
b43_write32(dev, B43_MMIO_MACCTL, macctl);
}
static void handle_irq_transmit_status(struct b43_wldev *dev)
{
u32 v0, v1;
u16 tmp;
struct b43_txstatus stat;
while (1) {
v0 = b43_read32(dev, B43_MMIO_XMITSTAT_0);
if (!(v0 & 0x00000001))
break;
v1 = b43_read32(dev, B43_MMIO_XMITSTAT_1);
stat.cookie = (v0 >> 16);
stat.seq = (v1 & 0x0000FFFF);
stat.phy_stat = ((v1 & 0x00FF0000) >> 16);
tmp = (v0 & 0x0000FFFF);
stat.frame_count = ((tmp & 0xF000) >> 12);
stat.rts_count = ((tmp & 0x0F00) >> 8);
stat.supp_reason = ((tmp & 0x001C) >> 2);
stat.pm_indicated = !!(tmp & 0x0080);
stat.intermediate = !!(tmp & 0x0040);
stat.for_ampdu = !!(tmp & 0x0020);
stat.acked = !!(tmp & 0x0002);
b43_handle_txstatus(dev, &stat);
}
}
static void drain_txstatus_queue(struct b43_wldev *dev)
{
u32 dummy;
if (dev->dev->core_rev < 5)
return;
while (1) {
dummy = b43_read32(dev, B43_MMIO_XMITSTAT_0);
if (!(dummy & 0x00000001))
break;
dummy = b43_read32(dev, B43_MMIO_XMITSTAT_1);
}
}
static u32 b43_jssi_read(struct b43_wldev *dev)
{
u32 val = 0;
val = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_JSSI1);
val <<= 16;
val |= b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_JSSI0);
return val;
}
static void b43_jssi_write(struct b43_wldev *dev, u32 jssi)
{
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_JSSI0,
(jssi & 0x0000FFFF));
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_JSSI1,
(jssi & 0xFFFF0000) >> 16);
}
static void b43_generate_noise_sample(struct b43_wldev *dev)
{
b43_jssi_write(dev, 0x7F7F7F7F);
b43_write32(dev, B43_MMIO_MACCMD,
b43_read32(dev, B43_MMIO_MACCMD) | B43_MACCMD_BGNOISE);
}
static void b43_calculate_link_quality(struct b43_wldev *dev)
{
if (dev->phy.type != B43_PHYTYPE_G)
return;
if (dev->noisecalc.calculation_running)
return;
dev->noisecalc.calculation_running = true;
dev->noisecalc.nr_samples = 0;
b43_generate_noise_sample(dev);
}
static void handle_irq_noise(struct b43_wldev *dev)
{
struct b43_phy_g *phy = dev->phy.g;
u16 tmp;
u8 noise[4];
u8 i, j;
s32 average;
if (dev->phy.type != B43_PHYTYPE_G)
return;
B43_WARN_ON(!dev->noisecalc.calculation_running);
*((__le32 *)noise) = cpu_to_le32(b43_jssi_read(dev));
if (noise[0] == 0x7F || noise[1] == 0x7F ||
noise[2] == 0x7F || noise[3] == 0x7F)
goto generate_new;
B43_WARN_ON(dev->noisecalc.nr_samples >= 8);
i = dev->noisecalc.nr_samples;
noise[0] = clamp_val(noise[0], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
noise[1] = clamp_val(noise[1], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
noise[2] = clamp_val(noise[2], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
noise[3] = clamp_val(noise[3], 0, ARRAY_SIZE(phy->nrssi_lt) - 1);
dev->noisecalc.samples[i][0] = phy->nrssi_lt[noise[0]];
dev->noisecalc.samples[i][1] = phy->nrssi_lt[noise[1]];
dev->noisecalc.samples[i][2] = phy->nrssi_lt[noise[2]];
dev->noisecalc.samples[i][3] = phy->nrssi_lt[noise[3]];
dev->noisecalc.nr_samples++;
if (dev->noisecalc.nr_samples == 8) {
average = 0;
for (i = 0; i < 8; i++) {
for (j = 0; j < 4; j++)
average += dev->noisecalc.samples[i][j];
}
average /= (8 * 4);
average *= 125;
average += 64;
average /= 128;
tmp = b43_shm_read16(dev, B43_SHM_SHARED, 0x40C);
tmp = (tmp / 128) & 0x1F;
if (tmp >= 8)
average += 2;
else
average -= 25;
if (tmp == 8)
average -= 72;
else
average -= 48;
dev->stats.link_noise = average;
dev->noisecalc.calculation_running = false;
return;
}
generate_new:
b43_generate_noise_sample(dev);
}
static void handle_irq_tbtt_indication(struct b43_wldev *dev)
{
if (b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) {
} else {
if (1 )
b43_power_saving_ctl_bits(dev, 0);
}
if (b43_is_mode(dev->wl, NL80211_IFTYPE_ADHOC))
dev->dfq_valid = true;
}
static void handle_irq_atim_end(struct b43_wldev *dev)
{
if (dev->dfq_valid) {
b43_write32(dev, B43_MMIO_MACCMD,
b43_read32(dev, B43_MMIO_MACCMD)
| B43_MACCMD_DFQ_VALID);
dev->dfq_valid = false;
}
}
static void handle_irq_pmq(struct b43_wldev *dev)
{
u32 tmp;
while (1) {
tmp = b43_read32(dev, B43_MMIO_PS_STATUS);
if (!(tmp & 0x00000008))
break;
}
b43_write16(dev, B43_MMIO_PS_STATUS, 0x0002);
}
static void b43_write_template_common(struct b43_wldev *dev,
const u8 *data, u16 size,
u16 ram_offset,
u16 shm_size_offset, u8 rate)
{
u32 i, tmp;
struct b43_plcp_hdr4 plcp;
plcp.data = 0;
b43_generate_plcp_hdr(&plcp, size + FCS_LEN, rate);
b43_ram_write(dev, ram_offset, le32_to_cpu(plcp.data));
ram_offset += sizeof(u32);
tmp = (u32) (data[0]) << 16;
tmp |= (u32) (data[1]) << 24;
b43_ram_write(dev, ram_offset, tmp);
ram_offset += sizeof(u32);
for (i = 2; i < size; i += sizeof(u32)) {
tmp = (u32) (data[i + 0]);
if (i + 1 < size)
tmp |= (u32) (data[i + 1]) << 8;
if (i + 2 < size)
tmp |= (u32) (data[i + 2]) << 16;
if (i + 3 < size)
tmp |= (u32) (data[i + 3]) << 24;
b43_ram_write(dev, ram_offset + i - 2, tmp);
}
b43_shm_write16(dev, B43_SHM_SHARED, shm_size_offset,
size + sizeof(struct b43_plcp_hdr6));
}
u8 b43_ieee80211_antenna_sanitize(struct b43_wldev *dev,
u8 antenna_nr)
{
u8 antenna_mask;
if (antenna_nr == 0) {
return 0;
}
if (dev->phy.gmode)
antenna_mask = dev->dev->bus_sprom->ant_available_bg;
else
antenna_mask = dev->dev->bus_sprom->ant_available_a;
if (!(antenna_mask & (1 << (antenna_nr - 1)))) {
return 0;
}
return antenna_nr;
}
static u16 b43_antenna_to_phyctl(int antenna)
{
switch (antenna) {
case B43_ANTENNA0:
return B43_TXH_PHY_ANT0;
case B43_ANTENNA1:
return B43_TXH_PHY_ANT1;
case B43_ANTENNA2:
return B43_TXH_PHY_ANT2;
case B43_ANTENNA3:
return B43_TXH_PHY_ANT3;
case B43_ANTENNA_AUTO0:
case B43_ANTENNA_AUTO1:
return B43_TXH_PHY_ANT01AUTO;
}
B43_WARN_ON(1);
return 0;
}
static void b43_write_beacon_template(struct b43_wldev *dev,
u16 ram_offset,
u16 shm_size_offset)
{
unsigned int i, len, variable_len;
const struct ieee80211_mgmt *bcn;
const u8 *ie;
bool tim_found = false;
unsigned int rate;
u16 ctl;
int antenna;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(dev->wl->current_beacon);
bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data);
len = min((size_t) dev->wl->current_beacon->len,
0x200 - sizeof(struct b43_plcp_hdr6));
rate = ieee80211_get_tx_rate(dev->wl->hw, info)->hw_value;
b43_write_template_common(dev, (const u8 *)bcn,
len, ram_offset, shm_size_offset, rate);
antenna = B43_ANTENNA_DEFAULT;
antenna = b43_antenna_to_phyctl(antenna);
ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
ctl &= ~B43_TXH_PHY_SHORTPRMBL;
ctl &= ~B43_TXH_PHY_ANT;
ctl &= ~B43_TXH_PHY_ENC;
ctl |= antenna;
if (b43_is_cck_rate(rate))
ctl |= B43_TXH_PHY_ENC_CCK;
else
ctl |= B43_TXH_PHY_ENC_OFDM;
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL, ctl);
ie = bcn->u.beacon.variable;
variable_len = len - offsetof(struct ieee80211_mgmt, u.beacon.variable);
for (i = 0; i < variable_len - 2; ) {
uint8_t ie_id, ie_len;
ie_id = ie[i];
ie_len = ie[i + 1];
if (ie_id == 5) {
u16 tim_position;
u16 dtim_period;
if (variable_len < ie_len + 2 + i)
break;
if (ie_len < 4)
break;
tim_found = true;
tim_position = sizeof(struct b43_plcp_hdr6);
tim_position += offsetof(struct ieee80211_mgmt, u.beacon.variable);
tim_position += i;
dtim_period = ie[i + 3];
b43_shm_write16(dev, B43_SHM_SHARED,
B43_SHM_SH_TIMBPOS, tim_position);
b43_shm_write16(dev, B43_SHM_SHARED,
B43_SHM_SH_DTIMPER, dtim_period);
break;
}
i += ie_len + 2;
}
if (!tim_found) {
b43_shm_write16(dev, B43_SHM_SHARED,
B43_SHM_SH_TIMBPOS,
len + sizeof(struct b43_plcp_hdr6));
b43_shm_write16(dev, B43_SHM_SHARED,
B43_SHM_SH_DTIMPER, 0);
}
b43dbg(dev->wl, "Updated beacon template at 0x%x\n", ram_offset);
}
static void b43_upload_beacon0(struct b43_wldev *dev)
{
struct b43_wl *wl = dev->wl;
if (wl->beacon0_uploaded)
return;
b43_write_beacon_template(dev, B43_SHM_SH_BT_BASE0, B43_SHM_SH_BTL0);
wl->beacon0_uploaded = true;
}
static void b43_upload_beacon1(struct b43_wldev *dev)
{
struct b43_wl *wl = dev->wl;
if (wl->beacon1_uploaded)
return;
b43_write_beacon_template(dev, B43_SHM_SH_BT_BASE1, B43_SHM_SH_BTL1);
wl->beacon1_uploaded = true;
}
static void handle_irq_beacon(struct b43_wldev *dev)
{
struct b43_wl *wl = dev->wl;
u32 cmd, beacon0_valid, beacon1_valid;
if (!b43_is_mode(wl, NL80211_IFTYPE_AP) &&
!b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) &&
!b43_is_mode(wl, NL80211_IFTYPE_ADHOC))
return;
dev->irq_mask &= ~B43_IRQ_BEACON;
cmd = b43_read32(dev, B43_MMIO_MACCMD);
beacon0_valid = (cmd & B43_MACCMD_BEACON0_VALID);
beacon1_valid = (cmd & B43_MACCMD_BEACON1_VALID);
if (beacon0_valid && beacon1_valid) {
b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_BEACON);
dev->irq_mask |= B43_IRQ_BEACON;
return;
}
if (unlikely(wl->beacon_templates_virgin)) {
wl->beacon_templates_virgin = false;
b43_upload_beacon0(dev);
b43_upload_beacon1(dev);
cmd = b43_read32(dev, B43_MMIO_MACCMD);
cmd |= B43_MACCMD_BEACON0_VALID;
b43_write32(dev, B43_MMIO_MACCMD, cmd);
} else {
if (!beacon0_valid) {
b43_upload_beacon0(dev);
cmd = b43_read32(dev, B43_MMIO_MACCMD);
cmd |= B43_MACCMD_BEACON0_VALID;
b43_write32(dev, B43_MMIO_MACCMD, cmd);
} else if (!beacon1_valid) {
b43_upload_beacon1(dev);
cmd = b43_read32(dev, B43_MMIO_MACCMD);
cmd |= B43_MACCMD_BEACON1_VALID;
b43_write32(dev, B43_MMIO_MACCMD, cmd);
}
}
}
static void b43_do_beacon_update_trigger_work(struct b43_wldev *dev)
{
u32 old_irq_mask = dev->irq_mask;
handle_irq_beacon(dev);
if (old_irq_mask != dev->irq_mask) {
B43_WARN_ON(!dev->irq_mask);
if (b43_read32(dev, B43_MMIO_GEN_IRQ_MASK)) {
b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
} else {
}
}
}
static void b43_beacon_update_trigger_work(struct work_struct *work)
{
struct b43_wl *wl = container_of(work, struct b43_wl,
beacon_update_trigger);
struct b43_wldev *dev;
mutex_lock(&wl->mutex);
dev = wl->current_dev;
if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
if (b43_bus_host_is_sdio(dev->dev)) {
b43_do_beacon_update_trigger_work(dev);
mmiowb();
} else {
spin_lock_irq(&wl->hardirq_lock);
b43_do_beacon_update_trigger_work(dev);
mmiowb();
spin_unlock_irq(&wl->hardirq_lock);
}
}
mutex_unlock(&wl->mutex);
}
static void b43_update_templates(struct b43_wl *wl)
{
struct sk_buff *beacon;
beacon = ieee80211_beacon_get(wl->hw, wl->vif);
if (unlikely(!beacon))
return;
if (wl->current_beacon)
dev_kfree_skb_any(wl->current_beacon);
wl->current_beacon = beacon;
wl->beacon0_uploaded = false;
wl->beacon1_uploaded = false;
ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger);
}
static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int)
{
b43_time_lock(dev);
if (dev->dev->core_rev >= 3) {
b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16));
b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10));
} else {
b43_write16(dev, 0x606, (beacon_int >> 6));
b43_write16(dev, 0x610, beacon_int);
}
b43_time_unlock(dev);
b43dbg(dev->wl, "Set beacon interval to %u\n", beacon_int);
}
static void b43_handle_firmware_panic(struct b43_wldev *dev)
{
u16 reason;
reason = b43_shm_read16(dev, B43_SHM_SCRATCH, B43_FWPANIC_REASON_REG);
b43err(dev->wl, "Whoopsy, firmware panic! Reason: %u\n", reason);
switch (reason) {
default:
b43dbg(dev->wl, "The panic reason is unknown.\n");
case B43_FWPANIC_DIE:
break;
case B43_FWPANIC_RESTART:
b43_controller_restart(dev, "Microcode panic");
break;
}
}
static void handle_irq_ucode_debug(struct b43_wldev *dev)
{
unsigned int i, cnt;
u16 reason, marker_id, marker_line;
__le16 *buf;
if (!dev->fw.opensource)
return;
reason = b43_shm_read16(dev, B43_SHM_SCRATCH, B43_DEBUGIRQ_REASON_REG);
switch (reason) {
case B43_DEBUGIRQ_PANIC:
b43_handle_firmware_panic(dev);
break;
case B43_DEBUGIRQ_DUMP_SHM:
if (!B43_DEBUG)
break;
buf = kmalloc(4096, GFP_ATOMIC);
if (!buf) {
b43dbg(dev->wl, "SHM-dump: Failed to allocate memory\n");
goto out;
}
for (i = 0; i < 4096; i += 2) {
u16 tmp = b43_shm_read16(dev, B43_SHM_SHARED, i);
buf[i / 2] = cpu_to_le16(tmp);
}
b43info(dev->wl, "Shared memory dump:\n");
print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET,
16, 2, buf, 4096, 1);
kfree(buf);
break;
case B43_DEBUGIRQ_DUMP_REGS:
if (!B43_DEBUG)
break;
b43info(dev->wl, "Microcode register dump:\n");
for (i = 0, cnt = 0; i < 64; i++) {
u16 tmp = b43_shm_read16(dev, B43_SHM_SCRATCH, i);
if (cnt == 0)
printk(KERN_INFO);
printk("r%02u: 0x%04X ", i, tmp);
cnt++;
if (cnt == 6) {
printk("\n");
cnt = 0;
}
}
printk("\n");
break;
case B43_DEBUGIRQ_MARKER:
if (!B43_DEBUG)
break;
marker_id = b43_shm_read16(dev, B43_SHM_SCRATCH,
B43_MARKER_ID_REG);
marker_line = b43_shm_read16(dev, B43_SHM_SCRATCH,
B43_MARKER_LINE_REG);
b43info(dev->wl, "The firmware just executed the MARKER(%u) "
"at line number %u\n",
marker_id, marker_line);
break;
default:
b43dbg(dev->wl, "Debug-IRQ triggered for unknown reason: %u\n",
reason);
}
out:
b43_shm_write16(dev, B43_SHM_SCRATCH,
B43_DEBUGIRQ_REASON_REG, B43_DEBUGIRQ_ACK);
}
static void b43_do_interrupt_thread(struct b43_wldev *dev)
{
u32 reason;
u32 dma_reason[ARRAY_SIZE(dev->dma_reason)];
u32 merged_dma_reason = 0;
int i;
if (unlikely(b43_status(dev) != B43_STAT_STARTED))
return;
reason = dev->irq_reason;
for (i = 0; i < ARRAY_SIZE(dma_reason); i++) {
dma_reason[i] = dev->dma_reason[i];
merged_dma_reason |= dma_reason[i];
}
if (unlikely(reason & B43_IRQ_MAC_TXERR))
b43err(dev->wl, "MAC transmission error\n");
if (unlikely(reason & B43_IRQ_PHY_TXERR)) {
b43err(dev->wl, "PHY transmission error\n");
rmb();
if (unlikely(atomic_dec_and_test(&dev->phy.txerr_cnt))) {
atomic_set(&dev->phy.txerr_cnt,
B43_PHY_TX_BADNESS_LIMIT);
b43err(dev->wl, "Too many PHY TX errors, "
"restarting the controller\n");
b43_controller_restart(dev, "PHY TX errors");
}
}
if (unlikely(merged_dma_reason & (B43_DMAIRQ_FATALMASK))) {
b43err(dev->wl,
"Fatal DMA error: 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
dma_reason[0], dma_reason[1],
dma_reason[2], dma_reason[3],
dma_reason[4], dma_reason[5]);
b43err(dev->wl, "This device does not support DMA "
"on your system. It will now be switched to PIO.\n");
dev->use_pio = true;
b43_controller_restart(dev, "DMA error");
return;
}
if (unlikely(reason & B43_IRQ_UCODE_DEBUG))
handle_irq_ucode_debug(dev);
if (reason & B43_IRQ_TBTT_INDI)
handle_irq_tbtt_indication(dev);
if (reason & B43_IRQ_ATIM_END)
handle_irq_atim_end(dev);
if (reason & B43_IRQ_BEACON)
handle_irq_beacon(dev);
if (reason & B43_IRQ_PMQ)
handle_irq_pmq(dev);
if (reason & B43_IRQ_TXFIFO_FLUSH_OK)
;
if (reason & B43_IRQ_NOISESAMPLE_OK)
handle_irq_noise(dev);
if (dma_reason[0] & B43_DMAIRQ_RDESC_UFLOW) {
if (B43_DEBUG)
b43warn(dev->wl, "RX descriptor underrun\n");
b43_dma_handle_rx_overflow(dev->dma.rx_ring);
}
if (dma_reason[0] & B43_DMAIRQ_RX_DONE) {
if (b43_using_pio_transfers(dev))
b43_pio_rx(dev->pio.rx_queue);
else
b43_dma_rx(dev->dma.rx_ring);
}
B43_WARN_ON(dma_reason[1] & B43_DMAIRQ_RX_DONE);
B43_WARN_ON(dma_reason[2] & B43_DMAIRQ_RX_DONE);
B43_WARN_ON(dma_reason[3] & B43_DMAIRQ_RX_DONE);
B43_WARN_ON(dma_reason[4] & B43_DMAIRQ_RX_DONE);
B43_WARN_ON(dma_reason[5] & B43_DMAIRQ_RX_DONE);
if (reason & B43_IRQ_TX_OK)
handle_irq_transmit_status(dev);
b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
#if B43_DEBUG
if (b43_debug(dev, B43_DBG_VERBOSESTATS)) {
dev->irq_count++;
for (i = 0; i < ARRAY_SIZE(dev->irq_bit_count); i++) {
if (reason & (1 << i))
dev->irq_bit_count[i]++;
}
}
#endif
}
static irqreturn_t b43_interrupt_thread_handler(int irq, void *dev_id)
{
struct b43_wldev *dev = dev_id;
mutex_lock(&dev->wl->mutex);
b43_do_interrupt_thread(dev);
mmiowb();
mutex_unlock(&dev->wl->mutex);
return IRQ_HANDLED;
}
static irqreturn_t b43_do_interrupt(struct b43_wldev *dev)
{
u32 reason;
reason = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
if (reason == 0xffffffff)
return IRQ_NONE;
reason &= dev->irq_mask;
if (!reason)
return IRQ_NONE;
dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON)
& 0x0001FC00;
dev->dma_reason[1] = b43_read32(dev, B43_MMIO_DMA1_REASON)
& 0x0000DC00;
dev->dma_reason[2] = b43_read32(dev, B43_MMIO_DMA2_REASON)
& 0x0000DC00;
dev->dma_reason[3] = b43_read32(dev, B43_MMIO_DMA3_REASON)
& 0x0001DC00;
dev->dma_reason[4] = b43_read32(dev, B43_MMIO_DMA4_REASON)
& 0x0000DC00;
b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, reason);
b43_write32(dev, B43_MMIO_DMA0_REASON, dev->dma_reason[0]);
b43_write32(dev, B43_MMIO_DMA1_REASON, dev->dma_reason[1]);
b43_write32(dev, B43_MMIO_DMA2_REASON, dev->dma_reason[2]);
b43_write32(dev, B43_MMIO_DMA3_REASON, dev->dma_reason[3]);
b43_write32(dev, B43_MMIO_DMA4_REASON, dev->dma_reason[4]);
b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
dev->irq_reason = reason;
return IRQ_WAKE_THREAD;
}
static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
{
struct b43_wldev *dev = dev_id;
irqreturn_t ret;
if (unlikely(b43_status(dev) < B43_STAT_STARTED))
return IRQ_NONE;
spin_lock(&dev->wl->hardirq_lock);
ret = b43_do_interrupt(dev);
mmiowb();
spin_unlock(&dev->wl->hardirq_lock);
return ret;
}
static void b43_sdio_interrupt_handler(struct b43_wldev *dev)
{
struct b43_wl *wl = dev->wl;
irqreturn_t ret;
mutex_lock(&wl->mutex);
ret = b43_do_interrupt(dev);
if (ret == IRQ_WAKE_THREAD)
b43_do_interrupt_thread(dev);
mutex_unlock(&wl->mutex);
}
void b43_do_release_fw(struct b43_firmware_file *fw)
{
release_firmware(fw->data);
fw->data = NULL;
fw->filename = NULL;
}
static void b43_release_firmware(struct b43_wldev *dev)
{
complete(&dev->fw_load_complete);
b43_do_release_fw(&dev->fw.ucode);
b43_do_release_fw(&dev->fw.pcm);
b43_do_release_fw(&dev->fw.initvals);
b43_do_release_fw(&dev->fw.initvals_band);
}
static void b43_print_fw_helptext(struct b43_wl *wl, bool error)
{
const char text[] =
"You must go to " \
"http://wireless.kernel.org/en/users/Drivers/b43#devicefirmware " \
"and download the correct firmware for this driver version. " \
"Please carefully read all instructions on this website.\n";
if (error)
b43err(wl, text);
else
b43warn(wl, text);
}
static void b43_fw_cb(const struct firmware *firmware, void *context)
{
struct b43_request_fw_context *ctx = context;
ctx->blob = firmware;
complete(&ctx->dev->fw_load_complete);
}
int b43_do_request_fw(struct b43_request_fw_context *ctx,
const char *name,
struct b43_firmware_file *fw, bool async)
{
struct b43_fw_header *hdr;
u32 size;
int err;
if (!name) {
b43_do_release_fw(fw);
return 0;
}
if (fw->filename) {
if ((fw->type == ctx->req_type) &&
(strcmp(fw->filename, name) == 0))
return 0;
b43_do_release_fw(fw);
}
switch (ctx->req_type) {
case B43_FWTYPE_PROPRIETARY:
snprintf(ctx->fwname, sizeof(ctx->fwname),
"b43%s/%s.fw",
modparam_fwpostfix, name);
break;
case B43_FWTYPE_OPENSOURCE:
snprintf(ctx->fwname, sizeof(ctx->fwname),
"b43-open%s/%s.fw",
modparam_fwpostfix, name);
break;
default:
B43_WARN_ON(1);
return -ENOSYS;
}
if (async) {
init_completion(&ctx->dev->fw_load_complete);
err = request_firmware_nowait(THIS_MODULE, 1, ctx->fwname,
ctx->dev->dev->dev, GFP_KERNEL,
ctx, b43_fw_cb);
if (err < 0) {
pr_err("Unable to load firmware\n");
return err;
}
wait_for_completion(&ctx->dev->fw_load_complete);
if (ctx->blob)
goto fw_ready;
}
err = request_firmware(&ctx->blob, ctx->fwname,
ctx->dev->dev->dev);
if (err == -ENOENT) {
snprintf(ctx->errors[ctx->req_type],
sizeof(ctx->errors[ctx->req_type]),
"Firmware file \"%s\" not found\n",
ctx->fwname);
return err;
} else if (err) {
snprintf(ctx->errors[ctx->req_type],
sizeof(ctx->errors[ctx->req_type]),
"Firmware file \"%s\" request failed (err=%d)\n",
ctx->fwname, err);
return err;
}
fw_ready:
if (ctx->blob->size < sizeof(struct b43_fw_header))
goto err_format;
hdr = (struct b43_fw_header *)(ctx->blob->data);
switch (hdr->type) {
case B43_FW_TYPE_UCODE:
case B43_FW_TYPE_PCM:
size = be32_to_cpu(hdr->size);
if (size != ctx->blob->size - sizeof(struct b43_fw_header))
goto err_format;
case B43_FW_TYPE_IV:
if (hdr->ver != 1)
goto err_format;
break;
default:
goto err_format;
}
fw->data = ctx->blob;
fw->filename = name;
fw->type = ctx->req_type;
return 0;
err_format:
snprintf(ctx->errors[ctx->req_type],
sizeof(ctx->errors[ctx->req_type]),
"Firmware file \"%s\" format error.\n", ctx->fwname);
release_firmware(ctx->blob);
return -EPROTO;
}
static int b43_try_request_fw(struct b43_request_fw_context *ctx)
{
struct b43_wldev *dev = ctx->dev;
struct b43_firmware *fw = &ctx->dev->fw;
const u8 rev = ctx->dev->dev->core_rev;
const char *filename;
u32 tmshigh;
int err;
if ((rev >= 5) && (rev <= 10)) {
filename = "ucode5";
} else if ((rev >= 11) && (rev <= 12)) {
filename = "ucode11";
} else if (rev == 13) {
filename = "ucode13";
} else if (rev == 14) {
filename = "ucode14";
} else if (rev == 15) {
filename = "ucode15";
} else {
switch (dev->phy.type) {
case B43_PHYTYPE_N:
if (rev >= 16)
filename = "ucode16_mimo";
else
goto err_no_ucode;
break;
case B43_PHYTYPE_HT:
if (rev == 29)
filename = "ucode29_mimo";
else
goto err_no_ucode;
break;
case B43_PHYTYPE_LCN:
if (rev == 24)
filename = "ucode24_mimo";
else
goto err_no_ucode;
break;
default:
goto err_no_ucode;
}
}
err = b43_do_request_fw(ctx, filename, &fw->ucode, true);
if (err)
goto err_load;
if ((rev >= 5) && (rev <= 10))
filename = "pcm5";
else if (rev >= 11)
filename = NULL;
else
goto err_no_pcm;
fw->pcm_request_failed = false;
err = b43_do_request_fw(ctx, filename, &fw->pcm, false);
if (err == -ENOENT) {
fw->pcm_request_failed = true;
} else if (err)
goto err_load;
switch (dev->phy.type) {
case B43_PHYTYPE_A:
if ((rev >= 5) && (rev <= 10)) {
tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
filename = "a0g1initvals5";
else
filename = "a0g0initvals5";
} else
goto err_no_initvals;
break;
case B43_PHYTYPE_G:
if ((rev >= 5) && (rev <= 10))
filename = "b0g0initvals5";
else if (rev >= 13)
filename = "b0g0initvals13";
else
goto err_no_initvals;
break;
case B43_PHYTYPE_N:
if (rev >= 16)
filename = "n0initvals16";
else if ((rev >= 11) && (rev <= 12))
filename = "n0initvals11";
else
goto err_no_initvals;
break;
case B43_PHYTYPE_LP:
if (rev == 13)
filename = "lp0initvals13";
else if (rev == 14)
filename = "lp0initvals14";
else if (rev >= 15)
filename = "lp0initvals15";
else
goto err_no_initvals;
break;
case B43_PHYTYPE_HT:
if (rev == 29)
filename = "ht0initvals29";
else
goto err_no_initvals;
break;
case B43_PHYTYPE_LCN:
if (rev == 24)
filename = "lcn0initvals24";
else
goto err_no_initvals;
break;
default:
goto err_no_initvals;
}
err = b43_do_request_fw(ctx, filename, &fw->initvals, false);
if (err)
goto err_load;
switch (dev->phy.type) {
case B43_PHYTYPE_A:
if ((rev >= 5) && (rev <= 10)) {
tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
filename = "a0g1bsinitvals5";
else
filename = "a0g0bsinitvals5";
} else if (rev >= 11)
filename = NULL;
else
goto err_no_initvals;
break;
case B43_PHYTYPE_G:
if ((rev >= 5) && (rev <= 10))
filename = "b0g0bsinitvals5";
else if (rev >= 11)
filename = NULL;
else
goto err_no_initvals;
break;
case B43_PHYTYPE_N:
if (rev >= 16)
filename = "n0bsinitvals16";
else if ((rev >= 11) && (rev <= 12))
filename = "n0bsinitvals11";
else
goto err_no_initvals;
break;
case B43_PHYTYPE_LP:
if (rev == 13)
filename = "lp0bsinitvals13";
else if (rev == 14)
filename = "lp0bsinitvals14";
else if (rev >= 15)
filename = "lp0bsinitvals15";
else
goto err_no_initvals;
break;
case B43_PHYTYPE_HT:
if (rev == 29)
filename = "ht0bsinitvals29";
else
goto err_no_initvals;
break;
case B43_PHYTYPE_LCN:
if (rev == 24)
filename = "lcn0bsinitvals24";
else
goto err_no_initvals;
break;
default:
goto err_no_initvals;
}
err = b43_do_request_fw(ctx, filename, &fw->initvals_band, false);
if (err)
goto err_load;
fw->opensource = (ctx->req_type == B43_FWTYPE_OPENSOURCE);
return 0;
err_no_ucode:
err = ctx->fatal_failure = -EOPNOTSUPP;
b43err(dev->wl, "The driver does not know which firmware (ucode) "
"is required for your device (wl-core rev %u)\n", rev);
goto error;
err_no_pcm:
err = ctx->fatal_failure = -EOPNOTSUPP;
b43err(dev->wl, "The driver does not know which firmware (PCM) "
"is required for your device (wl-core rev %u)\n", rev);
goto error;
err_no_initvals:
err = ctx->fatal_failure = -EOPNOTSUPP;
b43err(dev->wl, "The driver does not know which firmware (initvals) "
"is required for your device (wl-core rev %u)\n", rev);
goto error;
err_load:
goto error;
error:
b43_release_firmware(dev);
return err;
}
static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl);
static void b43_one_core_detach(struct b43_bus_dev *dev);
static int b43_rng_init(struct b43_wl *wl);
static void b43_request_firmware(struct work_struct *work)
{
struct b43_wl *wl = container_of(work,
struct b43_wl, firmware_load);
struct b43_wldev *dev = wl->current_dev;
struct b43_request_fw_context *ctx;
unsigned int i;
int err;
const char *errmsg;
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return;
ctx->dev = dev;
ctx->req_type = B43_FWTYPE_PROPRIETARY;
err = b43_try_request_fw(ctx);
if (!err)
goto start_ieee80211;
if (ctx->fatal_failure)
goto out;
ctx->req_type = B43_FWTYPE_OPENSOURCE;
err = b43_try_request_fw(ctx);
if (!err)
goto start_ieee80211;
if(ctx->fatal_failure)
goto out;
for (i = 0; i < B43_NR_FWTYPES; i++) {
errmsg = ctx->errors[i];
if (strlen(errmsg))
b43err(dev->wl, "%s", errmsg);
}
b43_print_fw_helptext(dev->wl, 1);
goto out;
start_ieee80211:
wl->hw->queues = B43_QOS_QUEUE_NUM;
if (!modparam_qos || dev->fw.opensource)
wl->hw->queues = 1;
err = ieee80211_register_hw(wl->hw);
if (err)
goto err_one_core_detach;
wl->hw_registred = true;
b43_leds_register(wl->current_dev);
b43_rng_init(wl);
goto out;
err_one_core_detach:
b43_one_core_detach(dev->dev);
out:
kfree(ctx);
}
static int b43_upload_microcode(struct b43_wldev *dev)
{
struct wiphy *wiphy = dev->wl->hw->wiphy;
const size_t hdr_len = sizeof(struct b43_fw_header);
const __be32 *data;
unsigned int i, len;
u16 fwrev, fwpatch, fwdate, fwtime;
u32 tmp, macctl;
int err = 0;
macctl = b43_read32(dev, B43_MMIO_MACCTL);
B43_WARN_ON(macctl & B43_MACCTL_PSM_RUN);
macctl |= B43_MACCTL_PSM_JMP0;
b43_write32(dev, B43_MMIO_MACCTL, macctl);
for (i = 0; i < 64; i++)
b43_shm_write16(dev, B43_SHM_SCRATCH, i, 0);
for (i = 0; i < 4096; i += 2)
b43_shm_write16(dev, B43_SHM_SHARED, i, 0);
data = (__be32 *) (dev->fw.ucode.data->data + hdr_len);
len = (dev->fw.ucode.data->size - hdr_len) / sizeof(__be32);
b43_shm_control_word(dev, B43_SHM_UCODE | B43_SHM_AUTOINC_W, 0x0000);
for (i = 0; i < len; i++) {
b43_write32(dev, B43_MMIO_SHM_DATA, be32_to_cpu(data[i]));
udelay(10);
}
if (dev->fw.pcm.data) {
data = (__be32 *) (dev->fw.pcm.data->data + hdr_len);
len = (dev->fw.pcm.data->size - hdr_len) / sizeof(__be32);
b43_shm_control_word(dev, B43_SHM_HW, 0x01EA);
b43_write32(dev, B43_MMIO_SHM_DATA, 0x00004000);
b43_shm_control_word(dev, B43_SHM_HW, 0x01EB);
for (i = 0; i < len; i++) {
b43_write32(dev, B43_MMIO_SHM_DATA, be32_to_cpu(data[i]));
udelay(10);
}
}
b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_ALL);
b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_JMP0,
B43_MACCTL_PSM_RUN);
i = 0;
while (1) {
tmp = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
if (tmp == B43_IRQ_MAC_SUSPENDED)
break;
i++;
if (i >= 20) {
b43err(dev->wl, "Microcode not responding\n");
b43_print_fw_helptext(dev->wl, 1);
err = -ENODEV;
goto error;
}
msleep(50);
}
b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
fwrev = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_UCODEREV);
fwpatch = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_UCODEPATCH);
fwdate = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_UCODEDATE);
fwtime = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_UCODETIME);
if (fwrev <= 0x128) {
b43err(dev->wl, "YOUR FIRMWARE IS TOO OLD. Firmware from "
"binary drivers older than version 4.x is unsupported. "
"You must upgrade your firmware files.\n");
b43_print_fw_helptext(dev->wl, 1);
err = -EOPNOTSUPP;
goto error;
}
dev->fw.rev = fwrev;
dev->fw.patch = fwpatch;
if (dev->fw.rev >= 598)
dev->fw.hdr_format = B43_FW_HDR_598;
else if (dev->fw.rev >= 410)
dev->fw.hdr_format = B43_FW_HDR_410;
else
dev->fw.hdr_format = B43_FW_HDR_351;
WARN_ON(dev->fw.opensource != (fwdate == 0xFFFF));
dev->qos_enabled = dev->wl->hw->queues > 1;
dev->hwcrypto_enabled = true;
if (dev->fw.opensource) {
u16 fwcapa;
dev->fw.patch = fwtime;
b43info(dev->wl, "Loading OpenSource firmware version %u.%u\n",
dev->fw.rev, dev->fw.patch);
fwcapa = b43_fwcapa_read(dev);
if (!(fwcapa & B43_FWCAPA_HWCRYPTO) || dev->fw.pcm_request_failed) {
b43info(dev->wl, "Hardware crypto acceleration not supported by firmware\n");
dev->hwcrypto_enabled = false;
}
WARN(fwcapa & B43_FWCAPA_QOS, "QoS in OpenFW not supported\n");
} else {
b43info(dev->wl, "Loading firmware version %u.%u "
"(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
fwrev, fwpatch,
(fwdate >> 12) & 0xF, (fwdate >> 8) & 0xF, fwdate & 0xFF,
(fwtime >> 11) & 0x1F, (fwtime >> 5) & 0x3F, fwtime & 0x1F);
if (dev->fw.pcm_request_failed) {
b43warn(dev->wl, "No \"pcm5.fw\" firmware file found. "
"Hardware accelerated cryptography is disabled.\n");
b43_print_fw_helptext(dev->wl, 0);
}
}
snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u",
dev->fw.rev, dev->fw.patch);
wiphy->hw_version = dev->dev->core_id;
if (dev->fw.hdr_format == B43_FW_HDR_351) {
b43warn(dev->wl, "You are using an old firmware image. "
"Support for old firmware will be removed soon "
"(official deadline was July 2008).\n");
b43_print_fw_helptext(dev->wl, 0);
}
return 0;
error:
b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_RUN,
B43_MACCTL_PSM_JMP0);
return err;
}
static int b43_write_initvals(struct b43_wldev *dev,
const struct b43_iv *ivals,
size_t count,
size_t array_size)
{
const struct b43_iv *iv;
u16 offset;
size_t i;
bool bit32;
BUILD_BUG_ON(sizeof(struct b43_iv) != 6);
iv = ivals;
for (i = 0; i < count; i++) {
if (array_size < sizeof(iv->offset_size))
goto err_format;
array_size -= sizeof(iv->offset_size);
offset = be16_to_cpu(iv->offset_size);
bit32 = !!(offset & B43_IV_32BIT);
offset &= B43_IV_OFFSET_MASK;
if (offset >= 0x1000)
goto err_format;
if (bit32) {
u32 value;
if (array_size < sizeof(iv->data.d32))
goto err_format;
array_size -= sizeof(iv->data.d32);
value = get_unaligned_be32(&iv->data.d32);
b43_write32(dev, offset, value);
iv = (const struct b43_iv *)((const uint8_t *)iv +
sizeof(__be16) +
sizeof(__be32));
} else {
u16 value;
if (array_size < sizeof(iv->data.d16))
goto err_format;
array_size -= sizeof(iv->data.d16);
value = be16_to_cpu(iv->data.d16);
b43_write16(dev, offset, value);
iv = (const struct b43_iv *)((const uint8_t *)iv +
sizeof(__be16) +
sizeof(__be16));
}
}
if (array_size)
goto err_format;
return 0;
err_format:
b43err(dev->wl, "Initial Values Firmware file-format error.\n");
b43_print_fw_helptext(dev->wl, 1);
return -EPROTO;
}
static int b43_upload_initvals(struct b43_wldev *dev)
{
const size_t hdr_len = sizeof(struct b43_fw_header);
const struct b43_fw_header *hdr;
struct b43_firmware *fw = &dev->fw;
const struct b43_iv *ivals;
size_t count;
int err;
hdr = (const struct b43_fw_header *)(fw->initvals.data->data);
ivals = (const struct b43_iv *)(fw->initvals.data->data + hdr_len);
count = be32_to_cpu(hdr->size);
err = b43_write_initvals(dev, ivals, count,
fw->initvals.data->size - hdr_len);
if (err)
goto out;
if (fw->initvals_band.data) {
hdr = (const struct b43_fw_header *)(fw->initvals_band.data->data);
ivals = (const struct b43_iv *)(fw->initvals_band.data->data + hdr_len);
count = be32_to_cpu(hdr->size);
err = b43_write_initvals(dev, ivals, count,
fw->initvals_band.data->size - hdr_len);
if (err)
goto out;
}
out:
return err;
}
static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev)
{
struct ssb_bus *bus = dev->dev->sdev->bus;
#ifdef CONFIG_SSB_DRIVER_PCICORE
return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
#else
return bus->chipco.dev;
#endif
}
static int b43_gpio_init(struct b43_wldev *dev)
{
struct ssb_device *gpiodev;
u32 mask, set;
b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);
b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xF);
mask = 0x0000001F;
set = 0x0000000F;
if (dev->dev->chip_id == 0x4301) {
mask |= 0x0060;
set |= 0x0060;
} else if (dev->dev->chip_id == 0x5354) {
set &= 0x2;
}
if (0 ) {
b43_write16(dev, B43_MMIO_GPIO_MASK,
b43_read16(dev, B43_MMIO_GPIO_MASK)
| 0x0100);
mask |= 0x0080;
set |= 0x0080;
mask |= 0x0100;
set |= 0x0100;
}
if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) {
b43_write16(dev, B43_MMIO_GPIO_MASK,
b43_read16(dev, B43_MMIO_GPIO_MASK)
| 0x0200);
mask |= 0x0200;
set |= 0x0200;
}
switch (dev->dev->bus_type) {
#ifdef CONFIG_B43_BCMA
case B43_BUS_BCMA:
bcma_chipco_gpio_control(&dev->dev->bdev->bus->drv_cc, mask, set);
break;
#endif
#ifdef CONFIG_B43_SSB
case B43_BUS_SSB:
gpiodev = b43_ssb_gpio_dev(dev);
if (gpiodev)
ssb_write32(gpiodev, B43_GPIO_CONTROL,
(ssb_read32(gpiodev, B43_GPIO_CONTROL)
& ~mask) | set);
break;
#endif
}
return 0;
}
static void b43_gpio_cleanup(struct b43_wldev *dev)
{
struct ssb_device *gpiodev;
switch (dev->dev->bus_type) {
#ifdef CONFIG_B43_BCMA
case B43_BUS_BCMA:
bcma_chipco_gpio_control(&dev->dev->bdev->bus->drv_cc, ~0, 0);
break;
#endif
#ifdef CONFIG_B43_SSB
case B43_BUS_SSB:
gpiodev = b43_ssb_gpio_dev(dev);
if (gpiodev)
ssb_write32(gpiodev, B43_GPIO_CONTROL, 0);
break;
#endif
}
}
void b43_mac_enable(struct b43_wldev *dev)
{
if (b43_debug(dev, B43_DBG_FIRMWARE)) {
u16 fwstate;
fwstate = b43_shm_read16(dev, B43_SHM_SHARED,
B43_SHM_SH_UCODESTAT);
if ((fwstate != B43_SHM_SH_UCODESTAT_SUSP) &&
(fwstate != B43_SHM_SH_UCODESTAT_SLEEP)) {
b43err(dev->wl, "b43_mac_enable(): The firmware "
"should be suspended, but current state is %u\n",
fwstate);
}
}
dev->mac_suspended--;
B43_WARN_ON(dev->mac_suspended < 0);
if (dev->mac_suspended == 0) {
b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_ENABLED);
b43_write32(dev, B43_MMIO_GEN_IRQ_REASON,
B43_IRQ_MAC_SUSPENDED);
b43_read32(dev, B43_MMIO_MACCTL);
b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
b43_power_saving_ctl_bits(dev, 0);
}
}
void b43_mac_suspend(struct b43_wldev *dev)
{
int i;
u32 tmp;
might_sleep();
B43_WARN_ON(dev->mac_suspended < 0);
if (dev->mac_suspended == 0) {
b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_ENABLED, 0);
b43_read32(dev, B43_MMIO_MACCTL);
for (i = 35; i; i--) {
tmp = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
if (tmp & B43_IRQ_MAC_SUSPENDED)
goto out;
udelay(10);
}
for (i = 40; i; i--) {
tmp = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
if (tmp & B43_IRQ_MAC_SUSPENDED)
goto out;
msleep(1);
}
b43err(dev->wl, "MAC suspend failed\n");
}
out:
dev->mac_suspended++;
}
void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on)
{
u32 tmp;
switch (dev->dev->bus_type) {
#ifdef CONFIG_B43_BCMA
case B43_BUS_BCMA:
tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
if (on)
tmp |= B43_BCMA_IOCTL_MACPHYCLKEN;
else
tmp &= ~B43_BCMA_IOCTL_MACPHYCLKEN;
bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
break;
#endif
#ifdef CONFIG_B43_SSB
case B43_BUS_SSB:
tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
if (on)
tmp |= B43_TMSLOW_MACPHYCLKEN;
else
tmp &= ~B43_TMSLOW_MACPHYCLKEN;
ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
break;
#endif
}
}
static void b43_adjust_opmode(struct b43_wldev *dev)
{
struct b43_wl *wl = dev->wl;
u32 ctl;
u16 cfp_pretbtt;
ctl = b43_read32(dev, B43_MMIO_MACCTL);
ctl &= ~B43_MACCTL_AP;
ctl &= ~B43_MACCTL_KEEP_CTL;
ctl &= ~B43_MACCTL_KEEP_BADPLCP;
ctl &= ~B43_MACCTL_KEEP_BAD;
ctl &= ~B43_MACCTL_PROMISC;
ctl &= ~B43_MACCTL_BEACPROMISC;
ctl |= B43_MACCTL_INFRA;
if (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT))
ctl |= B43_MACCTL_AP;
else if (b43_is_mode(wl, NL80211_IFTYPE_ADHOC))
ctl &= ~B43_MACCTL_INFRA;
if (wl->filter_flags & FIF_CONTROL)
ctl |= B43_MACCTL_KEEP_CTL;
if (wl->filter_flags & FIF_FCSFAIL)
ctl |= B43_MACCTL_KEEP_BAD;
if (wl->filter_flags & FIF_PLCPFAIL)
ctl |= B43_MACCTL_KEEP_BADPLCP;
if (wl->filter_flags & FIF_PROMISC_IN_BSS)
ctl |= B43_MACCTL_PROMISC;
if (wl->filter_flags & FIF_BCN_PRBRESP_PROMISC)
ctl |= B43_MACCTL_BEACPROMISC;
if (dev->dev->core_rev <= 4)
ctl |= B43_MACCTL_PROMISC;
b43_write32(dev, B43_MMIO_MACCTL, ctl);
cfp_pretbtt = 2;
if ((ctl & B43_MACCTL_INFRA) && !(ctl & B43_MACCTL_AP)) {
if (dev->dev->chip_id == 0x4306 &&
dev->dev->chip_rev == 3)
cfp_pretbtt = 100;
else
cfp_pretbtt = 50;
}
b43_write16(dev, 0x612, cfp_pretbtt);
if (0 )
b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_DISCPMQ, 0);
else
b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_DISCPMQ);
}
static void b43_rate_memory_write(struct b43_wldev *dev, u16 rate, int is_ofdm)
{
u16 offset;
if (is_ofdm) {
offset = 0x480;
offset += (b43_plcp_get_ratecode_ofdm(rate) & 0x000F) * 2;
} else {
offset = 0x4C0;
offset += (b43_plcp_get_ratecode_cck(rate) & 0x000F) * 2;
}
b43_shm_write16(dev, B43_SHM_SHARED, offset + 0x20,
b43_shm_read16(dev, B43_SHM_SHARED, offset));
}
static void b43_rate_memory_init(struct b43_wldev *dev)
{
switch (dev->phy.type) {
case B43_PHYTYPE_A:
case B43_PHYTYPE_G:
case B43_PHYTYPE_N:
case B43_PHYTYPE_LP:
case B43_PHYTYPE_HT:
case B43_PHYTYPE_LCN:
b43_rate_memory_write(dev, B43_OFDM_RATE_6MB, 1);
b43_rate_memory_write(dev, B43_OFDM_RATE_12MB, 1);
b43_rate_memory_write(dev, B43_OFDM_RATE_18MB, 1);
b43_rate_memory_write(dev, B43_OFDM_RATE_24MB, 1);
b43_rate_memory_write(dev, B43_OFDM_RATE_36MB, 1);
b43_rate_memory_write(dev, B43_OFDM_RATE_48MB, 1);
b43_rate_memory_write(dev, B43_OFDM_RATE_54MB, 1);
if (dev->phy.type == B43_PHYTYPE_A)
break;
case B43_PHYTYPE_B:
b43_rate_memory_write(dev, B43_CCK_RATE_1MB, 0);
b43_rate_memory_write(dev, B43_CCK_RATE_2MB, 0);
b43_rate_memory_write(dev, B43_CCK_RATE_5MB, 0);
b43_rate_memory_write(dev, B43_CCK_RATE_11MB, 0);
break;
default:
B43_WARN_ON(1);
}
}
static void b43_set_phytxctl_defaults(struct b43_wldev *dev)
{
u16 ctl = 0;
ctl |= B43_TXH_PHY_ENC_CCK;
ctl |= B43_TXH_PHY_ANT01AUTO;
ctl |= B43_TXH_PHY_TXPWR;
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL, ctl);
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_ACKCTSPHYCTL, ctl);
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PRPHYCTL, ctl);
}
static void b43_mgmtframe_txantenna(struct b43_wldev *dev, int antenna)
{
u16 ant;
u16 tmp;
ant = b43_antenna_to_phyctl(antenna);
tmp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_ACKCTSPHYCTL);
tmp = (tmp & ~B43_TXH_PHY_ANT) | ant;
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_ACKCTSPHYCTL, tmp);
tmp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_PRPHYCTL);
tmp = (tmp & ~B43_TXH_PHY_ANT) | ant;
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PRPHYCTL, tmp);
}
static void b43_chip_exit(struct b43_wldev *dev)
{
b43_phy_exit(dev);
b43_gpio_cleanup(dev);
}
static int b43_chip_init(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
int err;
u32 macctl;
u16 value16;
macctl = B43_MACCTL_IHR_ENABLED | B43_MACCTL_SHM_ENABLED;
if (dev->phy.gmode)
macctl |= B43_MACCTL_GMODE;
macctl |= B43_MACCTL_INFRA;
b43_write32(dev, B43_MMIO_MACCTL, macctl);
err = b43_upload_microcode(dev);
if (err)
goto out;
err = b43_gpio_init(dev);
if (err)
goto out;
err = b43_upload_initvals(dev);
if (err)
goto err_gpio_clean;
phy->ops->switch_analog(dev, 1);
err = b43_phy_init(dev);
if (err)
goto err_gpio_clean;
if (phy->ops->interf_mitigation)
phy->ops->interf_mitigation(dev, B43_INTERFMODE_NONE);
if (phy->ops->set_rx_antenna)
phy->ops->set_rx_antenna(dev, B43_ANTENNA_DEFAULT);
b43_mgmtframe_txantenna(dev, B43_ANTENNA_DEFAULT);
if (phy->type == B43_PHYTYPE_B) {
value16 = b43_read16(dev, 0x005E);
value16 |= 0x0004;
b43_write16(dev, 0x005E, value16);
}
b43_write32(dev, 0x0100, 0x01000000);
if (dev->dev->core_rev < 5)
b43_write32(dev, 0x010C, 0x01000000);
b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_INFRA, 0);
b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_INFRA);
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PRMAXTIME, 0);
b43_adjust_opmode(dev);
if (dev->dev->core_rev < 3) {
b43_write16(dev, 0x060E, 0x0000);
b43_write16(dev, 0x0610, 0x8000);
b43_write16(dev, 0x0604, 0x0000);
b43_write16(dev, 0x0606, 0x0200);
} else {
b43_write32(dev, 0x0188, 0x80000000);
b43_write32(dev, 0x018C, 0x02000000);
}
b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, 0x00004000);
b43_write32(dev, B43_MMIO_DMA0_IRQ_MASK, 0x0001FC00);
b43_write32(dev, B43_MMIO_DMA1_IRQ_MASK, 0x0000DC00);
b43_write32(dev, B43_MMIO_DMA2_IRQ_MASK, 0x0000DC00);
b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00);
b43_write32(dev, B43_MMIO_DMA4_IRQ_MASK, 0x0000DC00);
b43_write32(dev, B43_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
b43_mac_phy_clock_set(dev, true);
switch (dev->dev->bus_type) {
#ifdef CONFIG_B43_BCMA
case B43_BUS_BCMA:
b43_write16(dev, B43_MMIO_POWERUP_DELAY, 0xE74);
break;
#endif
#ifdef CONFIG_B43_SSB
case B43_BUS_SSB:
b43_write16(dev, B43_MMIO_POWERUP_DELAY,
dev->dev->sdev->bus->chipco.fast_pwrup_delay);
break;
#endif
}
err = 0;
b43dbg(dev->wl, "Chip initialized\n");
out:
return err;
err_gpio_clean:
b43_gpio_cleanup(dev);
return err;
}
static void b43_periodic_every60sec(struct b43_wldev *dev)
{
const struct b43_phy_operations *ops = dev->phy.ops;
if (ops->pwork_60sec)
ops->pwork_60sec(dev);
b43_phy_txpower_check(dev, B43_TXPWR_IGNORE_TIME);
}
static void b43_periodic_every30sec(struct b43_wldev *dev)
{
b43_calculate_link_quality(dev);
}
static void b43_periodic_every15sec(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
u16 wdr;
if (dev->fw.opensource) {
wdr = b43_shm_read16(dev, B43_SHM_SCRATCH, B43_WATCHDOG_REG);
if (unlikely(wdr)) {
b43err(dev->wl, "Firmware watchdog: The firmware died!\n");
b43_controller_restart(dev, "Firmware watchdog");
return;
} else {
b43_shm_write16(dev, B43_SHM_SCRATCH,
B43_WATCHDOG_REG, 1);
}
}
if (phy->ops->pwork_15sec)
phy->ops->pwork_15sec(dev);
atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
wmb();
#if B43_DEBUG
if (b43_debug(dev, B43_DBG_VERBOSESTATS)) {
unsigned int i;
b43dbg(dev->wl, "Stats: %7u IRQs/sec, %7u TX/sec, %7u RX/sec\n",
dev->irq_count / 15,
dev->tx_count / 15,
dev->rx_count / 15);
dev->irq_count = 0;
dev->tx_count = 0;
dev->rx_count = 0;
for (i = 0; i < ARRAY_SIZE(dev->irq_bit_count); i++) {
if (dev->irq_bit_count[i]) {
b43dbg(dev->wl, "Stats: %7u IRQ-%02u/sec (0x%08X)\n",
dev->irq_bit_count[i] / 15, i, (1 << i));
dev->irq_bit_count[i] = 0;
}
}
}
#endif
}
static void do_periodic_work(struct b43_wldev *dev)
{
unsigned int state;
state = dev->periodic_state;
if (state % 4 == 0)
b43_periodic_every60sec(dev);
if (state % 2 == 0)
b43_periodic_every30sec(dev);
b43_periodic_every15sec(dev);
}
static void b43_periodic_work_handler(struct work_struct *work)
{
struct b43_wldev *dev = container_of(work, struct b43_wldev,
periodic_work.work);
struct b43_wl *wl = dev->wl;
unsigned long delay;
mutex_lock(&wl->mutex);
if (unlikely(b43_status(dev) != B43_STAT_STARTED))
goto out;
if (b43_debug(dev, B43_DBG_PWORK_STOP))
goto out_requeue;
do_periodic_work(dev);
dev->periodic_state++;
out_requeue:
if (b43_debug(dev, B43_DBG_PWORK_FAST))
delay = msecs_to_jiffies(50);
else
delay = round_jiffies_relative(HZ * 15);
ieee80211_queue_delayed_work(wl->hw, &dev->periodic_work, delay);
out:
mutex_unlock(&wl->mutex);
}
static void b43_periodic_tasks_setup(struct b43_wldev *dev)
{
struct delayed_work *work = &dev->periodic_work;
dev->periodic_state = 0;
INIT_DELAYED_WORK(work, b43_periodic_work_handler);
ieee80211_queue_delayed_work(dev->wl->hw, work, 0);
}
static int b43_validate_chipaccess(struct b43_wldev *dev)
{
u32 v, backup0, backup4;
backup0 = b43_shm_read32(dev, B43_SHM_SHARED, 0);
backup4 = b43_shm_read32(dev, B43_SHM_SHARED, 4);
b43_shm_write32(dev, B43_SHM_SHARED, 0, 0x55AAAA55);
if (b43_shm_read32(dev, B43_SHM_SHARED, 0) != 0x55AAAA55)
goto error;
b43_shm_write32(dev, B43_SHM_SHARED, 0, 0xAA5555AA);
if (b43_shm_read32(dev, B43_SHM_SHARED, 0) != 0xAA5555AA)
goto error;
b43_shm_write16(dev, B43_SHM_SHARED, 0, 0x1122);
b43_shm_write16(dev, B43_SHM_SHARED, 2, 0x3344);
b43_shm_write16(dev, B43_SHM_SHARED, 4, 0x5566);
b43_shm_write16(dev, B43_SHM_SHARED, 6, 0x7788);
if (b43_shm_read32(dev, B43_SHM_SHARED, 2) != 0x55663344)
b43warn(dev->wl, "Unaligned 32bit SHM read access is broken\n");
b43_shm_write32(dev, B43_SHM_SHARED, 2, 0xAABBCCDD);
if (b43_shm_read16(dev, B43_SHM_SHARED, 0) != 0x1122 ||
b43_shm_read16(dev, B43_SHM_SHARED, 2) != 0xCCDD ||
b43_shm_read16(dev, B43_SHM_SHARED, 4) != 0xAABB ||
b43_shm_read16(dev, B43_SHM_SHARED, 6) != 0x7788)
b43warn(dev->wl, "Unaligned 32bit SHM write access is broken\n");
b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0);
b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4);
if ((dev->dev->core_rev >= 3) && (dev->dev->core_rev <= 10)) {
b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA);
b43_write32(dev, B43_MMIO_TSF_CFP_START, 0xCCCCBBBB);
if (b43_read16(dev, B43_MMIO_TSF_CFP_START_LOW) != 0xBBBB)
goto error;
if (b43_read16(dev, B43_MMIO_TSF_CFP_START_HIGH) != 0xCCCC)
goto error;
}
b43_write32(dev, B43_MMIO_TSF_CFP_START, 0);
v = b43_read32(dev, B43_MMIO_MACCTL);
v |= B43_MACCTL_GMODE;
if (v != (B43_MACCTL_GMODE | B43_MACCTL_IHR_ENABLED))
goto error;
return 0;
error:
b43err(dev->wl, "Failed to validate the chipaccess\n");
return -ENODEV;
}
static void b43_security_init(struct b43_wldev *dev)
{
dev->ktp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_KTP);
dev->ktp *= 2;
b43_write16(dev, B43_MMIO_RCMTA_COUNT, B43_NR_PAIRWISE_KEYS);
b43_clear_keys(dev);
}
#ifdef CONFIG_B43_HWRNG
static int b43_rng_read(struct hwrng *rng, u32 *data)
{
struct b43_wl *wl = (struct b43_wl *)rng->priv;
struct b43_wldev *dev;
int count = -ENODEV;
mutex_lock(&wl->mutex);
dev = wl->current_dev;
if (likely(dev && b43_status(dev) >= B43_STAT_INITIALIZED)) {
*data = b43_read16(dev, B43_MMIO_RNG);
count = sizeof(u16);
}
mutex_unlock(&wl->mutex);
return count;
}
#endif
static void b43_rng_exit(struct b43_wl *wl)
{
#ifdef CONFIG_B43_HWRNG
if (wl->rng_initialized)
hwrng_unregister(&wl->rng);
#endif
}
static int b43_rng_init(struct b43_wl *wl)
{
int err = 0;
#ifdef CONFIG_B43_HWRNG
snprintf(wl->rng_name, ARRAY_SIZE(wl->rng_name),
"%s_%s", KBUILD_MODNAME, wiphy_name(wl->hw->wiphy));
wl->rng.name = wl->rng_name;
wl->rng.data_read = b43_rng_read;
wl->rng.priv = (unsigned long)wl;
wl->rng_initialized = true;
err = hwrng_register(&wl->rng);
if (err) {
wl->rng_initialized = false;
b43err(wl, "Failed to register the random "
"number generator (%d)\n", err);
}
#endif
return err;
}
static void b43_tx_work(struct work_struct *work)
{
struct b43_wl *wl = container_of(work, struct b43_wl, tx_work);
struct b43_wldev *dev;
struct sk_buff *skb;
int queue_num;
int err = 0;
mutex_lock(&wl->mutex);
dev = wl->current_dev;
if (unlikely(!dev || b43_status(dev) < B43_STAT_STARTED)) {
mutex_unlock(&wl->mutex);
return;
}
for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++) {
while (skb_queue_len(&wl->tx_queue[queue_num])) {
skb = skb_dequeue(&wl->tx_queue[queue_num]);
if (b43_using_pio_transfers(dev))
err = b43_pio_tx(dev, skb);
else
err = b43_dma_tx(dev, skb);
if (err == -ENOSPC) {
wl->tx_queue_stopped[queue_num] = 1;
ieee80211_stop_queue(wl->hw, queue_num);
skb_queue_head(&wl->tx_queue[queue_num], skb);
break;
}
if (unlikely(err))
ieee80211_free_txskb(wl->hw, skb);
err = 0;
}
if (!err)
wl->tx_queue_stopped[queue_num] = 0;
}
#if B43_DEBUG
dev->tx_count++;
#endif
mutex_unlock(&wl->mutex);
}
static void b43_op_tx(struct ieee80211_hw *hw,
struct ieee80211_tx_control *control,
struct sk_buff *skb)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
if (unlikely(skb->len < 2 + 2 + 6)) {
ieee80211_free_txskb(hw, skb);
return;
}
B43_WARN_ON(skb_shinfo(skb)->nr_frags);
skb_queue_tail(&wl->tx_queue[skb->queue_mapping], skb);
if (!wl->tx_queue_stopped[skb->queue_mapping]) {
ieee80211_queue_work(wl->hw, &wl->tx_work);
} else {
ieee80211_stop_queue(wl->hw, skb->queue_mapping);
}
}
static void b43_qos_params_upload(struct b43_wldev *dev,
const struct ieee80211_tx_queue_params *p,
u16 shm_offset)
{
u16 params[B43_NR_QOSPARAMS];
int bslots, tmp;
unsigned int i;
if (!dev->qos_enabled)
return;
bslots = b43_read16(dev, B43_MMIO_RNG) & p->cw_min;
memset(¶ms, 0, sizeof(params));
params[B43_QOSPARAM_TXOP] = p->txop * 32;
params[B43_QOSPARAM_CWMIN] = p->cw_min;
params[B43_QOSPARAM_CWMAX] = p->cw_max;
params[B43_QOSPARAM_CWCUR] = p->cw_min;
params[B43_QOSPARAM_AIFS] = p->aifs;
params[B43_QOSPARAM_BSLOTS] = bslots;
params[B43_QOSPARAM_REGGAP] = bslots + p->aifs;
for (i = 0; i < ARRAY_SIZE(params); i++) {
if (i == B43_QOSPARAM_STATUS) {
tmp = b43_shm_read16(dev, B43_SHM_SHARED,
shm_offset + (i * 2));
tmp |= 0x100;
b43_shm_write16(dev, B43_SHM_SHARED,
shm_offset + (i * 2),
tmp);
} else {
b43_shm_write16(dev, B43_SHM_SHARED,
shm_offset + (i * 2),
params[i]);
}
}
}
static const u16 b43_qos_shm_offsets[] = {
[0] = B43_QOS_VOICE,
[1] = B43_QOS_VIDEO,
[2] = B43_QOS_BESTEFFORT,
[3] = B43_QOS_BACKGROUND,
};
static void b43_qos_upload_all(struct b43_wldev *dev)
{
struct b43_wl *wl = dev->wl;
struct b43_qos_params *params;
unsigned int i;
if (!dev->qos_enabled)
return;
BUILD_BUG_ON(ARRAY_SIZE(b43_qos_shm_offsets) !=
ARRAY_SIZE(wl->qos_params));
b43_mac_suspend(dev);
for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) {
params = &(wl->qos_params[i]);
b43_qos_params_upload(dev, &(params->p),
b43_qos_shm_offsets[i]);
}
b43_mac_enable(dev);
}
static void b43_qos_clear(struct b43_wl *wl)
{
struct b43_qos_params *params;
unsigned int i;
BUILD_BUG_ON(ARRAY_SIZE(b43_qos_shm_offsets) !=
ARRAY_SIZE(wl->qos_params));
for (i = 0; i < ARRAY_SIZE(wl->qos_params); i++) {
params = &(wl->qos_params[i]);
switch (b43_qos_shm_offsets[i]) {
case B43_QOS_VOICE:
params->p.txop = 0;
params->p.aifs = 2;
params->p.cw_min = 0x0001;
params->p.cw_max = 0x0001;
break;
case B43_QOS_VIDEO:
params->p.txop = 0;
params->p.aifs = 2;
params->p.cw_min = 0x0001;
params->p.cw_max = 0x0001;
break;
case B43_QOS_BESTEFFORT:
params->p.txop = 0;
params->p.aifs = 3;
params->p.cw_min = 0x0001;
params->p.cw_max = 0x03FF;
break;
case B43_QOS_BACKGROUND:
params->p.txop = 0;
params->p.aifs = 7;
params->p.cw_min = 0x0001;
params->p.cw_max = 0x03FF;
break;
default:
B43_WARN_ON(1);
}
}
}
static void b43_qos_init(struct b43_wldev *dev)
{
if (!dev->qos_enabled) {
b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_EDCF);
b43_write16(dev, B43_MMIO_IFSCTL,
b43_read16(dev, B43_MMIO_IFSCTL)
& ~B43_MMIO_IFSCTL_USE_EDCF);
b43dbg(dev->wl, "QoS disabled\n");
return;
}
b43_qos_upload_all(dev);
b43_hf_write(dev, b43_hf_read(dev) | B43_HF_EDCF);
b43_write16(dev, B43_MMIO_IFSCTL,
b43_read16(dev, B43_MMIO_IFSCTL)
| B43_MMIO_IFSCTL_USE_EDCF);
b43dbg(dev->wl, "QoS enabled\n");
}
static int b43_op_conf_tx(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, u16 _queue,
const struct ieee80211_tx_queue_params *params)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
unsigned int queue = (unsigned int)_queue;
int err = -ENODEV;
if (queue >= ARRAY_SIZE(wl->qos_params)) {
return 0;
}
BUILD_BUG_ON(ARRAY_SIZE(b43_qos_shm_offsets) !=
ARRAY_SIZE(wl->qos_params));
mutex_lock(&wl->mutex);
dev = wl->current_dev;
if (unlikely(!dev || (b43_status(dev) < B43_STAT_INITIALIZED)))
goto out_unlock;
memcpy(&(wl->qos_params[queue].p), params, sizeof(*params));
b43_mac_suspend(dev);
b43_qos_params_upload(dev, &(wl->qos_params[queue].p),
b43_qos_shm_offsets[queue]);
b43_mac_enable(dev);
err = 0;
out_unlock:
mutex_unlock(&wl->mutex);
return err;
}
static int b43_op_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
mutex_lock(&wl->mutex);
memcpy(stats, &wl->ieee_stats, sizeof(*stats));
mutex_unlock(&wl->mutex);
return 0;
}
static u64 b43_op_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
u64 tsf;
mutex_lock(&wl->mutex);
dev = wl->current_dev;
if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED))
b43_tsf_read(dev, &tsf);
else
tsf = 0;
mutex_unlock(&wl->mutex);
return tsf;
}
static void b43_op_set_tsf(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, u64 tsf)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
mutex_lock(&wl->mutex);
dev = wl->current_dev;
if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED))
b43_tsf_write(dev, tsf);
mutex_unlock(&wl->mutex);
}
static void b43_put_phy_into_reset(struct b43_wldev *dev)
{
u32 tmp;
switch (dev->dev->bus_type) {
#ifdef CONFIG_B43_BCMA
case B43_BUS_BCMA:
b43err(dev->wl,
"Putting PHY into reset not supported on BCMA\n");
break;
#endif
#ifdef CONFIG_B43_SSB
case B43_BUS_SSB:
tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
tmp &= ~B43_TMSLOW_GMODE;
tmp |= B43_TMSLOW_PHYRESET;
tmp |= SSB_TMSLOW_FGC;
ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
msleep(1);
tmp = ssb_read32(dev->dev->sdev, SSB_TMSLOW);
tmp &= ~SSB_TMSLOW_FGC;
tmp |= B43_TMSLOW_PHYRESET;
ssb_write32(dev->dev->sdev, SSB_TMSLOW, tmp);
msleep(1);
break;
#endif
}
}
static const char *band_to_string(enum ieee80211_band band)
{
switch (band) {
case IEEE80211_BAND_5GHZ:
return "5";
case IEEE80211_BAND_2GHZ:
return "2.4";
default:
break;
}
B43_WARN_ON(1);
return "";
}
static int b43_switch_band(struct b43_wl *wl, struct ieee80211_channel *chan)
{
struct b43_wldev *up_dev = NULL;
struct b43_wldev *down_dev;
struct b43_wldev *d;
int err;
bool uninitialized_var(gmode);
int prev_status;
list_for_each_entry(d, &wl->devlist, list) {
switch (chan->band) {
case IEEE80211_BAND_5GHZ:
if (d->phy.supports_5ghz) {
up_dev = d;
gmode = false;
}
break;
case IEEE80211_BAND_2GHZ:
if (d->phy.supports_2ghz) {
up_dev = d;
gmode = true;
}
break;
default:
B43_WARN_ON(1);
return -EINVAL;
}
if (up_dev)
break;
}
if (!up_dev) {
b43err(wl, "Could not find a device for %s-GHz band operation\n",
band_to_string(chan->band));
return -ENODEV;
}
if ((up_dev == wl->current_dev) &&
(!!wl->current_dev->phy.gmode == !!gmode)) {
return 0;
}
b43dbg(wl, "Switching to %s-GHz band\n",
band_to_string(chan->band));
down_dev = wl->current_dev;
prev_status = b43_status(down_dev);
if (prev_status >= B43_STAT_STARTED)
down_dev = b43_wireless_core_stop(down_dev);
if (prev_status >= B43_STAT_INITIALIZED)
b43_wireless_core_exit(down_dev);
if (down_dev != up_dev) {
b43_put_phy_into_reset(down_dev);
}
up_dev->phy.gmode = gmode;
if (prev_status >= B43_STAT_INITIALIZED) {
err = b43_wireless_core_init(up_dev);
if (err) {
b43err(wl, "Fatal: Could not initialize device for "
"selected %s-GHz band\n",
band_to_string(chan->band));
goto init_failure;
}
}
if (prev_status >= B43_STAT_STARTED) {
err = b43_wireless_core_start(up_dev);
if (err) {
b43err(wl, "Fatal: Could not start device for "
"selected %s-GHz band\n",
band_to_string(chan->band));
b43_wireless_core_exit(up_dev);
goto init_failure;
}
}
B43_WARN_ON(b43_status(up_dev) != prev_status);
wl->current_dev = up_dev;
return 0;
init_failure:
wl->current_dev = NULL;
return err;
}
static void b43_set_retry_limits(struct b43_wldev *dev,
unsigned int short_retry,
unsigned int long_retry)
{
short_retry = min(short_retry, (unsigned int)0xF);
long_retry = min(long_retry, (unsigned int)0xF);
b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_SRLIMIT,
short_retry);
b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_LRLIMIT,
long_retry);
}
static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
struct b43_phy *phy;
struct ieee80211_conf *conf = &hw->conf;
int antenna;
int err = 0;
bool reload_bss = false;
mutex_lock(&wl->mutex);
dev = wl->current_dev;
err = b43_switch_band(wl, conf->chandef.chan);
if (err)
goto out_unlock_mutex;
if (dev != wl->current_dev) {
dev = wl->current_dev;
changed = ~0;
reload_bss = true;
}
phy = &dev->phy;
if (conf_is_ht(conf))
phy->is_40mhz =
(conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf));
else
phy->is_40mhz = false;
b43_mac_suspend(dev);
if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
b43_set_retry_limits(dev, conf->short_frame_max_tx_count,
conf->long_frame_max_tx_count);
changed &= ~IEEE80211_CONF_CHANGE_RETRY_LIMITS;
if (!changed)
goto out_mac_enable;
if (conf->chandef.chan->hw_value != phy->channel)
b43_switch_channel(dev, conf->chandef.chan->hw_value);
dev->wl->radiotap_enabled = !!(conf->flags & IEEE80211_CONF_MONITOR);
if (conf->power_level != 0) {
if (conf->power_level != phy->desired_txpower) {
phy->desired_txpower = conf->power_level;
b43_phy_txpower_check(dev, B43_TXPWR_IGNORE_TIME |
B43_TXPWR_IGNORE_TSSI);
}
}
antenna = B43_ANTENNA_DEFAULT;
b43_mgmtframe_txantenna(dev, antenna);
antenna = B43_ANTENNA_DEFAULT;
if (phy->ops->set_rx_antenna)
phy->ops->set_rx_antenna(dev, antenna);
if (wl->radio_enabled != phy->radio_on) {
if (wl->radio_enabled) {
b43_software_rfkill(dev, false);
b43info(dev->wl, "Radio turned on by software\n");
if (!dev->radio_hw_enable) {
b43info(dev->wl, "The hardware RF-kill button "
"still turns the radio physically off. "
"Press the button to turn it on.\n");
}
} else {
b43_software_rfkill(dev, true);
b43info(dev->wl, "Radio turned off by software\n");
}
}
out_mac_enable:
b43_mac_enable(dev);
out_unlock_mutex:
mutex_unlock(&wl->mutex);
if (wl->vif && reload_bss)
b43_op_bss_info_changed(hw, wl->vif, &wl->vif->bss_conf, ~0);
return err;
}
static void b43_update_basic_rates(struct b43_wldev *dev, u32 brates)
{
struct ieee80211_supported_band *sband =
dev->wl->hw->wiphy->bands[b43_current_band(dev->wl)];
struct ieee80211_rate *rate;
int i;
u16 basic, direct, offset, basic_offset, rateptr;
for (i = 0; i < sband->n_bitrates; i++) {
rate = &sband->bitrates[i];
if (b43_is_cck_rate(rate->hw_value)) {
direct = B43_SHM_SH_CCKDIRECT;
basic = B43_SHM_SH_CCKBASIC;
offset = b43_plcp_get_ratecode_cck(rate->hw_value);
offset &= 0xF;
} else {
direct = B43_SHM_SH_OFDMDIRECT;
basic = B43_SHM_SH_OFDMBASIC;
offset = b43_plcp_get_ratecode_ofdm(rate->hw_value);
offset &= 0xF;
}
rate = ieee80211_get_response_rate(sband, brates, rate->bitrate);
if (b43_is_cck_rate(rate->hw_value)) {
basic_offset = b43_plcp_get_ratecode_cck(rate->hw_value);
basic_offset &= 0xF;
} else {
basic_offset = b43_plcp_get_ratecode_ofdm(rate->hw_value);
basic_offset &= 0xF;
}
rateptr = b43_shm_read16(dev, B43_SHM_SHARED,
direct + 2 * basic_offset);
b43_shm_write16(dev, B43_SHM_SHARED, basic + 2 * offset,
rateptr);
}
}
static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *conf,
u32 changed)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
mutex_lock(&wl->mutex);
dev = wl->current_dev;
if (!dev || b43_status(dev) < B43_STAT_STARTED)
goto out_unlock_mutex;
B43_WARN_ON(wl->vif != vif);
if (changed & BSS_CHANGED_BSSID) {
if (conf->bssid)
memcpy(wl->bssid, conf->bssid, ETH_ALEN);
else
memset(wl->bssid, 0, ETH_ALEN);
}
if (b43_status(dev) >= B43_STAT_INITIALIZED) {
if (changed & BSS_CHANGED_BEACON &&
(b43_is_mode(wl, NL80211_IFTYPE_AP) ||
b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) ||
b43_is_mode(wl, NL80211_IFTYPE_ADHOC)))
b43_update_templates(wl);
if (changed & BSS_CHANGED_BSSID)
b43_write_mac_bssid_templates(dev);
}
b43_mac_suspend(dev);
if (changed & BSS_CHANGED_BEACON_INT &&
(b43_is_mode(wl, NL80211_IFTYPE_AP) ||
b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) ||
b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) &&
conf->beacon_int)
b43_set_beacon_int(dev, conf->beacon_int);
if (changed & BSS_CHANGED_BASIC_RATES)
b43_update_basic_rates(dev, conf->basic_rates);
if (changed & BSS_CHANGED_ERP_SLOT) {
if (conf->use_short_slot)
b43_short_slot_timing_enable(dev);
else
b43_short_slot_timing_disable(dev);
}
b43_mac_enable(dev);
out_unlock_mutex:
mutex_unlock(&wl->mutex);
}
static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct ieee80211_vif *vif, struct ieee80211_sta *sta,
struct ieee80211_key_conf *key)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
u8 algorithm;
u8 index;
int err;
static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
if (modparam_nohwcrypt)
return -ENOSPC;
if ((vif->type == NL80211_IFTYPE_ADHOC ||
vif->type == NL80211_IFTYPE_MESH_POINT) &&
(key->cipher == WLAN_CIPHER_SUITE_TKIP ||
key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
return -EOPNOTSUPP;
}
mutex_lock(&wl->mutex);
dev = wl->current_dev;
err = -ENODEV;
if (!dev || b43_status(dev) < B43_STAT_INITIALIZED)
goto out_unlock;
if (dev->fw.pcm_request_failed || !dev->hwcrypto_enabled) {
err = -EOPNOTSUPP;
goto out_unlock;
}
err = -EINVAL;
switch (key->cipher) {
case WLAN_CIPHER_SUITE_WEP40:
algorithm = B43_SEC_ALGO_WEP40;
break;
case WLAN_CIPHER_SUITE_WEP104:
algorithm = B43_SEC_ALGO_WEP104;
break;
case WLAN_CIPHER_SUITE_TKIP:
algorithm = B43_SEC_ALGO_TKIP;
break;
case WLAN_CIPHER_SUITE_CCMP:
algorithm = B43_SEC_ALGO_AES;
break;
default:
B43_WARN_ON(1);
goto out_unlock;
}
index = (u8) (key->keyidx);
if (index > 3)
goto out_unlock;
switch (cmd) {
case SET_KEY:
if (algorithm == B43_SEC_ALGO_TKIP &&
(!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE) ||
!modparam_hwtkip)) {
err = -EOPNOTSUPP;
goto out_unlock;
}
if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
if (WARN_ON(!sta)) {
err = -EOPNOTSUPP;
goto out_unlock;
}
err = b43_key_write(dev, -1, algorithm,
key->key, key->keylen,
sta->addr, key);
} else {
err = b43_key_write(dev, index, algorithm,
key->key, key->keylen, NULL, key);
}
if (err)
goto out_unlock;
if (algorithm == B43_SEC_ALGO_WEP40 ||
algorithm == B43_SEC_ALGO_WEP104) {
b43_hf_write(dev, b43_hf_read(dev) | B43_HF_USEDEFKEYS);
} else {
b43_hf_write(dev,
b43_hf_read(dev) & ~B43_HF_USEDEFKEYS);
}
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
if (algorithm == B43_SEC_ALGO_TKIP)
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
break;
case DISABLE_KEY: {
err = b43_key_clear(dev, key->hw_key_idx);
if (err)
goto out_unlock;
break;
}
default:
B43_WARN_ON(1);
}
out_unlock:
if (!err) {
b43dbg(wl, "%s hardware based encryption for keyidx: %d, "
"mac: %pM\n",
cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
sta ? sta->addr : bcast_addr);
b43_dump_keymemory(dev);
}
mutex_unlock(&wl->mutex);
return err;
}
static void b43_op_configure_filter(struct ieee80211_hw *hw,
unsigned int changed, unsigned int *fflags,
u64 multicast)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
mutex_lock(&wl->mutex);
dev = wl->current_dev;
if (!dev) {
*fflags = 0;
goto out_unlock;
}
*fflags &= FIF_PROMISC_IN_BSS |
FIF_ALLMULTI |
FIF_FCSFAIL |
FIF_PLCPFAIL |
FIF_CONTROL |
FIF_OTHER_BSS |
FIF_BCN_PRBRESP_PROMISC;
changed &= FIF_PROMISC_IN_BSS |
FIF_ALLMULTI |
FIF_FCSFAIL |
FIF_PLCPFAIL |
FIF_CONTROL |
FIF_OTHER_BSS |
FIF_BCN_PRBRESP_PROMISC;
wl->filter_flags = *fflags;
if (changed && b43_status(dev) >= B43_STAT_INITIALIZED)
b43_adjust_opmode(dev);
out_unlock:
mutex_unlock(&wl->mutex);
}
static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev)
{
struct b43_wl *wl;
struct b43_wldev *orig_dev;
u32 mask;
int queue_num;
if (!dev)
return NULL;
wl = dev->wl;
redo:
if (!dev || b43_status(dev) < B43_STAT_STARTED)
return dev;
mutex_unlock(&wl->mutex);
cancel_delayed_work_sync(&dev->periodic_work);
cancel_work_sync(&wl->tx_work);
mutex_lock(&wl->mutex);
dev = wl->current_dev;
if (!dev || b43_status(dev) < B43_STAT_STARTED) {
return dev;
}
b43_set_status(dev, B43_STAT_INITIALIZED);
if (b43_bus_host_is_sdio(dev->dev)) {
b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
} else {
spin_lock_irq(&wl->hardirq_lock);
b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
spin_unlock_irq(&wl->hardirq_lock);
}
orig_dev = dev;
mutex_unlock(&wl->mutex);
if (b43_bus_host_is_sdio(dev->dev)) {
b43_sdio_free_irq(dev);
} else {
synchronize_irq(dev->dev->irq);
free_irq(dev->dev->irq, dev);
}
mutex_lock(&wl->mutex);
dev = wl->current_dev;
if (!dev)
return dev;
if (dev != orig_dev) {
if (b43_status(dev) >= B43_STAT_STARTED)
goto redo;
return dev;
}
mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
B43_WARN_ON(mask != 0xFFFFFFFF && mask);
for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++) {
while (skb_queue_len(&wl->tx_queue[queue_num])) {
struct sk_buff *skb;
skb = skb_dequeue(&wl->tx_queue[queue_num]);
ieee80211_free_txskb(wl->hw, skb);
}
}
b43_mac_suspend(dev);
b43_leds_exit(dev);
b43dbg(wl, "Wireless interface stopped\n");
return dev;
}
static int b43_wireless_core_start(struct b43_wldev *dev)
{
int err;
B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED);
drain_txstatus_queue(dev);
if (b43_bus_host_is_sdio(dev->dev)) {
err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler);
if (err) {
b43err(dev->wl, "Cannot request SDIO IRQ\n");
goto out;
}
} else {
err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler,
b43_interrupt_thread_handler,
IRQF_SHARED, KBUILD_MODNAME, dev);
if (err) {
b43err(dev->wl, "Cannot request IRQ-%d\n",
dev->dev->irq);
goto out;
}
}
ieee80211_wake_queues(dev->wl->hw);
b43_set_status(dev, B43_STAT_STARTED);
b43_mac_enable(dev);
b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
b43_periodic_tasks_setup(dev);
b43_leds_init(dev);
b43dbg(dev->wl, "Wireless interface started\n");
out:
return err;
}
static char *b43_phy_name(struct b43_wldev *dev, u8 phy_type)
{
switch (phy_type) {
case B43_PHYTYPE_A:
return "A";
case B43_PHYTYPE_B:
return "B";
case B43_PHYTYPE_G:
return "G";
case B43_PHYTYPE_N:
return "N";
case B43_PHYTYPE_LP:
return "LP";
case B43_PHYTYPE_SSLPN:
return "SSLPN";
case B43_PHYTYPE_HT:
return "HT";
case B43_PHYTYPE_LCN:
return "LCN";
case B43_PHYTYPE_LCNXN:
return "LCNXN";
case B43_PHYTYPE_LCN40:
return "LCN40";
case B43_PHYTYPE_AC:
return "AC";
}
return "UNKNOWN";
}
static int b43_phy_versioning(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
u32 tmp;
u8 analog_type;
u8 phy_type;
u8 phy_rev;
u16 radio_manuf;
u16 radio_ver;
u16 radio_rev;
int unsupported = 0;
tmp = b43_read16(dev, B43_MMIO_PHY_VER);
analog_type = (tmp & B43_PHYVER_ANALOG) >> B43_PHYVER_ANALOG_SHIFT;
phy_type = (tmp & B43_PHYVER_TYPE) >> B43_PHYVER_TYPE_SHIFT;
phy_rev = (tmp & B43_PHYVER_VERSION);
switch (phy_type) {
case B43_PHYTYPE_A:
if (phy_rev >= 4)
unsupported = 1;
break;
case B43_PHYTYPE_B:
if (phy_rev != 2 && phy_rev != 4 && phy_rev != 6
&& phy_rev != 7)
unsupported = 1;
break;
case B43_PHYTYPE_G:
if (phy_rev > 9)
unsupported = 1;
break;
#ifdef CONFIG_B43_PHY_N
case B43_PHYTYPE_N:
if (phy_rev > 9)
unsupported = 1;
break;
#endif
#ifdef CONFIG_B43_PHY_LP
case B43_PHYTYPE_LP:
if (phy_rev > 2)
unsupported = 1;
break;
#endif
#ifdef CONFIG_B43_PHY_HT
case B43_PHYTYPE_HT:
if (phy_rev > 1)
unsupported = 1;
break;
#endif
#ifdef CONFIG_B43_PHY_LCN
case B43_PHYTYPE_LCN:
if (phy_rev > 1)
unsupported = 1;
break;
#endif
default:
unsupported = 1;
}
if (unsupported) {
b43err(dev->wl, "FOUND UNSUPPORTED PHY (Analog %u, Type %d (%s), Revision %u)\n",
analog_type, phy_type, b43_phy_name(dev, phy_type),
phy_rev);
return -EOPNOTSUPP;
}
b43info(dev->wl, "Found PHY: Analog %u, Type %d (%s), Revision %u\n",
analog_type, phy_type, b43_phy_name(dev, phy_type), phy_rev);
if (dev->dev->core_rev >= 24) {
u16 radio24[3];
for (tmp = 0; tmp < 3; tmp++) {
b43_write16(dev, B43_MMIO_RADIO24_CONTROL, tmp);
radio24[tmp] = b43_read16(dev, B43_MMIO_RADIO24_DATA);
}
radio_manuf = 0x17F;
radio_ver = (radio24[2] << 8) | radio24[1];
radio_rev = (radio24[0] & 0xF);
} else {
if (dev->dev->chip_id == 0x4317) {
if (dev->dev->chip_rev == 0)
tmp = 0x3205017F;
else if (dev->dev->chip_rev == 1)
tmp = 0x4205017F;
else
tmp = 0x5205017F;
} else {
b43_write16(dev, B43_MMIO_RADIO_CONTROL,
B43_RADIOCTL_ID);
tmp = b43_read16(dev, B43_MMIO_RADIO_DATA_LOW);
b43_write16(dev, B43_MMIO_RADIO_CONTROL,
B43_RADIOCTL_ID);
tmp |= (u32)b43_read16(dev, B43_MMIO_RADIO_DATA_HIGH)
<< 16;
}
radio_manuf = (tmp & 0x00000FFF);
radio_ver = (tmp & 0x0FFFF000) >> 12;
radio_rev = (tmp & 0xF0000000) >> 28;
}
if (radio_manuf != 0x17F )
unsupported = 1;
switch (phy_type) {
case B43_PHYTYPE_A:
if (radio_ver != 0x2060)
unsupported = 1;
if (radio_rev != 1)
unsupported = 1;
if (radio_manuf != 0x17F)
unsupported = 1;
break;
case B43_PHYTYPE_B:
if ((radio_ver & 0xFFF0) != 0x2050)
unsupported = 1;
break;
case B43_PHYTYPE_G:
if (radio_ver != 0x2050)
unsupported = 1;
break;
case B43_PHYTYPE_N:
if (radio_ver != 0x2055 && radio_ver != 0x2056)
unsupported = 1;
break;
case B43_PHYTYPE_LP:
if (radio_ver != 0x2062 && radio_ver != 0x2063)
unsupported = 1;
break;
case B43_PHYTYPE_HT:
if (radio_ver != 0x2059)
unsupported = 1;
break;
case B43_PHYTYPE_LCN:
if (radio_ver != 0x2064)
unsupported = 1;
break;
default:
B43_WARN_ON(1);
}
if (unsupported) {
b43err(dev->wl, "FOUND UNSUPPORTED RADIO "
"(Manuf 0x%X, Version 0x%X, Revision %u)\n",
radio_manuf, radio_ver, radio_rev);
return -EOPNOTSUPP;
}
b43dbg(dev->wl, "Found Radio: Manuf 0x%X, Version 0x%X, Revision %u\n",
radio_manuf, radio_ver, radio_rev);
phy->radio_manuf = radio_manuf;
phy->radio_ver = radio_ver;
phy->radio_rev = radio_rev;
phy->analog = analog_type;
phy->type = phy_type;
phy->rev = phy_rev;
return 0;
}
static void setup_struct_phy_for_init(struct b43_wldev *dev,
struct b43_phy *phy)
{
phy->hardware_power_control = !!modparam_hwpctl;
phy->next_txpwr_check_time = jiffies;
atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
#if B43_DEBUG
phy->phy_locked = false;
phy->radio_locked = false;
#endif
}
static void setup_struct_wldev_for_init(struct b43_wldev *dev)
{
dev->dfq_valid = false;
dev->radio_hw_enable = true;
memset(&dev->stats, 0, sizeof(dev->stats));
setup_struct_phy_for_init(dev, &dev->phy);
dev->irq_reason = 0;
memset(dev->dma_reason, 0, sizeof(dev->dma_reason));
dev->irq_mask = B43_IRQ_MASKTEMPLATE;
if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
dev->irq_mask &= ~B43_IRQ_PHY_TXERR;
dev->mac_suspended = 1;
memset(&dev->noisecalc, 0, sizeof(dev->noisecalc));
}
static void b43_bluetooth_coext_enable(struct b43_wldev *dev)
{
struct ssb_sprom *sprom = dev->dev->bus_sprom;
u64 hf;
if (!modparam_btcoex)
return;
if (!(sprom->boardflags_lo & B43_BFL_BTCOEXIST))
return;
if (dev->phy.type != B43_PHYTYPE_B && !dev->phy.gmode)
return;
hf = b43_hf_read(dev);
if (sprom->boardflags_lo & B43_BFL_BTCMOD)
hf |= B43_HF_BTCOEXALT;
else
hf |= B43_HF_BTCOEX;
b43_hf_write(dev, hf);
}
static void b43_bluetooth_coext_disable(struct b43_wldev *dev)
{
if (!modparam_btcoex)
return;
}
static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev)
{
struct ssb_bus *bus;
u32 tmp;
if (dev->dev->bus_type != B43_BUS_SSB)
return;
bus = dev->dev->sdev->bus;
if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) ||
(bus->chip_id == 0x4312)) {
tmp = ssb_read32(dev->dev->sdev, SSB_IMCFGLO);
tmp &= ~SSB_IMCFGLO_REQTO;
tmp &= ~SSB_IMCFGLO_SERTO;
tmp |= 0x3;
ssb_write32(dev->dev->sdev, SSB_IMCFGLO, tmp);
ssb_commit_settings(bus);
}
}
static void b43_set_synth_pu_delay(struct b43_wldev *dev, bool idle)
{
u16 pu_delay;
if (dev->phy.type == B43_PHYTYPE_A)
pu_delay = 3700;
else
pu_delay = 1050;
if (b43_is_mode(dev->wl, NL80211_IFTYPE_ADHOC) || idle)
pu_delay = 500;
if ((dev->phy.radio_ver == 0x2050) && (dev->phy.radio_rev == 8))
pu_delay = max(pu_delay, (u16)2400);
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_SPUWKUP, pu_delay);
}
static void b43_set_pretbtt(struct b43_wldev *dev)
{
u16 pretbtt;
if (b43_is_mode(dev->wl, NL80211_IFTYPE_ADHOC)) {
pretbtt = 2;
} else {
if (dev->phy.type == B43_PHYTYPE_A)
pretbtt = 120;
else
pretbtt = 250;
}
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PRETBTT, pretbtt);
b43_write16(dev, B43_MMIO_TSF_CFP_PRETBTT, pretbtt);
}
static void b43_wireless_core_exit(struct b43_wldev *dev)
{
B43_WARN_ON(dev && b43_status(dev) > B43_STAT_INITIALIZED);
if (!dev || b43_status(dev) != B43_STAT_INITIALIZED)
return;
b43_set_status(dev, B43_STAT_UNINIT);
b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_RUN,
B43_MACCTL_PSM_JMP0);
switch (dev->dev->bus_type) {
#ifdef CONFIG_B43_BCMA
case B43_BUS_BCMA:
bcma_core_pci_down(dev->dev->bdev->bus);
break;
#endif
#ifdef CONFIG_B43_SSB
case B43_BUS_SSB:
break;
#endif
}
b43_dma_free(dev);
b43_pio_free(dev);
b43_chip_exit(dev);
dev->phy.ops->switch_analog(dev, 0);
if (dev->wl->current_beacon) {
dev_kfree_skb_any(dev->wl->current_beacon);
dev->wl->current_beacon = NULL;
}
b43_device_disable(dev, 0);
b43_bus_may_powerdown(dev);
}
static int b43_wireless_core_init(struct b43_wldev *dev)
{
struct ssb_sprom *sprom = dev->dev->bus_sprom;
struct b43_phy *phy = &dev->phy;
int err;
u64 hf;
B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT);
err = b43_bus_powerup(dev, 0);
if (err)
goto out;
if (!b43_device_is_enabled(dev))
b43_wireless_core_reset(dev, phy->gmode);
setup_struct_wldev_for_init(dev);
phy->ops->prepare_structs(dev);
switch (dev->dev->bus_type) {
#ifdef CONFIG_B43_BCMA
case B43_BUS_BCMA:
bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci[0],
dev->dev->bdev, true);
bcma_core_pci_up(dev->dev->bdev->bus);
break;
#endif
#ifdef CONFIG_B43_SSB
case B43_BUS_SSB:
ssb_pcicore_dev_irqvecs_enable(&dev->dev->sdev->bus->pcicore,
dev->dev->sdev);
break;
#endif
}
b43_imcfglo_timeouts_workaround(dev);
b43_bluetooth_coext_disable(dev);
if (phy->ops->prepare_hardware) {
err = phy->ops->prepare_hardware(dev);
if (err)
goto err_busdown;
}
err = b43_chip_init(dev);
if (err)
goto err_busdown;
b43_shm_write16(dev, B43_SHM_SHARED,
B43_SHM_SH_WLCOREREV, dev->dev->core_rev);
hf = b43_hf_read(dev);
if (phy->type == B43_PHYTYPE_G) {
hf |= B43_HF_SYMW;
if (phy->rev == 1)
hf |= B43_HF_GDCW;
if (sprom->boardflags_lo & B43_BFL_PACTRL)
hf |= B43_HF_OFDMPABOOST;
}
if (phy->radio_ver == 0x2050) {
if (phy->radio_rev == 6)
hf |= B43_HF_4318TSSI;
if (phy->radio_rev < 6)
hf |= B43_HF_VCORECALC;
}
if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
hf |= B43_HF_DSCRQ;
#ifdef CONFIG_SSB_DRIVER_PCICORE
if (dev->dev->bus_type == B43_BUS_SSB &&
dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI &&
dev->dev->sdev->bus->pcicore.dev->id.revision <= 10)
hf |= B43_HF_PCISCW;
#endif
hf &= ~B43_HF_SKCFPUP;
b43_hf_write(dev, hf);
b43_set_retry_limits(dev, B43_DEFAULT_SHORT_RETRY_LIMIT,
B43_DEFAULT_LONG_RETRY_LIMIT);
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_SFFBLIM, 3);
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_LFFBLIM, 2);
b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PRMAXTIME, 1);
b43_rate_memory_init(dev);
b43_set_phytxctl_defaults(dev);
if (phy->type == B43_PHYTYPE_B)
b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0x1F);
else
b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MINCONT, 0xF);
b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
if (b43_bus_host_is_pcmcia(dev->dev) ||
b43_bus_host_is_sdio(dev->dev)) {
dev->__using_pio_transfers = true;
err = b43_pio_init(dev);
} else if (dev->use_pio) {
b43warn(dev->wl, "Forced PIO by use_pio module parameter. "
"This should not be needed and will result in lower "
"performance.\n");
dev->__using_pio_transfers = true;
err = b43_pio_init(dev);
} else {
dev->__using_pio_transfers = false;
err = b43_dma_init(dev);
}
if (err)
goto err_chip_exit;
b43_qos_init(dev);
b43_set_synth_pu_delay(dev, 1);
b43_bluetooth_coext_enable(dev);
b43_bus_powerup(dev, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW));
b43_upload_card_macaddress(dev);
b43_security_init(dev);
ieee80211_wake_queues(dev->wl->hw);
b43_set_status(dev, B43_STAT_INITIALIZED);
out:
return err;
err_chip_exit:
b43_chip_exit(dev);
err_busdown:
b43_bus_may_powerdown(dev);
B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT);
return err;
}
static int b43_op_add_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
int err = -EOPNOTSUPP;
if (vif->type != NL80211_IFTYPE_AP &&
vif->type != NL80211_IFTYPE_MESH_POINT &&
vif->type != NL80211_IFTYPE_STATION &&
vif->type != NL80211_IFTYPE_WDS &&
vif->type != NL80211_IFTYPE_ADHOC)
return -EOPNOTSUPP;
mutex_lock(&wl->mutex);
if (wl->operating)
goto out_mutex_unlock;
b43dbg(wl, "Adding Interface type %d\n", vif->type);
dev = wl->current_dev;
wl->operating = true;
wl->vif = vif;
wl->if_type = vif->type;
memcpy(wl->mac_addr, vif->addr, ETH_ALEN);
b43_adjust_opmode(dev);
b43_set_pretbtt(dev);
b43_set_synth_pu_delay(dev, 0);
b43_upload_card_macaddress(dev);
err = 0;
out_mutex_unlock:
mutex_unlock(&wl->mutex);
if (err == 0)
b43_op_bss_info_changed(hw, vif, &vif->bss_conf, ~0);
return err;
}
static void b43_op_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev = wl->current_dev;
b43dbg(wl, "Removing Interface type %d\n", vif->type);
mutex_lock(&wl->mutex);
B43_WARN_ON(!wl->operating);
B43_WARN_ON(wl->vif != vif);
wl->vif = NULL;
wl->operating = false;
b43_adjust_opmode(dev);
memset(wl->mac_addr, 0, ETH_ALEN);
b43_upload_card_macaddress(dev);
mutex_unlock(&wl->mutex);
}
static int b43_op_start(struct ieee80211_hw *hw)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev = wl->current_dev;
int did_init = 0;
int err = 0;
memset(wl->bssid, 0, ETH_ALEN);
memset(wl->mac_addr, 0, ETH_ALEN);
wl->filter_flags = 0;
wl->radiotap_enabled = false;
b43_qos_clear(wl);
wl->beacon0_uploaded = false;
wl->beacon1_uploaded = false;
wl->beacon_templates_virgin = true;
wl->radio_enabled = true;
mutex_lock(&wl->mutex);
if (b43_status(dev) < B43_STAT_INITIALIZED) {
err = b43_wireless_core_init(dev);
if (err)
goto out_mutex_unlock;
did_init = 1;
}
if (b43_status(dev) < B43_STAT_STARTED) {
err = b43_wireless_core_start(dev);
if (err) {
if (did_init)
b43_wireless_core_exit(dev);
goto out_mutex_unlock;
}
}
wiphy_rfkill_start_polling(hw->wiphy);
out_mutex_unlock:
mutex_unlock(&wl->mutex);
if (!err)
b43_op_config(hw, ~0);
return err;
}
static void b43_op_stop(struct ieee80211_hw *hw)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev = wl->current_dev;
cancel_work_sync(&(wl->beacon_update_trigger));
if (!dev)
goto out;
mutex_lock(&wl->mutex);
if (b43_status(dev) >= B43_STAT_STARTED) {
dev = b43_wireless_core_stop(dev);
if (!dev)
goto out_unlock;
}
b43_wireless_core_exit(dev);
wl->radio_enabled = false;
out_unlock:
mutex_unlock(&wl->mutex);
out:
cancel_work_sync(&(wl->txpower_adjust_work));
}
static int b43_op_beacon_set_tim(struct ieee80211_hw *hw,
struct ieee80211_sta *sta, bool set)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
b43_update_templates(wl);
return 0;
}
static void b43_op_sta_notify(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
enum sta_notify_cmd notify_cmd,
struct ieee80211_sta *sta)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
B43_WARN_ON(!vif || wl->vif != vif);
}
static void b43_op_sw_scan_start_notifier(struct ieee80211_hw *hw)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
mutex_lock(&wl->mutex);
dev = wl->current_dev;
if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED)) {
b43_hf_write(dev, b43_hf_read(dev) | B43_HF_SKCFPUP);
}
mutex_unlock(&wl->mutex);
}
static void b43_op_sw_scan_complete_notifier(struct ieee80211_hw *hw)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev;
mutex_lock(&wl->mutex);
dev = wl->current_dev;
if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED)) {
b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_SKCFPUP);
}
mutex_unlock(&wl->mutex);
}
static int b43_op_get_survey(struct ieee80211_hw *hw, int idx,
struct survey_info *survey)
{
struct b43_wl *wl = hw_to_b43_wl(hw);
struct b43_wldev *dev = wl->current_dev;
struct ieee80211_conf *conf = &hw->conf;
if (idx != 0)
return -ENOENT;
survey->channel = conf->chandef.chan;
survey->filled = SURVEY_INFO_NOISE_DBM;
survey->noise = dev->stats.link_noise;
return 0;
}
static const struct ieee80211_ops b43_hw_ops = {
.tx = b43_op_tx,
.conf_tx = b43_op_conf_tx,
.add_interface = b43_op_add_interface,
.remove_interface = b43_op_remove_interface,
.config = b43_op_config,
.bss_info_changed = b43_op_bss_info_changed,
.configure_filter = b43_op_configure_filter,
.set_key = b43_op_set_key,
.update_tkip_key = b43_op_update_tkip_key,
.get_stats = b43_op_get_stats,
.get_tsf = b43_op_get_tsf,
.set_tsf = b43_op_set_tsf,
.start = b43_op_start,
.stop = b43_op_stop,
.set_tim = b43_op_beacon_set_tim,
.sta_notify = b43_op_sta_notify,
.sw_scan_start = b43_op_sw_scan_start_notifier,
.sw_scan_complete = b43_op_sw_scan_complete_notifier,
.get_survey = b43_op_get_survey,
.rfkill_poll = b43_rfkill_poll,
};
static void b43_chip_reset(struct work_struct *work)
{
struct b43_wldev *dev =
container_of(work, struct b43_wldev, restart_work);
struct b43_wl *wl = dev->wl;
int err = 0;
int prev_status;
mutex_lock(&wl->mutex);
prev_status = b43_status(dev);
if (prev_status >= B43_STAT_STARTED) {
dev = b43_wireless_core_stop(dev);
if (!dev) {
err = -ENODEV;
goto out;
}
}
if (prev_status >= B43_STAT_INITIALIZED)
b43_wireless_core_exit(dev);
if (prev_status >= B43_STAT_INITIALIZED) {
err = b43_wireless_core_init(dev);
if (err)
goto out;
}
if (prev_status >= B43_STAT_STARTED) {
err = b43_wireless_core_start(dev);
if (err) {
b43_wireless_core_exit(dev);
goto out;
}
}
out:
if (err)
wl->current_dev = NULL;
mutex_unlock(&wl->mutex);
if (err) {
b43err(wl, "Controller restart FAILED\n");
return;
}
b43_op_config(wl->hw, ~0);
if (wl->vif)
b43_op_bss_info_changed(wl->hw, wl->vif, &wl->vif->bss_conf, ~0);
b43info(wl, "Controller restarted\n");
}
static int b43_setup_bands(struct b43_wldev *dev,
bool have_2ghz_phy, bool have_5ghz_phy)
{
struct ieee80211_hw *hw = dev->wl->hw;
if (have_2ghz_phy)
hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &b43_band_2GHz;
if (dev->phy.type == B43_PHYTYPE_N) {
if (have_5ghz_phy)
hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_nphy;
} else {
if (have_5ghz_phy)
hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &b43_band_5GHz_aphy;
}
dev->phy.supports_2ghz = have_2ghz_phy;
dev->phy.supports_5ghz = have_5ghz_phy;
return 0;
}
static void b43_wireless_core_detach(struct b43_wldev *dev)
{
b43_release_firmware(dev);
b43_phy_free(dev);
}
static int b43_wireless_core_attach(struct b43_wldev *dev)
{
struct b43_wl *wl = dev->wl;
struct pci_dev *pdev = NULL;
int err;
u32 tmp;
bool have_2ghz_phy = false, have_5ghz_phy = false;
#ifdef CONFIG_B43_SSB
if (dev->dev->bus_type == B43_BUS_SSB &&
dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI)
pdev = dev->dev->sdev->bus->host_pci;
#endif
err = b43_bus_powerup(dev, 0);
if (err) {
b43err(wl, "Bus powerup failed\n");
goto out;
}
switch (dev->dev->bus_type) {
#ifdef CONFIG_B43_BCMA
case B43_BUS_BCMA:
tmp = bcma_aread32(dev->dev->bdev, BCMA_IOST);
have_2ghz_phy = !!(tmp & B43_BCMA_IOST_2G_PHY);
have_5ghz_phy = !!(tmp & B43_BCMA_IOST_5G_PHY);
break;
#endif
#ifdef CONFIG_B43_SSB
case B43_BUS_SSB:
if (dev->dev->core_rev >= 5) {
tmp = ssb_read32(dev->dev->sdev, SSB_TMSHIGH);
have_2ghz_phy = !!(tmp & B43_TMSHIGH_HAVE_2GHZ_PHY);
have_5ghz_phy = !!(tmp & B43_TMSHIGH_HAVE_5GHZ_PHY);
} else
B43_WARN_ON(1);
break;
#endif
}
dev->phy.gmode = have_2ghz_phy;
dev->phy.radio_on = true;
b43_wireless_core_reset(dev, dev->phy.gmode);
err = b43_phy_versioning(dev);
if (err)
goto err_powerdown;
if (!pdev ||
(pdev->device != 0x4312 &&
pdev->device != 0x4319 && pdev->device != 0x4324)) {
have_2ghz_phy = false;
have_5ghz_phy = false;
switch (dev->phy.type) {
case B43_PHYTYPE_A:
have_5ghz_phy = true;
break;
case B43_PHYTYPE_LP:
#if 0
have_5ghz_phy = 1;
#endif
case B43_PHYTYPE_G:
case B43_PHYTYPE_N:
case B43_PHYTYPE_HT:
case B43_PHYTYPE_LCN:
have_2ghz_phy = true;
break;
default:
B43_WARN_ON(1);
}
}
if (dev->phy.type == B43_PHYTYPE_A) {
b43err(wl, "IEEE 802.11a devices are unsupported\n");
err = -EOPNOTSUPP;
goto err_powerdown;
}
if (1 ) {
if (dev->phy.type != B43_PHYTYPE_N &&
dev->phy.type != B43_PHYTYPE_LP) {
have_2ghz_phy = true;
have_5ghz_phy = false;
}
}
err = b43_phy_allocate(dev);
if (err)
goto err_powerdown;
dev->phy.gmode = have_2ghz_phy;
b43_wireless_core_reset(dev, dev->phy.gmode);
err = b43_validate_chipaccess(dev);
if (err)
goto err_phy_free;
err = b43_setup_bands(dev, have_2ghz_phy, have_5ghz_phy);
if (err)
goto err_phy_free;
if (!wl->current_dev)
wl->current_dev = dev;
INIT_WORK(&dev->restart_work, b43_chip_reset);
dev->phy.ops->switch_analog(dev, 0);
b43_device_disable(dev, 0);
b43_bus_may_powerdown(dev);
out:
return err;
err_phy_free:
b43_phy_free(dev);
err_powerdown:
b43_bus_may_powerdown(dev);
return err;
}
static void b43_one_core_detach(struct b43_bus_dev *dev)
{
struct b43_wldev *wldev;
struct b43_wl *wl;
wldev = b43_bus_get_wldev(dev);
wl = wldev->wl;
b43_debugfs_remove_device(wldev);
b43_wireless_core_detach(wldev);
list_del(&wldev->list);
wl->nr_devs--;
b43_bus_set_wldev(dev, NULL);
kfree(wldev);
}
static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl)
{
struct b43_wldev *wldev;
int err = -ENOMEM;
wldev = kzalloc(sizeof(*wldev), GFP_KERNEL);
if (!wldev)
goto out;
wldev->use_pio = b43_modparam_pio;
wldev->dev = dev;
wldev->wl = wl;
b43_set_status(wldev, B43_STAT_UNINIT);
wldev->bad_frames_preempt = modparam_bad_frames_preempt;
INIT_LIST_HEAD(&wldev->list);
err = b43_wireless_core_attach(wldev);
if (err)
goto err_kfree_wldev;
list_add(&wldev->list, &wl->devlist);
wl->nr_devs++;
b43_bus_set_wldev(dev, wldev);
b43_debugfs_add_device(wldev);
out:
return err;
err_kfree_wldev:
kfree(wldev);
return err;
}
#define IS_PDEV(pdev, _vendor, _device, _subvendor, _subdevice) ( \
(pdev->vendor == PCI_VENDOR_ID_##_vendor) && \
(pdev->device == _device) && \
(pdev->subsystem_vendor == PCI_VENDOR_ID_##_subvendor) && \
(pdev->subsystem_device == _subdevice) )
static void b43_sprom_fixup(struct ssb_bus *bus)
{
struct pci_dev *pdev;
if (bus->boardinfo.vendor == SSB_BOARDVENDOR_DELL &&
bus->chip_id == 0x4301 && bus->sprom.board_rev == 0x74)
bus->sprom.boardflags_lo |= B43_BFL_BTCOEXIST;
if (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE &&
bus->boardinfo.type == 0x4E && bus->sprom.board_rev > 0x40)
bus->sprom.boardflags_lo |= B43_BFL_PACTRL;
if (bus->bustype == SSB_BUSTYPE_PCI) {
pdev = bus->host_pci;
if (IS_PDEV(pdev, BROADCOM, 0x4318, ASUSTEK, 0x100F) ||
IS_PDEV(pdev, BROADCOM, 0x4320, DELL, 0x0003) ||
IS_PDEV(pdev, BROADCOM, 0x4320, HP, 0x12f8) ||
IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0015) ||
IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0014) ||
IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0013) ||
IS_PDEV(pdev, BROADCOM, 0x4320, MOTOROLA, 0x7010))
bus->sprom.boardflags_lo &= ~B43_BFL_BTCOEXIST;
}
}
static void b43_wireless_exit(struct b43_bus_dev *dev, struct b43_wl *wl)
{
struct ieee80211_hw *hw = wl->hw;
ssb_set_devtypedata(dev->sdev, NULL);
ieee80211_free_hw(hw);
}
static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev)
{
struct ssb_sprom *sprom = dev->bus_sprom;
struct ieee80211_hw *hw;
struct b43_wl *wl;
char chip_name[6];
int queue_num;
hw = ieee80211_alloc_hw(sizeof(*wl), &b43_hw_ops);
if (!hw) {
b43err(NULL, "Could not allocate ieee80211 device\n");
return ERR_PTR(-ENOMEM);
}
wl = hw_to_b43_wl(hw);
hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
IEEE80211_HW_SIGNAL_DBM;
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_AP) |
BIT(NL80211_IFTYPE_MESH_POINT) |
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_WDS) |
BIT(NL80211_IFTYPE_ADHOC);
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
wl->hw_registred = false;
hw->max_rates = 2;
SET_IEEE80211_DEV(hw, dev->dev);
if (is_valid_ether_addr(sprom->et1mac))
SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac);
else
SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac);
wl->hw = hw;
mutex_init(&wl->mutex);
spin_lock_init(&wl->hardirq_lock);
INIT_LIST_HEAD(&wl->devlist);
INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work);
INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work);
INIT_WORK(&wl->tx_work, b43_tx_work);
for (queue_num = 0; queue_num < B43_QOS_QUEUE_NUM; queue_num++) {
skb_queue_head_init(&wl->tx_queue[queue_num]);
wl->tx_queue_stopped[queue_num] = 0;
}
snprintf(chip_name, ARRAY_SIZE(chip_name),
(dev->chip_id > 0x9999) ? "%d" : "%04X", dev->chip_id);
b43info(wl, "Broadcom %s WLAN found (core revision %u)\n", chip_name,
dev->core_rev);
return wl;
}
#ifdef CONFIG_B43_BCMA
static int b43_bcma_probe(struct bcma_device *core)
{
struct b43_bus_dev *dev;
struct b43_wl *wl;
int err;
if (!modparam_allhwsupport &&
(core->id.rev == 0x17 || core->id.rev == 0x18)) {
pr_err("Support for cores revisions 0x17 and 0x18 disabled by module param allhwsupport=0. Try b43.allhwsupport=1\n");
return -ENOTSUPP;
}
dev = b43_bus_dev_bcma_init(core);
if (!dev)
return -ENODEV;
wl = b43_wireless_init(dev);
if (IS_ERR(wl)) {
err = PTR_ERR(wl);
goto bcma_out;
}
err = b43_one_core_attach(dev, wl);
if (err)
goto bcma_err_wireless_exit;
INIT_WORK(&wl->firmware_load, b43_request_firmware);
schedule_work(&wl->firmware_load);
bcma_out:
return err;
bcma_err_wireless_exit:
ieee80211_free_hw(wl->hw);
return err;
}
static void b43_bcma_remove(struct bcma_device *core)
{
struct b43_wldev *wldev = bcma_get_drvdata(core);
struct b43_wl *wl = wldev->wl;
cancel_work_sync(&wldev->restart_work);
cancel_work_sync(&wl->firmware_load);
B43_WARN_ON(!wl);
if (!wldev->fw.ucode.data)
return;
if (wl->current_dev == wldev && wl->hw_registred) {
b43_leds_stop(wldev);
ieee80211_unregister_hw(wl->hw);
}
b43_one_core_detach(wldev->dev);
b43_rng_exit(wl);
b43_leds_unregister(wl);
ieee80211_free_hw(wl->hw);
}
static struct bcma_driver b43_bcma_driver = {
.name = KBUILD_MODNAME,
.id_table = b43_bcma_tbl,
.probe = b43_bcma_probe,
.remove = b43_bcma_remove,
};
#endif
#ifdef CONFIG_B43_SSB
static
int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id)
{
struct b43_bus_dev *dev;
struct b43_wl *wl;
int err;
int first = 0;
dev = b43_bus_dev_ssb_init(sdev);
if (!dev)
return -ENOMEM;
wl = ssb_get_devtypedata(sdev);
if (!wl) {
first = 1;
b43_sprom_fixup(sdev->bus);
wl = b43_wireless_init(dev);
if (IS_ERR(wl)) {
err = PTR_ERR(wl);
goto out;
}
ssb_set_devtypedata(sdev, wl);
B43_WARN_ON(ssb_get_devtypedata(sdev) != wl);
}
err = b43_one_core_attach(dev, wl);
if (err)
goto err_wireless_exit;
INIT_WORK(&wl->firmware_load, b43_request_firmware);
schedule_work(&wl->firmware_load);
out:
return err;
err_wireless_exit:
if (first)
b43_wireless_exit(dev, wl);
return err;
}
static void b43_ssb_remove(struct ssb_device *sdev)
{
struct b43_wl *wl = ssb_get_devtypedata(sdev);
struct b43_wldev *wldev = ssb_get_drvdata(sdev);
struct b43_bus_dev *dev = wldev->dev;
cancel_work_sync(&wldev->restart_work);
cancel_work_sync(&wl->firmware_load);
B43_WARN_ON(!wl);
if (!wldev->fw.ucode.data)
return;
if (wl->current_dev == wldev && wl->hw_registred) {
b43_leds_stop(wldev);
ieee80211_unregister_hw(wl->hw);
}
b43_one_core_detach(dev);
b43_rng_exit(wl);
if (list_empty(&wl->devlist)) {
b43_leds_unregister(wl);
b43_wireless_exit(dev, wl);
}
}
static struct ssb_driver b43_ssb_driver = {
.name = KBUILD_MODNAME,
.id_table = b43_ssb_tbl,
.probe = b43_ssb_probe,
.remove = b43_ssb_remove,
};
#endif
void b43_controller_restart(struct b43_wldev *dev, const char *reason)
{
if (b43_status(dev) < B43_STAT_INITIALIZED)
return;
b43info(dev->wl, "Controller RESET (%s) ...\n", reason);
ieee80211_queue_work(dev->wl->hw, &dev->restart_work);
}
static void b43_print_driverinfo(void)
{
const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "",
*feat_leds = "", *feat_sdio = "";
#ifdef CONFIG_B43_PCI_AUTOSELECT
feat_pci = "P";
#endif
#ifdef CONFIG_B43_PCMCIA
feat_pcmcia = "M";
#endif
#ifdef CONFIG_B43_PHY_N
feat_nphy = "N";
#endif
#ifdef CONFIG_B43_LEDS
feat_leds = "L";
#endif
#ifdef CONFIG_B43_SDIO
feat_sdio = "S";
#endif
printk(KERN_INFO "Broadcom 43xx driver loaded "
"[ Features: %s%s%s%s%s ]\n",
feat_pci, feat_pcmcia, feat_nphy,
feat_leds, feat_sdio);
}
static int __init b43_init(void)
{
int err;
b43_debugfs_init();
err = b43_pcmcia_init();
if (err)
goto err_dfs_exit;
err = b43_sdio_init();
if (err)
goto err_pcmcia_exit;
#ifdef CONFIG_B43_BCMA
err = bcma_driver_register(&b43_bcma_driver);
if (err)
goto err_sdio_exit;
#endif
#ifdef CONFIG_B43_SSB
err = ssb_driver_register(&b43_ssb_driver);
if (err)
goto err_bcma_driver_exit;
#endif
b43_print_driverinfo();
return err;
#ifdef CONFIG_B43_SSB
err_bcma_driver_exit:
#endif
#ifdef CONFIG_B43_BCMA
bcma_driver_unregister(&b43_bcma_driver);
err_sdio_exit:
#endif
b43_sdio_exit();
err_pcmcia_exit:
b43_pcmcia_exit();
err_dfs_exit:
b43_debugfs_exit();
return err;
}
static void __exit b43_exit(void)
{
#ifdef CONFIG_B43_SSB
ssb_driver_unregister(&b43_ssb_driver);
#endif
#ifdef CONFIG_B43_BCMA
bcma_driver_unregister(&b43_bcma_driver);
#endif
b43_sdio_exit();
b43_pcmcia_exit();
b43_debugfs_exit();
}
module_init(b43_init)
module_exit(b43_exit)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
- 470
- 471
- 472
- 473
- 474
- 475
- 476
- 477
- 478
- 479
- 480
- 481
- 482
- 483
- 484
- 485
- 486
- 487
- 488
- 489
- 490
- 491
- 492
- 493
- 494
- 495
- 496
- 497
- 498
- 499
- 500
- 501
- 502
- 503
- 504
- 505
- 506
- 507
- 508
- 509
- 510
- 511
- 512
- 513
- 514
- 515
- 516
- 517
- 518
- 519
- 520
- 521
- 522
- 523
- 524
- 525
- 526
- 527
- 528
- 529
- 530
- 531
- 532
- 533
- 534
- 535
- 536
- 537
- 538
- 539
- 540
- 541
- 542
- 543
- 544
- 545
- 546
- 547
- 548
- 549
- 550
- 551
- 552
- 553
- 554
- 555
- 556
- 557
- 558
- 559
- 560
- 561
- 562
- 563
- 564
- 565
- 566
- 567
- 568
- 569
- 570
- 571
- 572
- 573
- 574
- 575
- 576
- 577
- 578
- 579
- 580
- 581
- 582
- 583
- 584
- 585
- 586
- 587
- 588
- 589
- 590
- 591
- 592
- 593
- 594
- 595
- 596
- 597
- 598
- 599
- 600
- 601
- 602
- 603
- 604
- 605
- 606
- 607
- 608
- 609
- 610
- 611
- 612
- 613
- 614
- 615
- 616
- 617
- 618
- 619
- 620
- 621
- 622
- 623
- 624
- 625
- 626
- 627
- 628
- 629
- 630
- 631
- 632
- 633
- 634
- 635
- 636
- 637
- 638
- 639
- 640
- 641
- 642
- 643
- 644
- 645
- 646
- 647
- 648
- 649
- 650
- 651
- 652
- 653
- 654
- 655
- 656
- 657
- 658
- 659
- 660
- 661
- 662
- 663
- 664
- 665
- 666
- 667
- 668
- 669
- 670
- 671
- 672
- 673
- 674
- 675
- 676
- 677
- 678
- 679
- 680
- 681
- 682
- 683
- 684
- 685
- 686
- 687
- 688
- 689
- 690
- 691
- 692
- 693
- 694
- 695
- 696
- 697
- 698
- 699
- 700
- 701
- 702
- 703
- 704
- 705
- 706
- 707
- 708
- 709
- 710
- 711
- 712
- 713
- 714
- 715
- 716
- 717
- 718
- 719
- 720
- 721
- 722
- 723
- 724
- 725
- 726
- 727
- 728
- 729
- 730
- 731
- 732
- 733
- 734
- 735
- 736
- 737
- 738
- 739
- 740
- 741
- 742
- 743
- 744
- 745
- 746
- 747
- 748
- 749
- 750
- 751
- 752
- 753
- 754
- 755
- 756
- 757
- 758
- 759
- 760
- 761
- 762
- 763
- 764
- 765
- 766
- 767
- 768
- 769
- 770
- 771
- 772
- 773
- 774
- 775
- 776
- 777
- 778
- 779
- 780
- 781
- 782
- 783
- 784
- 785
- 786
- 787
- 788
- 789
- 790
- 791
- 792
- 793
- 794
- 795
- 796
- 797
- 798
- 799
- 800
- 801
- 802
- 803
- 804
- 805
- 806
- 807
- 808
- 809
- 810
- 811
- 812
- 813
- 814
- 815
- 816
- 817
- 818
- 819
- 820
- 821
- 822
- 823
- 824
- 825
- 826
- 827
- 828
- 829
- 830
- 831
- 832
- 833
- 834
- 835
- 836
- 837
- 838
- 839
- 840
- 841
- 842
- 843
- 844
- 845
- 846
- 847
- 848
- 849
- 850
- 851
- 852
- 853
- 854
- 855
- 856
- 857
- 858
- 859
- 860
- 861
- 862
- 863
- 864
- 865
- 866
- 867
- 868
- 869
- 870
- 871
- 872
- 873
- 874
- 875
- 876
- 877
- 878
- 879
- 880
- 881
- 882
- 883
- 884
- 885
- 886
- 887
- 888
- 889
- 890
- 891
- 892
- 893
- 894
- 895
- 896
- 897
- 898
- 899
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 908
- 909
- 910
- 911
- 912
- 913
- 914
- 915
- 916
- 917
- 918
- 919
- 920
- 921
- 922
- 923
- 924
- 925
- 926
- 927
- 928
- 929
- 930
- 931
- 932
- 933
- 934
- 935
- 936
- 937
- 938
- 939
- 940
- 941
- 942
- 943
- 944
- 945
- 946
- 947
- 948
- 949
- 950
- 951
- 952
- 953
- 954
- 955
- 956
- 957
- 958
- 959
- 960
- 961
- 962
- 963
- 964
- 965
- 966
- 967
- 968
- 969
- 970
- 971
- 972
- 973
- 974
- 975
- 976
- 977
- 978
- 979
- 980
- 981
- 982
- 983
- 984
- 985
- 986
- 987
- 988
- 989
- 990
- 991
- 992
- 993
- 994
- 995
- 996
- 997
- 998
- 999
- 1000
- 1001
- 1002
- 1003
- 1004
- 1005
- 1006
- 1007
- 1008
- 1009
- 1010
- 1011
- 1012
- 1013
- 1014
- 1015
- 1016
- 1017
- 1018
- 1019
- 1020
- 1021
- 1022
- 1023
- 1024
- 1025
- 1026
- 1027
- 1028
- 1029
- 1030
- 1031
- 1032
- 1033
- 1034
- 1035
- 1036
- 1037
- 1038
- 1039
- 1040
- 1041
- 1042
- 1043
- 1044
- 1045
- 1046
- 1047
- 1048
- 1049
- 1050
- 1051
- 1052
- 1053
- 1054
- 1055
- 1056
- 1057
- 1058
- 1059
- 1060
- 1061
- 1062
- 1063
- 1064
- 1065
- 1066
- 1067
- 1068
- 1069
- 1070
- 1071
- 1072
- 1073
- 1074
- 1075
- 1076
- 1077
- 1078
- 1079
- 1080
- 1081
- 1082
- 1083
- 1084
- 1085
- 1086
- 1087
- 1088
- 1089
- 1090
- 1091
- 1092
- 1093
- 1094
- 1095
- 1096
- 1097
- 1098
- 1099
- 1100
- 1101
- 1102
- 1103
- 1104
- 1105
- 1106
- 1107
- 1108
- 1109
- 1110
- 1111
- 1112
- 1113
- 1114
- 1115
- 1116
- 1117
- 1118
- 1119
- 1120
- 1121
- 1122
- 1123
- 1124
- 1125
- 1126
- 1127
- 1128
- 1129
- 1130
- 1131
- 1132
- 1133
- 1134
- 1135
- 1136
- 1137
- 1138
- 1139
- 1140
- 1141
- 1142
- 1143
- 1144
- 1145
- 1146
- 1147
- 1148
- 1149
- 1150
- 1151
- 1152
- 1153
- 1154
- 1155
- 1156
- 1157
- 1158
- 1159
- 1160
- 1161
- 1162
- 1163
- 1164
- 1165
- 1166
- 1167
- 1168
- 1169
- 1170
- 1171
- 1172
- 1173
- 1174
- 1175
- 1176
- 1177
- 1178
- 1179
- 1180
- 1181
- 1182
- 1183
- 1184
- 1185
- 1186
- 1187
- 1188
- 1189
- 1190
- 1191
- 1192
- 1193
- 1194
- 1195
- 1196
- 1197
- 1198
- 1199
- 1200
- 1201
- 1202
- 1203
- 1204
- 1205
- 1206
- 1207
- 1208
- 1209
- 1210
- 1211
- 1212
- 1213
- 1214
- 1215
- 1216
- 1217
- 1218
- 1219
- 1220
- 1221
- 1222
- 1223
- 1224
- 1225
- 1226
- 1227
- 1228
- 1229
- 1230
- 1231
- 1232
- 1233
- 1234
- 1235
- 1236
- 1237
- 1238
- 1239
- 1240
- 1241
- 1242
- 1243
- 1244
- 1245
- 1246
- 1247
- 1248
- 1249
- 1250
- 1251
- 1252
- 1253
- 1254
- 1255
- 1256
- 1257
- 1258
- 1259
- 1260
- 1261
- 1262
- 1263
- 1264
- 1265
- 1266
- 1267
- 1268
- 1269
- 1270
- 1271
- 1272
- 1273
- 1274
- 1275
- 1276
- 1277
- 1278
- 1279
- 1280
- 1281
- 1282
- 1283
- 1284
- 1285
- 1286
- 1287
- 1288
- 1289
- 1290
- 1291
- 1292
- 1293
- 1294
- 1295
- 1296
- 1297
- 1298
- 1299
- 1300
- 1301
- 1302
- 1303
- 1304
- 1305
- 1306
- 1307
- 1308
- 1309
- 1310
- 1311
- 1312
- 1313
- 1314
- 1315
- 1316
- 1317
- 1318
- 1319
- 1320
- 1321
- 1322
- 1323
- 1324
- 1325
- 1326
- 1327
- 1328
- 1329
- 1330
- 1331
- 1332
- 1333
- 1334
- 1335
- 1336
- 1337
- 1338
- 1339
- 1340
- 1341
- 1342
- 1343
- 1344
- 1345
- 1346
- 1347
- 1348
- 1349
- 1350
- 1351
- 1352
- 1353
- 1354
- 1355
- 1356
- 1357
- 1358
- 1359
- 1360
- 1361
- 1362
- 1363
- 1364
- 1365
- 1366
- 1367
- 1368
- 1369
- 1370
- 1371
- 1372
- 1373
- 1374
- 1375
- 1376
- 1377
- 1378
- 1379
- 1380
- 1381
- 1382
- 1383
- 1384
- 1385
- 1386
- 1387
- 1388
- 1389
- 1390
- 1391
- 1392
- 1393
- 1394
- 1395
- 1396
- 1397
- 1398
- 1399
- 1400
- 1401
- 1402
- 1403
- 1404
- 1405
- 1406
- 1407
- 1408
- 1409
- 1410
- 1411
- 1412
- 1413
- 1414
- 1415
- 1416
- 1417
- 1418
- 1419
- 1420
- 1421
- 1422
- 1423
- 1424
- 1425
- 1426
- 1427
- 1428
- 1429
- 1430
- 1431
- 1432
- 1433
- 1434
- 1435
- 1436
- 1437
- 1438
- 1439
- 1440
- 1441
- 1442
- 1443
- 1444
- 1445
- 1446
- 1447
- 1448
- 1449
- 1450
- 1451
- 1452
- 1453
- 1454
- 1455
- 1456
- 1457
- 1458
- 1459
- 1460
- 1461
- 1462
- 1463
- 1464
- 1465
- 1466
- 1467
- 1468
- 1469
- 1470
- 1471
- 1472
- 1473
- 1474
- 1475
- 1476
- 1477
- 1478
- 1479
- 1480
- 1481
- 1482
- 1483
- 1484
- 1485
- 1486
- 1487
- 1488
- 1489
- 1490
- 1491
- 1492
- 1493
- 1494
- 1495
- 1496
- 1497
- 1498
- 1499
- 1500
- 1501
- 1502
- 1503
- 1504
- 1505
- 1506
- 1507
- 1508
- 1509
- 1510
- 1511
- 1512
- 1513
- 1514
- 1515
- 1516
- 1517
- 1518
- 1519
- 1520
- 1521
- 1522
- 1523
- 1524
- 1525
- 1526
- 1527
- 1528
- 1529
- 1530
- 1531
- 1532
- 1533
- 1534
- 1535
- 1536
- 1537
- 1538
- 1539
- 1540
- 1541
- 1542
- 1543
- 1544
- 1545
- 1546
- 1547
- 1548
- 1549
- 1550
- 1551
- 1552
- 1553
- 1554
- 1555
- 1556
- 1557
- 1558
- 1559
- 1560
- 1561
- 1562
- 1563
- 1564
- 1565
- 1566
- 1567
- 1568
- 1569
- 1570
- 1571
- 1572
- 1573
- 1574
- 1575
- 1576
- 1577
- 1578
- 1579
- 1580
- 1581
- 1582
- 1583
- 1584
- 1585
- 1586
- 1587
- 1588
- 1589
- 1590
- 1591
- 1592
- 1593
- 1594
- 1595
- 1596
- 1597
- 1598
- 1599
- 1600
- 1601
- 1602
- 1603
- 1604
- 1605
- 1606
- 1607
- 1608
- 1609
- 1610
- 1611
- 1612
- 1613
- 1614
- 1615
- 1616
- 1617
- 1618
- 1619
- 1620
- 1621
- 1622
- 1623
- 1624
- 1625
- 1626
- 1627
- 1628
- 1629
- 1630
- 1631
- 1632
- 1633
- 1634
- 1635
- 1636
- 1637
- 1638
- 1639
- 1640
- 1641
- 1642
- 1643
- 1644
- 1645
- 1646
- 1647
- 1648
- 1649
- 1650
- 1651
- 1652
- 1653
- 1654
- 1655
- 1656
- 1657
- 1658
- 1659
- 1660
- 1661
- 1662
- 1663
- 1664
- 1665
- 1666
- 1667
- 1668
- 1669
- 1670
- 1671
- 1672
- 1673
- 1674
- 1675
- 1676
- 1677
- 1678
- 1679
- 1680
- 1681
- 1682
- 1683
- 1684
- 1685
- 1686
- 1687
- 1688
- 1689
- 1690
- 1691
- 1692
- 1693
- 1694
- 1695
- 1696
- 1697
- 1698
- 1699
- 1700
- 1701
- 1702
- 1703
- 1704
- 1705
- 1706
- 1707
- 1708
- 1709
- 1710
- 1711
- 1712
- 1713
- 1714
- 1715
- 1716
- 1717
- 1718
- 1719
- 1720
- 1721
- 1722
- 1723
- 1724
- 1725
- 1726
- 1727
- 1728
- 1729
- 1730
- 1731
- 1732
- 1733
- 1734
- 1735
- 1736
- 1737
- 1738
- 1739
- 1740
- 1741
- 1742
- 1743
- 1744
- 1745
- 1746
- 1747
- 1748
- 1749
- 1750
- 1751
- 1752
- 1753
- 1754
- 1755
- 1756
- 1757
- 1758
- 1759
- 1760
- 1761
- 1762
- 1763
- 1764
- 1765
- 1766
- 1767
- 1768
- 1769
- 1770
- 1771
- 1772
- 1773
- 1774
- 1775
- 1776
- 1777
- 1778
- 1779
- 1780
- 1781
- 1782
- 1783
- 1784
- 1785
- 1786
- 1787
- 1788
- 1789
- 1790
- 1791
- 1792
- 1793
- 1794
- 1795
- 1796
- 1797
- 1798
- 1799
- 1800
- 1801
- 1802
- 1803
- 1804
- 1805
- 1806
- 1807
- 1808
- 1809
- 1810
- 1811
- 1812
- 1813
- 1814
- 1815
- 1816
- 1817
- 1818
- 1819
- 1820
- 1821
- 1822
- 1823
- 1824
- 1825
- 1826
- 1827
- 1828
- 1829
- 1830
- 1831
- 1832
- 1833
- 1834
- 1835
- 1836
- 1837
- 1838
- 1839
- 1840
- 1841
- 1842
- 1843
- 1844
- 1845
- 1846
- 1847
- 1848
- 1849
- 1850
- 1851
- 1852
- 1853
- 1854
- 1855
- 1856
- 1857
- 1858
- 1859
- 1860
- 1861
- 1862
- 1863
- 1864
- 1865
- 1866
- 1867
- 1868
- 1869
- 1870
- 1871
- 1872
- 1873
- 1874
- 1875
- 1876
- 1877
- 1878
- 1879
- 1880
- 1881
- 1882
- 1883
- 1884
- 1885
- 1886
- 1887
- 1888
- 1889
- 1890
- 1891
- 1892
- 1893
- 1894
- 1895
- 1896
- 1897
- 1898
- 1899
- 1900
- 1901
- 1902
- 1903
- 1904
- 1905
- 1906
- 1907
- 1908
- 1909
- 1910
- 1911
- 1912
- 1913
- 1914
- 1915
- 1916
- 1917
- 1918
- 1919
- 1920
- 1921
- 1922
- 1923
- 1924
- 1925
- 1926
- 1927
- 1928
- 1929
- 1930
- 1931
- 1932
- 1933
- 1934
- 1935
- 1936
- 1937
- 1938
- 1939
- 1940
- 1941
- 1942
- 1943
- 1944
- 1945
- 1946
- 1947
- 1948
- 1949
- 1950
- 1951
- 1952
- 1953
- 1954
- 1955
- 1956
- 1957
- 1958
- 1959
- 1960
- 1961
- 1962
- 1963
- 1964
- 1965
- 1966
- 1967
- 1968
- 1969
- 1970
- 1971
- 1972
- 1973
- 1974
- 1975
- 1976
- 1977
- 1978
- 1979
- 1980
- 1981
- 1982
- 1983
- 1984
- 1985
- 1986
- 1987
- 1988
- 1989
- 1990
- 1991
- 1992
- 1993
- 1994
- 1995
- 1996
- 1997
- 1998
- 1999
- 2000
- 2001
- 2002
- 2003
- 2004
- 2005
- 2006
- 2007
- 2008
- 2009
- 2010
- 2011
- 2012
- 2013
- 2014
- 2015
- 2016
- 2017
- 2018
- 2019
- 2020
- 2021
- 2022
- 2023
- 2024
- 2025
- 2026
- 2027
- 2028
- 2029
- 2030
- 2031
- 2032
- 2033
- 2034
- 2035
- 2036
- 2037
- 2038
- 2039
- 2040
- 2041
- 2042
- 2043
- 2044
- 2045
- 2046
- 2047
- 2048
- 2049
- 2050
- 2051
- 2052
- 2053
- 2054
- 2055
- 2056
- 2057
- 2058
- 2059
- 2060
- 2061
- 2062
- 2063
- 2064
- 2065
- 2066
- 2067
- 2068
- 2069
- 2070
- 2071
- 2072
- 2073
- 2074
- 2075
- 2076
- 2077
- 2078
- 2079
- 2080
- 2081
- 2082
- 2083
- 2084
- 2085
- 2086
- 2087
- 2088
- 2089
- 2090
- 2091
- 2092
- 2093
- 2094
- 2095
- 2096
- 2097
- 2098
- 2099
- 2100
- 2101
- 2102
- 2103
- 2104
- 2105
- 2106
- 2107
- 2108
- 2109
- 2110
- 2111
- 2112
- 2113
- 2114
- 2115
- 2116
- 2117
- 2118
- 2119
- 2120
- 2121
- 2122
- 2123
- 2124
- 2125
- 2126
- 2127
- 2128
- 2129
- 2130
- 2131
- 2132
- 2133
- 2134
- 2135
- 2136
- 2137
- 2138
- 2139
- 2140
- 2141
- 2142
- 2143
- 2144
- 2145
- 2146
- 2147
- 2148
- 2149
- 2150
- 2151
- 2152
- 2153
- 2154
- 2155
- 2156
- 2157
- 2158
- 2159
- 2160
- 2161
- 2162
- 2163
- 2164
- 2165
- 2166
- 2167
- 2168
- 2169
- 2170
- 2171
- 2172
- 2173
- 2174
- 2175
- 2176
- 2177
- 2178
- 2179
- 2180
- 2181
- 2182
- 2183
- 2184
- 2185
- 2186
- 2187
- 2188
- 2189
- 2190
- 2191
- 2192
- 2193
- 2194
- 2195
- 2196
- 2197
- 2198
- 2199
- 2200
- 2201
- 2202
- 2203
- 2204
- 2205
- 2206
- 2207
- 2208
- 2209
- 2210
- 2211
- 2212
- 2213
- 2214
- 2215
- 2216
- 2217
- 2218
- 2219
- 2220
- 2221
- 2222
- 2223
- 2224
- 2225
- 2226
- 2227
- 2228
- 2229
- 2230
- 2231
- 2232
- 2233
- 2234
- 2235
- 2236
- 2237
- 2238
- 2239
- 2240
- 2241
- 2242
- 2243
- 2244
- 2245
- 2246
- 2247
- 2248
- 2249
- 2250
- 2251
- 2252
- 2253
- 2254
- 2255
- 2256
- 2257
- 2258
- 2259
- 2260
- 2261
- 2262
- 2263
- 2264
- 2265
- 2266
- 2267
- 2268
- 2269
- 2270
- 2271
- 2272
- 2273
- 2274
- 2275
- 2276
- 2277
- 2278
- 2279
- 2280
- 2281
- 2282
- 2283
- 2284
- 2285
- 2286
- 2287
- 2288
- 2289
- 2290
- 2291
- 2292
- 2293
- 2294
- 2295
- 2296
- 2297
- 2298
- 2299
- 2300
- 2301
- 2302
- 2303
- 2304
- 2305
- 2306
- 2307
- 2308
- 2309
- 2310
- 2311
- 2312
- 2313
- 2314
- 2315
- 2316
- 2317
- 2318
- 2319
- 2320
- 2321
- 2322
- 2323
- 2324
- 2325
- 2326
- 2327
- 2328
- 2329
- 2330
- 2331
- 2332
- 2333
- 2334
- 2335
- 2336
- 2337
- 2338
- 2339
- 2340
- 2341
- 2342
- 2343
- 2344
- 2345
- 2346
- 2347
- 2348
- 2349
- 2350
- 2351
- 2352
- 2353
- 2354
- 2355
- 2356
- 2357
- 2358
- 2359
- 2360
- 2361
- 2362
- 2363
- 2364
- 2365
- 2366
- 2367
- 2368
- 2369
- 2370
- 2371
- 2372
- 2373
- 2374
- 2375
- 2376
- 2377
- 2378
- 2379
- 2380
- 2381
- 2382
- 2383
- 2384
- 2385
- 2386
- 2387
- 2388
- 2389
- 2390
- 2391
- 2392
- 2393
- 2394
- 2395
- 2396
- 2397
- 2398
- 2399
- 2400
- 2401
- 2402
- 2403
- 2404
- 2405
- 2406
- 2407
- 2408
- 2409
- 2410
- 2411
- 2412
- 2413
- 2414
- 2415
- 2416
- 2417
- 2418
- 2419
- 2420
- 2421
- 2422
- 2423
- 2424
- 2425
- 2426
- 2427
- 2428
- 2429
- 2430
- 2431
- 2432
- 2433
- 2434
- 2435
- 2436
- 2437
- 2438
- 2439
- 2440
- 2441
- 2442
- 2443
- 2444
- 2445
- 2446
- 2447
- 2448
- 2449
- 2450
- 2451
- 2452
- 2453
- 2454
- 2455
- 2456
- 2457
- 2458
- 2459
- 2460
- 2461
- 2462
- 2463
- 2464
- 2465
- 2466
- 2467
- 2468
- 2469
- 2470
- 2471
- 2472
- 2473
- 2474
- 2475
- 2476
- 2477
- 2478
- 2479
- 2480
- 2481
- 2482
- 2483
- 2484
- 2485
- 2486
- 2487
- 2488
- 2489
- 2490
- 2491
- 2492
- 2493
- 2494
- 2495
- 2496
- 2497
- 2498
- 2499
- 2500
- 2501
- 2502
- 2503
- 2504
- 2505
- 2506
- 2507
- 2508
- 2509
- 2510
- 2511
- 2512
- 2513
- 2514
- 2515
- 2516
- 2517
- 2518
- 2519
- 2520
- 2521
- 2522
- 2523
- 2524
- 2525
- 2526
- 2527
- 2528
- 2529
- 2530
- 2531
- 2532
- 2533
- 2534
- 2535
- 2536
- 2537
- 2538
- 2539
- 2540
- 2541
- 2542
- 2543
- 2544
- 2545
- 2546
- 2547
- 2548
- 2549
- 2550
- 2551
- 2552
- 2553
- 2554
- 2555
- 2556
- 2557
- 2558
- 2559
- 2560
- 2561
- 2562
- 2563
- 2564
- 2565
- 2566
- 2567
- 2568
- 2569
- 2570
- 2571
- 2572
- 2573
- 2574
- 2575
- 2576
- 2577
- 2578
- 2579
- 2580
- 2581
- 2582
- 2583
- 2584
- 2585
- 2586
- 2587
- 2588
- 2589
- 2590
- 2591
- 2592
- 2593
- 2594
- 2595
- 2596
- 2597
- 2598
- 2599
- 2600
- 2601
- 2602
- 2603
- 2604
- 2605
- 2606
- 2607
- 2608
- 2609
- 2610
- 2611
- 2612
- 2613
- 2614
- 2615
- 2616
- 2617
- 2618
- 2619
- 2620
- 2621
- 2622
- 2623
- 2624
- 2625
- 2626
- 2627
- 2628
- 2629
- 2630
- 2631
- 2632
- 2633
- 2634
- 2635
- 2636
- 2637
- 2638
- 2639
- 2640
- 2641
- 2642
- 2643
- 2644
- 2645
- 2646
- 2647
- 2648
- 2649
- 2650
- 2651
- 2652
- 2653
- 2654
- 2655
- 2656
- 2657
- 2658
- 2659
- 2660
- 2661
- 2662
- 2663
- 2664
- 2665
- 2666
- 2667
- 2668
- 2669
- 2670
- 2671
- 2672
- 2673
- 2674
- 2675
- 2676
- 2677
- 2678
- 2679
- 2680
- 2681
- 2682
- 2683
- 2684
- 2685
- 2686
- 2687
- 2688
- 2689
- 2690
- 2691
- 2692
- 2693
- 2694
- 2695
- 2696
- 2697
- 2698
- 2699
- 2700
- 2701
- 2702
- 2703
- 2704
- 2705
- 2706
- 2707
- 2708
- 2709
- 2710
- 2711
- 2712
- 2713
- 2714
- 2715
- 2716
- 2717
- 2718
- 2719
- 2720
- 2721
- 2722
- 2723
- 2724
- 2725
- 2726
- 2727
- 2728
- 2729
- 2730
- 2731
- 2732
- 2733
- 2734
- 2735
- 2736
- 2737
- 2738
- 2739
- 2740
- 2741
- 2742
- 2743
- 2744
- 2745
- 2746
- 2747
- 2748
- 2749
- 2750
- 2751
- 2752
- 2753
- 2754
- 2755
- 2756
- 2757
- 2758
- 2759
- 2760
- 2761
- 2762
- 2763
- 2764
- 2765
- 2766
- 2767
- 2768
- 2769
- 2770
- 2771
- 2772
- 2773
- 2774
- 2775
- 2776
- 2777
- 2778
- 2779
- 2780
- 2781
- 2782
- 2783
- 2784
- 2785
- 2786
- 2787
- 2788
- 2789
- 2790
- 2791
- 2792
- 2793
- 2794
- 2795
- 2796
- 2797
- 2798
- 2799
- 2800
- 2801
- 2802
- 2803
- 2804
- 2805
- 2806
- 2807
- 2808
- 2809
- 2810
- 2811
- 2812
- 2813
- 2814
- 2815
- 2816
- 2817
- 2818
- 2819
- 2820
- 2821
- 2822
- 2823
- 2824
- 2825
- 2826
- 2827
- 2828
- 2829
- 2830
- 2831
- 2832
- 2833
- 2834
- 2835
- 2836
- 2837
- 2838
- 2839
- 2840
- 2841
- 2842
- 2843
- 2844
- 2845
- 2846
- 2847
- 2848
- 2849
- 2850
- 2851
- 2852
- 2853
- 2854
- 2855
- 2856
- 2857
- 2858
- 2859
- 2860
- 2861
- 2862
- 2863
- 2864
- 2865
- 2866
- 2867
- 2868
- 2869
- 2870
- 2871
- 2872
- 2873
- 2874
- 2875
- 2876
- 2877
- 2878
- 2879
- 2880
- 2881
- 2882
- 2883
- 2884
- 2885
- 2886
- 2887
- 2888
- 2889
- 2890
- 2891
- 2892
- 2893
- 2894
- 2895
- 2896
- 2897
- 2898
- 2899
- 2900
- 2901
- 2902
- 2903
- 2904
- 2905
- 2906
- 2907
- 2908
- 2909
- 2910
- 2911
- 2912
- 2913
- 2914
- 2915
- 2916
- 2917
- 2918
- 2919
- 2920
- 2921
- 2922
- 2923
- 2924
- 2925
- 2926
- 2927
- 2928
- 2929
- 2930
- 2931
- 2932
- 2933
- 2934
- 2935
- 2936
- 2937
- 2938
- 2939
- 2940
- 2941
- 2942
- 2943
- 2944
- 2945
- 2946
- 2947
- 2948
- 2949
- 2950
- 2951
- 2952
- 2953
- 2954
- 2955
- 2956
- 2957
- 2958
- 2959
- 2960
- 2961
- 2962
- 2963
- 2964
- 2965
- 2966
- 2967
- 2968
- 2969
- 2970
- 2971
- 2972
- 2973
- 2974
- 2975
- 2976
- 2977
- 2978
- 2979
- 2980
- 2981
- 2982
- 2983
- 2984
- 2985
- 2986
- 2987
- 2988
- 2989
- 2990
- 2991
- 2992
- 2993
- 2994
- 2995
- 2996
- 2997
- 2998
- 2999
- 3000
- 3001
- 3002
- 3003
- 3004
- 3005
- 3006
- 3007
- 3008
- 3009
- 3010
- 3011
- 3012
- 3013
- 3014
- 3015
- 3016
- 3017
- 3018
- 3019
- 3020
- 3021
- 3022
- 3023
- 3024
- 3025
- 3026
- 3027
- 3028
- 3029
- 3030
- 3031
- 3032
- 3033
- 3034
- 3035
- 3036
- 3037
- 3038
- 3039
- 3040
- 3041
- 3042
- 3043
- 3044
- 3045
- 3046
- 3047
- 3048
- 3049
- 3050
- 3051
- 3052
- 3053
- 3054
- 3055
- 3056
- 3057
- 3058
- 3059
- 3060
- 3061
- 3062
- 3063
- 3064
- 3065
- 3066
- 3067
- 3068
- 3069
- 3070
- 3071
- 3072
- 3073
- 3074
- 3075
- 3076
- 3077
- 3078
- 3079
- 3080
- 3081
- 3082
- 3083
- 3084
- 3085
- 3086
- 3087
- 3088
- 3089
- 3090
- 3091
- 3092
- 3093
- 3094
- 3095
- 3096
- 3097
- 3098
- 3099
- 3100
- 3101
- 3102
- 3103
- 3104
- 3105
- 3106
- 3107
- 3108
- 3109
- 3110
- 3111
- 3112
- 3113
- 3114
- 3115
- 3116
- 3117
- 3118
- 3119
- 3120
- 3121
- 3122
- 3123
- 3124
- 3125
- 3126
- 3127
- 3128
- 3129
- 3130
- 3131
- 3132
- 3133
- 3134
- 3135
- 3136
- 3137
- 3138
- 3139
- 3140
- 3141
- 3142
- 3143
- 3144
- 3145
- 3146
- 3147
- 3148
- 3149
- 3150
- 3151
- 3152
- 3153
- 3154
- 3155
- 3156
- 3157
- 3158
- 3159
- 3160
- 3161
- 3162
- 3163
- 3164
- 3165
- 3166
- 3167
- 3168
- 3169
- 3170
- 3171
- 3172
- 3173
- 3174
- 3175
- 3176
- 3177
- 3178
- 3179
- 3180
- 3181
- 3182
- 3183
- 3184
- 3185
- 3186
- 3187
- 3188
- 3189
- 3190
- 3191
- 3192
- 3193
- 3194
- 3195
- 3196
- 3197
- 3198
- 3199
- 3200
- 3201
- 3202
- 3203
- 3204
- 3205
- 3206
- 3207
- 3208
- 3209
- 3210
- 3211
- 3212
- 3213
- 3214
- 3215
- 3216
- 3217
- 3218
- 3219
- 3220
- 3221
- 3222
- 3223
- 3224
- 3225
- 3226
- 3227
- 3228
- 3229
- 3230
- 3231
- 3232
- 3233
- 3234
- 3235
- 3236
- 3237
- 3238
- 3239
- 3240
- 3241
- 3242
- 3243
- 3244
- 3245
- 3246
- 3247
- 3248
- 3249
- 3250
- 3251
- 3252
- 3253
- 3254
- 3255
- 3256
- 3257
- 3258
- 3259
- 3260
- 3261
- 3262
- 3263
- 3264
- 3265
- 3266
- 3267
- 3268
- 3269
- 3270
- 3271
- 3272
- 3273
- 3274
- 3275
- 3276
- 3277
- 3278
- 3279
- 3280
- 3281
- 3282
- 3283
- 3284
- 3285
- 3286
- 3287
- 3288
- 3289
- 3290
- 3291
- 3292
- 3293
- 3294
- 3295
- 3296
- 3297
- 3298
- 3299
- 3300
- 3301
- 3302
- 3303
- 3304
- 3305
- 3306
- 3307
- 3308
- 3309
- 3310
- 3311
- 3312
- 3313
- 3314
- 3315
- 3316
- 3317
- 3318
- 3319
- 3320
- 3321
- 3322
- 3323
- 3324
- 3325
- 3326
- 3327
- 3328
- 3329
- 3330
- 3331
- 3332
- 3333
- 3334
- 3335
- 3336
- 3337
- 3338
- 3339
- 3340
- 3341
- 3342
- 3343
- 3344
- 3345
- 3346
- 3347
- 3348
- 3349
- 3350
- 3351
- 3352
- 3353
- 3354
- 3355
- 3356
- 3357
- 3358
- 3359
- 3360
- 3361
- 3362
- 3363
- 3364
- 3365
- 3366
- 3367
- 3368
- 3369
- 3370
- 3371
- 3372
- 3373
- 3374
- 3375
- 3376
- 3377
- 3378
- 3379
- 3380
- 3381
- 3382
- 3383
- 3384
- 3385
- 3386
- 3387
- 3388
- 3389
- 3390
- 3391
- 3392
- 3393
- 3394
- 3395
- 3396
- 3397
- 3398
- 3399
- 3400
- 3401
- 3402
- 3403
- 3404
- 3405
- 3406
- 3407
- 3408
- 3409
- 3410
- 3411
- 3412
- 3413
- 3414
- 3415
- 3416
- 3417
- 3418
- 3419
- 3420
- 3421
- 3422
- 3423
- 3424
- 3425
- 3426
- 3427
- 3428
- 3429
- 3430
- 3431
- 3432
- 3433
- 3434
- 3435
- 3436
- 3437
- 3438
- 3439
- 3440
- 3441
- 3442
- 3443
- 3444
- 3445
- 3446
- 3447
- 3448
- 3449
- 3450
- 3451
- 3452
- 3453
- 3454
- 3455
- 3456
- 3457
- 3458
- 3459
- 3460
- 3461
- 3462
- 3463
- 3464
- 3465
- 3466
- 3467
- 3468
- 3469
- 3470
- 3471
- 3472
- 3473
- 3474
- 3475
- 3476
- 3477
- 3478
- 3479
- 3480
- 3481
- 3482
- 3483
- 3484
- 3485
- 3486
- 3487
- 3488
- 3489
- 3490
- 3491
- 3492
- 3493
- 3494
- 3495
- 3496
- 3497
- 3498
- 3499
- 3500
- 3501
- 3502
- 3503
- 3504
- 3505
- 3506
- 3507
- 3508
- 3509
- 3510
- 3511
- 3512
- 3513
- 3514
- 3515
- 3516
- 3517
- 3518
- 3519
- 3520
- 3521
- 3522
- 3523
- 3524
- 3525
- 3526
- 3527
- 3528
- 3529
- 3530
- 3531
- 3532
- 3533
- 3534
- 3535
- 3536
- 3537
- 3538
- 3539
- 3540
- 3541
- 3542
- 3543
- 3544
- 3545
- 3546
- 3547
- 3548
- 3549
- 3550
- 3551
- 3552
- 3553
- 3554
- 3555
- 3556
- 3557
- 3558
- 3559
- 3560
- 3561
- 3562
- 3563
- 3564
- 3565
- 3566
- 3567
- 3568
- 3569
- 3570
- 3571
- 3572
- 3573
- 3574
- 3575
- 3576
- 3577
- 3578
- 3579
- 3580
- 3581
- 3582
- 3583
- 3584
- 3585
- 3586
- 3587
- 3588
- 3589
- 3590
- 3591
- 3592
- 3593
- 3594
- 3595
- 3596
- 3597
- 3598
- 3599
- 3600
- 3601
- 3602
- 3603
- 3604
- 3605
- 3606
- 3607
- 3608
- 3609
- 3610
- 3611
- 3612
- 3613
- 3614
- 3615
- 3616
- 3617
- 3618
- 3619
- 3620
- 3621
- 3622
- 3623
- 3624
- 3625
- 3626
- 3627
- 3628
- 3629
- 3630
- 3631
- 3632
- 3633
- 3634
- 3635
- 3636
- 3637
- 3638
- 3639
- 3640
- 3641
- 3642
- 3643
- 3644
- 3645
- 3646
- 3647
- 3648
- 3649
- 3650
- 3651
- 3652
- 3653
- 3654
- 3655
- 3656
- 3657
- 3658
- 3659
- 3660
- 3661
- 3662
- 3663
- 3664
- 3665
- 3666
- 3667
- 3668
- 3669
- 3670
- 3671
- 3672
- 3673
- 3674
- 3675
- 3676
- 3677
- 3678
- 3679
- 3680
- 3681
- 3682
- 3683
- 3684
- 3685
- 3686
- 3687
- 3688
- 3689
- 3690
- 3691
- 3692
- 3693
- 3694
- 3695
- 3696
- 3697
- 3698
- 3699
- 3700
- 3701
- 3702
- 3703
- 3704
- 3705
- 3706
- 3707
- 3708
- 3709
- 3710
- 3711
- 3712
- 3713
- 3714
- 3715
- 3716
- 3717
- 3718
- 3719
- 3720
- 3721
- 3722
- 3723
- 3724
- 3725
- 3726
- 3727
- 3728
- 3729
- 3730
- 3731
- 3732
- 3733
- 3734
- 3735
- 3736
- 3737
- 3738
- 3739
- 3740
- 3741
- 3742
- 3743
- 3744
- 3745
- 3746
- 3747
- 3748
- 3749
- 3750
- 3751
- 3752
- 3753
- 3754
- 3755
- 3756
- 3757
- 3758
- 3759
- 3760
- 3761
- 3762
- 3763
- 3764
- 3765
- 3766
- 3767
- 3768
- 3769
- 3770
- 3771
- 3772
- 3773
- 3774
- 3775
- 3776
- 3777
- 3778
- 3779
- 3780
- 3781
- 3782
- 3783
- 3784
- 3785
- 3786
- 3787
- 3788
- 3789
- 3790
- 3791
- 3792
- 3793
- 3794
- 3795
- 3796
- 3797
- 3798
- 3799
- 3800
- 3801
- 3802
- 3803
- 3804
- 3805
- 3806
- 3807
- 3808
- 3809
- 3810
- 3811
- 3812
- 3813
- 3814
- 3815
- 3816
- 3817
- 3818
- 3819
- 3820
- 3821
- 3822
- 3823
- 3824
- 3825
- 3826
- 3827
- 3828
- 3829
- 3830
- 3831
- 3832
- 3833
- 3834
- 3835
- 3836
- 3837
- 3838
- 3839
- 3840
- 3841
- 3842
- 3843
- 3844
- 3845
- 3846
- 3847
- 3848
- 3849
- 3850
- 3851
- 3852
- 3853
- 3854
- 3855
- 3856
- 3857
- 3858
- 3859
- 3860
- 3861
- 3862
- 3863
- 3864
- 3865
- 3866
- 3867
- 3868
- 3869
- 3870
- 3871
- 3872
- 3873
- 3874
- 3875
- 3876
- 3877
- 3878
- 3879
- 3880
- 3881
- 3882
- 3883
- 3884
- 3885
- 3886
- 3887
- 3888
- 3889
- 3890
- 3891
- 3892
- 3893
- 3894
- 3895
- 3896
- 3897
- 3898
- 3899
- 3900
- 3901
- 3902
- 3903
- 3904
- 3905
- 3906
- 3907
- 3908
- 3909
- 3910
- 3911
- 3912
- 3913
- 3914
- 3915
- 3916
- 3917
- 3918
- 3919
- 3920
- 3921
- 3922
- 3923
- 3924
- 3925
- 3926
- 3927
- 3928
- 3929
- 3930
- 3931
- 3932
- 3933
- 3934
- 3935
- 3936
- 3937
- 3938
- 3939
- 3940
- 3941
- 3942
- 3943
- 3944
- 3945
- 3946
- 3947
- 3948
- 3949
- 3950
- 3951
- 3952
- 3953
- 3954
- 3955
- 3956
- 3957
- 3958
- 3959
- 3960
- 3961
- 3962
- 3963
- 3964
- 3965
- 3966
- 3967
- 3968
- 3969
- 3970
- 3971
- 3972
- 3973
- 3974
- 3975
- 3976
- 3977
- 3978
- 3979
- 3980
- 3981
- 3982
- 3983
- 3984
- 3985
- 3986
- 3987
- 3988
- 3989
- 3990
- 3991
- 3992
- 3993
- 3994
- 3995
- 3996
- 3997
- 3998
- 3999
- 4000
- 4001
- 4002
- 4003
- 4004
- 4005
- 4006
- 4007
- 4008
- 4009
- 4010
- 4011
- 4012
- 4013
- 4014
- 4015
- 4016
- 4017
- 4018
- 4019
- 4020
- 4021
- 4022
- 4023
- 4024
- 4025
- 4026
- 4027
- 4028
- 4029
- 4030
- 4031
- 4032
- 4033
- 4034
- 4035
- 4036
- 4037
- 4038
- 4039
- 4040
- 4041
- 4042
- 4043
- 4044
- 4045
- 4046
- 4047
- 4048
- 4049
- 4050
- 4051
- 4052
- 4053
- 4054
- 4055
- 4056
- 4057
- 4058
- 4059
- 4060
- 4061
- 4062
- 4063
- 4064
- 4065
- 4066
- 4067
- 4068
- 4069
- 4070
- 4071
- 4072
- 4073
- 4074
- 4075
- 4076
- 4077
- 4078
- 4079
- 4080
- 4081
- 4082
- 4083
- 4084
- 4085
- 4086
- 4087
- 4088
- 4089
- 4090
- 4091
- 4092
- 4093
- 4094
- 4095
- 4096
- 4097
- 4098
- 4099
- 4100
- 4101
- 4102
- 4103
- 4104
- 4105
- 4106
- 4107
- 4108
- 4109
- 4110
- 4111
- 4112
- 4113
- 4114
- 4115
- 4116
- 4117
- 4118
- 4119
- 4120
- 4121
- 4122
- 4123
- 4124
- 4125
- 4126
- 4127
- 4128
- 4129
- 4130
- 4131
- 4132
- 4133
- 4134
- 4135
- 4136
- 4137
- 4138
- 4139
- 4140
- 4141
- 4142
- 4143
- 4144
- 4145
- 4146
- 4147
- 4148
- 4149
- 4150
- 4151
- 4152
- 4153
- 4154
- 4155
- 4156
- 4157
- 4158
- 4159
- 4160
- 4161
- 4162
- 4163
- 4164
- 4165
- 4166
- 4167
- 4168
- 4169
- 4170
- 4171
- 4172
- 4173
- 4174
- 4175
- 4176
- 4177
- 4178
- 4179
- 4180
- 4181
- 4182
- 4183
- 4184
- 4185
- 4186
- 4187
- 4188
- 4189
- 4190
- 4191
- 4192
- 4193
- 4194
- 4195
- 4196
- 4197
- 4198
- 4199
- 4200
- 4201
- 4202
- 4203
- 4204
- 4205
- 4206
- 4207
- 4208
- 4209
- 4210
- 4211
- 4212
- 4213
- 4214
- 4215
- 4216
- 4217
- 4218
- 4219
- 4220
- 4221
- 4222
- 4223
- 4224
- 4225
- 4226
- 4227
- 4228
- 4229
- 4230
- 4231
- 4232
- 4233
- 4234
- 4235
- 4236
- 4237
- 4238
- 4239
- 4240
- 4241
- 4242
- 4243
- 4244
- 4245
- 4246
- 4247
- 4248
- 4249
- 4250
- 4251
- 4252
- 4253
- 4254
- 4255
- 4256
- 4257
- 4258
- 4259
- 4260
- 4261
- 4262
- 4263
- 4264
- 4265
- 4266
- 4267
- 4268
- 4269
- 4270
- 4271
- 4272
- 4273
- 4274
- 4275
- 4276
- 4277
- 4278
- 4279
- 4280
- 4281
- 4282
- 4283
- 4284
- 4285
- 4286
- 4287
- 4288
- 4289
- 4290
- 4291
- 4292
- 4293
- 4294
- 4295
- 4296
- 4297
- 4298
- 4299
- 4300
- 4301
- 4302
- 4303
- 4304
- 4305
- 4306
- 4307
- 4308
- 4309
- 4310
- 4311
- 4312
- 4313
- 4314
- 4315
- 4316
- 4317
- 4318
- 4319
- 4320
- 4321
- 4322
- 4323
- 4324
- 4325
- 4326
- 4327
- 4328
- 4329
- 4330
- 4331
- 4332
- 4333
- 4334
- 4335
- 4336
- 4337
- 4338
- 4339
- 4340
- 4341
- 4342
- 4343
- 4344
- 4345
- 4346
- 4347
- 4348
- 4349
- 4350
- 4351
- 4352
- 4353
- 4354
- 4355
- 4356
- 4357
- 4358
- 4359
- 4360
- 4361
- 4362
- 4363
- 4364
- 4365
- 4366
- 4367
- 4368
- 4369
- 4370
- 4371
- 4372
- 4373
- 4374
- 4375
- 4376
- 4377
- 4378
- 4379
- 4380
- 4381
- 4382
- 4383
- 4384
- 4385
- 4386
- 4387
- 4388
- 4389
- 4390
- 4391
- 4392
- 4393
- 4394
- 4395
- 4396
- 4397
- 4398
- 4399
- 4400
- 4401
- 4402
- 4403
- 4404
- 4405
- 4406
- 4407
- 4408
- 4409
- 4410
- 4411
- 4412
- 4413
- 4414
- 4415
- 4416
- 4417
- 4418
- 4419
- 4420
- 4421
- 4422
- 4423
- 4424
- 4425
- 4426
- 4427
- 4428
- 4429
- 4430
- 4431
- 4432
- 4433
- 4434
- 4435
- 4436
- 4437
- 4438
- 4439
- 4440
- 4441
- 4442
- 4443
- 4444
- 4445
- 4446
- 4447
- 4448
- 4449
- 4450
- 4451
- 4452
- 4453
- 4454
- 4455
- 4456
- 4457
- 4458
- 4459
- 4460
- 4461
- 4462
- 4463
- 4464
- 4465
- 4466
- 4467
- 4468
- 4469
- 4470
- 4471
- 4472
- 4473
- 4474
- 4475
- 4476
- 4477
- 4478
- 4479
- 4480
- 4481
- 4482
- 4483
- 4484
- 4485
- 4486
- 4487
- 4488
- 4489
- 4490
- 4491
- 4492
- 4493
- 4494
- 4495
- 4496
- 4497
- 4498
- 4499
- 4500
- 4501
- 4502
- 4503
- 4504
- 4505
- 4506
- 4507
- 4508
- 4509
- 4510
- 4511
- 4512
- 4513
- 4514
- 4515
- 4516
- 4517
- 4518
- 4519
- 4520
- 4521
- 4522
- 4523
- 4524
- 4525
- 4526
- 4527
- 4528
- 4529
- 4530
- 4531
- 4532
- 4533
- 4534
- 4535
- 4536
- 4537
- 4538
- 4539
- 4540
- 4541
- 4542
- 4543
- 4544
- 4545
- 4546
- 4547
- 4548
- 4549
- 4550
- 4551
- 4552
- 4553
- 4554
- 4555
- 4556
- 4557
- 4558
- 4559
- 4560
- 4561
- 4562
- 4563
- 4564
- 4565
- 4566
- 4567
- 4568
- 4569
- 4570
- 4571
- 4572
- 4573
- 4574
- 4575
- 4576
- 4577
- 4578
- 4579
- 4580
- 4581
- 4582
- 4583
- 4584
- 4585
- 4586
- 4587
- 4588
- 4589
- 4590
- 4591
- 4592
- 4593
- 4594
- 4595
- 4596
- 4597
- 4598
- 4599
- 4600
- 4601
- 4602
- 4603
- 4604
- 4605
- 4606
- 4607
- 4608
- 4609
- 4610
- 4611
- 4612
- 4613
- 4614
- 4615
- 4616
- 4617
- 4618
- 4619
- 4620
- 4621
- 4622
- 4623
- 4624
- 4625
- 4626
- 4627
- 4628
- 4629
- 4630
- 4631
- 4632
- 4633
- 4634
- 4635
- 4636
- 4637
- 4638
- 4639
- 4640
- 4641
- 4642
- 4643
- 4644
- 4645
- 4646
- 4647
- 4648
- 4649
- 4650
- 4651
- 4652
- 4653
- 4654
- 4655
- 4656
- 4657
- 4658
- 4659
- 4660
- 4661
- 4662
- 4663
- 4664
- 4665
- 4666
- 4667
- 4668
- 4669
- 4670
- 4671
- 4672
- 4673
- 4674
- 4675
- 4676
- 4677
- 4678
- 4679
- 4680
- 4681
- 4682
- 4683
- 4684
- 4685
- 4686
- 4687
- 4688
- 4689
- 4690
- 4691
- 4692
- 4693
- 4694
- 4695
- 4696
- 4697
- 4698
- 4699
- 4700
- 4701
- 4702
- 4703
- 4704
- 4705
- 4706
- 4707
- 4708
- 4709
- 4710
- 4711
- 4712
- 4713
- 4714
- 4715
- 4716
- 4717
- 4718
- 4719
- 4720
- 4721
- 4722
- 4723
- 4724
- 4725
- 4726
- 4727
- 4728
- 4729
- 4730
- 4731
- 4732
- 4733
- 4734
- 4735
- 4736
- 4737
- 4738
- 4739
- 4740
- 4741
- 4742
- 4743
- 4744
- 4745
- 4746
- 4747
- 4748
- 4749
- 4750
- 4751
- 4752
- 4753
- 4754
- 4755
- 4756
- 4757
- 4758
- 4759
- 4760
- 4761
- 4762
- 4763
- 4764
- 4765
- 4766
- 4767
- 4768
- 4769
- 4770
- 4771
- 4772
- 4773
- 4774
- 4775
- 4776
- 4777
- 4778
- 4779
- 4780
- 4781
- 4782
- 4783
- 4784
- 4785
- 4786
- 4787
- 4788
- 4789
- 4790
- 4791
- 4792
- 4793
- 4794
- 4795
- 4796
- 4797
- 4798
- 4799
- 4800
- 4801
- 4802
- 4803
- 4804
- 4805
- 4806
- 4807
- 4808
- 4809
- 4810
- 4811
- 4812
- 4813
- 4814
- 4815
- 4816
- 4817
- 4818
- 4819
- 4820
- 4821
- 4822
- 4823
- 4824
- 4825
- 4826
- 4827
- 4828
- 4829
- 4830
- 4831
- 4832
- 4833
- 4834
- 4835
- 4836
- 4837
- 4838
- 4839
- 4840
- 4841
- 4842
- 4843
- 4844
- 4845
- 4846
- 4847
- 4848
- 4849
- 4850
- 4851
- 4852
- 4853
- 4854
- 4855
- 4856
- 4857
- 4858
- 4859
- 4860
- 4861
- 4862
- 4863
- 4864
- 4865
- 4866
- 4867
- 4868
- 4869
- 4870
- 4871
- 4872
- 4873
- 4874
- 4875
- 4876
- 4877
- 4878
- 4879
- 4880
- 4881
- 4882
- 4883
- 4884
- 4885
- 4886
- 4887
- 4888
- 4889
- 4890
- 4891
- 4892
- 4893
- 4894
- 4895
- 4896
- 4897
- 4898
- 4899
- 4900
- 4901
- 4902
- 4903
- 4904
- 4905
- 4906
- 4907
- 4908
- 4909
- 4910
- 4911
- 4912
- 4913
- 4914
- 4915
- 4916
- 4917
- 4918
- 4919
- 4920
- 4921
- 4922
- 4923
- 4924
- 4925
- 4926
- 4927
- 4928
- 4929
- 4930
- 4931
- 4932
- 4933
- 4934
- 4935
- 4936
- 4937
- 4938
- 4939
- 4940
- 4941
- 4942
- 4943
- 4944
- 4945
- 4946
- 4947
- 4948
- 4949
- 4950
- 4951
- 4952
- 4953
- 4954
- 4955
- 4956
- 4957
- 4958
- 4959
- 4960
- 4961
- 4962
- 4963
- 4964
- 4965
- 4966
- 4967
- 4968
- 4969
- 4970
- 4971
- 4972
- 4973
- 4974
- 4975
- 4976
- 4977
- 4978
- 4979
- 4980
- 4981
- 4982
- 4983
- 4984
- 4985
- 4986
- 4987
- 4988
- 4989
- 4990
- 4991
- 4992
- 4993
- 4994
- 4995
- 4996
- 4997
- 4998
- 4999
- 5000
- 5001
- 5002
- 5003
- 5004
- 5005
- 5006
- 5007
- 5008
- 5009
- 5010
- 5011
- 5012
- 5013
- 5014
- 5015
- 5016
- 5017
- 5018
- 5019
- 5020
- 5021
- 5022
- 5023
- 5024
- 5025
- 5026
- 5027
- 5028
- 5029
- 5030
- 5031
- 5032
- 5033
- 5034
- 5035
- 5036
- 5037
- 5038
- 5039
- 5040
- 5041
- 5042
- 5043
- 5044
- 5045
- 5046
- 5047
- 5048
- 5049
- 5050
- 5051
- 5052
- 5053
- 5054
- 5055
- 5056
- 5057
- 5058
- 5059
- 5060
- 5061
- 5062
- 5063
- 5064
- 5065
- 5066
- 5067
- 5068
- 5069
- 5070
- 5071
- 5072
- 5073
- 5074
- 5075
- 5076
- 5077
- 5078
- 5079
- 5080
- 5081
- 5082
- 5083
- 5084
- 5085
- 5086
- 5087
- 5088
- 5089
- 5090
- 5091
- 5092
- 5093
- 5094
- 5095
- 5096
- 5097
- 5098
- 5099
- 5100
- 5101
- 5102
- 5103
- 5104
- 5105
- 5106
- 5107
- 5108
- 5109
- 5110
- 5111
- 5112
- 5113
- 5114
- 5115
- 5116
- 5117
- 5118
- 5119
- 5120
- 5121
- 5122
- 5123
- 5124
- 5125
- 5126
- 5127
- 5128
- 5129
- 5130
- 5131
- 5132
- 5133
- 5134
- 5135
- 5136
- 5137
- 5138
- 5139
- 5140
- 5141
- 5142
- 5143
- 5144
- 5145
- 5146
- 5147
- 5148
- 5149
- 5150
- 5151
- 5152
- 5153
- 5154
- 5155
- 5156
- 5157
- 5158
- 5159
- 5160
- 5161
- 5162
- 5163
- 5164
- 5165
- 5166
- 5167
- 5168
- 5169
- 5170
- 5171
- 5172
- 5173
- 5174
- 5175
- 5176
- 5177
- 5178
- 5179
- 5180
- 5181
- 5182
- 5183
- 5184
- 5185
- 5186
- 5187
- 5188
- 5189
- 5190
- 5191
- 5192
- 5193
- 5194
- 5195
- 5196
- 5197
- 5198
- 5199
- 5200
- 5201
- 5202
- 5203
- 5204
- 5205
- 5206
- 5207
- 5208
- 5209
- 5210
- 5211
- 5212
- 5213
- 5214
- 5215
- 5216
- 5217
- 5218
- 5219
- 5220
- 5221
- 5222
- 5223
- 5224
- 5225
- 5226
- 5227
- 5228
- 5229
- 5230
- 5231
- 5232
- 5233
- 5234
- 5235
- 5236
- 5237
- 5238
- 5239
- 5240
- 5241
- 5242
- 5243
- 5244
- 5245
- 5246
- 5247
- 5248
- 5249
- 5250
- 5251
- 5252
- 5253
- 5254
- 5255
- 5256
- 5257
- 5258
- 5259
- 5260
- 5261
- 5262
- 5263
- 5264
- 5265
- 5266
- 5267
- 5268
- 5269
- 5270
- 5271
- 5272
- 5273
- 5274
- 5275
- 5276
- 5277
- 5278
- 5279
- 5280
- 5281
- 5282
- 5283
- 5284
- 5285
- 5286
- 5287
- 5288
- 5289
- 5290
- 5291
- 5292
- 5293
- 5294
- 5295
- 5296
- 5297
- 5298
- 5299
- 5300
- 5301
- 5302
- 5303
- 5304
- 5305
- 5306
- 5307
- 5308
- 5309
- 5310
- 5311
- 5312
- 5313
- 5314
- 5315
- 5316
- 5317
- 5318
- 5319
- 5320
- 5321
- 5322
- 5323
- 5324
- 5325
- 5326
- 5327
- 5328
- 5329
- 5330
- 5331
- 5332
- 5333
- 5334
- 5335
- 5336
- 5337
- 5338
- 5339
- 5340
- 5341
- 5342
- 5343
- 5344
- 5345
- 5346
- 5347
- 5348
- 5349
- 5350
- 5351
- 5352
- 5353
- 5354
- 5355
- 5356
- 5357
- 5358
- 5359
- 5360
- 5361
- 5362
- 5363
- 5364
- 5365
- 5366
- 5367
- 5368
- 5369
- 5370
- 5371
- 5372
- 5373
- 5374
- 5375
- 5376
- 5377
- 5378
- 5379
- 5380
- 5381
- 5382
- 5383
- 5384
- 5385
- 5386
- 5387
- 5388
- 5389
- 5390
- 5391
- 5392
- 5393
- 5394
- 5395
- 5396
- 5397
- 5398
- 5399
- 5400
- 5401
- 5402
- 5403
- 5404
- 5405
- 5406
- 5407
- 5408
- 5409
- 5410
- 5411
- 5412
- 5413
- 5414
- 5415
- 5416
- 5417
- 5418
- 5419
- 5420
- 5421
- 5422
- 5423
- 5424
- 5425
- 5426
- 5427
- 5428
- 5429
- 5430
- 5431
- 5432
- 5433
- 5434
- 5435
- 5436
- 5437
- 5438
- 5439
- 5440
- 5441
- 5442
- 5443
- 5444
- 5445
- 5446
- 5447
- 5448
- 5449
- 5450
- 5451
- 5452
- 5453
- 5454
- 5455
- 5456
- 5457
- 5458
- 5459
- 5460
- 5461
- 5462
- 5463
- 5464
- 5465
- 5466
- 5467
- 5468
- 5469
- 5470
- 5471
- 5472
- 5473
- 5474
- 5475
- 5476
- 5477
- 5478
- 5479
- 5480
- 5481
- 5482
- 5483
- 5484
- 5485
- 5486
- 5487
- 5488
- 5489
- 5490
- 5491
- 5492
- 5493
- 5494
- 5495
- 5496
- 5497
- 5498
- 5499
- 5500
- 5501
- 5502
- 5503
- 5504
- 5505
- 5506
- 5507
- 5508
- 5509
- 5510
- 5511
- 5512
- 5513
- 5514
- 5515
- 5516
- 5517
- 5518
- 5519
- 5520
- 5521
- 5522
- 5523
- 5524
- 5525
- 5526
- 5527
- 5528
- 5529
- 5530
- 5531
- 5532
- 5533
- 5534
- 5535
- 5536
- 5537
- 5538
- 5539
- 5540
- 5541
- 5542
- 5543
- 5544
- 5545
- 5546
- 5547
- 5548
- 5549
- 5550
- 5551
- 5552
- 5553
- 5554
- 5555
- 5556
- 5557
- 5558
- 5559
- 5560
- 5561
- 5562
- 5563
- 5564
- 5565
- 5566
- 5567
- 5568
- 5569
- 5570
- 5571
- 5572
- 5573
- 5574
- 5575
- 5576
- 5577
- 5578
- 5579
- 5580
- 5581
- 5582
- 5583
- 5584
- 5585
- 5586
- 5587
- 5588
- 5589
- 5590
- 5591
- 5592
- 5593
- 5594
- 5595
- 5596
- 5597
- 5598
- 5599
- 5600
- 5601
- 5602
- 5603
- 5604
- 5605
- 5606
- 5607
- 5608
- 5609
- 5610
- 5611
- 5612
- 5613
- 5614
- 5615
- 5616
- 5617
- 5618
- 5619
- 5620
- 5621
- 5622
- 5623
- 5624
- 5625
- 5626
- 5627
- 5628
- 5629
- 5630
- 5631
- 5632
- 5633
- 5634
- 5635
- 5636
- 5637
- 5638
- 5639
- 5640
- 5641
- 5642
- 5643
- 5644
- 5645
- 5646
- 5647
- 5648
- 5649
- 5650
- 5651
- 5652
- 5653
- 5654
- 5655
- 5656