3c59x.c

来自「linux 内核源代码」· C语言 代码 · 共 1,988 行 · 第 1/5 页

C
1,988
字号
	local_irq_restore(flags);}#endif#ifdef CONFIG_PMstatic int vortex_suspend(struct pci_dev *pdev, pm_message_t state){	struct net_device *dev = pci_get_drvdata(pdev);	if (dev && dev->priv) {		if (netif_running(dev)) {			netif_device_detach(dev);			vortex_down(dev, 1);		}		pci_save_state(pdev);		pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);		free_irq(dev->irq, dev);		pci_disable_device(pdev);		pci_set_power_state(pdev, pci_choose_state(pdev, state));	}	return 0;}static int vortex_resume(struct pci_dev *pdev){	struct net_device *dev = pci_get_drvdata(pdev);	struct vortex_private *vp = netdev_priv(dev);	int err;	if (dev && vp) {		pci_set_power_state(pdev, PCI_D0);		pci_restore_state(pdev);		err = pci_enable_device(pdev);		if (err) {			printk(KERN_WARNING "%s: Could not enable device \n",				dev->name);			return err;		}		pci_set_master(pdev);		if (request_irq(dev->irq, vp->full_bus_master_rx ?				&boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev)) {			printk(KERN_WARNING "%s: Could not reserve IRQ %d\n", dev->name, dev->irq);			pci_disable_device(pdev);			return -EBUSY;		}		if (netif_running(dev)) {			err = vortex_up(dev);			if (err)				return err;			else				netif_device_attach(dev);		}	}	return 0;}#endif /* CONFIG_PM */#ifdef CONFIG_EISAstatic struct eisa_device_id vortex_eisa_ids[] = {	{ "TCM5920", CH_3C592 },	{ "TCM5970", CH_3C597 },	{ "" }};MODULE_DEVICE_TABLE(eisa, vortex_eisa_ids);static int __init vortex_eisa_probe(struct device *device){	void __iomem *ioaddr;	struct eisa_device *edev;	edev = to_eisa_device(device);	if (!request_region(edev->base_addr, VORTEX_TOTAL_SIZE, DRV_NAME))		return -EBUSY;	ioaddr = ioport_map(edev->base_addr, VORTEX_TOTAL_SIZE);	if (vortex_probe1(device, ioaddr, ioread16(ioaddr + 0xC88) >> 12,					  edev->id.driver_data, vortex_cards_found)) {		release_region(edev->base_addr, VORTEX_TOTAL_SIZE);		return -ENODEV;	}	vortex_cards_found++;	return 0;}static int __devexit vortex_eisa_remove(struct device *device){	struct eisa_device *edev;	struct net_device *dev;	struct vortex_private *vp;	void __iomem *ioaddr;	edev = to_eisa_device(device);	dev = eisa_get_drvdata(edev);	if (!dev) {		printk("vortex_eisa_remove called for Compaq device!\n");		BUG();	}	vp = netdev_priv(dev);	ioaddr = vp->ioaddr;	unregister_netdev(dev);	iowrite16(TotalReset|0x14, ioaddr + EL3_CMD);	release_region(dev->base_addr, VORTEX_TOTAL_SIZE);	free_netdev(dev);	return 0;}static struct eisa_driver vortex_eisa_driver = {	.id_table = vortex_eisa_ids,	.driver   = {		.name    = "3c59x",		.probe   = vortex_eisa_probe,		.remove  = __devexit_p(vortex_eisa_remove)	}};#endif /* CONFIG_EISA *//* returns count found (>= 0), or negative on error */static int __init vortex_eisa_init(void){	int eisa_found = 0;	int orig_cards_found = vortex_cards_found;#ifdef CONFIG_EISA	int err;	err = eisa_driver_register (&vortex_eisa_driver);	if (!err) {		/*		 * Because of the way EISA bus is probed, we cannot assume		 * any device have been found when we exit from		 * eisa_driver_register (the bus root driver may not be		 * initialized yet). So we blindly assume something was		 * found, and let the sysfs magic happend...		 */		eisa_found = 1;	}#endif	/* Special code to work-around the Compaq PCI BIOS32 problem. */	if (compaq_ioaddr) {		vortex_probe1(NULL, ioport_map(compaq_ioaddr, VORTEX_TOTAL_SIZE),			      compaq_irq, compaq_device_id, vortex_cards_found++);	}	return vortex_cards_found - orig_cards_found + eisa_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, unit, pci_bar;	struct vortex_chip_info *vci;	void __iomem *ioaddr;	/* wake up and enable device */	rc = pci_enable_device(pdev);	if (rc < 0)		goto out;	unit = vortex_cards_found;	if (global_use_mmio < 0 && (unit >= MAX_UNITS || use_mmio[unit] < 0)) {		/* Determine the default if the user didn't override us */		vci = &vortex_info_tbl[ent->driver_data];		pci_bar = vci->drv_flags & (IS_CYCLONE | IS_TORNADO) ? 1 : 0;	} else if (unit < MAX_UNITS && use_mmio[unit] >= 0)		pci_bar = use_mmio[unit] ? 1 : 0;	else		pci_bar = global_use_mmio ? 1 : 0;	ioaddr = pci_iomap(pdev, pci_bar, 0);	if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */		ioaddr = pci_iomap(pdev, 0, 0);	rc = vortex_probe1(&pdev->dev, ioaddr, pdev->irq,			   ent->driver_data, unit);	if (rc < 0) {		pci_disable_device(pdev);		goto out;	}	vortex_cards_found++;out:	return rc;}/* * Start up the PCI/EISA device which is described by *gendev. * Return 0 on success. * * NOTE: pdev can be NULL, for the case of a Compaq device */static int __devinit vortex_probe1(struct device *gendev,				   void __iomem *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 = "3c59x";	struct pci_dev *pdev = NULL;	struct eisa_device *edev = NULL;	DECLARE_MAC_BUF(mac);	if (!printed_version) {		printk (version);		printed_version = 1;	}	if (gendev) {		if ((pdev = DEVICE_PCI(gendev))) {			print_name = pci_name(pdev);		}		if ((edev = DEVICE_EISA(gendev))) {			print_name = edev->dev.bus_id;		}	}	dev = alloc_etherdev(sizeof(*vp));	retval = -ENOMEM;	if (!dev) {		printk (KERN_ERR PFX "unable to allocate etherdev, aborting\n");		goto out;	}	SET_NETDEV_DEV(dev, gendev);	vp = netdev_priv(dev);	option = global_options;	/* 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) {		if (options[card_idx] >= 0)			option = options[card_idx];	}	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 %p.\n",	       print_name,	       pdev ? "PCI" : "EISA",	       vci->name,	       ioaddr);	dev->base_addr = (unsigned long)ioaddr;	dev->irq = irq;	dev->mtu = mtu;	vp->ioaddr = ioaddr;	vp->large_frames = mtu > 1500;	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 Compaq device */	if (gendev == NULL) {		compaq_net_device = 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(dev->base_addr, 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);	vp->gendev = gendev;	vp->mii.dev = dev;	vp->mii.mdio_read = mdio_read;	vp->mii.mdio_write = mdio_write;	vp->mii.phy_id_mask = 0x1f;	vp->mii.reg_num_mask = 0x1f;	/* 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)		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);	if (edev)		eisa_set_drvdata(edev, 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 (global_full_duplex > 0)		vp->full_duplex = 1;	if (global_enable_wol > 0)		vp->enable_wol = 1;	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->mii.force_media = 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;		else if (vci->drv_flags & EEPROM_OFFSET)			base = EEPROM_Read + 0x30;		else			base = EEPROM_Read;		for (i = 0; i < 0x40; i++) {			int timer;			iowrite16(base + i, ioaddr + Wn0EepromCmd);			/* Pause for at least 162 us. for the read to take place. */			for (timer = 10; timer >= 0; timer--) {				udelay(162);				if ((ioread16(ioaddr + Wn0EepromCmd) & 0x8000) == 0)					break;			}			eeprom[i] = ioread16(ioaddr + Wn0EepromData);		}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?