📄 tms380tr.c
字号:
tms380tr_exec_cmd(dev, OC_RECEIVE); if(tp->ReOpenInProgress) tp->ReOpenInProgress = 0; return; } else /* The adapter did not open. */ { if(ssb_parm_0 & NODE_ADDR_ERROR) printk(KERN_INFO "%s: Node address error\n", dev->name); if(ssb_parm_0 & LIST_SIZE_ERROR) printk(KERN_INFO "%s: List size error\n", dev->name); if(ssb_parm_0 & BUF_SIZE_ERROR) printk(KERN_INFO "%s: Buffer size error\n", dev->name); if(ssb_parm_0 & TX_BUF_COUNT_ERROR) printk(KERN_INFO "%s: Tx buffer count error\n", dev->name); if(ssb_parm_0 & INVALID_OPEN_OPTION) printk(KERN_INFO "%s: Invalid open option\n", dev->name); if(ssb_parm_0 & OPEN_ERROR) { /* Show the open phase. */ switch(ssb_parm_0 & OPEN_PHASES_MASK) { case LOBE_MEDIA_TEST: if(!tp->LobeWireFaultLogged) { tp->LobeWireFaultLogged = 1; printk(KERN_INFO "%s: %s Lobe wire fault (check cable !).\n", dev->name, open_err); } tp->ReOpenInProgress = 1; tp->AdapterOpenFlag = 0; tp->AdapterVirtOpenFlag = 1; tms380tr_open_adapter(dev); return; case PHYSICAL_INSERTION: printk(KERN_INFO "%s: %s Physical insertion.\n", dev->name, open_err); break; case ADDRESS_VERIFICATION: printk(KERN_INFO "%s: %s Address verification.\n", dev->name, open_err); break; case PARTICIPATION_IN_RING_POLL: printk(KERN_INFO "%s: %s Participation in ring poll.\n", dev->name, open_err); break; case REQUEST_INITIALISATION: printk(KERN_INFO "%s: %s Request initialisation.\n", dev->name, open_err); break; case FULLDUPLEX_CHECK: printk(KERN_INFO "%s: %s Full duplex check.\n", dev->name, open_err); break; default: printk(KERN_INFO "%s: %s Unknown open phase\n", dev->name, open_err); break; } /* Show the open errors. */ switch(ssb_parm_0 & OPEN_ERROR_CODES_MASK) { case OPEN_FUNCTION_FAILURE: printk(KERN_INFO "%s: %s OPEN_FUNCTION_FAILURE", dev->name, code_err); tp->LastOpenStatus = OPEN_FUNCTION_FAILURE; break; case OPEN_SIGNAL_LOSS: printk(KERN_INFO "%s: %s OPEN_SIGNAL_LOSS\n", dev->name, code_err); tp->LastOpenStatus = OPEN_SIGNAL_LOSS; break; case OPEN_TIMEOUT: printk(KERN_INFO "%s: %s OPEN_TIMEOUT\n", dev->name, code_err); tp->LastOpenStatus = OPEN_TIMEOUT; break; case OPEN_RING_FAILURE: printk(KERN_INFO "%s: %s OPEN_RING_FAILURE\n", dev->name, code_err); tp->LastOpenStatus = OPEN_RING_FAILURE; break; case OPEN_RING_BEACONING: printk(KERN_INFO "%s: %s OPEN_RING_BEACONING\n", dev->name, code_err); tp->LastOpenStatus = OPEN_RING_BEACONING; break; case OPEN_DUPLICATE_NODEADDR: printk(KERN_INFO "%s: %s OPEN_DUPLICATE_NODEADDR\n", dev->name, code_err); tp->LastOpenStatus = OPEN_DUPLICATE_NODEADDR; break; case OPEN_REQUEST_INIT: printk(KERN_INFO "%s: %s OPEN_REQUEST_INIT\n", dev->name, code_err); tp->LastOpenStatus = OPEN_REQUEST_INIT; break; case OPEN_REMOVE_RECEIVED: printk(KERN_INFO "%s: %s OPEN_REMOVE_RECEIVED", dev->name, code_err); tp->LastOpenStatus = OPEN_REMOVE_RECEIVED; break; case OPEN_FULLDUPLEX_SET: printk(KERN_INFO "%s: %s OPEN_FULLDUPLEX_SET\n", dev->name, code_err); tp->LastOpenStatus = OPEN_FULLDUPLEX_SET; break; default: printk(KERN_INFO "%s: %s Unknown open err code", dev->name, code_err); tp->LastOpenStatus = OPEN_FUNCTION_FAILURE; break; } } tp->AdapterOpenFlag = 0; tp->AdapterVirtOpenFlag = 0; return; } } else { if(ssb_cmd != READ_ERROR_LOG) return; /* Add values from the error log table to the MAC * statistics counters and update the errorlogtable * memory. */ tp->MacStat.line_errors += tp->errorlogtable.Line_Error; tp->MacStat.burst_errors += tp->errorlogtable.Burst_Error; tp->MacStat.A_C_errors += tp->errorlogtable.ARI_FCI_Error; tp->MacStat.lost_frames += tp->errorlogtable.Lost_Frame_Error; tp->MacStat.recv_congest_count += tp->errorlogtable.Rx_Congest_Error; tp->MacStat.rx_errors += tp->errorlogtable.Rx_Congest_Error; tp->MacStat.frame_copied_errors += tp->errorlogtable.Frame_Copied_Error; tp->MacStat.token_errors += tp->errorlogtable.Token_Error; tp->MacStat.dummy1 += tp->errorlogtable.DMA_Bus_Error; tp->MacStat.dummy1 += tp->errorlogtable.DMA_Parity_Error; tp->MacStat.abort_delimiters += tp->errorlogtable.AbortDelimeters; tp->MacStat.frequency_errors += tp->errorlogtable.Frequency_Error; tp->MacStat.internal_errors += tp->errorlogtable.Internal_Error; } return;}/* * The inverse routine to tms380tr_open(). */int tms380tr_close(struct net_device *dev){ struct net_local *tp = netdev_priv(dev); netif_stop_queue(dev); del_timer(&tp->timer); /* Flush the Tx and disable Rx here. */ tp->HaltInProgress = 1; tms380tr_exec_cmd(dev, OC_CLOSE); tp->timer.expires = jiffies + 1*HZ; tp->timer.function = tms380tr_timer_end_wait; tp->timer.data = (unsigned long)dev; add_timer(&tp->timer); tms380tr_enable_interrupts(dev); tp->Sleeping = 1; interruptible_sleep_on(&tp->wait_for_tok_int); tp->TransmitCommandActive = 0; del_timer(&tp->timer); tms380tr_disable_interrupts(dev); #ifdef CONFIG_ISA if(dev->dma > 0) { unsigned long flags=claim_dma_lock(); disable_dma(dev->dma); release_dma_lock(flags); }#endif SIFWRITEW(0xFF00, SIFCMD);#if 0 if(dev->dma > 0) /* what the? */ SIFWRITEB(0xff, POSREG);#endif tms380tr_cancel_tx_queue(tp); return (0);}/* * Get the current statistics. This may be called with the card open * or closed. */static struct net_device_stats *tms380tr_get_stats(struct net_device *dev){ struct net_local *tp = netdev_priv(dev); return ((struct net_device_stats *)&tp->MacStat);}/* * Set or clear the multicast filter for this adapter. */static void tms380tr_set_multicast_list(struct net_device *dev){ struct net_local *tp = netdev_priv(dev); unsigned int OpenOptions; OpenOptions = tp->ocpl.OPENOptions & ~(PASS_ADAPTER_MAC_FRAMES | PASS_ATTENTION_FRAMES | PASS_BEACON_MAC_FRAMES | COPY_ALL_MAC_FRAMES | COPY_ALL_NON_MAC_FRAMES); tp->ocpl.FunctAddr = 0; if(dev->flags & IFF_PROMISC) /* Enable promiscuous mode */ OpenOptions |= COPY_ALL_NON_MAC_FRAMES | COPY_ALL_MAC_FRAMES; else { if(dev->flags & IFF_ALLMULTI) { /* Disable promiscuous mode, use normal mode. */ tp->ocpl.FunctAddr = 0xFFFFFFFF; } else { int i; struct dev_mc_list *mclist = dev->mc_list; for (i=0; i< dev->mc_count; i++) { ((char *)(&tp->ocpl.FunctAddr))[0] |= mclist->dmi_addr[2]; ((char *)(&tp->ocpl.FunctAddr))[1] |= mclist->dmi_addr[3]; ((char *)(&tp->ocpl.FunctAddr))[2] |= mclist->dmi_addr[4]; ((char *)(&tp->ocpl.FunctAddr))[3] |= mclist->dmi_addr[5]; mclist = mclist->next; } } tms380tr_exec_cmd(dev, OC_SET_FUNCT_ADDR); } tp->ocpl.OPENOptions = OpenOptions; tms380tr_exec_cmd(dev, OC_MODIFY_OPEN_PARMS); return;}/* * Wait for some time (microseconds) */void tms380tr_wait(unsigned long time){#if 0 long tmp; tmp = jiffies + time/(1000000/HZ); do { tmp = schedule_timeout_interruptible(tmp); } while(time_after(tmp, jiffies));#else udelay(time);#endif return;}/* * Write a command value to the SIFCMD register */static void tms380tr_exec_sifcmd(struct net_device *dev, unsigned int WriteValue){ unsigned short cmd; unsigned short SifStsValue; unsigned long loop_counter; WriteValue = ((WriteValue ^ CMD_SYSTEM_IRQ) | CMD_INTERRUPT_ADAPTER); cmd = (unsigned short)WriteValue; loop_counter = 0,5 * 800000; do { SifStsValue = SIFREADW(SIFSTS); } while((SifStsValue & CMD_INTERRUPT_ADAPTER) && loop_counter--); SIFWRITEW(cmd, SIFCMD); return;}/* * Processes adapter hardware reset, halts adapter and downloads firmware, * clears the halt bit. */static int tms380tr_reset_adapter(struct net_device *dev){ struct net_local *tp = netdev_priv(dev); unsigned short *fw_ptr; unsigned short count, c, count2; const struct firmware *fw_entry = NULL; if (request_firmware(&fw_entry, "tms380tr.bin", tp->pdev) != 0) { printk(KERN_ALERT "%s: firmware %s is missing, cannot start.\n", dev->name, "tms380tr.bin"); return (-1); } fw_ptr = (unsigned short *)fw_entry->data; count2 = fw_entry->size / 2; /* Hardware adapter reset */ SIFWRITEW(ACL_ARESET, SIFACL); tms380tr_wait(40); c = SIFREADW(SIFACL); tms380tr_wait(20); if(dev->dma == 0) /* For PCI adapters */ { c &= ~(ACL_NSELOUT0 | ACL_NSELOUT1); /* Clear bits */ if(tp->setnselout) c |= (*tp->setnselout)(dev); } /* In case a command is pending - forget it */ tp->ScbInUse = 0; c &= ~ACL_ARESET; /* Clear adapter reset bit */ c |= ACL_CPHALT; /* Halt adapter CPU, allow download */ c |= ACL_BOOT; c |= ACL_SINTEN; c &= ~ACL_PSDMAEN; /* Clear pseudo dma bit */ SIFWRITEW(c, SIFACL); tms380tr_wait(40); count = 0; /* Download firmware via DIO interface: */ do { if (count2 < 3) continue; /* Download first address part */ SIFWRITEW(*fw_ptr, SIFADX); fw_ptr++; count2--; /* Download second address part */ SIFWRITEW(*fw_ptr, SIFADD); fw_ptr++; count2--; if((count = *fw_ptr) != 0) /* Load loop counter */ { fw_ptr++; /* Download block data */ count2--; if (count > count2) continue; for(; count > 0; count--) { SIFWRITEW(*fw_ptr, SIFINC); fw_ptr++; count2--; } } else /* Stop, if last block downloaded */ { c = SIFREADW(SIFACL); c &= (~ACL_CPHALT | ACL_SINTEN); /* Clear CPHALT and start BUD */ SIFWRITEW(c, SIFACL); if (fw_entry) release_firmware(fw_entry); return (1); } } while(count == 0); if (fw_entry) release_firmware(fw_entry); printk(KERN_INFO "%s: Adapter Download Failed\n", dev->name); return (-1);}/* * Starts bring up diagnostics of token ring adapter and evaluates * diagnostic results. */static int tms380tr_bringup_diags(struct net_device *dev){ int loop_cnt, retry_cnt; unsigned short Status; tms380tr_wait(HALF_SECOND); tms380tr_exec_sifcmd(dev, EXEC_SOFT_RESET); tms380tr_wait(HALF_SECOND); retry_cnt = BUD_MAX_RETRIES; /* maximal number of retrys */ do { retry_cnt--; if(tms380tr_debug > 3) printk(KERN_DEBUG "BUD-Status: "); loop_cnt = BUD_MAX_LOOPCNT; /* maximum: three seconds*/ do { /* Inspect BUD results */ loop_cnt--; tms380tr_wait(HALF_SECOND); Status = SIFREADW(SIFSTS); Status &= STS_MASK; if(tms380tr_debug > 3) printk(KERN_DEBUG " %04X \n", Status); /* BUD successfully completed */ if(Status == STS_INITIALIZE) return (1); /* Unrecoverable hardware error, BUD not completed? */ } while((loop_cnt > 0) && ((Status & (STS_ERROR | STS_TEST)) != (STS_ERROR | STS_TEST))); /* Error preventing completion of BUD */ if(retry_cnt > 0) { printk(KERN_INFO "%s: Adapter Software Reset.\n", dev->name); tms380tr_exec_sifcmd(dev, EXEC_SOFT_RESET); tms380tr_wait(HALF_SECOND); } } while(retry_cnt > 0); Status = SIFREADW(SIFSTS); printk(KERN_INFO "%s: Hardware error\n", dev->name); /* Hardware error occurred! */ Status &= 0x001f; if (Status & 0x0010) printk(KERN_INFO "%s: BUD Error: Timeout\n", dev->name); else if ((Status & 0x000f) > 6) printk(KERN_INFO "%s: BUD Error: Illegal Failure\n", dev->name); else printk(KERN_INFO "%s: Bring Up Diagnostics Error (%04X) occurred\n", dev->name, Status & 0x000f); return (-1);}/* * Copy initialisation data to adapter memory, beginning at address * 1:0A00; Starting DMA test and evaluating result bits. */static int tms380tr_init_adapter(struct net_device *dev){ struct net_local *tp = netdev_priv(dev); const unsigned char SCB_Test[6] = {0x00, 0x00, 0xC1, 0xE2, 0xD4, 0x8B}; const unsigned char SSB_Test[8] = {0xFF, 0xFF, 0xD1, 0xD7, 0xC5, 0xD9, 0xC3, 0xD4}; void *ptr = (void *)&tp->ipb; unsigned short *ipb_ptr = (unsigned short *)ptr; unsigned char *cb_ptr = (unsigned char *) &tp->scb; unsigned char *sb_ptr = (unsigned char *) &tp->ssb; unsigned short Status;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -