/* ZD1211 USB-WLAN driver for Linux
*
* Copyright (C) 2005-2007 Ulrich Kunitz <kune@deine-taler.de>
* Copyright (C) 2006-2007 Daniel Drake <dsd@gentoo.org>
* Copyright (C) 2006-2007 Michael Wu <flamingice@sourmilk.net>
* Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
*
* 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; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/usb.h>
#include <linux/jiffies.h>
#include <net/ieee80211_radiotap.h>
#include "zd_def.h"
#include "zd_chip.h"
#include "zd_mac.h"
#include "zd_ieee80211.h"
#include "zd_rf.h"
/* This table contains the hardware specific values for the modulation rates. */
static const struct ieee80211_rate zd_rates[] = {
{ .rate = 10,
.val = ZD_CCK_RATE_1M,
.flags = IEEE80211_RATE_CCK },
{ .rate = 20,
.val = ZD_CCK_RATE_2M,
.val2 = ZD_CCK_RATE_2M | ZD_CCK_PREA_SHORT,
.flags = IEEE80211_RATE_CCK_2 },
{ .rate = 55,
.val = ZD_CCK_RATE_5_5M,
.val2 = ZD_CCK_RATE_5_5M | ZD_CCK_PREA_SHORT,
.flags = IEEE80211_RATE_CCK_2 },
{ .rate = 110,
.val = ZD_CCK_RATE_11M,
.val2 = ZD_CCK_RATE_11M | ZD_CCK_PREA_SHORT,
.flags = IEEE80211_RATE_CCK_2 },
{ .rate = 60,
.val = ZD_OFDM_RATE_6M,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 90,
.val = ZD_OFDM_RATE_9M,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 120,
.val = ZD_OFDM_RATE_12M,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 180,
.val = ZD_OFDM_RATE_18M,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 240,
.val = ZD_OFDM_RATE_24M,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 360,
.val = ZD_OFDM_RATE_36M,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 480,
.val = ZD_OFDM_RATE_48M,
.flags = IEEE80211_RATE_OFDM },
{ .rate = 540,
.val = ZD_OFDM_RATE_54M,
.flags = IEEE80211_RATE_OFDM },
};
static const struct ieee80211_channel zd_channels[] = {
{ .chan = 1,
.freq = 2412},
{ .chan = 2,
.freq = 2417},
{ .chan = 3,
.freq = 2422},
{ .chan = 4,
.freq = 2427},
{ .chan = 5,
.freq = 2432},
{ .chan = 6,
.freq = 2437},
{ .chan = 7,
.freq = 2442},
{ .chan = 8,
.freq = 2447},
{ .chan = 9,
.freq = 2452},
{ .chan = 10,
.freq = 2457},
{ .chan = 11,
.freq = 2462},
{ .chan = 12,
.freq = 2467},
{ .chan = 13,
.freq = 2472},
{ .chan = 14,
.freq = 2484}
};
static void housekeeping_init(struct zd_mac *mac);
static void housekeeping_enable(struct zd_mac *mac);
static void housekeeping_disable(struct zd_mac *mac);
int zd_mac_preinit_hw(struct ieee80211_hw *hw)
{
int r;
u8 addr[ETH_ALEN];
struct zd_mac *mac = zd_hw_mac(hw);
r = zd_chip_read_mac_addr_fw(&mac->chip, addr);
if (r)
return r;
SET_IEEE80211_PERM_ADDR(hw, addr);
return 0;
}
int zd_mac_init_hw(struct ieee80211_hw *hw)
{
int r;
struct zd_mac *mac = zd_hw_mac(hw);
struct zd_chip *<