📄 lanstreamer.c
字号:
err_out: free_netdev(dev);#if STREAMER_DEBUG printk("lanstreamer: Exit error %x\n",rc);#endif return rc;}static void __devexit streamer_remove_one(struct pci_dev *pdev){ struct net_device *dev=pci_get_drvdata(pdev); struct streamer_private *streamer_priv;#if STREAMER_DEBUG printk("lanstreamer::streamer_remove_one entry pdev %p\n",pdev);#endif if (dev == NULL) { printk(KERN_ERR "lanstreamer::streamer_remove_one, ERROR dev is NULL\n"); return; } streamer_priv=dev->priv; if (streamer_priv == NULL) { printk(KERN_ERR "lanstreamer::streamer_remove_one, ERROR dev->priv is NULL\n"); return; }#if STREAMER_NETWORK_MONITOR#ifdef CONFIG_PROC_FS { struct streamer_private **p, **next; for (p = &dev_streamer; *p; p = next) { next = &(*p)->next; if (*p == streamer_priv) { *p = *next; break; } } if (!dev_streamer) remove_proc_entry("net/streamer_tr", NULL); }#endif#endif unregister_netdev(dev); iounmap(streamer_priv->streamer_mmio); release_mem_region(pci_resource_start(pdev, 1), pci_resource_len(pdev,1)); release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev,0)); pci_clear_mwi(pdev); pci_disable_device(pdev); free_netdev(dev); pci_set_drvdata(pdev, NULL);}static int streamer_reset(struct net_device *dev){ struct streamer_private *streamer_priv; __u8 __iomem *streamer_mmio; unsigned long t; unsigned int uaa_addr; struct sk_buff *skb = NULL; __u16 misr; streamer_priv = (struct streamer_private *) dev->priv; streamer_mmio = streamer_priv->streamer_mmio; writew(readw(streamer_mmio + BCTL) | BCTL_SOFTRESET, streamer_mmio + BCTL); t = jiffies; /* Hold soft reset bit for a while */ ssleep(1); writew(readw(streamer_mmio + BCTL) & ~BCTL_SOFTRESET, streamer_mmio + BCTL);#if STREAMER_DEBUG printk("BCTL: %x\n", readw(streamer_mmio + BCTL)); printk("GPR: %x\n", readw(streamer_mmio + GPR)); printk("SISRMASK: %x\n", readw(streamer_mmio + SISR_MASK));#endif writew(readw(streamer_mmio + BCTL) | (BCTL_RX_FIFO_8 | BCTL_TX_FIFO_8), streamer_mmio + BCTL ); if (streamer_priv->streamer_ring_speed == 0) { /* Autosense */ writew(readw(streamer_mmio + GPR) | GPR_AUTOSENSE, streamer_mmio + GPR); if (streamer_priv->streamer_message_level) printk(KERN_INFO "%s: Ringspeed autosense mode on\n", dev->name); } else if (streamer_priv->streamer_ring_speed == 16) { if (streamer_priv->streamer_message_level) printk(KERN_INFO "%s: Trying to open at 16 Mbps as requested\n", dev->name); writew(GPR_16MBPS, streamer_mmio + GPR); } else if (streamer_priv->streamer_ring_speed == 4) { if (streamer_priv->streamer_message_level) printk(KERN_INFO "%s: Trying to open at 4 Mbps as requested\n", dev->name); writew(0, streamer_mmio + GPR); } skb = dev_alloc_skb(streamer_priv->pkt_buf_sz); if (!skb) { printk(KERN_INFO "%s: skb allocation for diagnostics failed...proceeding\n", dev->name); } else { struct streamer_rx_desc *rx_ring; u8 *data; rx_ring=(struct streamer_rx_desc *)skb->data; data=((u8 *)skb->data)+sizeof(struct streamer_rx_desc); rx_ring->forward=0; rx_ring->status=0; rx_ring->buffer=cpu_to_le32(pci_map_single(streamer_priv->pci_dev, data, 512, PCI_DMA_FROMDEVICE)); rx_ring->framelen_buflen=512; writel(cpu_to_le32(pci_map_single(streamer_priv->pci_dev, rx_ring, 512, PCI_DMA_FROMDEVICE)), streamer_mmio+RXBDA); }#if STREAMER_DEBUG printk("GPR = %x\n", readw(streamer_mmio + GPR));#endif /* start solo init */ writew(SISR_MI, streamer_mmio + SISR_MASK_SUM); while (!((readw(streamer_mmio + SISR)) & SISR_SRB_REPLY)) { msleep_interruptible(100); if (jiffies - t > 40 * HZ) { printk(KERN_ERR "IBM PCI tokenring card not responding\n"); release_region(dev->base_addr, STREAMER_IO_SPACE); if (skb) dev_kfree_skb(skb); return -1; } } writew(~SISR_SRB_REPLY, streamer_mmio + SISR_RUM); misr = readw(streamer_mmio + MISR_RUM); writew(~misr, streamer_mmio + MISR_RUM); if (skb) dev_kfree_skb(skb); /* release skb used for diagnostics */#if STREAMER_DEBUG printk("LAPWWO: %x, LAPA: %x LAPE: %x\n", readw(streamer_mmio + LAPWWO), readw(streamer_mmio + LAPA), readw(streamer_mmio + LAPE));#endif#if STREAMER_DEBUG { int i; writew(readw(streamer_mmio + LAPWWO), streamer_mmio + LAPA); printk("initialization response srb dump: "); for (i = 0; i < 10; i++) printk("%x:", ntohs(readw(streamer_mmio + LAPDINC))); printk("\n"); }#endif writew(readw(streamer_mmio + LAPWWO) + 6, streamer_mmio + LAPA); if (readw(streamer_mmio + LAPD)) { printk(KERN_INFO "tokenring card initialization failed. errorcode : %x\n", ntohs(readw(streamer_mmio + LAPD))); release_region(dev->base_addr, STREAMER_IO_SPACE); return -1; } writew(readw(streamer_mmio + LAPWWO) + 8, streamer_mmio + LAPA); uaa_addr = ntohs(readw(streamer_mmio + LAPDINC)); readw(streamer_mmio + LAPDINC); /* skip over Level.Addr field */ streamer_priv->streamer_addr_table_addr = ntohs(readw(streamer_mmio + LAPDINC)); streamer_priv->streamer_parms_addr = ntohs(readw(streamer_mmio + LAPDINC));#if STREAMER_DEBUG printk("UAA resides at %x\n", uaa_addr);#endif /* setup uaa area for access with LAPD */ { int i; __u16 addr; writew(uaa_addr, streamer_mmio + LAPA); for (i = 0; i < 6; i += 2) { addr=ntohs(readw(streamer_mmio+LAPDINC)); dev->dev_addr[i]= (addr >> 8) & 0xff; dev->dev_addr[i+1]= addr & 0xff; }#if STREAMER_DEBUG printk("Adapter address: "); for (i = 0; i < 6; i++) { printk("%02x:", dev->dev_addr[i]); } printk("\n");#endif } return 0;}static int streamer_open(struct net_device *dev){ struct streamer_private *streamer_priv = (struct streamer_private *) dev->priv; __u8 __iomem *streamer_mmio = streamer_priv->streamer_mmio; unsigned long flags; char open_error[255]; int i, open_finished = 1; __u16 srb_word; __u16 srb_open; int rc; if (readw(streamer_mmio+BMCTL_SUM) & BMCTL_RX_ENABLED) { rc=streamer_reset(dev); } if (request_irq(dev->irq, &streamer_interrupt, SA_SHIRQ, "lanstreamer", dev)) { return -EAGAIN; }#if STREAMER_DEBUG printk("BMCTL: %x\n", readw(streamer_mmio + BMCTL_SUM)); printk("pending ints: %x\n", readw(streamer_mmio + SISR));#endif writew(SISR_MI | SISR_SRB_REPLY, streamer_mmio + SISR_MASK); /* more ints later, doesn't stop arb cmd interrupt */ writew(LISR_LIE, streamer_mmio + LISR); /* more ints later */ /* adapter is closed, so SRB is pointed to by LAPWWO */ writew(readw(streamer_mmio + LAPWWO), streamer_mmio + LAPA);#if STREAMER_DEBUG printk("LAPWWO: %x, LAPA: %x\n", readw(streamer_mmio + LAPWWO), readw(streamer_mmio + LAPA)); printk("LAPE: %x\n", readw(streamer_mmio + LAPE)); printk("SISR Mask = %04x\n", readw(streamer_mmio + SISR_MASK));#endif do { int i; for (i = 0; i < SRB_COMMAND_SIZE; i += 2) { writew(0, streamer_mmio + LAPDINC); } writew(readw(streamer_mmio+LAPWWO),streamer_mmio+LAPA); writew(htons(SRB_OPEN_ADAPTER<<8),streamer_mmio+LAPDINC) ; /* open */ writew(htons(STREAMER_CLEAR_RET_CODE<<8),streamer_mmio+LAPDINC); writew(STREAMER_CLEAR_RET_CODE, streamer_mmio + LAPDINC); writew(readw(streamer_mmio + LAPWWO) + 8, streamer_mmio + LAPA);#if STREAMER_NETWORK_MONITOR /* If Network Monitor, instruct card to copy MAC frames through the ARB */ writew(htons(OPEN_ADAPTER_ENABLE_FDX | OPEN_ADAPTER_PASS_ADC_MAC | OPEN_ADAPTER_PASS_ATT_MAC | OPEN_ADAPTER_PASS_BEACON), streamer_mmio + LAPDINC); /* offset 8 word contains open options */#else writew(htons(OPEN_ADAPTER_ENABLE_FDX), streamer_mmio + LAPDINC); /* Offset 8 word contains Open.Options */#endif if (streamer_priv->streamer_laa[0]) { writew(readw(streamer_mmio + LAPWWO) + 12, streamer_mmio + LAPA); writew(htons((streamer_priv->streamer_laa[0] << 8) | streamer_priv->streamer_laa[1]),streamer_mmio+LAPDINC); writew(htons((streamer_priv->streamer_laa[2] << 8) | streamer_priv->streamer_laa[3]),streamer_mmio+LAPDINC); writew(htons((streamer_priv->streamer_laa[4] << 8) | streamer_priv->streamer_laa[5]),streamer_mmio+LAPDINC); memcpy(dev->dev_addr, streamer_priv->streamer_laa, dev->addr_len); } /* save off srb open offset */ srb_open = readw(streamer_mmio + LAPWWO);#if STREAMER_DEBUG writew(readw(streamer_mmio + LAPWWO), streamer_mmio + LAPA); printk("srb open request: \n"); for (i = 0; i < 16; i++) { printk("%x:", ntohs(readw(streamer_mmio + LAPDINC))); } printk("\n");#endif spin_lock_irqsave(&streamer_priv->streamer_lock, flags); streamer_priv->srb_queued = 1; /* signal solo that SRB command has been issued */ writew(LISR_SRB_CMD, streamer_mmio + LISR_SUM); spin_unlock_irqrestore(&streamer_priv->streamer_lock, flags); while (streamer_priv->srb_queued) { interruptible_sleep_on_timeout(&streamer_priv->srb_wait, 5 * HZ); if (signal_pending(current)) { printk(KERN_WARNING "%s: SRB timed out.\n", dev->name); printk(KERN_WARNING "SISR=%x MISR=%x, LISR=%x\n", readw(streamer_mmio + SISR), readw(streamer_mmio + MISR_RUM), readw(streamer_mmio + LISR)); streamer_priv->srb_queued = 0; break; } }#if STREAMER_DEBUG printk("SISR_MASK: %x\n", readw(streamer_mmio + SISR_MASK)); printk("srb open response:\n"); writew(srb_open, streamer_mmio + LAPA); for (i = 0; i < 10; i++) { printk("%x:", ntohs(readw(streamer_mmio + LAPDINC))); }#endif /* If we get the same return response as we set, the interrupt wasn't raised and the open * timed out. */ writew(srb_open + 2, streamer_mmio + LAPA); srb_word = ntohs(readw(streamer_mmio + LAPD)) >> 8; if (srb_word == STREAMER_CLEAR_RET_CODE) { printk(KERN_WARNING "%s: Adapter Open time out or error.\n", dev->name); return -EIO; } if (srb_word != 0) { if (srb_word == 0x07) { if (!streamer_priv->streamer_ring_speed && open_finished) { /* Autosense , first time around */ printk(KERN_WARNING "%s: Retrying at different ring speed \n", dev->name); open_finished = 0; } else { __u16 error_code; writew(srb_open + 6, streamer_mmio + LAPA); error_code = ntohs(readw(streamer_mmio + LAPD)); strcpy(open_error, open_maj_error[(error_code & 0xf0) >> 4]); strcat(open_error, " - "); strcat(open_error, open_min_error[(error_code & 0x0f)]); if (!streamer_priv->streamer_ring_speed && ((error_code & 0x0f) == 0x0d)) { printk(KERN_WARNING "%s: Tried to autosense ring speed with no monitors present\n", dev->name); printk(KERN_WARNING "%s: Please try again with a specified ring speed \n", dev->name); free_irq(dev->irq, dev); return -EIO; } printk(KERN_WARNING "%s: %s\n", dev->name, open_error); free_irq(dev->irq, dev); return -EIO; } /* if autosense && open_finished */ } else { printk(KERN_WARNING "%s: Bad OPEN response: %x\n", dev->name, srb_word); free_irq(dev->irq, dev); return -EIO; } } else open_finished = 1; } while (!(open_finished)); /* Will only loop if ring speed mismatch re-open attempted && autosense is on */ writew(srb_open + 18, streamer_mmio + LAPA); srb_word=ntohs(readw(streamer_mmio+LAPD)) >> 8; if (srb_word & (1 << 3)) if (streamer_priv->streamer_message_level) printk(KERN_INFO "%s: Opened in FDX Mode\n", dev->name); if (srb_word & 1) streamer_priv->streamer_ring_speed = 16; else streamer_priv->streamer_ring_speed = 4; if (streamer_priv->streamer_message_level) printk(KERN_INFO "%s: Opened in %d Mbps mode\n", dev->name, streamer_priv->streamer_ring_speed); writew(srb_open + 8, streamer_mmio + LAPA); streamer_priv->asb = ntohs(readw(streamer_mmio + LAPDINC)); streamer_priv->srb = ntohs(readw(streamer_mmio + LAPDINC)); streamer_priv->arb = ntohs(readw(streamer_mmio + LAPDINC)); readw(streamer_mmio + LAPDINC); /* offset 14 word is rsvd */ streamer_priv->trb = ntohs(readw(streamer_mmio + LAPDINC)); streamer_priv->streamer_receive_options = 0x00;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -