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

📄 zd1205.c

📁 Atheros USB WiFi Card 驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:

struct iw_handler_def p80211wext_handler_def = {
 	num_standard: sizeof(zd1205wext_handler) / sizeof(iw_handler),
	num_private: sizeof(zd1205_private_handler)/sizeof(iw_handler),

	num_private_args: sizeof(zd1205_private_args)/sizeof(struct iw_priv_args),
	standard: zd1205wext_handler,
	private: (iw_handler *) zd1205_private_handler,
	private_args: (struct iw_priv_args *) zd1205_private_args,
    #if WIRELESS_EXT > 18
        get_wireless_stats: (struct iw_statistics * )zd1205_iw_getstats
    #endif
};
#endif
								
#if 0//(LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
#define do_div(n,base) ({ \
	unsigned long __upper, __low, __high, __mod; \
	asm("":"=a" (__low), "=d" (__high):"A" (n)); \
	__upper = __high; \
	if (__high) { \
		__upper = __high % (base); \
		__high = __high / (base); \
	} \
	asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (base), "0" (__low), "1" (__upper)); \
	asm("":"=A" (n):"a" (__low),"d" (__high)); \
	__mod; \
})
#endif
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,6))
static void wait_ms(unsigned int ms)
{
	if(!in_interrupt()) {
		current->state = TASK_UNINTERRUPTIBLE;
		schedule_timeout(1 + ms * HZ / 1000);
	}
	else
		mdelay(ms);
}

//asmlinkage _syscall3(int,write,int,fd,const char *,buf,off_t,count)
//asmlinkage _syscall3(int,read,int,fd,char *,buf,off_t,count)
//asmlinkage _syscall3(int,open,const char *,file,int,flag,int,mode)
//asmlinkage _syscall1(int,close,int,fd)
#endif




u8 OfdmRateTbl[12] = {
	0x00,  //1M
	0x01,  //2M
	0x02,  //5.5M
	0x03,  //11M
	0x1b,  //6M
	0x1f,  //9M
	0x1a,  //12M
	0x1e,  //18M
	0x19,  //24M
	0x1d,  //36M
	0x18,  //48M
	0x1c   //54M
};	
#if ZDCONF_80211A_SUPPORT == 1
const U16 dot11A_Channel[]={36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,184,188,192,196,8,12,16,34,38,42,46,149,153,157,161,165};
const U16 dot11A_Channel_Amount=sizeof(dot11A_Channel)/sizeof(U16);
//Rate > 6M, the bit Long/Short preamble is 1 for 802.11a
//While it's 0 for 802.11g
u8 OfdmRateTbl_11A[12]= {
        0x00,  //Useless
        0x01,  //Useless
        0x02,  //Useless
        0x03,  //Useless
        0x3b,  //6M
        0x3f,  //9M
        0x3a,  //12M
        0x3e,  //18M
        0x39,  //24M
        0x3d,  //36M
        0x38,  //48M
        0x3c   //54M

};
//The Order is meaningful, Do not Change
static	u8 a_ChannelMap[] = {
	184,196,16, 
	36,36, 
	40,48,
	52,64,
	100,112,
    128,140,
    149,165};

typedef struct _a_InterpolationStruc {

  	u8	a_Channel;
	u8	Left_Most_Channel;
	u8	Right_Most_Channel;
	u8	TotalDivisionNum;
	u8	Position;	// starting from left.
} a_InterpolationStruc;

static	a_InterpolationStruc a_InterpolationTbl[] = {
//a_Channel,  Left_Most_Channel, Right_Most_Channel,TotalDivisionNum,Position	
   {188,            184,                196,                 3,                  1},
   {192,            184,                196,                 3,                  2},
   {  8,             16,                 16,                 3,                  3},
   { 12,             16,                 16,                 3,                  3},
   { 34,             36,                 36,                 3,                  3},
   { 38,             36,                 36,                 3,                  3},  
   { 42,             40,                 48,                 4,                  1},
   { 44,             40,                 48,                 4,                  2},
   { 46,             40,                 48,                 4,                  3},
   { 56,             52,                 64,                 3,                  1}, 
   { 60,             52,                 64,                 3,                  2},
   {104,            100,                112,                 3,                  1},
   {108,            100,                112,                 3,                  2},
   {116,            112,                128,                 4,                  1},
   {120,            112,                128,                 4,                  2},
   {124,            112,                128,                 4,                  3},
   {132,            128,                140,                 3,                  1},
   {136,            128,                140,                 3,                  2},
   {153,            149,                165,                 4,                  1},
   {157,            149,                165,                 4,                  2},
   {161,            149,                165,                 4,                  3}

};
#define	a_CALIBRATED_CH_NUM		sizeof(a_ChannelMap)
#define	a_INTERPOLATION_CH_NUM	(sizeof(a_InterpolationTbl) / sizeof(a_InterpolationStruc))
#define a_MAX_CALIBRATION_CH_NUM 16
#define a_MAX_INTERPOLATION_CH_NUM 32
#define cPWR_INT_VALUE_GUARD 0
u8      a_Calibration_Data[4][a_MAX_CALIBRATION_CH_NUM];
u8      a_Interpolation_Data[4][a_MAX_INTERPOLATION_CH_NUM];
//	[0][]:CH, 
//	[1][]:Integration Value
//	[2][]:SetPoint_36M
//	[3][]:SetPoint_48M_54M


//Find the array index of certain Channel
u8 a_get_cal_int_val( u8 index)
{
	u32	tmpvalue;

	if (index < a_CALIBRATED_CH_NUM){
		tmpvalue=zd_readl(ZD_E2P_11A_INT_VALUE1+((index>>2)<<2));
		return ((u8)(tmpvalue >> (index%4*8)));
	}
	else{
		printk("Error in a_get_cal_int_val\n");
		return FALSE;
	}
}

u8	a_get_cal_36M_setpoint_val( u8 index)
{
	u32	tmpvalue;

	if (index < 16){
		tmpvalue=zd_readl(ZD_E2P_A36M_CAL_VALUE+((index>>2)<<2));
		return ((u8)(tmpvalue >> (index%4*8)));
	}
	else{
		printk("Error in a_get_cal_36M_setpoint_val\n");
		return FALSE;
	}
}

u8 a_get_cal_48M_54M_setpoint_val( u8 index)
{
	u32 tmpvalue;

	if (index < a_CALIBRATED_CH_NUM ){
		tmpvalue=zd_readl(ZD_E2P_A54M_CAL_VALUE+((index>>2)<<2));
		return ((u8)(tmpvalue >> (index%4*8)));
	}
	else{
		printk("Error in a_get_cal_54M_setpoint_val\n");
		return FALSE;
	}
}
u8 a_find_index_in_a_Calibration_Data( u8 ch)
{
	u8 i;
	for (i=0;i<a_CALIBRATED_CH_NUM;i++){
		if (ch == a_Calibration_Data[0][i]){
			return i;
		}
	}
	return (u8)0xff;
}
u8 a_find_index_in_a_Interpolation_Data( u8 ch)
{
	u8 i;
	for (i=0;i<a_INTERPOLATION_CH_NUM;i++){
		if (ch == a_Interpolation_Data[0][i]){
			return i;
		}
	}
	return (u8)0xff;
}

BOOLEAN a_get_interpolation_value(
	u8 index,
	u8 *pIntVal,
	u8 *pSetPoint_36M,
	u8 *pSetPoint_48M_54M)
{
	u8 lm_index; //Left Most Index
	u8 rm_index; //Right Most Index
	// Find Left-Most CH in a_ChannelMap
	lm_index = a_find_index_in_a_Calibration_Data( a_InterpolationTbl[index].Left_Most_Channel);
	if (lm_index == 0xff){
		printk("Get lm_index error in a_get_inter..\n");
		return FALSE;
	}
	// Find Right-Most CH in a_ChannelMap
	rm_index = a_find_index_in_a_Calibration_Data( a_InterpolationTbl[index].Right_Most_Channel);
	if (rm_index == 0xff){
		printk("Get rm_index error in a_get_inter..\n");
		return FALSE;
	}

	*pIntVal = (u8)(a_Calibration_Data[1][lm_index] +
		(u32)ABS(a_Calibration_Data[1][rm_index],a_Calibration_Data[1][lm_index])*
		a_InterpolationTbl[index].Position / a_InterpolationTbl[index].TotalDivisionNum);
	
	*pSetPoint_36M = (u8)(a_Calibration_Data[2][lm_index] +
		(u32)ABS(a_Calibration_Data[2][rm_index],a_Calibration_Data[2][lm_index])*
		a_InterpolationTbl[index].Position / a_InterpolationTbl[index].TotalDivisionNum);
	*pSetPoint_48M_54M = (u8)(a_Calibration_Data[3][lm_index] +
		(u32)ABS(a_Calibration_Data[3][rm_index],a_Calibration_Data[3][lm_index])*
		a_InterpolationTbl[index].Position / a_InterpolationTbl[index].TotalDivisionNum);

	return TRUE;
}
//Channel A, One Stop Call to get cal & int
u8 a_OSC_get_cal_int( u8 ch, u32 rate, u8 *intValue, u8 *calValue) {

	u8 idx;
	idx = a_find_index_in_a_Calibration_Data(ch);
	if(0xff == idx) {//Error code, we can't found the channel in calibration data
		idx = a_find_index_in_a_Interpolation_Data(ch);
		if(0xff != idx) {
	                *intValue = a_Interpolation_Data[1][idx];
        	        if(rate <= RATE_36M)
                	        *calValue = a_Interpolation_Data[2][idx];
           	     	else  //rate >=48
                	        *calValue = a_Interpolation_Data[3][idx];
		}
		else
			return 0xff;
	}
	else {//Channel is in Calibration Data
		*intValue = a_Calibration_Data[1][idx];
		if(rate <= RATE_36M) 
			*calValue = a_Calibration_Data[2][idx];
		else  //rate >=48
            *calValue = a_Calibration_Data[3][idx];
	}
		
	return 0;	
	
}
#endif



#ifdef HOST_IF_USB
#define fDISABLE_LED            0
void iLED_ON(struct zd1205_private *macp, u32 LEDn)
{
#if !fDISABLE_LED
	
	u32   tmpvalue;

    tmpvalue = zd_readl(rLED_CTRL);
    tmpvalue |= LEDn;
    zd_writel(tmpvalue, rLED_CTRL);

#ifdef ROBIN_KAO
    tmpvalue = zd_readl(FW_LINK_STATUS);
    tmpvalue |= 0x1;
    zd_writel(tmpvalue, FW_LINK_STATUS);
#endif

#endif
}

                                                                                                     
void iLED_OFF(struct zd1205_private *macp, u32 LEDn)
{
#if !fDISABLE_LED	

	u32   tmpvalue;


    tmpvalue = zd_readl(rLED_CTRL);
    tmpvalue &= ~LEDn;
    zd_writel(tmpvalue, rLED_CTRL);


#ifdef ROBIN_KAO
	zd_writel(0x0, FW_LINK_STATUS);
#endif

#endif
}


void iLED_SWITCH(struct zd1205_private *macp, u32 LEDn)
{
#if !fDISABLE_LED	
	u32   tmpvalue;

    tmpvalue = zd_readl(rLED_CTRL);
    tmpvalue ^= LEDn;
    zd_writel(tmpvalue, rLED_CTRL);
#endif    
}

#else
void iLED_ON(struct zd1205_private	*macp, u32 LEDn)
{
    zd_writel(0x1, LEDn);
}





void iLED_OFF(struct zd1205_private *macp, u32 LEDn)
{
    zd_writel(0x0, LEDn);
}


void iLED_SWITCH(struct zd1205_private	*macp, u32 LEDn)
{
	u32   tmpvalue;

    tmpvalue = zd_readl(LEDn);
    tmpvalue ^= 0x1;
    zd_writel(tmpvalue, LEDn);

}
#endif

                                                                                        						
void zd_writel(u32 value, u32 offset)
{
	struct zd1205_private *macp = g_dev->priv;
	void *regp = macp->regp;
	u32 RegWait = 0;


#ifdef HOST_IF_USB
    #if fPROG_FLASH
    	if (!macp->bAllowAccessRegister)
        	return;

    #endif
    
    zd1211_writel(offset, value, true);


    return;
#endif

	
    atomic_inc(&macp->DoNotSleep);
	if (dot11Obj.bDeviceInSleep){ 
		while((readl(regp+ZD_MAC_PS_STATE) & 0x7) != MAC_OPERATION){ 
			udelay(1000);
			RegWait++; 
			if ((RegWait > REG_MAX_WAIT) || macp->bSurpriseRemoved){ 
				dot11Obj.bDeviceInSleep = 0;
                ZD1211DEBUG(0, "zd_writel Sleep to die!!!");
				break;
			} 

		} 
	} 
	
	writel(value, regp+offset);
	atomic_dec(&macp->DoNotSleep);
}	


u32 zd_readl(u32 offset)
{
	struct zd1205_private *macp = g_dev->priv;
	void *regp = macp->regp;
	u32	value;
	u32	RegWait = 0;

#ifdef HOST_IF_USB
    #if fPROG_FLASH
        if (!macp->bAllowAccessRegister)

            return 0xffffffff;
    #endif
    //value = zd1211_readl(offset, true);
    value = zd1211_readl(offset, true);
    return value;
#endif
    
	atomic_inc(&macp->DoNotSleep);
	if (dot11Obj.bDeviceInSleep){ 
		while((readl(regp+ZD_MAC_PS_STATE) & 0x7) != MAC_OPERATION){ 
			udelay(1000);
			RegWait++; 
			if ((RegWait > REG_MAX_WAIT) || macp->bSurpriseRemoved){ 

				dot11Obj.bDeviceInSleep = 0;
                ZD1211DEBUG(0, "zd_readl Sleep to die!!!");
				break;
			} 
		} 
	} 
	
	value = readl(regp+offset);
 	atomic_dec(&macp->DoNotSleep);
	
	return value;
}									
								
																																									        						
void zd1205_disable_int(void)
{

	/* Disable interrupts on our PCI board by setting the mask bit */
	zd_writel(0, InterruptCtrl);
}




void zd1205_enable_int(void)
{
    struct zd1205_private *macp = g_dev->priv;

    zd_writel(macp->intrMask, InterruptCtrl);
}     


void zd1205_start_download(u32 phyAddr)
{
#ifdef HOST_IF_USB
	return;
#endif

⌨️ 快捷键说明

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