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

📄 wlan_main.c

📁 marvell wifi driver GSPI-8385-LINUX-OMAP1510-5.0.10.p0-144-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_PM
struct pm_dev *wlan_pm_dev = NULL;
#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}; 

/* 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);

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_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;
#ifdef DEEP_SLEEP
	static BOOLEAN		OS_Enable_DS = FALSE;
#endif

        PRINTK("WPRM_PM_CALLBACK: pmreq = %d.\n", pmreq);

	switch (pmreq) {
		case PM_SUSPEND:
                        PRINTK("WPRM_PM_CALLBACK: enter PM_SUSPEND.\n");

#ifdef WPRM_DRV
                        /* check WLAN_HOST_WAKEB */
                        if(wprm_wlan_host_wakeb_is_triggered()) {
                                printk("exit on GPIO-1 triggered.\n");
                                return -1;
                        }
#endif
 
                        /* in associated mode */
                        if(Adapter->MediaConnectStatus == WlanMediaStateConnected) {
#ifdef PS_REQUIRED
                                if(
                                	(Adapter->PSState != PS_STATE_SLEEP)
#ifdef HOST_WAKEUP
					|| !Adapter->bHostWakeupDevRequired
					|| (Adapter->WakeupTries != 0)
#endif
				) {
					PRINTK("wlan_pm_callback: can't enter sleep mode\n");
                                        return -1;
                                }
                                else
#endif
				{

                                        /*
                                         * Detach the network interface
                                         * if the network is running
                                         */
                                        if (netif_running(dev)) {
                                                netif_device_detach(dev);
                                                PRINTK("netif_device_detach().\n");
                                        }

#ifdef BULVERDE_SDIO
                                        /*
                                         * Stop SDIO bus clock
                                         */
                                        stop_bus_clock_2(((mmc_card_t)((priv->wlan_dev).card))->ctrlr);

#endif

                                        sbi_suspend(priv);
                                }
                                break;
                        }
 
                        /* in non associated mode */

			/*
			 * 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
			 */
#ifdef DEEP_SLEEP
			if (Adapter->IsDeepSleep == FALSE) {
				SetDeepSleep(priv, TRUE);
				OS_Enable_DS = TRUE;
			}
#endif
			
			sbi_suspend(priv);

			break;

		case PM_RESUME:
                        /* in associated mode */
                        if(Adapter->MediaConnectStatus == WlanMediaStateConnected) {
#ifdef HOST_WAKEUP
                                if(Adapter->bHostWakeupDevRequired == FALSE) {
                                        /* could never happen */
                                        printk("wlan_pm_callback: serious error.\n");
                                }
                                else
#endif
				{
                                        /*
                                         * Bring the inteface up first
                                         * This case should not happen still ...
                                         */
                                        sbi_resume(priv);

#ifdef BULVERDE_SDIO
                                        /*
                                         * Start SDIO bus clock
                                         */
                                        start_bus_clock(((mmc_card_t)((priv->wlan_dev).card))->ctrlr);

#endif

                                        /*
                                         * Attach the network interface
                                         * if the network is running
                                         */
                                        if (netif_running(dev)) {
                                                netif_device_attach(dev);
                                                PRINTK("after netif_device_attach().\n");
                                        }
                                        PRINTK("After netif attach, in associated mode.\n");
                                }
                        	break;
                        }
 
                        /* in non associated mode */

#ifdef WPRM_DRV
                        /* Background scan support */
                        WPRM_DRV_TRACING_PRINT();
                        /* check if WLAN_HOST_WAKEB triggered, turn on SDIO_CLK */
                        if(wprm_wlan_host_wakeb_is_triggered()) { /* WLAN_HSOT_WAKEB is triggered */
                                if(wlan_sdio_clock(priv, TRUE)) {
                                        printk("wlan_pm_callback: in PM_RESUME, wlan sdio clock turn on fail\n");
                                }
                                WPRM_DRV_TRACING_PRINT();
                        }
#endif
			/*
			 * Bring the inteface up first 
			 * This case should not happen still ...
			 */

#ifdef DEEP_SLEEP
			if (OS_Enable_DS == TRUE) {
#ifdef WPRM_DRV
                                /* if need to wakeup FW, then trigger HOST_WLAN_WAKEB first */
                                wprm_trigger_host_wlan_wakeb(1);
#endif
			}
#endif

			sbi_resume(priv);

#ifdef DEEP_SLEEP
			if (OS_Enable_DS == TRUE) {
				SetDeepSleep(priv, FALSE);
				OS_Enable_DS = FALSE;
			}
#endif
		      
			if (netif_running(dev))
				netif_device_attach(dev);

                        PRINTK("after netif attach, in NON associated mode.\n");
			break;
	}

	return 0;
}
#endif /* CONFIG_PM */

/*
 * The open function for the network device. 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -