📄 wavelan_cs.c
字号:
wait_completed = TRUE; /* Busy wait while the LAN controller executes the command. */ spin = 1000; do { /* Time calibration of the loop */ udelay(10); /* Read the interrupt register */ outb(CR0_STATUS_0 | OP0_NOP, LCCR(base)); status = inb(LCSR(base)); /* Check if there was an interrupt posted */ if((status & SR0_INTERRUPT)) { /* Acknowledge the interrupt */ outb(CR0_INT_ACK | OP0_NOP, LCCR(base)); /* Check if interrupt is a command completion */ if(((status & SR0_BOTH_RX_TX) != SR0_BOTH_RX_TX) && ((status & SR0_BOTH_RX_TX) != 0x0) && !(status & SR0_RECEPTION)) { /* Signal command completion */ wait_completed = FALSE; } else { /* Note : Rx interrupts will be handled later, because we can * handle multiple Rx packets at once */#ifdef DEBUG_INTERRUPT_INFO printk(KERN_INFO "wv_82593_cmd: not our interrupt\n");#endif } } } while(wait_completed && (spin-- > 0)); /* If the interrupt hasn't be posted */ if(wait_completed) {#ifdef DEBUG_INTERRUPT_ERROR printk(KERN_INFO "wv_82593_cmd: %s timeout, status 0x%02x\n", str, status);#endif return(FALSE); } /* Check the return code returned by the card (see above) against * the expected return code provided by the caller */ if((status & SR0_EVENT_MASK) != result) {#ifdef DEBUG_INTERRUPT_ERROR printk(KERN_INFO "wv_82593_cmd: %s failed, status = 0x%x\n", str, status);#endif return(FALSE); } return(TRUE);} /* wv_82593_cmd *//*------------------------------------------------------------------*//* * This routine does a 593 op-code number 7, and obtains the diagnose * status for the WaveLAN. */static inline intwv_diag(device * dev){ int ret = FALSE; if(wv_82593_cmd(dev, "wv_diag(): diagnose", OP0_DIAGNOSE, SR0_DIAGNOSE_PASSED)) ret = TRUE;#ifdef DEBUG_CONFIG_ERROR printk(KERN_INFO "wavelan_cs: i82593 Self Test failed!\n");#endif return(ret);} /* wv_diag *//*------------------------------------------------------------------*//* * Routine to read len bytes from the i82593's ring buffer, starting at * chip address addr. The results read from the chip are stored in buf. * The return value is the address to use for next the call. */static intread_ringbuf(device * dev, int addr, char * buf, int len){ ioaddr_t base = dev->base_addr; int ring_ptr = addr; int chunk_len; char * buf_ptr = buf; /* Get all the buffer */ while(len > 0) { /* Position the Program I/O Register at the ring buffer pointer */ outb(ring_ptr & 0xff, PIORL(base)); outb(((ring_ptr >> 8) & PIORH_MASK), PIORH(base)); /* First, determine how much we can read without wrapping around the ring buffer */ if((addr + len) < (RX_BASE + RX_SIZE)) chunk_len = len; else chunk_len = RX_BASE + RX_SIZE - addr; insb(PIOP(base), buf_ptr, chunk_len); buf_ptr += chunk_len; len -= chunk_len; ring_ptr = (ring_ptr - RX_BASE + chunk_len) % RX_SIZE + RX_BASE; } return(ring_ptr);} /* read_ringbuf *//*------------------------------------------------------------------*//* * Reconfigure the i82593, or at least ask for it... * Because wv_82593_config use the transmission buffer, we must do it * when we are sure that there is no transmission, so we do it now * or in wavelan_packet_xmit() (I can't find any better place, * wavelan_interrupt is not an option...), so you may experience * some delay sometime... */static inline voidwv_82593_reconfig(device * dev){ net_local * lp = (net_local *)dev->priv; dev_link_t * link = ((net_local *) dev->priv)->link; unsigned long flags; /* Arm the flag, will be cleard in wv_82593_config() */ lp->reconfig_82593 = TRUE; /* Check if we can do it now ! */ if((link->open) && (netif_running(dev)) && !(netif_queue_stopped(dev))) { wv_splhi(lp, &flags); /* Disable interrupts */ wv_82593_config(dev); wv_splx(lp, &flags); /* Re-enable interrupts */ } else {#ifdef DEBUG_IOCTL_INFO printk(KERN_DEBUG "%s: wv_82593_reconfig(): delayed (state = %lX, link = %d)\n", dev->name, devstate(dev), link->open);#endif }}/********************* DEBUG & INFO SUBROUTINES *********************//* * This routines are used in the code to show debug informations. * Most of the time, it dump the content of hardware structures... */#ifdef DEBUG_PSA_SHOW/*------------------------------------------------------------------*//* * Print the formatted contents of the Parameter Storage Area. */static voidwv_psa_show(psa_t * p){ printk(KERN_DEBUG "##### wavelan psa contents: #####\n"); printk(KERN_DEBUG "psa_io_base_addr_1: 0x%02X %02X %02X %02X\n", p->psa_io_base_addr_1, p->psa_io_base_addr_2, p->psa_io_base_addr_3, p->psa_io_base_addr_4); printk(KERN_DEBUG "psa_rem_boot_addr_1: 0x%02X %02X %02X\n", p->psa_rem_boot_addr_1, p->psa_rem_boot_addr_2, p->psa_rem_boot_addr_3); printk(KERN_DEBUG "psa_holi_params: 0x%02x, ", p->psa_holi_params); printk("psa_int_req_no: %d\n", p->psa_int_req_no);#ifdef DEBUG_SHOW_UNUSED printk(KERN_DEBUG "psa_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X\n", p->psa_unused0[0], p->psa_unused0[1], p->psa_unused0[2], p->psa_unused0[3], p->psa_unused0[4], p->psa_unused0[5], p->psa_unused0[6]);#endif /* DEBUG_SHOW_UNUSED */ printk(KERN_DEBUG "psa_univ_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02x\n", p->psa_univ_mac_addr[0], p->psa_univ_mac_addr[1], p->psa_univ_mac_addr[2], p->psa_univ_mac_addr[3], p->psa_univ_mac_addr[4], p->psa_univ_mac_addr[5]); printk(KERN_DEBUG "psa_local_mac_addr[]: %02x:%02x:%02x:%02x:%02x:%02x\n", p->psa_local_mac_addr[0], p->psa_local_mac_addr[1], p->psa_local_mac_addr[2], p->psa_local_mac_addr[3], p->psa_local_mac_addr[4], p->psa_local_mac_addr[5]); printk(KERN_DEBUG "psa_univ_local_sel: %d, ", p->psa_univ_local_sel); printk("psa_comp_number: %d, ", p->psa_comp_number); printk("psa_thr_pre_set: 0x%02x\n", p->psa_thr_pre_set); printk(KERN_DEBUG "psa_feature_select/decay_prm: 0x%02x, ", p->psa_feature_select); printk("psa_subband/decay_update_prm: %d\n", p->psa_subband); printk(KERN_DEBUG "psa_quality_thr: 0x%02x, ", p->psa_quality_thr); printk("psa_mod_delay: 0x%02x\n", p->psa_mod_delay); printk(KERN_DEBUG "psa_nwid: 0x%02x%02x, ", p->psa_nwid[0], p->psa_nwid[1]); printk("psa_nwid_select: %d\n", p->psa_nwid_select); printk(KERN_DEBUG "psa_encryption_select: %d, ", p->psa_encryption_select); printk("psa_encryption_key[]: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", p->psa_encryption_key[0], p->psa_encryption_key[1], p->psa_encryption_key[2], p->psa_encryption_key[3], p->psa_encryption_key[4], p->psa_encryption_key[5], p->psa_encryption_key[6], p->psa_encryption_key[7]); printk(KERN_DEBUG "psa_databus_width: %d\n", p->psa_databus_width); printk(KERN_DEBUG "psa_call_code/auto_squelch: 0x%02x, ", p->psa_call_code[0]); printk("psa_call_code[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", p->psa_call_code[0], p->psa_call_code[1], p->psa_call_code[2], p->psa_call_code[3], p->psa_call_code[4], p->psa_call_code[5], p->psa_call_code[6], p->psa_call_code[7]);#ifdef DEBUG_SHOW_UNUSED printk(KERN_DEBUG "psa_reserved[]: %02X:%02X:%02X:%02X\n", p->psa_reserved[0], p->psa_reserved[1], p->psa_reserved[2], p->psa_reserved[3]);#endif /* DEBUG_SHOW_UNUSED */ printk(KERN_DEBUG "psa_conf_status: %d, ", p->psa_conf_status); printk("psa_crc: 0x%02x%02x, ", p->psa_crc[0], p->psa_crc[1]); printk("psa_crc_status: 0x%02x\n", p->psa_crc_status);} /* wv_psa_show */#endif /* DEBUG_PSA_SHOW */#ifdef DEBUG_MMC_SHOW/*------------------------------------------------------------------*//* * Print the formatted status of the Modem Management Controller. * This function need to be completed... */static voidwv_mmc_show(device * dev){ ioaddr_t base = dev->base_addr; net_local * lp = (net_local *)dev->priv; mmr_t m; /* Basic check */ if(hasr_read(base) & HASR_NO_CLK) { printk(KERN_WARNING "%s: wv_mmc_show: modem not connected\n", dev->name); return; } wv_splhi(lp, &flags); /* Read the mmc */ mmc_out(base, mmwoff(0, mmw_freeze), 1); mmc_read(base, 0, (u_char *)&m, sizeof(m)); mmc_out(base, mmwoff(0, mmw_freeze), 0);#ifdef WIRELESS_EXT /* If wireless extension exist in the kernel */ /* Don't forget to update statistics */ lp->wstats.discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;#endif /* WIRELESS_EXT */ wv_splx(lp, &flags); printk(KERN_DEBUG "##### wavelan modem status registers: #####\n");#ifdef DEBUG_SHOW_UNUSED printk(KERN_DEBUG "mmc_unused0[]: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", m.mmr_unused0[0], m.mmr_unused0[1], m.mmr_unused0[2], m.mmr_unused0[3], m.mmr_unused0[4], m.mmr_unused0[5], m.mmr_unused0[6], m.mmr_unused0[7]);#endif /* DEBUG_SHOW_UNUSED */ printk(KERN_DEBUG "Encryption algorythm: %02X - Status: %02X\n", m.mmr_des_avail, m.mmr_des_status);#ifdef DEBUG_SHOW_UNUSED printk(KERN_DEBUG "mmc_unused1[]: %02X:%02X:%02X:%02X:%02X\n", m.mmr_unused1[0], m.mmr_unused1[1], m.mmr_unused1[2], m.mmr_unused1[3], m.mmr_unused1[4]);#endif /* DEBUG_SHOW_UNUSED */ printk(KERN_DEBUG "dce_status: 0x%x [%s%s%s%s]\n", m.mmr_dce_status, (m.mmr_dce_status & MMR_DCE_STATUS_RX_BUSY) ? "energy detected,":"", (m.mmr_dce_status & MMR_DCE_STATUS_LOOPT_IND) ? "loop test indicated," : "", (m.mmr_dce_status & MMR_DCE_STATUS_TX_BUSY) ? "transmitter on," : "", (m.mmr_dce_status & MMR_DCE_STATUS_JBR_EXPIRED) ? "jabber timer expired," : ""); printk(KERN_DEBUG "Dsp ID: %02X\n", m.mmr_dsp_id);#ifdef DEBUG_SHOW_UNUSED printk(KERN_DEBUG "mmc_unused2[]: %02X:%02X\n", m.mmr_unused2[0], m.mmr_unused2[1]);#endif /* DEBUG_SHOW_UNUSED */ printk(KERN_DEBUG "# correct_nwid: %d, # wrong_nwid: %d\n", (m.mmr_correct_nwid_h << 8) | m.mmr_correct_nwid_l, (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l); printk(KERN_DEBUG "thr_pre_set: 0x%x [current signal %s]\n", m.mmr_thr_pre_set & MMR_THR_PRE_SET, (m.mmr_thr_pre_set & MMR_THR_PRE_SET_CUR) ? "above" : "below"); printk(KERN_DEBUG "signal_lvl: %d [%s], ", m.mmr_signal_lvl & MMR_SIGNAL_LVL, (m.mmr_signal_lvl & MMR_SIGNAL_LVL_VALID) ? "new msg" : "no new msg"); printk("silence_lvl: %d [%s], ", m.mmr_silence_lvl & MMR_SILENCE_LVL, (m.mmr_silence_lvl & MMR_SILENCE_LVL_VALID) ? "update done" : "no new update"); printk("sgnl_qual: 0x%x [%s]\n", m.mmr_sgnl_qual & MMR_SGNL_QUAL, (m.mmr_sgnl_qual & MMR_SGNL_QUAL_ANT) ? "Antenna 1" : "Antenna 0");#ifdef DEBUG_SHOW_UNUSED printk(KERN_DEBUG "netw_id_l: %x\n", m.mmr_netw_id_l);#endif /* DEBUG_SHOW_UNUSED */} /* wv_mmc_show */#endif /* DEBUG_MMC_SHOW */#ifdef DEBUG_I82593_SHOW/*------------------------------------------------------------------*//* * Print the formatted status of the i82593's receive unit. */static voidwv_ru_show(device * dev){ net_local *lp = (net_local *) dev->priv; printk(KERN_DEBUG "##### wavelan i82593 receiver status: #####\n"); printk(KERN_DEBUG "ru: rfp %d stop %d", lp->rfp, lp->stop); /* * Not implemented yet... */ printk("\n");} /* wv_ru_show */#endif /* DEBUG_I82593_SHOW */#ifdef DEBUG_DEVICE_SHOW/*------------------------------------------------------------------*//* * Print the formatted status of the WaveLAN PCMCIA device driver. */static voidwv_dev_show(device * dev){ printk(KERN_DEBUG "dev:"); printk(" state=%lX,", devstate(dev)); printk(" trans_start=%ld,", dev->trans_start); printk(" flags=0x%x,", dev->flags); printk("\n");} /* wv_dev_show *//*------------------------------------------------------------------*//* * Print the formatted status of the WaveLAN PCMCIA device driver's * private information. */static voidwv_local_show(device * dev){ net_local *lp; lp = (net_local *)dev->priv; printk(KERN_DEBUG "local:"); /* * Not implemented yet... */ printk("\n");} /* wv_local_show */#endif /* DEBUG_DEVICE_SHOW */#if defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO)/*------------------------------------------------------------------*//* * Dump packet header (and content if necessary) on the screen */static inline voidwv_packet_info(u_char * p, /* Packet to dump */ int length, /* Length of the packet */ char * msg1, /* Name of the device */ char * msg2) /* Name of the function */{ int i; int maxi; printk(KERN_DEBUG "%s: %s(): dest %02X:%02X:%02X:%02X:%02X:%02X, length %d\n", msg1, msg2, p[0], p[1], p[2], p[3], p[4], p[5], length); printk(KERN_DEBUG "%s: %s(): src %02X:%02X:%02X:%02X:%02X:%02X, type 0x%02X%02X\n", msg1, msg2, p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13]);#ifdef DEBUG_PACKET_DUMP printk(KERN_DEBUG "data=\""); if((maxi = length) > DEBUG_PACKET_DUMP) maxi = DEBUG_PACKET_DUMP; for(i = 14; i < maxi; i++) if(p[i] >= ' ' && p[i] <= '~') printk(" %c", p[i]); else printk("%02X", p[i]); if(maxi < length) printk(".."); printk("\"\n"); printk(KERN_DEBUG "\n");#endif /* DEBUG_PACKET_DUMP */}#endif /* defined(DEBUG_RX_INFO) || defined(DEBUG_TX_INFO) *//*------------------------------------------------------------------*//* * This is the information which is displayed by the driver at startup * There is a lot of flag to configure it at your will... */static inline voidwv_init_info(device * dev){ ioaddr_t base = dev->base_addr; psa_t psa; int i; /* Read the parameter storage area */ psa_read(dev, 0, (unsigned char *) &psa, sizeof(psa));#ifdef DEBUG_PSA_SHOW wv_psa_show(&psa);#endif#ifdef DEBUG_MMC_SHOW wv_mmc_show(dev);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -