📄 olympic.c
字号:
writeb(ASB_RECEIVE_DATA,asb_block); /* Receive data */ writeb(OLYMPIC_CLEAR_RET_CODE,asb_block+2); /* Necessary ?? */ writeb(readb(arb_block+6),asb_block+6); /* Must send the address back to the adapter */ writeb(readb(arb_block+7),asb_block+7); /* To let it know we have dealt with the data */ writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM); olympic_priv->asb_queued = 2 ; return ; } else if (readb(arb_block) == ARB_LAN_CHANGE_STATUS) { /* Lan.change.status */ lan_status = swab16(readw(arb_block+6)); fdx_prot_error = readb(arb_block+8) ; /* Issue ARB Free */ writel(LISR_ARB_FREE,olympic_priv->olympic_mmio+LISR_SUM); lan_status_diff = olympic_priv->olympic_lan_status ^ lan_status ; if (lan_status_diff & (LSC_LWF | LSC_ARW | LSC_FPE | LSC_RR) ) { if (lan_status_diff & LSC_LWF) printk(KERN_WARNING "%s: Short circuit detected on the lobe\n",dev->name); if (lan_status_diff & LSC_ARW) printk(KERN_WARNING "%s: Auto removal error\n",dev->name); if (lan_status_diff & LSC_FPE) printk(KERN_WARNING "%s: FDX Protocol Error\n",dev->name); if (lan_status_diff & LSC_RR) printk(KERN_WARNING "%s: Force remove MAC frame received\n",dev->name); /* Adapter has been closed by the hardware */ /* reset tx/rx fifo's and busmaster logic */ writel(readl(olympic_mmio+BCTL)|(3<<13),olympic_mmio+BCTL); udelay(1); writel(readl(olympic_mmio+BCTL)&~(3<<13),olympic_mmio+BCTL); netif_stop_queue(dev); olympic_priv->srb = readw(olympic_priv->olympic_lap + LAPWWO) ; for(i=0;i<OLYMPIC_RX_RING_SIZE;i++) { dev_kfree_skb_irq(olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]); if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer != 0xdeadbeef) { pci_unmap_single(olympic_priv->pdev, le32_to_cpu(olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer), olympic_priv->pkt_buf_sz, PCI_DMA_FROMDEVICE); } olympic_priv->rx_status_last_received++; olympic_priv->rx_status_last_received&=OLYMPIC_RX_RING_SIZE-1; } /* unmap rings */ pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_status_ring_dma_addr, sizeof(struct olympic_rx_status) * OLYMPIC_RX_RING_SIZE, PCI_DMA_FROMDEVICE); pci_unmap_single(olympic_priv->pdev, olympic_priv->rx_ring_dma_addr, sizeof(struct olympic_rx_desc) * OLYMPIC_RX_RING_SIZE, PCI_DMA_TODEVICE); pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_status_ring_dma_addr, sizeof(struct olympic_tx_status) * OLYMPIC_TX_RING_SIZE, PCI_DMA_FROMDEVICE); pci_unmap_single(olympic_priv->pdev, olympic_priv->tx_ring_dma_addr, sizeof(struct olympic_tx_desc) * OLYMPIC_TX_RING_SIZE, PCI_DMA_TODEVICE); free_irq(dev->irq,dev); dev->stop=NULL; printk(KERN_WARNING "%s: Adapter has been closed \n", dev->name) ; } /* If serious error */ if (olympic_priv->olympic_message_level) { if (lan_status_diff & LSC_SIG_LOSS) printk(KERN_WARNING "%s: No receive signal detected \n", dev->name) ; if (lan_status_diff & LSC_HARD_ERR) printk(KERN_INFO "%s: Beaconing \n",dev->name); if (lan_status_diff & LSC_SOFT_ERR) printk(KERN_WARNING "%s: Adapter transmitted Soft Error Report Mac Frame \n",dev->name); if (lan_status_diff & LSC_TRAN_BCN) printk(KERN_INFO "%s: We are tranmitting the beacon, aaah\n",dev->name); if (lan_status_diff & LSC_SS) printk(KERN_INFO "%s: Single Station on the ring \n", dev->name); if (lan_status_diff & LSC_RING_REC) printk(KERN_INFO "%s: Ring recovery ongoing\n",dev->name); if (lan_status_diff & LSC_FDX_MODE) printk(KERN_INFO "%s: Operating in FDX mode\n",dev->name); } if (lan_status_diff & LSC_CO) { if (olympic_priv->olympic_message_level) printk(KERN_INFO "%s: Counter Overflow \n", dev->name); /* Issue READ.LOG command */ writeb(SRB_READ_LOG, srb); writeb(0,srb+1); writeb(OLYMPIC_CLEAR_RET_CODE,srb+2); writeb(0,srb+3); writeb(0,srb+4); writeb(0,srb+5); olympic_priv->srb_queued=2; /* Can't sleep, use srb_bh */ writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM); } if (lan_status_diff & LSC_SR_CO) { if (olympic_priv->olympic_message_level) printk(KERN_INFO "%s: Source routing counters overflow\n", dev->name); /* Issue a READ.SR.COUNTERS */ writeb(SRB_READ_SR_COUNTERS,srb); writeb(0,srb+1); writeb(OLYMPIC_CLEAR_RET_CODE,srb+2); writeb(0,srb+3); olympic_priv->srb_queued=2; /* Can't sleep, use srb_bh */ writel(LISR_SRB_CMD,olympic_mmio+LISR_SUM); } olympic_priv->olympic_lan_status = lan_status ; } /* Lan.change.status */ else printk(KERN_WARNING "%s: Unknown arb command \n", dev->name);}static void olympic_asb_bh(struct net_device *dev) { struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv ; u8 *arb_block, *asb_block ; arb_block = (u8 *)(olympic_priv->olympic_lap + olympic_priv->arb) ; asb_block = (u8 *)(olympic_priv->olympic_lap + olympic_priv->asb) ; if (olympic_priv->asb_queued == 1) { /* Dropped through the first time */ writeb(ASB_RECEIVE_DATA,asb_block); /* Receive data */ writeb(OLYMPIC_CLEAR_RET_CODE,asb_block+2); /* Necessary ?? */ writeb(readb(arb_block+6),asb_block+6); /* Must send the address back to the adapter */ writeb(readb(arb_block+7),asb_block+7); /* To let it know we have dealt with the data */ writel(LISR_ASB_REPLY | LISR_ASB_FREE_REQ,olympic_priv->olympic_mmio+LISR_SUM); olympic_priv->asb_queued = 2 ; return ; } if (olympic_priv->asb_queued == 2) { switch (readb(asb_block+2)) { case 0x01: printk(KERN_WARNING "%s: Unrecognized command code \n", dev->name); break ; case 0x26: printk(KERN_WARNING "%s: Unrecognized buffer address \n", dev->name); break ; case 0xFF: /* Valid response, everything should be ok again */ break ; default: printk(KERN_WARNING "%s: Invalid return code in asb\n",dev->name); break ; } } olympic_priv->asb_queued = 0 ; } static int olympic_change_mtu(struct net_device *dev, int mtu) { struct olympic_private *olympic_priv = (struct olympic_private *) dev->priv; u16 max_mtu ; if (olympic_priv->olympic_ring_speed == 4) max_mtu = 4500 ; else max_mtu = 18000 ; if (mtu > max_mtu) return -EINVAL ; if (mtu < 100) return -EINVAL ; dev->mtu = mtu ; olympic_priv->pkt_buf_sz = mtu + TR_HLEN ; return 0 ; }static int olympic_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data){ struct net_device *dev = (struct net_device *)data ; struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv; u8 *oat = (u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ; u8 *opt = (u8 *)(olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ; int size = 0 ; int len=0; off_t begin=0; off_t pos=0; size = sprintf(buffer, "IBM Pit/Pit-Phy/Olympic Chipset Token Ring Adapter %s\n",dev->name); size += sprintf(buffer+size, "\n%6s: Adapter Address : Node Address : Functional Addr\n", dev->name); size += sprintf(buffer+size, "%6s: %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x\n", dev->name, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2], dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5], readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)), readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+1), readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+2), readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+3), readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+4), readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr)+5), readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)), readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+1), readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2), readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3)); size += sprintf(buffer+size, "\n%6s: Token Ring Parameters Table:\n", dev->name); size += sprintf(buffer+size, "%6s: Physical Addr : Up Node Address : Poll Address : AccPri : Auth Src : Att Code :\n", dev->name) ; size += sprintf(buffer+size, "%6s: %02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x:%02x:%02x : %04x : %04x : %04x :\n", dev->name, readb(opt+offsetof(struct olympic_parameters_table, phys_addr)), readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+1), readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+2), readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+3), readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)), readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+1), readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+2), readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+3), readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+4), readb(opt+offsetof(struct olympic_parameters_table, up_node_addr)+5), readb(opt+offsetof(struct olympic_parameters_table, poll_addr)), readb(opt+offsetof(struct olympic_parameters_table, poll_addr)+1), readb(opt+offsetof(struct olympic_parameters_table, poll_addr)+2), readb(opt+offsetof(struct olympic_parameters_table, poll_addr)+3), readb(opt+offsetof(struct olympic_parameters_table, poll_addr)+4), readb(opt+offsetof(struct olympic_parameters_table, poll_addr)+5), swab16(readw(opt+offsetof(struct olympic_parameters_table, acc_priority))), swab16(readw(opt+offsetof(struct olympic_parameters_table, auth_source_class))), swab16(readw(opt+offsetof(struct olympic_parameters_table, att_code)))); size += sprintf(buffer+size, "%6s: Source Address : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n", dev->name) ; size += sprintf(buffer+size, "%6s: %02x:%02x:%02x:%02x:%02x:%02x : %04x : %04x : %04x : %04x : %04x : %04x : \n", dev->name, readb(opt+offsetof(struct olympic_parameters_table, source_addr)), readb(opt+offsetof(struct olympic_parameters_table, source_addr)+1), readb(opt+offsetof(struct olympic_parameters_table, source_addr)+2), readb(opt+offsetof(struct olympic_parameters_table, source_addr)+3), readb(opt+offsetof(struct olympic_parameters_table, source_addr)+4), readb(opt+offsetof(struct olympic_parameters_table, source_addr)+5), swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_type))), swab16(readw(opt+offsetof(struct olympic_parameters_table, major_vector))), swab16(readw(opt+offsetof(struct olympic_parameters_table, lan_status))), swab16(readw(opt+offsetof(struct olympic_parameters_table, local_ring))), swab16(readw(opt+offsetof(struct olympic_parameters_table, mon_error))), swab16(readw(opt+offsetof(struct olympic_parameters_table, frame_correl)))); size += sprintf(buffer+size, "%6s: Beacon Details : Tx : Rx : NAUN Node Address : NAUN Node Phys : \n", dev->name) ; size += sprintf(buffer+size, "%6s: : %02x : %02x : %02x:%02x:%02x:%02x:%02x:%02x : %02x:%02x:%02x:%02x : \n", dev->name, swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_transmit))), swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_receive))), readb(opt+offsetof(struct olympic_parameters_table, beacon_naun)), readb(opt+offsetof(struct olympic_parameters_table, beacon_naun)+1), readb(opt+offsetof(struct olympic_parameters_table, beacon_naun)+2), readb(opt+offsetof(struct olympic_parameters_table, beacon_naun)+3), readb(opt+offsetof(struct olympic_parameters_table, beacon_naun)+4), readb(opt+offsetof(struct olympic_parameters_table, beacon_naun)+5), readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)), readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+1), readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+2), readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+3)); len=size; pos=begin+size; if (pos<offset) { len=0; begin=pos; } *start=buffer+(offset-begin); /* Start of wanted data */ len-=(offset-begin); /* Start slop */ if(len>length) len=length; /* Ending slop */ return len;}static void __devexit olympic_remove_one(struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata(pdev) ; struct olympic_private *olympic_priv=(struct olympic_private *)dev->priv; if (olympic_priv->olympic_network_monitor) { char proc_name[20] ; strcpy(proc_name,"net/olympic_") ; strcat(proc_name,dev->name) ; remove_proc_entry(proc_name,NULL); } unregister_trdev(dev) ; iounmap(olympic_priv->olympic_mmio) ; iounmap(olympic_priv->olympic_lap) ; pci_release_regions(pdev) ; pci_set_drvdata(pdev,NULL) ; kfree(dev) ; }static struct pci_driver olympic_driver = { name: "olympic", id_table: olympic_pci_tbl, probe: olympic_probe, remove: __devexit_p(olympic_remove_one),};static int __init olympic_pci_init(void) { return pci_module_init (&olympic_driver) ; }static void __exit olympic_pci_cleanup(void){ return pci_unregister_driver(&olympic_driver) ; } module_init(olympic_pci_init) ; module_exit(olympic_pci_cleanup) ; MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -