⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wlan_main.c

📁 marvell cf wifi driver source code CF-8385-linux-x86-5.0.4.p0-132-src.rar
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * 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 + -