/*
*
* Broadcom B43legacy wireless driver
*
* Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>
* Copyright (c) 2005-2008 Stefano Brivio <stefano.brivio@polimi.it>
* Copyright (c) 2005, 2006 Michael Buesch <mb@bu3sch.de>
* Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
* Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
* Copyright (c) 2007 Larry Finger <Larry.Finger@lwfinger.net>
*
* Some parts of the code in this file are derived from the ipw2200
* driver Copyright(c) 2003 - 2004 Intel Corporation.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*/
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
#include <linux/firmware.h>
#include <linux/wireless.h>
#include <linux/workqueue.h>
#include <linux/skbuff.h>
#include <linux/dma-mapping.h>
#include <net/dst.h>
#include <asm/unaligned.h>
#include "b43legacy.h"
#include "main.h"
#include "debugfs.h"
#include "phy.h"
#include "dma.h"
#include "pio.h"
#include "sysfs.h"
#include "xmit.h"
#include "radio.h"
MODULE_DESCRIPTION("Broadcom B43legacy wireless driver");
MODULE_AUTHOR("Martin Langer");
MODULE_AUTHOR("Stefano Brivio");
MODULE_AUTHOR("Michael Buesch");
MODULE_LICENSE("GPL");
MODULE_FIRMWARE(B43legacy_SUPPORTED_FIRMWARE_ID);
#if defined(CONFIG_B43LEGACY_DMA) && defined(CONFIG_B43LEGACY_PIO)
static int modparam_pio;
module_param_named(pio, modparam_pio, int, 0444);
MODULE_PARM_DESC(pio, "enable(1) / disable(0) PIO mode");
#elif defined(CONFIG_B43LEGACY_DMA)
# define modparam_pio 0
#elif defined(CONFIG_B43LEGACY_PIO)
# define modparam_pio 1
#endif
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 firmware files to load.");
/* The following table supports BCM4301, BCM4303 and BCM4306/2 devices. */
static const struct ssb_device_id b43legacy_ssb_tbl[] = {
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 2),
SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 4),
SSB_DEVTABLE_END
};
MODULE_DEVICE_TABLE(ssb, b43legacy_ssb_tbl);
/* Channel and ratetables are shared for all devices.
* They can't be const, because ieee80211 puts some precalculated
* data in there. This data is the same for all devices, so we don't
* get concurrency issues */
#define RATETAB_ENT(_rateid, _flags) \
{ \
.bitrate = B43legacy_RATE_TO_100KBPS(_rateid), \
.hw_value = (_rateid), \
.flags = (_flags), \
}
/*
* NOTE: When changing this, sync with xmit.c's
* b43legacy_plcp_get_bitrate_idx_* functions!
*/
static struct ieee80211_rate __b43legacy_ratetable[] = {
RATETAB_ENT(B43legacy_CCK_RATE_1MB, 0),
RATETAB_ENT(B43legacy_CCK_RATE_2MB, IEEE80211_RATE_SHORT_PREAMBLE),
RATETAB_ENT(B43legacy_CCK_RATE_5MB, IEEE80211_RATE_SHORT_PREAMBLE),
RATETAB_ENT(B43legacy_CCK_RATE_11MB, IEEE80211_RATE_SHORT_PREAMBLE),
RATETAB_ENT(B43legacy_OFDM_RATE_6MB, 0),
RATETAB_ENT(B43legacy_OFDM_RATE_9MB, 0),
RATETAB_ENT(B43legacy_OFDM_RATE_12MB, 0),
RATETAB_ENT(B43legacy_OFDM_RATE_18MB, 0),
RATETAB_ENT(B43legacy_OFDM_RATE_24MB, 0),
RATETAB_ENT(B43legacy_OFDM_RATE_36MB, 0),
RATETAB_ENT(B43legacy_OFDM_RATE_48MB, 0),
RATETAB_ENT(B43legacy_OFDM_RATE_54MB, 0),
};
#define b43legacy_b_ratetable (__b43legacy_ratetable + 0)
#define b43legacy_b_ratetable_size 4
#define b43legacy_g_ratetable (__b43legacy_ratetable + 0)
#define b43legacy_g_ratetable_size 12
#define CHANTAB_ENT(_chanid, _freq) \
{ \
.center_freq = (_freq), \
.hw_value = (_chanid), \
}
static struct ieee80211_channel b43legacy_bg_chantable[] = {
CHANTAB_ENT(1, 2412),
CHANTAB_ENT(2, 2417),
CHANTAB_ENT(3, 2422),
CHANTAB_ENT(4, 2427),
CHANTAB_ENT(5, 2432),
CHANTAB_ENT(6, 2437),
CHANTAB_ENT(7, 2442),
CHANTAB_ENT(8, 2447),
CHANTAB_ENT(9, 2452),
CHANTAB_ENT(10, 2457),
CHANTAB_ENT(11, 2462),
CHANTAB_ENT(12, 2467),
CHANTAB_ENT(13, 2472),
CHANTAB_ENT(14, 2484),
};
static struct ieee80211_supported_band b43legacy_band_2GHz_BPHY = {
.channels = b43legacy_bg_chantable,
.n_channels = ARRAY_SIZE(b43legacy_bg_chantable),
.bitrates = b43legacy_b_ratetable,
.n_bitrates = b43legacy_b_ratetable_size,
};
static struct ieee80211_supported_band b43legacy_band_2GHz_GPHY = {
.channels = b43legacy_bg_chantable,
.n_channels = ARRAY_SIZE(b43legacy_bg_chantable),
.bitrates = b43legacy_g_ratetable,
.n_bitrates = b43legacy_g_ratetable_size,
};
static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev);
static int b43legacy_wireless_core_init(struct b43legacy_wldev *dev);
static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev);