📄 wlan_main.c
字号:
/*
* File : wlan_main.c The main device driver file.
*/
#include "include.h"
#ifdef TXRX_DEBUG
int tx_n = 0;
unsigned long tt[7][16];
struct TRD trd[TRD_N];
int trd_n = 0;
int trd_p = 0;
#endif
#ifdef CONFIG_MARVELL_PM
struct pm_dev *wlan_pm_dev = NULL;
#endif
#ifdef WLAN_MEM_CHECK
u32 kmalloc_count,
kfree_count;
u32 rxskb_alloc,
rxskb_free;
u32 txskb_alloc,
txskb_free;
#endif
u32 DSFreqList[15] = {
0, 2412000, 2417000, 2422000, 2427000, 2432000, 2437000, 2442000,
2447000, 2452000, 2457000, 2462000, 2467000, 2472000, 2484000
};
/* region code table */
u16 RegionCodeToIndex[MRVDRV_MAX_REGION_CODE] =
{ 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
#define WLAN_TX_PWR_DEFAULT 20 /*100mW*/
#define WLAN_TX_PWR_US_DEFAULT 20 /*100mW*/
#define WLAN_TX_PWR_JP_DEFAULT 16 /*50mW*/
#define WLAN_TX_PWR_FR_DEFAULT 20 /*100mW*/
#define WLAN_TX_PWR_EMEA_DEFAULT 20 /*100mW*/
/*
* Format { Channel, Frequency (MHz), MaxTxPower }
*/
/* Band: 'B/G', Region: USA FCC/Canada IC*/
CHANNEL_FREQ_POWER channel_freq_power_US_BG[] = {
{1, 2412, WLAN_TX_PWR_US_DEFAULT},
{2, 2417, WLAN_TX_PWR_US_DEFAULT},
{3, 2422, WLAN_TX_PWR_US_DEFAULT},
{4, 2427, WLAN_TX_PWR_US_DEFAULT},
{5, 2432, WLAN_TX_PWR_US_DEFAULT},
{6, 2437, WLAN_TX_PWR_US_DEFAULT},
{7, 2442, WLAN_TX_PWR_US_DEFAULT},
{8, 2447, WLAN_TX_PWR_US_DEFAULT},
{9, 2452, WLAN_TX_PWR_US_DEFAULT},
{10, 2457, WLAN_TX_PWR_US_DEFAULT},
{11, 2462, WLAN_TX_PWR_US_DEFAULT}
};
/* Band: 'B/G', Region: Europe ETSI*/
CHANNEL_FREQ_POWER channel_freq_power_EU_BG[] = {
{1, 2412, WLAN_TX_PWR_EMEA_DEFAULT},
{2, 2417, WLAN_TX_PWR_EMEA_DEFAULT},
{3, 2422, WLAN_TX_PWR_EMEA_DEFAULT},
{4, 2427, WLAN_TX_PWR_EMEA_DEFAULT},
{5, 2432, WLAN_TX_PWR_EMEA_DEFAULT},
{6, 2437, WLAN_TX_PWR_EMEA_DEFAULT},
{7, 2442, WLAN_TX_PWR_EMEA_DEFAULT},
{8, 2447, WLAN_TX_PWR_EMEA_DEFAULT},
{9, 2452, WLAN_TX_PWR_EMEA_DEFAULT},
{10, 2457, WLAN_TX_PWR_EMEA_DEFAULT},
{11, 2462, WLAN_TX_PWR_EMEA_DEFAULT},
{12, 2467, WLAN_TX_PWR_EMEA_DEFAULT},
{13, 2472, WLAN_TX_PWR_EMEA_DEFAULT}
};
/* Band: 'B/G', Region: Spain */
CHANNEL_FREQ_POWER channel_freq_power_SPN_BG[] = {
{10, 2457, WLAN_TX_PWR_DEFAULT},
{11, 2462, WLAN_TX_PWR_DEFAULT}
};
/* Band: 'B/G', Region: France */
CHANNEL_FREQ_POWER channel_freq_power_FR_BG[] = {
{10, 2457, WLAN_TX_PWR_FR_DEFAULT},
{11, 2462, WLAN_TX_PWR_FR_DEFAULT},
{12, 2467, WLAN_TX_PWR_FR_DEFAULT},
{13, 2472, WLAN_TX_PWR_FR_DEFAULT}
};
/* Band: 'B/G', Region: Japan */
CHANNEL_FREQ_POWER channel_freq_power_JPN_BG[] = {
{1, 2412, WLAN_TX_PWR_JP_DEFAULT},
{2, 2417, WLAN_TX_PWR_JP_DEFAULT},
{3, 2422, WLAN_TX_PWR_JP_DEFAULT},
{4, 2427, WLAN_TX_PWR_JP_DEFAULT},
{5, 2432, WLAN_TX_PWR_JP_DEFAULT},
{6, 2437, WLAN_TX_PWR_JP_DEFAULT},
{7, 2442, WLAN_TX_PWR_JP_DEFAULT},
{8, 2447, WLAN_TX_PWR_JP_DEFAULT},
{9, 2452, WLAN_TX_PWR_JP_DEFAULT},
{10, 2457, WLAN_TX_PWR_JP_DEFAULT},
{11, 2462, WLAN_TX_PWR_JP_DEFAULT},
{12, 2467, WLAN_TX_PWR_JP_DEFAULT},
{13, 2472, WLAN_TX_PWR_JP_DEFAULT},
{14, 2484, WLAN_TX_PWR_JP_DEFAULT}
};
#ifdef MULTI_BANDS
/* Band: 'A', Region: USA FCC, Canada IC, Spain, France */
CHANNEL_FREQ_POWER channel_freq_power_A[] = {
{36, 5180, WLAN_TX_PWR_US_DEFAULT},
{40, 5200, WLAN_TX_PWR_US_DEFAULT},
{44, 5220, WLAN_TX_PWR_US_DEFAULT},
{48, 5240, WLAN_TX_PWR_US_DEFAULT},
{52, 5260, WLAN_TX_PWR_US_DEFAULT},
{56, 5280, WLAN_TX_PWR_US_DEFAULT},
{60, 5300, WLAN_TX_PWR_US_DEFAULT},
{64, 5320, WLAN_TX_PWR_US_DEFAULT},
{149, 5745, WLAN_TX_PWR_US_DEFAULT},
{153, 5765, WLAN_TX_PWR_US_DEFAULT},
{157, 5785, WLAN_TX_PWR_US_DEFAULT},
{161, 5805, WLAN_TX_PWR_US_DEFAULT},
{165, 5825, WLAN_TX_PWR_US_DEFAULT}
};
/* Band: 'A', Region: Europe ETSI */
CHANNEL_FREQ_POWER channel_freq_power_EU_A[] = {
{36, 5180, WLAN_TX_PWR_EMEA_DEFAULT},
{40, 5200, WLAN_TX_PWR_EMEA_DEFAULT},
{44, 5220, WLAN_TX_PWR_EMEA_DEFAULT},
{48, 5240, WLAN_TX_PWR_EMEA_DEFAULT},
{52, 5260, WLAN_TX_PWR_EMEA_DEFAULT},
{56, 5280, WLAN_TX_PWR_EMEA_DEFAULT},
{60, 5300, WLAN_TX_PWR_EMEA_DEFAULT},
{64, 5320, WLAN_TX_PWR_EMEA_DEFAULT},
{100, 5500, WLAN_TX_PWR_EMEA_DEFAULT},
{104, 5520, WLAN_TX_PWR_EMEA_DEFAULT},
{108, 5540, WLAN_TX_PWR_EMEA_DEFAULT},
{112, 5560, WLAN_TX_PWR_EMEA_DEFAULT},
{116, 5580, WLAN_TX_PWR_EMEA_DEFAULT},
{120, 5600, WLAN_TX_PWR_EMEA_DEFAULT},
{124, 5620, WLAN_TX_PWR_EMEA_DEFAULT},
{128, 5640, WLAN_TX_PWR_EMEA_DEFAULT},
{132, 5660, WLAN_TX_PWR_EMEA_DEFAULT},
{136, 5680, WLAN_TX_PWR_EMEA_DEFAULT},
{140, 5700, WLAN_TX_PWR_EMEA_DEFAULT}
};
/* Band: 'A', Region: Japan */
CHANNEL_FREQ_POWER channel_freq_power_JPN_A[] = {
{8, 5040, WLAN_TX_PWR_JP_DEFAULT},
{12, 5060, WLAN_TX_PWR_JP_DEFAULT},
{16, 5080, WLAN_TX_PWR_JP_DEFAULT},
{34, 5170, WLAN_TX_PWR_JP_DEFAULT},
{38, 5190, WLAN_TX_PWR_JP_DEFAULT},
{42, 5210, WLAN_TX_PWR_JP_DEFAULT},
{46, 5230, WLAN_TX_PWR_JP_DEFAULT},
/*
{240, 4920, WLAN_TX_PWR_JP_DEFAULT},
{244, 4940, WLAN_TX_PWR_JP_DEFAULT},
{248, 4960, WLAN_TX_PWR_JP_DEFAULT},
{252, 4980, WLAN_TX_PWR_JP_DEFAULT}
Removed these 4 11J channels*/
};
#endif /* MULTI BANDS */
typedef struct _region_cfp_table {
u8 region;
CHANNEL_FREQ_POWER *cfp_BG;
int cfp_no_BG;
#ifdef MULTI_BANDS
CHANNEL_FREQ_POWER *cfp_A;
int cfp_no_A;
#endif /* MULTI BANDS */
} region_cfp_table_t;
/*region_cfp_table defines all the supported region-band- chan list*/
region_cfp_table_t region_cfp_table[] = {
{ 0x10, /*US FCC*/
channel_freq_power_US_BG,
sizeof(channel_freq_power_US_BG)/sizeof(CHANNEL_FREQ_POWER),
#ifdef MULTI_BANDS
channel_freq_power_A,
sizeof(channel_freq_power_A)/sizeof(CHANNEL_FREQ_POWER),
#endif /* MULTI BANDS */
},
{ 0x20, /*CANADA IC*/
channel_freq_power_US_BG,
sizeof(channel_freq_power_US_BG)/sizeof(CHANNEL_FREQ_POWER),
#ifdef MULTI_BANDS
channel_freq_power_A,
sizeof(channel_freq_power_A)/sizeof(CHANNEL_FREQ_POWER),
#endif /* MULTI BANDS */
},
{ 0x30, /*EU*/
channel_freq_power_EU_BG,
sizeof(channel_freq_power_EU_BG)/sizeof(CHANNEL_FREQ_POWER),
#ifdef MULTI_BANDS
channel_freq_power_EU_A,
sizeof(channel_freq_power_EU_A)/sizeof(CHANNEL_FREQ_POWER),
#endif /* MULTI BANDS */
},
{ 0x31, /*SPAIN*/
channel_freq_power_SPN_BG,
sizeof(channel_freq_power_SPN_BG)/sizeof(CHANNEL_FREQ_POWER),
#ifdef MULTI_BANDS
channel_freq_power_A,
sizeof(channel_freq_power_A)/sizeof(CHANNEL_FREQ_POWER),
#endif /* MULTI BANDS */
},
{ 0x32, /*FRANCE*/
channel_freq_power_FR_BG,
sizeof(channel_freq_power_FR_BG)/sizeof(CHANNEL_FREQ_POWER),
#ifdef MULTI_BANDS
channel_freq_power_A,
sizeof(channel_freq_power_A)/sizeof(CHANNEL_FREQ_POWER),
#endif /* MULTI BANDS */
},
{ 0x40, /*JAPAN*/
channel_freq_power_JPN_BG,
sizeof(channel_freq_power_JPN_BG)/sizeof(CHANNEL_FREQ_POWER),
#ifdef MULTI_BANDS
channel_freq_power_JPN_A,
sizeof(channel_freq_power_JPN_A)/sizeof(CHANNEL_FREQ_POWER),
#endif /* MULTI BANDS */
},
/*Add new region here */
};
u8 WlanDataRates[WLAN_SUPPORTED_RATES] =
{ 0x02, 0x04, 0x0B, 0x16, 0x00, 0x0C, 0x12,
0x18, 0x24, 0x30, 0x48, 0x60, 0x6C, 0x00 };
#ifdef MULTI_BANDS
u8 SupportedRates[A_SUPPORTED_RATES];
/* First two rates are basic rates */
u8 SupportedRates_B[B_SUPPORTED_RATES] =
{ 0x82, 0x84, 0x0b, 0x16, 0, 0, 0, 0 };
/* First four rates are basic rates */
u8 SupportedRates_G[G_SUPPORTED_RATES] =
{ 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, 0};
/* TODO: Check which are basic rates for band 'a' */
/* First two rates are basic rates */
u8 SupportedRates_A[A_SUPPORTED_RATES] =
{ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c, 0};
u8 AdhocRates_A[A_SUPPORTED_RATES] =
{ 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c, 0};
#else
#ifdef G_RATE
u8 SupportedRates[G_SUPPORTED_RATES] =
{ 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, 0};
#else
u8 SupportedRates[B_SUPPORTED_RATES] =
{ 0x82, 0x84, 0x0b, 0x16, 0, 0, 0, 0 };
#endif
#endif
#ifdef ADHOC_GRATE
u8 AdhocRates_G[G_SUPPORTED_RATES] =
{ 0x82, 0x84, 0x8b, 0x96, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, 0};
#else ///ADHOC_GRATE
u8 AdhocRates_G[4] =
{ 0x82, 0x84, 0x8b, 0x96};
#endif ///ADHOC_GRATE
u8 AdhocRates_B[4] =
{ 0x82, 0x84, 0x8b, 0x96};
static wlan_private *wlan_add_card(void *card);
static int wlan_remove_card(void *card);
//static void free_private(wlan_private * priv);
char *driver_name = "marvell";
wlan_private *wlanpriv = NULL;
const char *errRequestMem = "request_mem_region failed!";
const char *errAllocation = "memory allocation failed!";
const char *errNoEtherDev = "cannot initialize ethernet device!";
CHANNEL_FREQ_POWER *wlan_get_region_cfp_table(u8 region, u8 band, int *cfp_no)
{
int i;
ENTER();
for ( i=0; i< sizeof(region_cfp_table)/sizeof(region_cfp_table_t);
i++ ) {
PRINTK2("region_cfp_table[i].region=%d\n", region_cfp_table[i].region );
if (region_cfp_table[i].region == region ) {
#ifdef MULTI_BANDS
if (band & (BAND_B | BAND_G))
#endif
{
*cfp_no = region_cfp_table[i].cfp_no_BG;
LEAVE();
return region_cfp_table[i].cfp_BG;
}
#ifdef MULTI_BANDS
else {
if (band & BAND_A) {
*cfp_no = region_cfp_table[i].cfp_no_A;
LEAVE();
return region_cfp_table[i].cfp_A;
}
else {
PRINTK2("Error Band[%x]\n", band );
LEAVE();
return NULL;
}
}
#endif
}
}
LEAVE();
return NULL;
}
int wlan_set_regiontable(wlan_private *priv, u8 region, u8 band)
{
wlan_adapter *Adapter = priv->adapter;
int i = 0;
CHANNEL_FREQ_POWER *cfp;
int cfp_no;
ENTER();
memset(Adapter->region_channel, 0, sizeof(Adapter->region_channel));
#ifdef MULTI_BANDS
if (band & (BAND_B | BAND_G))
#endif
{
#ifdef MULTI_BANDS
cfp = wlan_get_region_cfp_table( region, BAND_G|BAND_B, &cfp_no);
#else
cfp = wlan_get_region_cfp_table( region, band, &cfp_no);
#endif
if ( cfp != NULL ) {
Adapter->region_channel[i].NrCFP = cfp_no;
Adapter->region_channel[i].CFP = cfp;
}
else {
PRINTK2("wrong region code %#x in Band B-G\n",region);
return -1;
}
Adapter->region_channel[i].Valid = TRUE;
Adapter->region_channel[i].Region = region;
#ifdef MULTI_BANDS
Adapter->region_channel[i].Band =
(band & BAND_G) ? BAND_G : BAND_B;
#else
Adapter->region_channel[i].Band = band;
#endif
i++;
}
#ifdef MULTI_BANDS
if (band & BAND_A) {
cfp = wlan_get_region_cfp_table( region, BAND_A, &cfp_no);
if ( cfp != NULL ) {
Adapter->region_channel[i].NrCFP = cfp_no;
Adapter->region_channel[i].CFP = cfp;
}
else {
PRINTK2("wrong region code %#x in Band A\n",region);
return -1;
}
Adapter->region_channel[i].Valid = TRUE;
Adapter->region_channel[i].Region = region;
Adapter->region_channel[i].Band = BAND_A;
}
#endif
LEAVE();
return 0;
}
#ifdef CONFIG_MARVELL_PM
extern int SetDeepSleep(wlan_private *priv, BOOLEAN bDeepSleep);
/* Linux Power Management */
static int wlan_pm_callback(struct pm_dev *pmdev, pm_request_t pmreq,
void *pmdata)
{
wlan_private *priv = wlanpriv;
wlan_adapter *Adapter = priv->adapter;
struct net_device *dev = priv->wlan_dev.netdev;
switch (pmreq) {
case PM_SUSPEND:
/*
* Check for Association, if associated return -1
* indicating NOT to put the host processor to sleep
*/
if ((Adapter->MediaConnectStatus ==
WlanMediaStateConnected) &&
(Adapter->DeepSleep_State !=
DEEP_SLEEP_USER_ENABLED))
return -1;
/*
* Detach the network interface
* if the network is running
*/
if (netif_running(dev))
netif_device_detach(dev);
/*
* Storing and restoring of the regs be taken care
* at the driver rest will be done at wlan driver
* this makes driver independent of the card
*/
if (Adapter->DeepSleep_State == DEEP_SLEEP_DISABLED) {
#if defined(DEEP_SLEEP_CMD)
SetDeepSleep(priv, TRUE);
#else
sbi_enter_deep_sleep(priv);
#endif
Adapter->DeepSleep_State =
DEEP_SLEEP_OS_ENABLED;
}
if (Adapter->PM_State == PM_DISABLED) {
sbi_suspend(priv);
Adapter->PM_State = PM_ENABLED;
}
break;
case PM_RESUME:
/*
* Bring the inteface up first
* This case should not happen still ...
*/
if (Adapter->PM_State == PM_ENABLED) {
sbi_resume(priv);
Adapter->PM_State = PM_DISABLED;
}
if (Adapter->DeepSleep_State == DEEP_SLEEP_OS_ENABLED) {
#if defined(DEEP_SLEEP_CMD)
SetDeepSleep(priv, FALSE);
#else
sbi_exit_deep_sleep(priv);
#endif
Adapter->DeepSleep_State = DEEP_SLEEP_DISABLED;
}
if (netif_running(dev))
netif_device_attach(dev);
break;
}
return 0;
}
#endif /* CONFIG_MARVELL_PM */
/*
* The open function for the network device.
*/
static int wlan_open(struct net_device *dev)
{
wlan_private *priv = (wlan_private *) dev->priv;
wlan_adapter *adapter = priv->adapter;
ENTER();
memcpy(dev->dev_addr, adapter->PermanentAddr, ETH_ALEN);
MOD_INC_USE_COUNT;
priv->open = TRUE;
//netif_carrier_on(dev);
netif_start_queue(dev); // To be compatible with ifconfig up/down
LEAVE();
return 0;
}
/*
* Network stop function
*/
static int wlan_stop(struct net_device *dev)
{
wlan_private *priv = dev->priv;
ENTER();
/* Flush all the packets upto the OS before stopping */
wlan_send_rxskbQ(priv);
netif_stop_queue(dev);
/*
* TODO: Tell the card to stop receiving. TODO: Tell the card to stop
* transmitting. TODO: If possible - power of the card
*/
MOD_DEC_USE_COUNT;
priv->open = FALSE;
LEAVE();
return 0;
}
/*
* To push the packets on to the net work
*/
int wlan_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
int ret;
wlan_private *priv = dev->priv;
wlan_adapter *adapter = priv->adapter;
#ifdef OMAP1510_TIMER_DEBUG
int i;
#endif /* OMAP1510_TIMER_DEBUG */
ENTER();
if (adapter->SurpriseRemoved) {
PRINTK1("Card Removed!!\n");
ret = 1;
goto done;
}
if (!skb) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -