📄 3c59x.c
字号:
struct sk_buff* tx_skbuff[TX_RING_SIZE]; struct net_device *next_module; /* NULL if PCI device */ unsigned int cur_rx, cur_tx; /* The next free ring entry */ unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */ struct net_device_stats stats; struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl. */ dma_addr_t tx_skb_dma; /* Allocated DMA address for bus master ctrl DMA. */ /* PCI configuration space information. */ struct pci_dev *pdev; char *cb_fn_base; /* CardBus function status addr space. */ /* Some values here only for performance evaluation and path-coverage */ int rx_nocopy, rx_copy, queued_packet, rx_csumhits; int card_idx; /* The remainder are related to chip state, mostly media selection. */ struct timer_list timer; /* Media selection timer. */ struct timer_list rx_oom_timer; /* Rx skb allocation retry timer */ int options; /* User-settable misc. driver options. */ unsigned int media_override:4, /* Passed-in media type. */ default_media:4, /* Read from the EEPROM/Wn3_Config. */ full_duplex:1, force_fd:1, autoselect:1, bus_master:1, /* Vortex can only do a fragment bus-m. */ full_bus_master_tx:1, full_bus_master_rx:2, /* Boomerang */ flow_ctrl:1, /* Use 802.3x flow control (PAUSE only) */ partner_flow_ctrl:1, /* Partner supports flow control */ has_nway:1, enable_wol:1, /* Wake-on-LAN is enabled */ pm_state_valid:1, /* power_state[] has sane contents */ open:1, medialock:1, must_free_region:1; /* Flag: if zero, Cardbus owns the I/O region */ int drv_flags; u16 status_enable; u16 intr_enable; u16 available_media; /* From Wn3_Options. */ u16 capabilities, info1, info2; /* Various, from EEPROM. */ u16 advertising; /* NWay media advertisement */ unsigned char phys[2]; /* MII device addresses. */ u16 deferred; /* Resend these interrupts when we * bale from the ISR */ u16 io_size; /* Size of PCI region (for release_region) */ spinlock_t lock; /* Serialise access to device & its vortex_private */ spinlock_t mdio_lock; /* Serialise access to mdio hardware */ u32 power_state[16];};/* The action to take with a media selection timer tick. Note that we deviate from the 3Com order by checking 10base2 before AUI. */enum xcvr_types { XCVR_10baseT=0, XCVR_AUI, XCVR_10baseTOnly, XCVR_10base2, XCVR_100baseTx, XCVR_100baseFx, XCVR_MII=6, XCVR_NWAY=8, XCVR_ExtMII=9, XCVR_Default=10,};static struct media_table { char *name; unsigned int media_bits:16, /* Bits to set in Wn4_Media register. */ mask:8, /* The transceiver-present bit in Wn3_Config.*/ next:8; /* The media type to try next. */ int wait; /* Time before we check media status. */} media_tbl[] = { { "10baseT", Media_10TP,0x08, XCVR_10base2, (14*HZ)/10}, { "10Mbs AUI", Media_SQE, 0x20, XCVR_Default, (1*HZ)/10}, { "undefined", 0, 0x80, XCVR_10baseT, 10000}, { "10base2", 0, 0x10, XCVR_AUI, (1*HZ)/10}, { "100baseTX", Media_Lnk, 0x02, XCVR_100baseFx, (14*HZ)/10}, { "100baseFX", Media_Lnk, 0x04, XCVR_MII, (14*HZ)/10}, { "MII", 0, 0x41, XCVR_10baseT, 3*HZ }, { "undefined", 0, 0x01, XCVR_10baseT, 10000}, { "Autonegotiate", 0, 0x41, XCVR_10baseT, 3*HZ}, { "MII-External", 0, 0x41, XCVR_10baseT, 3*HZ }, { "Default", 0, 0xFF, XCVR_10baseT, 10000},};static int vortex_probe1(struct pci_dev *pdev, long ioaddr, int irq, int chip_idx, int card_idx);static void vortex_up(struct net_device *dev);static void vortex_down(struct net_device *dev);static int vortex_open(struct net_device *dev);static void mdio_sync(long ioaddr, int bits);static int mdio_read(struct net_device *dev, int phy_id, int location);static void mdio_write(struct net_device *vp, int phy_id, int location, int value);static void vortex_timer(unsigned long arg);static void rx_oom_timer(unsigned long arg);static int vortex_start_xmit(struct sk_buff *skb, struct net_device *dev);static int boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev);static int vortex_rx(struct net_device *dev);static int boomerang_rx(struct net_device *dev);static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs);static void boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs);static int vortex_close(struct net_device *dev);static void dump_tx_ring(struct net_device *dev);static void update_stats(long ioaddr, struct net_device *dev);static struct net_device_stats *vortex_get_stats(struct net_device *dev);static void set_rx_mode(struct net_device *dev);static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);static void vortex_tx_timeout(struct net_device *dev);static void acpi_set_WOL(struct net_device *dev);/* This driver uses 'options' to pass the media type, full-duplex flag, etc. *//* Option count limit only -- unlimited interfaces are supported. */#define MAX_UNITS 8static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1,};static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};static int hw_checksums[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};static int flow_ctrl[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};static int enable_wol[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};/* #define dev_alloc_skb dev_alloc_skb_debug *//* A list of all installed Vortex EISA devices, for removing the driver module. */static struct net_device *root_vortex_eisa_dev;/* Variables to work-around the Compaq PCI BIOS32 problem. */static int compaq_ioaddr, compaq_irq, compaq_device_id = 0x5900;static int vortex_cards_found;#ifdef CONFIG_PMstatic int vortex_suspend (struct pci_dev *pdev, u32 state){ struct net_device *dev = pci_get_drvdata(pdev); if (dev && dev->priv) { if (netif_running(dev)) { netif_device_detach(dev); vortex_down(dev); } } return 0;}static int vortex_resume (struct pci_dev *pdev){ struct net_device *dev = pci_get_drvdata(pdev); if (dev && dev->priv) { if (netif_running(dev)) { vortex_up(dev); netif_device_attach(dev); } } return 0;}#endif /* CONFIG_PM *//* returns count found (>= 0), or negative on error */static int __init vortex_eisa_init (void){ long ioaddr; int rc; int orig_cards_found = vortex_cards_found; /* Now check all slots of the EISA bus. */ if (!EISA_bus) return 0; for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) { int device_id; if (request_region(ioaddr, VORTEX_TOTAL_SIZE, DRV_NAME) == NULL) continue; /* Check the standard EISA ID register for an encoded '3Com'. */ if (inw(ioaddr + 0xC80) != 0x6d50) { release_region (ioaddr, VORTEX_TOTAL_SIZE); continue; } /* Check for a product that we support, 3c59{2,7} any rev. */ device_id = (inb(ioaddr + 0xC82)<<8) + inb(ioaddr + 0xC83); if ((device_id & 0xFF00) != 0x5900) { release_region (ioaddr, VORTEX_TOTAL_SIZE); continue; } rc = vortex_probe1(NULL, ioaddr, inw(ioaddr + 0xC88) >> 12, EISA_TBL_OFFSET, vortex_cards_found); if (rc == 0) vortex_cards_found++; else release_region (ioaddr, VORTEX_TOTAL_SIZE); } /* Special code to work-around the Compaq PCI BIOS32 problem. */ if (compaq_ioaddr) { vortex_probe1(NULL, compaq_ioaddr, compaq_irq, compaq_device_id, vortex_cards_found++); } return vortex_cards_found - orig_cards_found;}/* returns count (>= 0), or negative on error */static int __devinit vortex_init_one (struct pci_dev *pdev, const struct pci_device_id *ent){ int rc; /* wake up and enable device */ if (pci_enable_device (pdev)) { rc = -EIO; } else { rc = vortex_probe1 (pdev, pci_resource_start (pdev, 0), pdev->irq, ent->driver_data, vortex_cards_found); if (rc == 0) vortex_cards_found++; } return rc;}/* * Start up the PCI device which is described by *pdev. * Return 0 on success. * * NOTE: pdev can be NULL, for the case of an EISA driver */static int __devinit vortex_probe1(struct pci_dev *pdev, long ioaddr, int irq, int chip_idx, int card_idx){ struct vortex_private *vp; int option; unsigned int eeprom[0x40], checksum = 0; /* EEPROM contents */ int i, step; struct net_device *dev; static int printed_version; int retval, print_info; struct vortex_chip_info * const vci = &vortex_info_tbl[chip_idx]; char *print_name; if (!printed_version) { printk (version); printed_version = 1; } print_name = pdev ? pdev->slot_name : "3c59x"; dev = alloc_etherdev(sizeof(*vp)); retval = -ENOMEM; if (!dev) { printk (KERN_ERR PFX "unable to allocate etherdev, aborting\n"); goto out; } SET_MODULE_OWNER(dev); vp = dev->priv; /* The lower four bits are the media type. */ if (dev->mem_start) { /* * The 'options' param is passed in as the third arg to the * LILO 'ether=' argument for non-modular use */ option = dev->mem_start; } else if (card_idx < MAX_UNITS) option = options[card_idx]; else option = -1; if (option > 0) { if (option & 0x8000) vortex_debug = 7; if (option & 0x4000) vortex_debug = 2; if (option & 0x0400) vp->enable_wol = 1; } print_info = (vortex_debug > 1); if (print_info) printk (KERN_INFO "See Documentation/networking/vortex.txt\n"); printk(KERN_INFO "%s: 3Com %s %s at 0x%lx. Vers " DRV_VERSION "\n", print_name, pdev ? "PCI" : "EISA", vci->name, ioaddr); dev->base_addr = ioaddr; dev->irq = irq; dev->mtu = mtu; vp->drv_flags = vci->drv_flags; vp->has_nway = (vci->drv_flags & HAS_NWAY) ? 1 : 0; vp->io_size = vci->io_size; vp->card_idx = card_idx; /* module list only for EISA devices */ if (pdev == NULL) { vp->next_module = root_vortex_eisa_dev; root_vortex_eisa_dev = dev; } /* PCI-only startup logic */ if (pdev) { /* EISA resources already marked, so only PCI needs to do this here */ /* Ignore return value, because Cardbus drivers already allocate for us */ if (request_region(ioaddr, vci->io_size, print_name) != NULL) vp->must_free_region = 1; /* enable bus-mastering if necessary */ if (vci->flags & PCI_USES_MASTER) pci_set_master (pdev); if (vci->drv_flags & IS_VORTEX) { u8 pci_latency; u8 new_latency = 248; /* Check the PCI latency value. On the 3c590 series the latency timer must be set to the maximum value to avoid data corruption that occurs when the timer expires during a transfer. This bug exists the Vortex chip only. */ pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency); if (pci_latency < new_latency) { printk(KERN_INFO "%s: Overriding PCI latency" " timer (CFLT) setting of %d, new value is %d.\n", print_name, pci_latency, new_latency); pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency); } } } spin_lock_init(&vp->lock); spin_lock_init(&vp->mdio_lock); vp->pdev = pdev; /* Makes sure rings are at least 16 byte aligned. */ vp->rx_ring = pci_alloc_consistent(pdev, sizeof(struct boom_rx_desc) * RX_RING_SIZE + sizeof(struct boom_tx_desc) * TX_RING_SIZE, &vp->rx_ring_dma); retval = -ENOMEM; if (vp->rx_ring == 0) goto free_region; vp->tx_ring = (struct boom_tx_desc *)(vp->rx_ring + RX_RING_SIZE); vp->tx_ring_dma = vp->rx_ring_dma + sizeof(struct boom_rx_desc) * RX_RING_SIZE; /* if we are a PCI driver, we store info in pdev->driver_data * instead of a module list */ if (pdev) pci_set_drvdata(pdev, dev); vp->media_override = 7; if (option >= 0) { vp->media_override = ((option & 7) == 2) ? 0 : option & 15; if (vp->media_override != 7) vp->medialock = 1; vp->full_duplex = (option & 0x200) ? 1 : 0; vp->bus_master = (option & 16) ? 1 : 0; } if (card_idx < MAX_UNITS) { if (full_duplex[card_idx] > 0) vp->full_duplex = 1; if (flow_ctrl[card_idx] > 0) vp->flow_ctrl = 1; if (enable_wol[card_idx] > 0) vp->enable_wol = 1; } vp->force_fd = vp->full_duplex; vp->options = option; /* Read the station address from the EEPROM. */ EL3WINDOW(0); { int base; if (vci->drv_flags & EEPROM_8BIT) base = 0x230;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -