/*
* Copyright 2008 Pavel Machek <pavel@suse.cz>
*
* Distribute under GPLv2.
*
* The original driver was written by:
* Jeff Lee <YY_Lee@issc.com.tw>
*
* and was adapted to the 2.6 kernel by:
* Costantino Leandro (Rxart Desktop) <le_costantino@pixartargentina.com.ar>
*/
#include <net/mac80211.h>
#include <linux/usb.h>
#include "core.h"
#include "mds_f.h"
#include "mlmetxrx_f.h"
#include "mto.h"
#include "wbhal_f.h"
#include "wblinux_f.h"
MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION("0.1");
static struct usb_device_id wb35_table[] __devinitdata = {
{ USB_DEVICE(0x0416, 0x0035) },
{ USB_DEVICE(0x18E8, 0x6201) },
{ USB_DEVICE(0x18E8, 0x6206) },
{ USB_DEVICE(0x18E8, 0x6217) },
{ USB_DEVICE(0x18E8, 0x6230) },
{ USB_DEVICE(0x18E8, 0x6233) },
{ USB_DEVICE(0x1131, 0x2035) },
{ 0, }
};
MODULE_DEVICE_TABLE(usb, wb35_table);
static struct ieee80211_rate wbsoft_rates[] = {
{ .bitrate = 10, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
};
static struct ieee80211_channel wbsoft_channels[] = {
{ .center_freq = 2412 },
};
static struct ieee80211_supported_band wbsoft_band_2GHz = {
.channels = wbsoft_channels,
.n_channels = ARRAY_SIZE(wbsoft_channels),
.bitrates = wbsoft_rates,
.n_bitrates = ARRAY_SIZE(wbsoft_rates),
};
static void hal_set_beacon_period(struct hw_data *pHwData, u16 beacon_period)
{
u32 tmp;
if (pHwData->SurpriseRemove)
return;
pHwData->BeaconPeriod = beacon_period;
tmp = pHwData->BeaconPeriod << 16;
tmp |= pHwData->ProbeDelay;
Wb35Reg_Write(pHwData, 0x0848, tmp);
}
static int wbsoft_add_interface(struct ieee80211_hw *dev,
struct ieee80211_if_init_conf *conf)
{
struct wbsoft_priv *priv = dev->priv;
hal_set_beacon_period(&priv->sHwData, conf->vif->bss_conf.beacon_int);
return 0;
}
static void wbsoft_remove_interface(struct ieee80211_hw *dev,
struct ieee80211_if_init_conf *conf)
{
printk("wbsoft_remove interface called\n");
}
static void wbsoft_stop(struct ieee80211_hw *hw)
{
printk(KERN_INFO "%s called\n", __func__);
}
static int wbsoft_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats)
{
printk(KERN_INFO "%s called\n", __func__);
return 0;
}
static int wbsoft_get_tx_stats(struct ieee80211_hw *hw,
struct ieee80211_tx_queue_stats *stats)
{
printk(KERN_INFO "%s called\n", __func__);
return 0;
}
static u64 wbsoft_prepare_multicast(struct ieee80211_hw *hw, int mc_count,
struct dev_addr_list *mc_list)
{
return mc_count;
}
static void wbsoft_configure_filter(struct ieee80211_hw *dev,
unsigned int changed_flags,
unsigned int *total_flags,
u64 multicast)
{
unsigned int new_flags;
new_flags = 0;
if (*total_flags & FIF_PROMISC_IN_BSS)
new_flags |= FIF_PROMISC_IN_BSS;
else if ((*total_flags & FIF_ALLMULTI) || (multicast > 32))
new_flags |= FIF_ALLMULTI;
dev->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS;
*total_flags = new_flags;
}
static int wbsoft_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
{
struct wbsoft_priv *priv = dev->priv;
MLMESendFrame(priv, skb->data, skb->len, FRAME_TYPE_802_11_MANAGEMENT);
return NETDEV_TX_OK;
}
static int wbsoft_start(struct ieee80211_hw *dev)
{
struct wbsoft_priv *priv = dev->priv;
priv->enabled = true;
return 0;
}
static void hal_set_radio_mode(struct hw_data *pHwData, unsigned char radio_off)
{
struct wb35_reg *reg = &pHwData->reg;
if (pHwData->SurpriseRemove)
return;
if (radio_off) //disable Baseband receive off
{
pHwData->CurrentRadioSw = 1; // off
reg->M24_MacControl &= 0xffffffbf;
} else {
pHwData->CurrentRadioSw = 0; // on
reg->M24_MacControl |= 0x00000040;
}
Wb35Reg_Write(pHwData, 0x0824, reg->M24_MacControl);
}
static void
hal_set_current_channel_ex(struct hw_data *pHwData, ChanInfo channel)
{
struct wb35_reg *reg = &pHwData->reg;
if (pHwData->SurpriseRemove)
return;
printk("Going to channel: %d/%d\n<