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

📄 natsemi.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
	IntrRxEarly		= 0x0008,	IntrRxIdle		= 0x0010,	IntrRxOverrun		= 0x0020,	IntrTxDone		= 0x0040,	IntrTxIntr		= 0x0080,	IntrTxErr		= 0x0100,	IntrTxIdle		= 0x0200,	IntrTxUnderrun		= 0x0400,	StatsMax		= 0x0800,	SWInt			= 0x1000,	WOLPkt			= 0x2000,	LinkChange		= 0x4000,	IntrHighBits		= 0x8000,	RxStatusFIFOOver	= 0x10000,	IntrPCIErr		= 0xf00000,	RxResetDone		= 0x1000000,	TxResetDone		= 0x2000000,	IntrAbnormalSummary	= 0xCD20,};/* * Default Interrupts: * Rx OK, Rx Packet Error, Rx Overrun,  * Tx OK, Tx Packet Error, Tx Underrun,  * MIB Service, Phy Interrupt, High Bits, * Rx Status FIFO overrun, * Received Target Abort, Received Master Abort,  * Signalled System Error, Received Parity Error */#define DEFAULT_INTR 0x00f1cd65enum TxConfig_bits {	TxDrthMask		= 0x3f,	TxFlthMask		= 0x3f00,	TxMxdmaMask		= 0x700000,	TxMxdma_512		= 0x0,	TxMxdma_4		= 0x100000,	TxMxdma_8		= 0x200000,	TxMxdma_16		= 0x300000,	TxMxdma_32		= 0x400000,	TxMxdma_64		= 0x500000,	TxMxdma_128		= 0x600000,	TxMxdma_256		= 0x700000,	TxCollRetry		= 0x800000,	TxAutoPad		= 0x10000000,	TxMacLoop		= 0x20000000,	TxHeartIgn		= 0x40000000,	TxCarrierIgn		= 0x80000000};enum RxConfig_bits {	RxDrthMask		= 0x3e,	RxMxdmaMask		= 0x700000,	RxMxdma_512		= 0x0,	RxMxdma_4		= 0x100000,	RxMxdma_8		= 0x200000,	RxMxdma_16		= 0x300000,	RxMxdma_32		= 0x400000,	RxMxdma_64		= 0x500000,	RxMxdma_128		= 0x600000,	RxMxdma_256		= 0x700000,	RxAcceptLong		= 0x8000000,	RxAcceptTx		= 0x10000000,	RxAcceptRunt		= 0x40000000,	RxAcceptErr		= 0x80000000};enum ClkRun_bits {	PMEEnable		= 0x100,	PMEStatus		= 0x8000,};enum WolCmd_bits {	WakePhy			= 0x1,	WakeUnicast		= 0x2,	WakeMulticast		= 0x4,	WakeBroadcast		= 0x8,	WakeArp			= 0x10,	WakePMatch0		= 0x20,	WakePMatch1		= 0x40,	WakePMatch2		= 0x80,	WakePMatch3		= 0x100,	WakeMagic		= 0x200,	WakeMagicSecure		= 0x400,	SecureHack		= 0x100000,	WokePhy			= 0x400000,	WokeUnicast		= 0x800000,	WokeMulticast		= 0x1000000,	WokeBroadcast		= 0x2000000,	WokeArp			= 0x4000000,	WokePMatch0		= 0x8000000,	WokePMatch1		= 0x10000000,	WokePMatch2		= 0x20000000,	WokePMatch3		= 0x40000000,	WokeMagic		= 0x80000000,	WakeOptsSummary		= 0x7ff};enum RxFilterAddr_bits {	RFCRAddressMask		= 0x3ff,	AcceptMulticast		= 0x00200000,	AcceptMyPhys		= 0x08000000,	AcceptAllPhys		= 0x10000000,	AcceptAllMulticast	= 0x20000000,	AcceptBroadcast		= 0x40000000,	RxFilterEnable		= 0x80000000};enum StatsCtrl_bits {	StatsWarn		= 0x1,	StatsFreeze		= 0x2,	StatsClear		= 0x4,	StatsStrobe		= 0x8,};enum MIntrCtrl_bits {	MICRIntEn		= 0x2,};enum PhyCtrl_bits {	PhyAddrMask		= 0xf,};#define SRR_REV_C	0x0302#define SRR_REV_D	0x0403/* The Rx and Tx buffer descriptors. *//* Note that using only 32 bit fields simplifies conversion to big-endian   architectures. */struct netdev_desc {	u32 next_desc;	s32 cmd_status;	u32 addr;	u32 software_use;};/* Bits in network_desc.status */enum desc_status_bits {	DescOwn=0x80000000, DescMore=0x40000000, DescIntr=0x20000000,	DescNoCRC=0x10000000, DescPktOK=0x08000000, 	DescSizeMask=0xfff,	DescTxAbort=0x04000000, DescTxFIFO=0x02000000, 	DescTxCarrier=0x01000000, DescTxDefer=0x00800000,	DescTxExcDefer=0x00400000, DescTxOOWCol=0x00200000,	DescTxExcColl=0x00100000, DescTxCollCount=0x000f0000,		DescRxAbort=0x04000000, DescRxOver=0x02000000,	DescRxDest=0x01800000, DescRxLong=0x00400000,	DescRxRunt=0x00200000, DescRxInvalid=0x00100000,	DescRxCRC=0x00080000, DescRxAlign=0x00040000,	DescRxLoop=0x00020000, DesRxColl=0x00010000,};struct netdev_private {	/* Descriptor rings first for alignment. */	dma_addr_t ring_dma;	struct netdev_desc* rx_ring;	struct netdev_desc* tx_ring;	/* The addresses of receive-in-place skbuffs. */	struct sk_buff* rx_skbuff[RX_RING_SIZE];	dma_addr_t rx_dma[RX_RING_SIZE];	/* The saved address of a sent-in-place packet/buffer, for later free(). */	struct sk_buff* tx_skbuff[TX_RING_SIZE];	dma_addr_t tx_dma[TX_RING_SIZE];	struct net_device_stats stats;	struct timer_list timer;	/* Media monitoring timer. */	/* Frequently used values: keep some adjacent for cache effect. */	struct pci_dev *pci_dev;	struct netdev_desc *rx_head_desc;	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. */	/* These values are keep track of the transceiver/media in use. */	unsigned int full_duplex;	/* Rx filter. */	u32 cur_rx_mode;	u32 rx_filter[16];	/* FIFO and PCI burst thresholds. */	u32 tx_config, rx_config;	/* original contents of ClkRun register */	u32 SavedClkRun;	/* silicon revision */	u32 srr;	/* MII transceiver section. */	u16 advertising; /* NWay media advertisement */	unsigned int iosize;	spinlock_t lock;	u32 msg_enable;};static int eeprom_read(long ioaddr, int location);static int mdio_read(struct net_device *dev, int phy_id, int reg);static void mdio_write(struct net_device *dev, int phy_id, int reg, u16 data);static void natsemi_reset(struct net_device *dev);static void natsemi_reload_eeprom(struct net_device *dev);static void natsemi_stop_rxtx(struct net_device *dev);static int netdev_open(struct net_device *dev);static void check_link(struct net_device *dev);static void netdev_timer(unsigned long data);static void tx_timeout(struct net_device *dev);static int alloc_ring(struct net_device *dev);static void init_ring(struct net_device *dev);static void drain_ring(struct net_device *dev);static void free_ring(struct net_device *dev);static void init_registers(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 void netdev_rx(struct net_device *dev);static void netdev_tx_done(struct net_device *dev);static void __set_rx_mode(struct net_device *dev);static void set_rx_mode(struct net_device *dev);static void __get_stats(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_set_wol(struct net_device *dev, u32 newval);static int netdev_get_wol(struct net_device *dev, u32 *supported, u32 *cur);static int netdev_set_sopass(struct net_device *dev, u8 *newval);static int netdev_get_sopass(struct net_device *dev, u8 *data);static int netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd);static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd);static void enable_wol_mode(struct net_device *dev, int enable_intr);static int netdev_close(struct net_device *dev);static int netdev_get_regs(struct net_device *dev, u8 *buf);static int netdev_get_eeprom(struct net_device *dev, u8 *buf);static int __devinit natsemi_probe1 (struct pci_dev *pdev,				     const struct pci_device_id *ent){	struct net_device *dev;	struct netdev_private *np;	int i, option, irq, chip_idx = ent->driver_data;	static int find_cnt = -1;	unsigned long ioaddr, iosize;	const int pcibar = 1; /* PCI base address register */	int prev_eedata;	u32 tmp;/* 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	i = pci_enable_device(pdev);	if (i) return i;	/* natsemi has a non-standard PM control register	 * in PCI config space.  Some boards apparently need	 * to be brought to D0 in this manner.	 */	pci_read_config_dword(pdev, PCIPM, &tmp);	if (tmp & PCI_PM_CTRL_STATE_MASK) {		/* D0 state, disable PME assertion */		u32 newtmp = tmp & ~PCI_PM_CTRL_STATE_MASK;		pci_write_config_dword(pdev, PCIPM, newtmp);	}	find_cnt++;	ioaddr = pci_resource_start(pdev, pcibar);	iosize = pci_resource_len(pdev, pcibar);	irq = pdev->irq;	if (natsemi_pci_info[chip_idx].flags & PCI_USES_MASTER)		pci_set_master(pdev);	dev = alloc_etherdev(sizeof (struct netdev_private));	if (!dev)		return -ENOMEM;	SET_MODULE_OWNER(dev);	i = pci_request_regions(pdev, dev->name);	if (i) {		kfree(dev);		return i;	}	{		void *mmio = ioremap (ioaddr, iosize);		if (!mmio) {			pci_release_regions(pdev);			kfree(dev);			return -ENOMEM;		}		ioaddr = (unsigned long) mmio;	}	/* Work around the dropped serial bit. */	prev_eedata = eeprom_read(ioaddr, 6);	for (i = 0; i < 3; i++) {		int eedata = eeprom_read(ioaddr, i + 7);		dev->dev_addr[i*2] = (eedata << 1) + (prev_eedata >> 15);		dev->dev_addr[i*2+1] = eedata >> 7;		prev_eedata = eedata;	}	dev->base_addr = ioaddr;	dev->irq = irq;	np = dev->priv;	np->pci_dev = pdev;	pci_set_drvdata(pdev, dev);	np->iosize = iosize;	spin_lock_init(&np->lock);	np->msg_enable = debug;	/* Reset the chip to erase previous misconfiguration. */	natsemi_reload_eeprom(dev);	natsemi_reset(dev);	option = find_cnt < MAX_UNITS ? options[find_cnt] : 0;	if (dev->mem_start)		option = dev->mem_start;	/* The lower four bits are the media type. */	if (option > 0) {		if (option & 0x200)			np->full_duplex = 1;		if (option & 15)			printk(KERN_INFO 				"%s: ignoring user supplied media type %d",				dev->name, option & 15);	}	if (find_cnt < MAX_UNITS  &&  full_duplex[find_cnt] > 0)		np->full_duplex = 1;	/* 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;	if (mtu)		dev->mtu = mtu;	i = register_netdev(dev);	if (i) {		pci_release_regions(pdev);		unregister_netdev(dev);		kfree(dev);		pci_set_drvdata(pdev, NULL);		return i;	}	netif_carrier_off(dev);	if (netif_msg_drv(np)) {		printk(KERN_INFO "%s: %s at %#08lx, ",			   dev->name, natsemi_pci_info[chip_idx].name, ioaddr);		for (i = 0; i < ETH_ALEN-1; i++)				printk("%02x:", dev->dev_addr[i]);		printk("%02x, IRQ %d.\n", dev->dev_addr[i], irq);	}	np->advertising = mdio_read(dev, 1, MII_ADVERTISE);	if ((readl(ioaddr + ChipConfig) & 0xe000) != 0xe000 	 && netif_msg_probe(np)) {		u32 chip_config = readl(ioaddr + ChipConfig);		printk(KERN_INFO "%s: Transceiver default autonegotiation %s "			   "10%s %s duplex.\n",			   dev->name,			   chip_config & CfgAnegEnable ? "enabled, advertise" : "disabled, force",			   chip_config & CfgAneg100 ? "0" : "",			   chip_config & CfgAnegFull ? "full" : "half");	}	if (netif_msg_probe(np))		printk(KERN_INFO 			"%s: Transceiver status %#04x advertising %#04x.\n",			dev->name, mdio_read(dev, 1, MII_BMSR), 			np->advertising);	/* save the silicon revision for later querying */	np->srr = readl(ioaddr + SiliconRev);	if (netif_msg_hw(np))		printk(KERN_INFO "%s: silicon revision %#04x.\n",				dev->name, np->srr);	return 0;}/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.   The EEPROM code is for the common 93c06/46 EEPROMs with 6 bit addresses. *//* Delay between EEPROM clock transitions.   No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need   a delay.  Note that pre-2.0.34 kernels had a cache-alignment bug that   made udelay() unreliable.   The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is   depricated.*/#define eeprom_delay(ee_addr)	readl(ee_addr)#define EE_Write0 (EE_ChipSelect)#define EE_Write1 (EE_ChipSelect | EE_DataIn)/* The EEPROM commands include the alway-set leading bit. */enum EEPROM_Cmds {	EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),};static int eeprom_read(long addr, int location){	int i;	int retval = 0;	long ee_addr = addr + EECtrl;	int read_cmd = location | EE_ReadCmd;	writel(EE_Write0, ee_addr);	/* Shift the read command bits out. */	for (i = 10; i >= 0; i--) {		short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;		writel(dataval, ee_addr);		eeprom_delay(ee_addr);		writel(dataval | EE_ShiftClk, ee_addr);		eeprom_delay(ee_addr);	}	writel(EE_ChipSelect, ee_addr);	eeprom_delay(ee_addr);	for (i = 0; i < 16; i++) {		writel(EE_ChipSelect | EE_ShiftClk, ee_addr);		eeprom_delay(ee_addr);		retval |= (readl(ee_addr) & EE_DataOut) ? 1 << i : 0;		writel(EE_ChipSelect, ee_addr);		eeprom_delay(ee_addr);	}	/* Terminate the EEPROM access. */	writel(EE_Write0, ee_addr);	writel(0, ee_addr);	return retval;}/*  MII transceiver control section.	The 83815 series has an internal transceiver, and we present the	management registers as if they were MII connected. */static int mdio_read(struct net_device *dev, int phy_id, int reg){	if (phy_id == 1 && reg < 32)		return readl(dev->base_addr+BasicControl+(reg<<2))&0xffff;	else		return 0xffff;}

⌨️ 快捷键说明

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