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

📄 dgrs.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	/*	 * NVRAM configurables from Space.c	 */	priv0->bcomm->bc_spantree = dgrs_spantree;	priv0->bcomm->bc_hashexpire = dgrs_hashexpire;	memcpy(priv0->bcomm->bc_ipaddr, dgrs_ipaddr, 4);	memcpy(priv0->bcomm->bc_iptrap, dgrs_iptrap, 4);	memcpy(priv0->bcomm->bc_ipxnet, &dgrs_ipxnet, 4);	/*	 * Release processor, wait 8 seconds for board to initialize	 */	proc_reset(dev0, 0);	for (i = jiffies + 8 * HZ; time_after(i, jiffies); )	{		if (priv0->bcomm->bc_status >= BC_RUN)			break;	}	if (priv0->bcomm->bc_status < BC_RUN)	{		printk("%s: board not operating\n", dev0->name);		return -ENXIO;	}	priv0->port = (PORT *) S2H(priv0->bcomm->bc_port);	priv0->scbp = (I596_SCB *) S2H(priv0->port->scbp);	priv0->rfdp = (I596_RFD *) S2H(priv0->scbp->rfdp);	priv0->rbdp = (I596_RBD *) S2H(priv0->rfdp->rbdp);	priv0->scbp->status = I596_SCB_CNA;	/* CU is idle */	/*	 *	Get switch physical and host virtual pointers to DMA	 *	chaining area.  NOTE: the MSB of the switch physical	 *	address *must* be turned off.  Otherwise, the HW kludge	 *	that allows host access of the PLX DMA registers will	 *	erroneously select the PLX registers.	 */	priv0->dmadesc_s = (DMACHAIN *) S2DMA(priv0->bcomm->bc_hostarea);	if (priv0->dmadesc_s)		priv0->dmadesc_h = (DMACHAIN *) S2H(priv0->dmadesc_s);	else		priv0->dmadesc_h = NULL;	/*	 *	Enable board interrupts	 */	if (priv0->plxreg)	{	/* PCI bus */		OUTL(dev0->base_addr + PLX_INT_CSR,			inl(dev0->base_addr + PLX_INT_CSR)			| PLX_PCI_DOORBELL_IE);	/* Enable intr to host */		OUTL(dev0->base_addr + PLX_LCL2PCI_DOORBELL, 1);	}	else	{	/* EISA bus */	}	return (0);}/* *	Probe (init) a board */__initfunc(intdgrs_probe1(struct device *dev)){	DGRS_PRIV	*priv = (DGRS_PRIV *) dev->priv;	int		i;	int		rc;	printk("%s: Digi RightSwitch io=%lx mem=%lx irq=%d plx=%lx dma=%lx\n",		dev->name, dev->base_addr, dev->mem_start, dev->irq,		priv->plxreg, priv->plxdma);	/*	 *	Download the firmware and light the processor	 */	rc = dgrs_download(dev);	if (rc)	{		return rc;	}	/*	 * Get ether address of board	 */	printk("%s: Ethernet address", dev->name);	memcpy(dev->dev_addr, priv->port->ethaddr, 6);	for (i = 0; i < 6; ++i)		printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);	printk("\n");	if (dev->dev_addr[0] & 1)	{		printk("%s: Illegal Ethernet Address\n", dev->name);		return (-ENXIO);	}	/*	 *	ACK outstanding interrupts, hook the interrupt,	 *	and verify that we are getting interrupts from the board.	 */	if (priv->plxreg)		OUTL(dev->base_addr + PLX_LCL2PCI_DOORBELL, 1);	rc = request_irq(dev->irq, &dgrs_intr, 0, "RightSwitch", dev);	if (rc)		return (rc);	priv->intrcnt = 0;	for (i = jiffies + 2*HZ + HZ/2; time_after(i, jiffies); )		if (priv->intrcnt >= 2)			break;	if (priv->intrcnt < 2)	{		printk("%s: Not interrupting on IRQ %d (%d)\n",				dev->name, dev->irq, priv->intrcnt);		return (-ENXIO);	}	/*	 *	Register the /proc/ioports information...	 */	request_region(dev->base_addr, 256, "RightSwitch");	/*	 *	Entry points...	 */	dev->open = &dgrs_open;	dev->stop = &dgrs_close;	dev->get_stats = &dgrs_get_stats;	dev->hard_start_xmit = &dgrs_start_xmit;	dev->set_multicast_list = &dgrs_set_multicast_list;	dev->do_ioctl = &dgrs_ioctl;	return (0);}__initfunc(intdgrs_initclone(struct device *dev)){	DGRS_PRIV	*priv = (DGRS_PRIV *) dev->priv;	int		i;	printk("%s: Digi RightSwitch port %d ",		dev->name, priv->chan);	for (i = 0; i < 6; ++i)		printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);	printk("\n");	return (0);}__initfunc(static intdgrs_found_device(	struct device	*dev,	int		io,	ulong		mem,	int		irq,	ulong		plxreg,	ulong		plxdma)){	DGRS_PRIV	*priv;	#ifdef MODULE	{		/* Allocate and fill new device structure. */		int dev_size = sizeof(struct device) + sizeof(DGRS_PRIV);		int i;		dev = (struct device *) kmalloc(dev_size, GFP_KERNEL);		memset(dev, 0, dev_size);		dev->priv = ((void *)dev) + sizeof(struct device);		priv = (DGRS_PRIV *)dev->priv;		dev->name = priv->devname; /* An empty string. */		dev->base_addr = io;		dev->mem_start = mem;		dev->mem_end = mem + 2048 * 1024 - 1;		dev->irq = irq;		priv->plxreg = plxreg;		priv->plxdma = plxdma;		priv->vplxdma = NULL;		priv->chan = 1;		priv->devtbl[0] = dev;		dev->init = dgrs_probe1;		ether_setup(dev);		priv->next_dev = dgrs_root_dev;		dgrs_root_dev = dev;		if (register_netdev(dev) != 0)			return -EIO;		if ( !dgrs_nicmode )			return (0);	/* Switch mode, we are done */		/*		 * Operating card as N separate NICs		 */		priv->nports = priv->bcomm->bc_nports;		for (i = 1; i < priv->nports; ++i)		{			struct device	*devN;			DGRS_PRIV	*privN;			/* Allocate new dev and priv structures */			devN = (struct device *) kmalloc(dev_size, GFP_KERNEL);			/* Make it an exact copy of dev[0]... */			memcpy(devN, dev, dev_size);			devN->priv = ((void *)devN) + sizeof(struct device);			privN = (DGRS_PRIV *)devN->priv;			/* ... but seset devname to a NULL string */			privN->devname[0] = 0;			devN->name = privN->devname;			/* ... and zero out VM areas */			privN->vmem = 0;			privN->vplxdma = 0;			/* ... and zero out IRQ */			devN->irq = 0;			/* ... and base MAC address off address of 1st port */			devN->dev_addr[5] += i;			privN->chan = i+1;			priv->devtbl[i] = devN;			devN->init = dgrs_initclone;			ether_setup(devN);			privN->next_dev = dgrs_root_dev;			dgrs_root_dev = devN;			if (register_netdev(devN) != 0)				return -EIO;		}	}	#else	{		if (dev)		{			dev->priv = kmalloc(sizeof (DGRS_PRIV), GFP_KERNEL);			memset(dev->priv, 0, sizeof (DGRS_PRIV));		}		dev = init_etherdev(dev, sizeof(DGRS_PRIV));		priv = (DGRS_PRIV *)dev->priv;		dev->base_addr = io;		dev->mem_start = mem;		dev->mem_end = mem + 2048 * 1024;		dev->irq = irq;		priv->plxreg = plxreg;		priv->plxdma = plxdma;		priv->vplxdma = NULL;		priv->chan = 1;		priv->devtbl[0] = dev;		dgrs_probe1(dev);	}	#endif	return (0);}/* *	Scan for all boards */static int is2iv[8] __initdata = { 0, 3, 5, 7, 10, 11, 12, 15 };__initfunc(static intdgrs_scan(struct device *dev)){	int	cards_found = 0;	uint	io;	uint	mem;	uint	irq;	uint	plxreg;	uint	plxdma;	/*	 *	First, check for PCI boards	 */	if (pci_present())	{		int pci_index = 0;		for (; pci_index < 8; pci_index++)		{			uchar	pci_bus, pci_device_fn;#if LINUX_VERSION_CODE < 0x20100			uchar	pci_irq;#else			uint	pci_irq;			struct pci_dev *pdev;#endif			uchar	pci_latency;			ushort	pci_command;			if (pcibios_find_device(SE6_PCI_VENDOR_ID,							SE6_PCI_DEVICE_ID,							pci_index, &pci_bus,							&pci_device_fn))					break;#if LINUX_VERSION_CODE < 0x20100			pcibios_read_config_byte(pci_bus, pci_device_fn,					PCI_INTERRUPT_LINE, &pci_irq);			pcibios_read_config_dword(pci_bus, pci_device_fn,					PCI_BASE_ADDRESS_0, &plxreg);			pcibios_read_config_dword(pci_bus, pci_device_fn,					PCI_BASE_ADDRESS_1, &io);			pcibios_read_config_dword(pci_bus, pci_device_fn,					PCI_BASE_ADDRESS_2, &mem);#else			pdev = pci_find_slot(pci_bus, pci_device_fn);			pci_irq = pdev->irq;			plxreg = pdev->base_address[0];			io = pdev->base_address[1];			mem = pdev->base_address[2];#endif			pcibios_read_config_dword(pci_bus, pci_device_fn,					0x30, &plxdma);			irq = pci_irq;			plxreg &= ~15;			io &= ~3;			mem &= ~15;			plxdma &= ~15;			/*			 * On some BIOSES, the PLX "expansion rom" (used for DMA)			 * address comes up as "0".  This is probably because			 * the BIOS doesn't see a valid 55 AA ROM signature at			 * the "ROM" start and zeroes the address.  To get			 * around this problem the SE-6 is configured to ask			 * for 4 MB of space for the dual port memory.  We then			 * must set its range back to 2 MB, and use the upper			 * half for DMA register access			 */			OUTL(io + PLX_SPACE0_RANGE, 0xFFE00000L);			if (plxdma == 0)				plxdma = mem + (2048L * 1024L);			pcibios_write_config_dword(pci_bus, pci_device_fn,					0x30, plxdma + 1);			pcibios_read_config_dword(pci_bus, pci_device_fn,					0x30, &plxdma);			plxdma &= ~15;			/*			 * Get and check the bus-master and latency values.			 * Some PCI BIOSes fail to set the master-enable bit,			 * and the latency timer must be set to the maximum			 * value to avoid data corruption that occurs when the			 * timer expires during a transfer.  Yes, it's a bug.			 */			pcibios_read_config_word(pci_bus, pci_device_fn,						 PCI_COMMAND, &pci_command);			if ( ! (pci_command & PCI_COMMAND_MASTER))			{				printk("  Setting the PCI Master Bit!\n");				pci_command |= PCI_COMMAND_MASTER;				pcibios_write_config_word(pci_bus,						pci_device_fn,						PCI_COMMAND, pci_command);			}			pcibios_read_config_byte(pci_bus, pci_device_fn,					 PCI_LATENCY_TIMER, &pci_latency);			if (pci_latency != 255)			{				printk("  Overriding PCI latency timer: "					"was %d, now is 255.\n", pci_latency);				pcibios_write_config_byte(pci_bus,						pci_device_fn,						PCI_LATENCY_TIMER, 255);			}			dgrs_found_device(dev, io, mem, irq, plxreg, plxdma);			dev = 0;			cards_found++;		}	}	/*	 *	Second, check for EISA boards	 */	if (EISA_bus)	{		for (io = 0x1000; io < 0x9000; io += 0x1000)		{			if (inb(io+ES4H_MANUFmsb) != 0x10				|| inb(io+ES4H_MANUFlsb) != 0x49				|| inb(io+ES4H_PRODUCT) != ES4H_PRODUCT_CODE)				continue;			if ( ! (inb(io+ES4H_EC) & ES4H_EC_ENABLE) )				continue; /* Not EISA configured */			mem = (inb(io+ES4H_AS_31_24) << 24)				+ (inb(io+ES4H_AS_23_16) << 16);			irq = is2iv[ inb(io+ES4H_IS) & ES4H_IS_INTMASK ];			dgrs_found_device(dev, io, mem, irq, 0L, 0L);			dev = 0;			++cards_found;		}	}	return cards_found;}/* *	Module/driver initialization points.  Two ways, depending on *	whether we are a module or statically linked, ala Don Becker's *	3c59x driver. */#ifdef MODULE/* *	Variables that can be overriden from command line */static int	debug = -1;static int	dma = -1;static int	hashexpire = -1;static int	spantree = -1;static int	ipaddr[4] = { -1 };static int	iptrap[4] = { -1 };static __u32	ipxnet = -1;static int	nicmode = -1;MODULE_PARM(debug, "i");MODULE_PARM(dma, "i");MODULE_PARM(hashexpire, "i");MODULE_PARM(spantree, "i");MODULE_PARM(ipaddr, "1-4i");MODULE_PARM(iptrap, "1-4i");MODULE_PARM(ipxnet, "i");MODULE_PARM(nicmode, "i");intinit_module(void){	int	cards_found;	int	i;	/*	 *	Command line variable overrides	 *		debug=NNN	 *		dma=0/1	 *		spantree=0/1	 *		hashexpire=NNN	 *		ipaddr=A,B,C,D	 *		iptrap=A,B,C,D	 *		ipxnet=NNN	 *		nicmode=NNN	 */	if (debug >= 0)		dgrs_debug = debug;	if (dma >= 0)		dgrs_dma = dma;	if (nicmode >= 0)		dgrs_nicmode = nicmode;	if (hashexpire >= 0)		dgrs_hashexpire = hashexpire;	if (spantree >= 0)		dgrs_spantree = spantree;	if (ipaddr[0] != -1)		for (i = 0; i < 4; ++i)			dgrs_ipaddr[i] = ipaddr[i];	if (iptrap[0] != -1)		for (i = 0; i < 4; ++i)			dgrs_iptrap[i] = iptrap[i];	if (ipxnet != -1)		dgrs_ipxnet = htonl( ipxnet );	if (dgrs_debug)	{		printk("dgrs: SW=%s FW=Build %d %s\n",			version, dgrs_firmnum, dgrs_firmdate);	}	/*	 *	Find and configure all the cards	 */	dgrs_root_dev = NULL;	cards_found = dgrs_scan(0);	return cards_found ? 0 : -ENODEV;}voidcleanup_module(void){        while (dgrs_root_dev)	{		struct device	*next_dev;		DGRS_PRIV	*priv;		priv = (DGRS_PRIV *) dgrs_root_dev->priv;                next_dev = priv->next_dev;                unregister_netdev(dgrs_root_dev);		proc_reset(priv->devtbl[0], 1);		if (priv->vmem)			IOUNMAP(priv->vmem);		if (priv->vplxdma)			IOUNMAP((uchar *) priv->vplxdma);		release_region(dgrs_root_dev->base_addr, 256);		if (dgrs_root_dev->irq)			free_irq(dgrs_root_dev->irq, dgrs_root_dev);                kfree(dgrs_root_dev);                dgrs_root_dev = next_dev;        }}#else__initfunc(intdgrs_probe(struct device *dev)){	int	cards_found;	cards_found = dgrs_scan(dev);	if (dgrs_debug && cards_found)		printk("dgrs: SW=%s FW=Build %d %s\n",			version, dgrs_firmnum, dgrs_firmdate);	return cards_found ? 0 : -ENODEV;}#endif

⌨️ 快捷键说明

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