📄 aironet4500_core.c
字号:
udelay(1); if (cycles > 10000) { printk(KERN_CRIT "deadlock in bap\n"); goto return_AWC_ERROR; }; status = AWC_IN(cmd->bap->offset); if (status & AWC_BAP_BUSY) { if (cycles % 100 == 99 ) { save_flags(flags); cli(); if (!cleared){ AWC_IN(cmd->dev->base_addr + 0x26); AWC_OUT(cmd->dev->base_addr + 0x26, 0); WAIT61x3; cleared = 1; } AWC_OUT(cmd->bap->select, cmd->rid); WAIT61x3; AWC_OUT(cmd->bap->offset, cmd->offset); restore_flags(flags); #ifdef AWC_DEBUG printk("B"); #endif if ( cmd->priv->sleeping_bap) udelay(bap_sleep); else udelay(30); //restart_timeout(); } if (jiffies - jiff > 1 ) { AWC_ENTRY_EXIT_DEBUG(" BAD BUSY exit \n"); awc_dump_registers(cmd->dev); goto return_AWC_ERROR; } continue; } if (status & AWC_BAP_DONE) { WAIT61x3; WAIT61x3; WAIT61x3; // if ((status & 0xfff) != cmd->offset) // printk(KERN_ERR "awcPBD %x ",status); AWC_ENTRY_EXIT_DEBUG(" exit \n"); if (cmd->priv->sleeping_bap) udelay(bap_sleep_after_setup); // success goto return_AWC_SUCCESS; } if (status & AWC_BAP_ERR) { AWC_ENTRY_EXIT_DEBUG(" BAD exit \n"); // invalid rid or offset printk(KERN_ERR "bap setup error bit set for rid %x offset %x \n",cmd->rid,cmd->offset); awc_dump_registers(cmd->dev); goto return_AWC_ERROR; } if ( cmd->priv->sleeping_bap) udelay(bap_sleep); else udelay(1); // -- awc missed it, try again save_flags(flags); cli(); AWC_OUT(cmd->bap->select, cmd->rid); WAIT61x3; AWC_OUT(cmd->bap->offset, cmd->offset); WAIT61x3; restore_flags(flags); if (jiffies - jiff > HZ) if (! (status &(AWC_BAP_ERR |AWC_BAP_DONE |AWC_BAP_BUSY))){ printk("aironet4500: bap setup lock without any status bits set"); awc_dump_registers(cmd->dev); goto return_AWC_ERROR; }; } AWC_ENTRY_EXIT_DEBUG(" WE MUST NOT BE HERE exit \n");ejected_unlock: if (bap_setup_spinlock) my_spin_unlock_irqrestore(&cmd->priv->bap_setup_spinlock,cmd->priv->bap_setup_spinlock_flags); AWC_ENTRY_EXIT_DEBUG(" ejected_unlock_exit \n"); return -1;return_AWC_ERROR: if (bap_setup_spinlock) my_spin_unlock_irqrestore(&cmd->priv->bap_setup_spinlock,cmd->priv->bap_setup_spinlock_flags); AWC_ENTRY_EXIT_DEBUG(" AWC_ERROR_exit \n"); return AWC_ERROR; return_AWC_SUCCESS: if (bap_setup_spinlock) my_spin_unlock_irqrestore(&cmd->priv->bap_setup_spinlock,cmd->priv->bap_setup_spinlock_flags); AWC_ENTRY_EXIT_DEBUG(" exit \n"); return AWC_SUCCESS; } // requires call to awc_bap_setup() firstinline intawc_bap_read(struct awc_command * cmd) { register u16 len; register u16 * buff = (u16 *) cmd->buff; register u16 port= cmd->bap->data; AWC_ENTRY_EXIT_DEBUG(" entry awc_bap_read "); if (!cmd->bap && !(cmd->lock_state & (AWC_BAP_SEMALOCKED |AWC_BAP_LOCKED))) DEBUG(0,"no bap or bap not locked %d !!", cmd->command); cmd->len = (cmd->len + 1) & (~1); // round up to even value len = cmd->len / 2; if (cmd->priv->ejected) return -1; if (cmd->priv->sleeping_bap) udelay(bap_sleep_before_write); if (!cmd->priv->sleeping_bap) while ( len-- > 0) *buff++ = AWC_IN(port); else while ( len-- > 0){ *buff++ = AWC_IN(port); } AWC_ENTRY_EXIT_DEBUG(" exit \n"); if (cmd->priv->ejected) return -1; return AWC_SUCCESS;} // requires call to awc_bap_setup() firstinline intawc_bap_write(struct awc_command * cmd){ register u16 len; register u16 * buff = (u16 *) cmd->buff; register u16 port= cmd->bap->data; AWC_ENTRY_EXIT_DEBUG(" entry awc_bap_write "); if (!cmd->bap && !(cmd->lock_state & (AWC_BAP_SEMALOCKED |AWC_BAP_LOCKED))) DEBUG(0,"no bap or bap not locked %d !!", cmd->command); cmd->len = (cmd->len + 1) & (~1); // round up to even value len = cmd->len / 2; if (cmd->priv->ejected) return -1; if (cmd->priv->sleeping_bap) udelay(bap_sleep_before_write); if (!cmd->priv->sleeping_bap) while (len-- > 0) AWC_OUT(port, *buff++); else while ( len-- > 0){ AWC_OUT(port, *buff++); } if (cmd->priv->ejected) return -1; AWC_ENTRY_EXIT_DEBUG(" exit \n"); return AWC_SUCCESS;}/***************************** RID READ/WRITE ********************/const struct aironet4500_rid_selector aironet4500_RID_Select_General_Config =(const struct aironet4500_rid_selector){ 0xFF10, 1,0,0, "General Configuration" }; // See notes General Configuration Many configuration items.const struct aironet4500_rid_selector aironet4500_RID_Select_SSID_list =(const struct aironet4500_rid_selector){ 0xFF11, 1,0,0, "Valid SSID list" }; // See notes Valid SSID list List of SSIDs which the station may associate to.const struct aironet4500_rid_selector aironet4500_RID_Select_AP_list =(const struct aironet4500_rid_selector){ 0xFF12, 1,0,0, "Valid AP list" }; // See notes Valid AP list List of APs which the station may associate to.const struct aironet4500_rid_selector aironet4500_RID_Select_Driver_name =(const struct aironet4500_rid_selector){ 0xFF13, 1,0,0, "Driver name" }; // See notes Driver name The name and version of the driver (for debugging)const struct aironet4500_rid_selector aironet4500_RID_Select_Encapsulation =(const struct aironet4500_rid_selector){ 0xFF14, 1,0,0, "Ethernet Protocol" }; // See notes Ethernet Protocol Rules for encapsulating ethernet payloads onto 802.11.const struct aironet4500_rid_selector aironet4500_RID_Select_WEP_volatile =(const struct aironet4500_rid_selector){ 0xFF15, 1,0,0, "WEP key volatile" }; // const struct aironet4500_rid_selector aironet4500_RID_Select_WEP_nonvolatile =(const struct aironet4500_rid_selector){ 0xFF16, 1,0,0, "WEP key non-volatile" }; //const struct aironet4500_rid_selector aironet4500_RID_Select_Modulation =(const struct aironet4500_rid_selector){ 0xFF17, 1,0,0, "Modulation" }; //const struct aironet4500_rid_selector aironet4500_RID_Select_Active_Config =(const struct aironet4500_rid_selector){ 0xFF20, 0,1,1, "Actual Configuration" }; // Read only Actual Configuration This has the same format as the General Configuration.const struct aironet4500_rid_selector aironet4500_RID_Select_Capabilities =(const struct aironet4500_rid_selector){ 0xFF00, 0,1,0, "Capabilities" }; // Read Only Capabilities PC4500 Informationconst struct aironet4500_rid_selector aironet4500_RID_Select_AP_Info =(const struct aironet4500_rid_selector){ 0xFF01, 0,1,1, "AP Info" }; // Read Only AP Info Access Point Informationconst struct aironet4500_rid_selector aironet4500_RID_Select_Radio_Info =(const struct aironet4500_rid_selector){ 0xFF02, 0,1,1, "Radio Info" }; // Read Only Radio Info Radio Information -- note radio specificconst struct aironet4500_rid_selector aironet4500_RID_Select_Status =(const struct aironet4500_rid_selector){ 0xFF50, 0,1,1, "Status" }; // Read Only Status PC4500 Current Status Informationconst struct aironet4500_rid_selector aironet4500_RID_Select_16_stats =(const struct aironet4500_rid_selector){ 0xFF60, 0,1,1, "Cumulative 16-bit Statistics" }; // Read Only 16-bit Statistics Cumulative 16-bit Statisticsconst struct aironet4500_rid_selector aironet4500_RID_Select_16_stats_delta =(const struct aironet4500_rid_selector){ 0xFF61, 0,1,1, "Delta 16-bit Statistics" }; // Read Only 16-bit Statistics Delta 16-bit Statistics (since last clear)const struct aironet4500_rid_selector aironet4500_RID_Select_16_stats_clear =(const struct aironet4500_rid_selector){ 0xFF62, 0,1,1, "Delta 16-bit Statistics and Clear" }; // Read Only / 16-bit Statistics Delta 16-bit Statistics and Clearconst struct aironet4500_rid_selector aironet4500_RID_Select_32_stats =(const struct aironet4500_rid_selector){ 0xFF68, 0,1,1, "Cumulative 32-bit Statistics" }; // Read Only 32-bit Statistics Cumulative 32-bit Statisticsconst struct aironet4500_rid_selector aironet4500_RID_Select_32_stats_delta =(const struct aironet4500_rid_selector){ 0xFF69, 0,1,1, "Delta 32-bit Statistics" }; // Read Only 32-bit Statistics Delta 32-bit Statistics (since last clear)const struct aironet4500_rid_selector aironet4500_RID_Select_32_stats_clear =(const struct aironet4500_rid_selector){ 0xFF6A, 0,1,1, "Delta 32-bit Statistics and Clear" }; // Read Only / 32-bit Statistics Delta 32-bit Statistics and ClearEXPORT_SYMBOL(aironet4500_RID_Select_General_Config); EXPORT_SYMBOL(aironet4500_RID_Select_SSID_list); EXPORT_SYMBOL(aironet4500_RID_Select_AP_list); EXPORT_SYMBOL(aironet4500_RID_Select_Driver_name); EXPORT_SYMBOL(aironet4500_RID_Select_Encapsulation); EXPORT_SYMBOL(aironet4500_RID_Select_WEP_volatile); EXPORT_SYMBOL(aironet4500_RID_Select_WEP_nonvolatile); EXPORT_SYMBOL(aironet4500_RID_Select_Modulation); EXPORT_SYMBOL(aironet4500_RID_Select_Active_Config); EXPORT_SYMBOL(aironet4500_RID_Select_Capabilities); EXPORT_SYMBOL(aironet4500_RID_Select_AP_Info); EXPORT_SYMBOL(aironet4500_RID_Select_Radio_Info); EXPORT_SYMBOL(aironet4500_RID_Select_Status); EXPORT_SYMBOL(aironet4500_RID_Select_16_stats); EXPORT_SYMBOL(aironet4500_RID_Select_16_stats_delta); EXPORT_SYMBOL(aironet4500_RID_Select_16_stats_clear); EXPORT_SYMBOL(aironet4500_RID_Select_32_stats); EXPORT_SYMBOL(aironet4500_RID_Select_32_stats_delta); EXPORT_SYMBOL(aironet4500_RID_Select_32_stats_clear); struct awc_rid_dir awc_rids_temp[]={ // following MUST be consistent with awc_rids_setup !!! {&aironet4500_RID_Select_General_Config, 0x100 , NULL, NULL, NULL,0 }, {&aironet4500_RID_Select_SSID_list, 0x68 , NULL, NULL, NULL,0 }, {&aironet4500_RID_Select_AP_list, 0x20 , NULL, NULL, NULL,0 }, {&aironet4500_RID_Select_Driver_name, 0x12 , NULL, NULL, NULL,0 }, {&aironet4500_RID_Select_Encapsulation, 0x22 , NULL, NULL, NULL,0 }, {&aironet4500_RID_Select_Active_Config, 0x100 , NULL, NULL, NULL,0 }, {&aironet4500_RID_Select_Capabilities, 0x80 , NULL, NULL, NULL,0 }, {&aironet4500_RID_Select_Status, 0x6c , NULL, NULL, NULL,0 }, {&aironet4500_RID_Select_AP_Info, 0x06 , NULL, NULL, NULL,0 }, {&aironet4500_RID_Select_32_stats, 0x184 , NULL, NULL, NULL,0 }, {&aironet4500_RID_Select_32_stats_delta, 0x184 , NULL, NULL, NULL,0 }, {&aironet4500_RID_Select_32_stats_clear, 0x184 , NULL, NULL, NULL,0 }, {&aironet4500_RID_Select_WEP_volatile, 0x1c , NULL, NULL, NULL,0 }, {&aironet4500_RID_Select_WEP_nonvolatile, 0x1c , NULL, NULL, NULL,0 }, {&aironet4500_RID_Select_Modulation, 0x04 , NULL, NULL, NULL,0 },#ifdef AWC_USE_16BIT_STATS {&aironet4500_RID_Select_16_stats, 0xC2 , NULL, NULL, NULL,0 }, {&aironet4500_RID_Select_16_stats_delta, 0xC2 , NULL, NULL, NULL,0 }, {&aironet4500_RID_Select_16_stats_clear, 0xC2 , NULL, NULL, NULL,0 },#else {NULL},{NULL},{NULL},#endif {0} };int awc_readrid(struct net_device * dev, struct aironet4500_RID * rid, void *pBuf ){ struct awc_command cmd; int sleep_state ; AWC_ENTRY_EXIT_DEBUG(" entry awc_readrid "); if (!rid) return -1; if (!rid->selector) return -1; AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,0x21, rid->selector->selector, rid->selector->selector, rid->offset, (rid->bits / 8),pBuf); sleep_state = cmd.priv->sleeping_bap ; cmd.priv->sleeping_bap = 1; udelay(500); AWC_BAP_LOCK_NOT_CLI(cmd); if (awc_issue_command_and_block(&cmd)) goto final; udelay(1); if (awc_bap_setup(&cmd)) goto final; udelay(1); if (awc_bap_read(&cmd)) goto final; cmd.priv->sleeping_bap = sleep_state; AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" exit \n"); return 0; final: cmd.priv->sleeping_bap = sleep_state; AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" BAD exit \n"); return -1; ;}int awc_writerid(struct net_device * dev, struct aironet4500_RID * rid, void *pBuf){ struct awc_command cmd; int sleep_state ; AWC_ENTRY_EXIT_DEBUG(" entry awc_writerid "); AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,0x21, rid->selector->selector, rid->selector->selector,rid->offset, rid->bits/8,pBuf); sleep_state = cmd.priv->sleeping_bap ; cmd.priv->sleeping_bap = 1; udelay(500); AWC_BAP_LOCK_NOT_CLI(cmd); if (awc_issue_command_and_block(&cmd)) goto final; udelay(10); if (awc_bap_setup(&cmd)) goto final; udelay(10); if (awc_bap_write(&cmd)) goto final; udelay(10); cmd.command=0x121; if (awc_issue_command_and_block(&cmd)) goto final; cmd.priv->sleeping_bap = sleep_state; AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" exit \n"); return 0; final: cmd.priv->sleeping_bap = sleep_state; AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" BAD exit \n"); return -1; ;}int awc_readrid_dir(struct net_device * dev, struct awc_rid_dir * rid ){ struct awc_command cmd; int sleep_state; AWC_ENTRY_EXIT_DEBUG(" entry awcreadrid_dir "); AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,0x21, rid->selector->selector, rid->selector->selector,0, rid->bufflen,rid->buff); sleep_state = cmd.priv->sleeping_bap ; cmd.priv->sleeping_bap = 1; udelay(500); AWC_BAP_LOCK_NOT_CLI(cmd); if (awc_issue_command_and_block(&cmd)) goto final; if (awc_bap_setup(&cmd)) goto final; if (awc_bap_read(&cmd)) goto final; cmd.priv->sleeping_bap = sleep_state; AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" exit \n"); return 0; final: cmd.priv->sleeping_bap = sleep_state; AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" BAD exit \n"); return -1; ;}int awc_writerid_dir(struct net_device * dev, struct awc_rid_dir * rid){ struct awc_command cmd; int sleep_state ; AWC_ENTRY_EXIT_DEBUG(" entry awc_writerid_dir "); AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,0x21, rid->selector->selector, rid->selector->selector,0, rid->bufflen,((char *)rid->buff)); sleep_state = cmd.priv->sleeping_bap ; cmd.priv->sleeping_bap = 1; udelay(500); AWC_BAP_LOCK_NOT_CLI(cmd); if (awc_issue_command_and_block(&cmd)) goto final; if (awc_bap_setup(&cmd)) goto final; if (awc_bap_write(&cmd)) goto final; cmd.priv->sleeping_bap = sleep_state; cmd.command=0x121; udelay(500); if (awc_issue_command_and_block(&cmd)) goto final; AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" exit \n"); return 0; final: cmd.priv->sleeping_bap = sleep_state; AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" BAD exit \n"); return -1; ;}EXPORT_SYMBOL(awc_readrid);EXPORT_SYMBOL(awc_writerid);EXPORT_SYMBOL(awc_readrid_dir);EXPORT_SYMBOL(awc_writerid_dir);/***************************** STARTUP *******************/inlineintawc_issue_blocking_command(struct net_device * dev,u16 comm){ struct awc_command cmd;// struct awc_private * priv = (struct awc_private *)dev->priv; AWC_ENTRY_EXIT_DEBUG(" entry awc_issue_blocking_command "); AWC_INIT_COMMAND(AWC_NOT_CLI,cmd,dev,comm,0, 0, 0, 0 ,0 ); AWC_BAP_LOCK_NOT_CLI(cmd); if (awc_issue_command_and_block(&cmd)) goto final; AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" exit \n"); return 0; final: AWC_RELEASE_COMMAND(cmd); AWC_ENTRY_EXIT_DEBUG(" BAD exit \n"); return -1; ; };int awc_issue_soft_reset(struct net_device * dev){ u16 status ;// int i= 0;/* outw(inw(dev->base_addr + 0x30), dev->base_addr + 0x32); udelay(10); outw(inw(dev->base_addr + 0x30), dev->base_addr + 0x34); for (i=0; i< 32; i++) outw(0,dev->base_addr + i*2); udelay(100); outw(0x6,dev->base_addr + 0x34);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -