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

📄 starfire.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
enum intr_status_bits {	IntrLinkChange=0xf0000000, IntrStatsMax=0x08000000,	IntrAbnormalSummary=0x02000000, IntrGeneralTimer=0x01000000,	IntrSoftware=0x800000, IntrRxComplQ1Low=0x400000,	IntrTxComplQLow=0x200000, IntrPCI=0x100000,	IntrDMAErr=0x080000, IntrTxDataLow=0x040000,	IntrRxComplQ2Low=0x020000, IntrRxDescQ1Low=0x010000,	IntrNormalSummary=0x8000, IntrTxDone=0x4000,	IntrTxDMADone=0x2000, IntrTxEmpty=0x1000,	IntrEarlyRxQ2=0x0800, IntrEarlyRxQ1=0x0400,	IntrRxQ2Done=0x0200, IntrRxQ1Done=0x0100,	IntrRxGFPDead=0x80, IntrRxDescQ2Low=0x40,	IntrNoTxCsum=0x20, IntrTxBadID=0x10,	IntrHiPriTxBadID=0x08, IntrRxGfp=0x04,	IntrTxGfp=0x02, IntrPCIPad=0x01,	/* not quite bits */	IntrRxDone=IntrRxQ2Done | IntrRxQ1Done,	IntrRxEmpty=IntrRxDescQ1Low | IntrRxDescQ2Low,	IntrNormalMask=0xff00, IntrAbnormalMask=0x3ff00fe,};/* Bits in the RxFilterMode register. */enum rx_mode_bits {	AcceptBroadcast=0x04, AcceptAllMulticast=0x02, AcceptAll=0x01,	AcceptMulticast=0x10, AcceptMyPhys=0xE040,};/* Bits in the TxDescCtrl register. */enum tx_ctrl_bits {	TxDescSpaceUnlim=0x00, TxDescSpace32=0x10, TxDescSpace64=0x20,	TxDescSpace128=0x30, TxDescSpace256=0x40,	TxDescType0=0x00, TxDescType1=0x01, TxDescType2=0x02,	TxDescType3=0x03, TxDescType4=0x04,	TxNoDMACompletion=0x08, TxDescQ64bit=0x80,	TxHiPriFIFOThreshShift=24, TxPadLenShift=16,	TxDMABurstSizeShift=8,};/* Bits in the RxDescQCtrl register. */enum rx_ctrl_bits {	RxBufferLenShift=16, RxMinDescrThreshShift=0,	RxPrefetchMode=0x8000, Rx2048QEntries=0x4000,	RxVariableQ=0x2000, RxDesc64bit=0x1000,	RxDescQAddr64bit=0x0100,	RxDescSpace4=0x000, RxDescSpace8=0x100,	RxDescSpace16=0x200, RxDescSpace32=0x300,	RxDescSpace64=0x400, RxDescSpace128=0x500,	RxConsumerWrEn=0x80,};/* Bits in the RxCompletionAddr register */enum rx_compl_bits {	RxComplQAddr64bit=0x80, TxComplProducerWrEn=0x40,	RxComplType0=0x00, RxComplType1=0x10,	RxComplType2=0x20, RxComplType3=0x30,	RxComplThreshShift=0,};/* The Rx and Tx buffer descriptors. */struct starfire_rx_desc {	u32 rxaddr;			/* Optionally 64 bits. */};enum rx_desc_bits {	RxDescValid=1, RxDescEndRing=2,};/* Completion queue entry.   You must update the page allocation, init_ring and the shift count in rx()   if using a larger format. */#ifdef HAS_FIRMWARE#define csum_rx_status#endif /* HAS_FIRMWARE */struct rx_done_desc {	u32 status;			/* Low 16 bits is length. */#ifdef csum_rx_status	u32 status2;			/* Low 16 bits is csum */#endif /* csum_rx_status */#ifdef full_rx_status	u32 status2;	u16 vlanid;	u16 csum;			/* partial checksum */	u32 timestamp;#endif /* full_rx_status */};enum rx_done_bits {	RxOK=0x20000000, RxFIFOErr=0x10000000, RxBufQ2=0x08000000,};#ifdef ZEROCOPY/* Type 0 Tx descriptor. *//* If more fragments are needed, don't forget to change the   descriptor spacing as well! */struct starfire_tx_desc {	u32 status;	u32 nbufs;	u32 first_addr;	u16 first_len;	u16 total_len;	struct {		u32 addr;		u32 len;	} frag[MAX_STARFIRE_FRAGS];};#else  /* not ZEROCOPY *//* Type 1 Tx descriptor. */struct starfire_tx_desc {	u32 status;			/* Upper bits are status, lower 16 length. */	u32 first_addr;};#endif /* not ZEROCOPY */enum tx_desc_bits {	TxDescID=0xB0000000,	TxCRCEn=0x01000000, TxDescIntr=0x08000000,	TxRingWrap=0x04000000, TxCalTCP=0x02000000,};struct tx_done_report {	u32 status;			/* timestamp, index. */#if 0	u32 intrstatus;			/* interrupt status */#endif};struct rx_ring_info {	struct sk_buff *skb;	dma_addr_t mapping;};struct tx_ring_info {	struct sk_buff *skb;	dma_addr_t first_mapping;#ifdef ZEROCOPY	dma_addr_t frag_mapping[MAX_STARFIRE_FRAGS];#endif /* ZEROCOPY */};#define PHY_CNT		2struct netdev_private {	/* Descriptor rings first for alignment. */	struct starfire_rx_desc *rx_ring;	struct starfire_tx_desc *tx_ring;	dma_addr_t rx_ring_dma;	dma_addr_t tx_ring_dma;	/* The addresses of rx/tx-in-place skbuffs. */	struct rx_ring_info rx_info[RX_RING_SIZE];	struct tx_ring_info tx_info[TX_RING_SIZE];	/* Pointers to completion queues (full pages). */	struct rx_done_desc *rx_done_q;	dma_addr_t rx_done_q_dma;	unsigned int rx_done;	struct tx_done_report *tx_done_q;	dma_addr_t tx_done_q_dma;	unsigned int tx_done;	struct net_device_stats stats;	struct pci_dev *pci_dev;	/* Frequently used values: keep some adjacent for cache effect. */	unsigned int cur_rx, dirty_rx;	/* Producer/consumer ring indices */	unsigned int cur_tx, dirty_tx;	unsigned int rx_buf_sz;		/* Based on MTU+slack. */	unsigned int tx_full:1,		/* The Tx queue is full. */	/* These values keep track of the transceiver/media in use. */		autoneg:1,		/* Autonegotiation allowed. */		full_duplex:1,		/* Full-duplex operation. */		speed100:1;		/* Set if speed == 100MBit. */	unsigned int intr_mitigation;	u32 tx_mode;	u8 tx_threshold;	/* MII transceiver section. */	u16 advertising;		/* NWay media advertisement */	int phy_cnt;			/* MII device addresses. */	unsigned char phys[PHY_CNT];	/* MII device addresses. */};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	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 void	netdev_media_change(struct net_device *dev);static int __devinit starfire_init_one(struct pci_dev *pdev,				       const struct pci_device_id *ent){	struct netdev_private *np;	int i, irq, option, chip_idx = ent->driver_data;	struct net_device *dev;	static int card_idx = -1;	long ioaddr;	int drv_flags, io_size;	int boguscnt;	u8 cache;/* 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	card_idx++;	if (pci_enable_device (pdev))		return -EIO;	ioaddr = pci_resource_start(pdev, 0);	io_size = pci_resource_len(pdev, 0);	if (!ioaddr || ((pci_resource_flags(pdev, 0) & IORESOURCE_MEM) == 0)) {		printk (KERN_ERR DRV_NAME " %d: no PCI MEM resources, aborting\n", card_idx);		return -ENODEV;	}	dev = alloc_etherdev(sizeof(*np));	if (!dev) {		printk (KERN_ERR DRV_NAME " %d: cannot alloc etherdev, aborting\n", card_idx);		return -ENOMEM;	}	SET_MODULE_OWNER(dev);	irq = pdev->irq;	if (pci_request_regions (pdev, dev->name)) {		printk (KERN_ERR DRV_NAME " %d: cannot reserve PCI resources, aborting\n", card_idx);		goto err_out_free_netdev;	}	ioaddr = (long) ioremap (ioaddr, io_size);	if (!ioaddr) {		printk (KERN_ERR DRV_NAME " %d: cannot remap 0x%x @ 0x%lx, aborting\n",			card_idx, io_size, ioaddr);		goto err_out_free_res;	}	pci_set_master (pdev);	/* set PCI cache size */	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache);	if ((cache << 2) != SMP_CACHE_BYTES) {		printk(KERN_INFO "  PCI cache line size set incorrectly "		       "(%i bytes) by BIOS/FW, correcting to %i\n",		       (cache << 2), SMP_CACHE_BYTES);		pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,				      SMP_CACHE_BYTES >> 2);	}#ifdef ZEROCOPY	/* Starfire can do SG and TCP/UDP checksumming */	dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;#endif /* ZEROCOPY */	/* Serial EEPROM reads are hidden by the hardware. */	for (i = 0; i < 6; i++)		dev->dev_addr[i] = readb(ioaddr + EEPROMCtrl + 20-i);#if ! defined(final_version) /* Dump the EEPROM contents during development. */	if (debug > 4)		for (i = 0; i < 0x20; i++)			printk("%2.2x%s",			       (unsigned int)readb(ioaddr + EEPROMCtrl + i),			       i % 16 != 15 ? " " : "\n");#endif	/* Issue soft reset */	writel(0x8000, ioaddr + TxMode);	udelay(1000);	writel(0, ioaddr + TxMode);	/* Reset the chip to erase previous misconfiguration. */	writel(1, ioaddr + PCIDeviceConfig);	boguscnt = 1000;	while (--boguscnt > 0) {		udelay(10);		if ((readl(ioaddr + PCIDeviceConfig) & 1) == 0)			break;	}	if (boguscnt == 0)		printk("%s: chipset reset never completed!\n", dev->name);	/* wait a little longer */	udelay(1000);	dev->base_addr = ioaddr;	dev->irq = irq;	np = dev->priv;	pci_set_drvdata(pdev, dev);	np->pci_dev = pdev;	drv_flags = netdrv_tbl[chip_idx].drv_flags;	option = card_idx < MAX_UNITS ? options[card_idx] : 0;	if (dev->mem_start)		option = dev->mem_start;	/* The lower four bits are the media type. */	if (option & 0x200)		np->full_duplex = 1;	if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)		np->full_duplex = 1;	if (np->full_duplex)		np->autoneg = 0;	else		np->autoneg = 1;	np->speed100 = 1;	/* The chip-specific entries in the device structure. */	dev->open = &netdev_open;	dev->hard_start_xmit = &start_tx;	init_tx_timer(dev, tx_timeout, TX_TIMEOUT);	dev->stop = &netdev_close;	dev->get_stats = &get_stats;	dev->set_multicast_list = &set_rx_mode;	dev->do_ioctl = &netdev_ioctl;	if (mtu)		dev->mtu = mtu;	i = register_netdev(dev);	if (i)		goto err_out_cleardev;	printk(KERN_INFO "%s: %s at 0x%lx, ",		   dev->name, netdrv_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 (drv_flags & CanHaveMII) {		int phy, phy_idx = 0;		int mii_status;		for (phy = 0; phy < 32 && phy_idx < PHY_CNT; phy++) {			mdio_write(dev, phy, MII_BMCR, BMCR_RESET);			mdelay(100);			boguscnt = 1000;			while (--boguscnt > 0)				if ((mdio_read(dev, phy, MII_BMCR) & BMCR_RESET) == 0)					break;			if (boguscnt == 0) {				printk("%s: PHY reset never completed!\n", dev->name);				continue;			}			mii_status = mdio_read(dev, phy, MII_BMSR);			if (mii_status != 0) {				np->phys[phy_idx++] = phy;				np->advertising = mdio_read(dev, phy, MII_ADVERTISE);				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);				/* there can be only one PHY on-board */				break;			}		}		np->phy_cnt = phy_idx;	}#ifdef ZEROCOPY	printk(KERN_INFO "%s: scatter-gather and hardware TCP cksumming enabled.\n",	       dev->name);#else  /* not ZEROCOPY */	printk(KERN_INFO "%s: scatter-gather and hardware TCP cksumming disabled.\n",	       dev->name);#endif /* not ZEROCOPY */	return 0;err_out_cleardev:	pci_set_drvdata(pdev, NULL);	iounmap((void *)ioaddr);err_out_free_res:	pci_release_regions (pdev);err_out_free_netdev:	unregister_netdev(dev);	kfree(dev);	return -ENODEV;}/* Read the MII Management Data I/O (MDIO) interfaces. */static int mdio_read(struct net_device *dev, int phy_id, int location){	long mdio_addr = dev->base_addr + MIICtrl + (phy_id<<7) + (location<<2);	int result, boguscnt=1000;	/* ??? Should we add a busy-wait here? */	do		result = readl(mdio_addr);	while ((result & 0xC0000000) != 0x80000000 && --boguscnt > 0);	if (boguscnt == 0)		return 0;	if ((result & 0xffff) == 0xffff)		return 0;	return result & 0xffff;}static void mdio_write(struct net_device *dev, int phy_id, int location, int value){	long mdio_addr = dev->base_addr + MIICtrl + (phy_id<<7) + (location<<2);	writel(value, mdio_addr);

⌨️ 快捷键说明

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