📄 zd1205.c
字号:
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 + -