⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sundance.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 4 页
字号:
	DescEndRing=0x2000,	LastFrag=0x80000000,	DescIntrOnTx=0x8000,	DescIntrOnDMADone=0x80000000,	DisableAlign = 0x00000001,};#define PRIV_ALIGN	15 	/* Required alignment mask *//* Use  __attribute__((aligned (L1_CACHE_BYTES)))  to maintain alignment   within the structure. */#define MII_CNT		4struct netdev_private {	/* Descriptor rings first for alignment. */	struct netdev_desc *rx_ring;	struct netdev_desc *tx_ring;	struct sk_buff* rx_skbuff[RX_RING_SIZE];	struct sk_buff* tx_skbuff[TX_RING_SIZE];        dma_addr_t tx_ring_dma;        dma_addr_t rx_ring_dma;	struct net_device_stats stats;	struct timer_list timer;	/* Media monitoring timer. */	/* Frequently used values: keep some adjacent for cache effect. */	spinlock_t lock;	int chip_id, drv_flags;	unsigned int cur_rx, dirty_rx;		/* Producer/consumer ring indices */	unsigned int rx_buf_sz;				/* Based on MTU+slack. */	spinlock_t txlock;					/* Group with Tx control cache line. */	struct netdev_desc *last_tx;		/* Last Tx descriptor used. */	unsigned int cur_tx, dirty_tx;	unsigned int tx_full:1;				/* The Tx queue is full. */	/* These values are keep track of the transceiver/media in use. */	unsigned int full_duplex:1;			/* Full-duplex operation requested. */	unsigned int medialock:1;			/* Do not sense media. */	unsigned int default_port:4;		/* Last dev->if_port value. */	unsigned int an_enable:1;	unsigned int speed;	/* Multicast and receive mode. */	spinlock_t mcastlock;				/* SMP lock multicast updates. */	u16 mcast_filter[4];	/* MII transceiver section. */	int mii_cnt;						/* MII device addresses. */	u16 advertising;					/* NWay media advertisement */	unsigned char phys[MII_CNT];		/* MII device addresses, only first one used. */	struct pci_dev *pci_dev;};/* The station address location in the EEPROM. */#define EEPROM_SA_OFFSET	0x10static int  eeprom_read(long ioaddr, int location);static int  mdio_read(struct net_device *dev, int phy_id, int location);static void mdio_write(struct net_device *dev, int phy_id, int location, int value);static int  netdev_open(struct net_device *dev);static void check_duplex(struct net_device *dev);static void netdev_timer(unsigned long data);static void tx_timeout(struct net_device *dev);static void init_ring(struct net_device *dev);static int  start_tx(struct sk_buff *skb, struct net_device *dev);static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs);static void netdev_error(struct net_device *dev, int intr_status);static int  netdev_rx(struct net_device *dev);static void netdev_error(struct net_device *dev, int intr_status);static void set_rx_mode(struct net_device *dev);static struct net_device_stats *get_stats(struct net_device *dev);static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);static int  netdev_close(struct net_device *dev);static int __devinit sundance_probe1 (struct pci_dev *pdev,				      const struct pci_device_id *ent){	struct net_device *dev;	struct netdev_private *np;	static int card_idx;	int chip_idx = ent->driver_data;	int irq;	int i;	long ioaddr;	u16 mii_ctl;	void *ring_space;	dma_addr_t ring_dma;/* when built into the kernel, we only print version if device is found */#ifndef MODULE	static int printed_version;	if (!printed_version++)		printk(version);#endif	if (pci_enable_device(pdev))		return -EIO;	pci_set_master(pdev);	irq = pdev->irq;	dev = alloc_etherdev(sizeof(*np));	if (!dev)		return -ENOMEM;	SET_MODULE_OWNER(dev);	if (pci_request_regions(pdev, DRV_NAME))		goto err_out_netdev;#ifdef USE_IO_OPS	ioaddr = pci_resource_start(pdev, 0);#else	ioaddr = pci_resource_start(pdev, 1);	ioaddr = (long) ioremap (ioaddr, pci_id_tbl[chip_idx].io_size);	if (!ioaddr)		goto err_out_res;#endif	for (i = 0; i < 3; i++)		((u16 *)dev->dev_addr)[i] =			le16_to_cpu(eeprom_read(ioaddr, i + EEPROM_SA_OFFSET));	dev->base_addr = ioaddr;	dev->irq = irq;	np = dev->priv;	np->chip_id = chip_idx;	np->drv_flags = pci_id_tbl[chip_idx].drv_flags;	np->pci_dev = pdev;	spin_lock_init(&np->lock);	ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma);	if (!ring_space)		goto err_out_cleardev;	np->tx_ring = (struct netdev_desc *)ring_space;	np->tx_ring_dma = ring_dma;	ring_space = pci_alloc_consistent(pdev, RX_TOTAL_SIZE, &ring_dma);	if (!ring_space)		goto err_out_unmap_tx;	np->rx_ring = (struct netdev_desc *)ring_space;	np->rx_ring_dma = ring_dma;	/* The chip-specific entries in the device structure. */	dev->open = &netdev_open;	dev->hard_start_xmit = &start_tx;	dev->stop = &netdev_close;	dev->get_stats = &get_stats;	dev->set_multicast_list = &set_rx_mode;	dev->do_ioctl = &netdev_ioctl;	dev->tx_timeout = &tx_timeout;	dev->watchdog_timeo = TX_TIMEOUT;	pci_set_drvdata(pdev, dev);	if (mtu)		dev->mtu = mtu;	i = register_netdev(dev);	if (i)		goto err_out_unmap_rx;	printk(KERN_INFO "%s: %s at 0x%lx, ",		   dev->name, pci_id_tbl[chip_idx].name, ioaddr);	for (i = 0; i < 5; i++)			printk("%2.2x:", dev->dev_addr[i]);	printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);	if (1) {		int phy, phy_idx = 0;		np->phys[0] = 1;		/* Default setting */		for (phy = 0; phy < 32 && phy_idx < MII_CNT; phy++) {			int mii_status = mdio_read(dev, phy, 1);			if (mii_status != 0xffff  &&  mii_status != 0x0000) {				np->phys[phy_idx++] = phy;				np->advertising = mdio_read(dev, phy, 4);				printk(KERN_INFO "%s: MII PHY found at address %d, status "					   "0x%4.4x advertising %4.4x.\n",					   dev->name, phy, mii_status, np->advertising);			}		}		np->mii_cnt = phy_idx;		if (phy_idx == 0)			printk(KERN_INFO "%s: No MII transceiver found!, ASIC status %x\n",				   dev->name, readl(ioaddr + ASICCtrl));	}	/* Parse override configuration */	np->an_enable = 1;	if (card_idx < MAX_UNITS) {		if (media[card_idx] != NULL) {			np->an_enable = 0;			if (strcmp (media[card_idx], "100mbps_fd") == 0 ||			    strcmp (media[card_idx], "4") == 0) {				np->speed = 100;				np->full_duplex = 1;			} else if (strcmp (media[card_idx], "100mbps_hd") == 0				   || strcmp (media[card_idx], "3") == 0) {				np->speed = 100;				np->full_duplex = 0;			} else if (strcmp (media[card_idx], "10mbps_fd") == 0 ||				   strcmp (media[card_idx], "2") == 0) {				np->speed = 10;				np->full_duplex = 1;			} else if (strcmp (media[card_idx], "10mbps_hd") == 0 ||				   strcmp (media[card_idx], "1") == 0) {				np->speed = 10;				np->full_duplex = 0;			} else {				np->an_enable = 1;			}		}	}	/* Fibre PHY? */	if (readl (ioaddr + ASICCtrl) & 0x80) {		/* Default 100Mbps Full */		if (np->an_enable) {			np->speed = 100;			np->full_duplex = 1;			np->an_enable = 0;		}	}	/* Reset PHY */	mdio_write (dev, np->phys[0], MII_BMCR, BMCR_RESET);	mdelay (300);	mdio_write (dev, np->phys[0], MII_BMCR, BMCR_ANENABLE|BMCR_ANRESTART);	/* Force media type */	if (!np->an_enable) {		mii_ctl = 0;		mii_ctl |= (np->speed == 100) ? BMCR_SPEED100 : 0;		mii_ctl |= (np->full_duplex) ? BMCR_FULLDPLX : 0;		mdio_write (dev, np->phys[0], MII_BMCR, mii_ctl);		printk (KERN_INFO "Override speed=%d, %s duplex\n",			np->speed, np->full_duplex ? "Full" : "Half");	}	/* Perhaps move the reset here? */	/* Reset the chip to erase previous misconfiguration. */	if (debug > 1)		printk("ASIC Control is %x.\n", readl(ioaddr + ASICCtrl));	writew(0x007f, ioaddr + ASICCtrl + 2);	if (debug > 1)		printk("ASIC Control is now %x.\n", readl(ioaddr + ASICCtrl));	card_idx++;	return 0;err_out_unmap_rx:        pci_free_consistent(pdev, RX_TOTAL_SIZE, np->rx_ring, np->rx_ring_dma);err_out_unmap_tx:        pci_free_consistent(pdev, TX_TOTAL_SIZE, np->tx_ring, np->tx_ring_dma);err_out_cleardev:	pci_set_drvdata(pdev, NULL);#ifndef USE_IO_OPS	iounmap((void *)ioaddr);err_out_res:#endif	pci_release_regions(pdev);err_out_netdev:	kfree (dev);	return -ENODEV;}/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. */static int eeprom_read(long ioaddr, int location){	int boguscnt = 1000;		/* Typical 190 ticks. */	writew(0x0200 | (location & 0xff), ioaddr + EECtrl);	do {		if (! (readw(ioaddr + EECtrl) & 0x8000)) {			return readw(ioaddr + EEData);		}	} while (--boguscnt > 0);	return 0;}/*  MII transceiver control section.	Read and write the MII registers using software-generated serial	MDIO protocol.  See the MII specifications or DP83840A data sheet	for details.	The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually	met by back-to-back 33Mhz PCI cycles. */#define mdio_delay() readb(mdio_addr)/* Set iff a MII transceiver on any interface requires mdio preamble.   This only set with older tranceivers, so the extra   code size of a per-interface flag is not worthwhile. */static const char mii_preamble_required = 1;enum mii_reg_bits {	MDIO_ShiftClk=0x0001, MDIO_Data=0x0002, MDIO_EnbOutput=0x0004,};#define MDIO_EnbIn  (0)#define MDIO_WRITE0 (MDIO_EnbOutput)#define MDIO_WRITE1 (MDIO_Data | MDIO_EnbOutput)/* Generate the preamble required for initial synchronization and   a few older transceivers. */static void mdio_sync(long mdio_addr){	int bits = 32;	/* Establish sync by sending at least 32 logic ones. */	while (--bits >= 0) {		writeb(MDIO_WRITE1, mdio_addr);		mdio_delay();		writeb(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);		mdio_delay();	}}static int mdio_read(struct net_device *dev, int phy_id, int location){	long mdio_addr = dev->base_addr + MIICtrl;	int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;	int i, retval = 0;	if (mii_preamble_required)		mdio_sync(mdio_addr);	/* Shift the read command bits out. */	for (i = 15; i >= 0; i--) {		int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;		writeb(dataval, mdio_addr);		mdio_delay();		writeb(dataval | MDIO_ShiftClk, mdio_addr);		mdio_delay();	}	/* Read the two transition, 16 data, and wire-idle bits. */	for (i = 19; i > 0; i--) {		writeb(MDIO_EnbIn, mdio_addr);		mdio_delay();		retval = (retval << 1) | ((readb(mdio_addr) & MDIO_Data) ? 1 : 0);		writeb(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);		mdio_delay();	}	return (retval>>1) & 0xffff;}static void mdio_write(struct net_device *dev, int phy_id, int location, int value){	long mdio_addr = dev->base_addr + MIICtrl;	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;	int i;	if (mii_preamble_required)		mdio_sync(mdio_addr);	/* Shift the command bits out. */	for (i = 31; i >= 0; i--) {		int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;		writeb(dataval, mdio_addr);		mdio_delay();		writeb(dataval | MDIO_ShiftClk, mdio_addr);		mdio_delay();	}	/* Clear out extra bits. */	for (i = 2; i > 0; i--) {		writeb(MDIO_EnbIn, mdio_addr);		mdio_delay();		writeb(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);		mdio_delay();	}	return;}static int netdev_open(struct net_device *dev){	struct netdev_private *np = dev->priv;	long ioaddr = dev->base_addr;	int i;	/* Do we need to reset the chip??? */	i = request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev);	if (i)

⌨️ 快捷键说明

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