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

📄 declance.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 3 页
字号:
static void lance_tx_timeout(struct net_device *dev){	struct lance_private *lp = (struct lance_private *) dev->priv;	volatile struct lance_regs *ll = lp->ll;	printk(KERN_ERR "%s: transmit timed out, status %04x, reset\n",			       dev->name, ll->rdp);			lance_reset(dev);	netif_wake_queue(dev);}static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev){	struct lance_private *lp = (struct lance_private *) dev->priv;	volatile struct lance_regs *ll = lp->ll;	volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start);	int entry, skblen, len;	skblen = skb->len;	len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen;	lp->stats.tx_bytes += len;	entry = lp->tx_new & TX_RING_MOD_MASK;	ib->btx_ring[entry].length = (-len);	ib->btx_ring[entry].misc = 0;	cp_to_buf((char *) lp->tx_buf_ptr_cpu[entry], skb->data, skblen);	/* Clear the slack of the packet, do I need this? */	/* For a firewall its a good idea - AC *//*   if (len != skblen)   memset ((char *) &ib->tx_buf [entry][skblen], 0, (len - skblen) << 1); */	/* Now, give the packet to the lance */	ib->btx_ring[entry].tmd1_bits = (LE_T1_POK | LE_T1_OWN);	lp->tx_new = (lp->tx_new + 1) & TX_RING_MOD_MASK;	if (TX_BUFFS_AVAIL <= 0)		netif_stop_queue(dev);	/* Kick the lance: transmit now */	writereg(&ll->rdp, LE_C0_INEA | LE_C0_TDMD);	spin_unlock_irq(&lp->lock);	dev->trans_start = jiffies;	dev_kfree_skb(skb); 	return 0;}static struct net_device_stats *lance_get_stats(struct net_device *dev){	struct lance_private *lp = (struct lance_private *) dev->priv;	return &lp->stats;}static void lance_load_multicast(struct net_device *dev){	volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start);	volatile u16 *mcast_table = (u16 *) & ib->filter;	struct dev_mc_list *dmi = dev->mc_list;	char *addrs;	int i, j, bit, byte;	u32 crc, poly = CRC_POLYNOMIAL_BE;	/* set all multicast bits */	if (dev->flags & IFF_ALLMULTI) {		ib->filter[0] = 0xffff;		ib->filter[2] = 0xffff;		ib->filter[4] = 0xffff;		ib->filter[6] = 0xffff;		return;	}	/* clear the multicast filter */	ib->filter[0] = 0;	ib->filter[2] = 0;	ib->filter[4] = 0;	ib->filter[6] = 0;	/* Add addresses */	for (i = 0; i < dev->mc_count; i++) {		addrs = dmi->dmi_addr;		dmi = dmi->next;		/* multicast address? */		if (!(*addrs & 1))			continue;		crc = 0xffffffff;		for (byte = 0; byte < 6; byte++)			for (bit = *addrs++, j = 0; j < 8; j++, bit >>= 1) {				int test;				test = ((bit ^ crc) & 0x01);				crc >>= 1;				if (test) {					crc = crc ^ poly;				}			}		crc = crc >> 26;		mcast_table[crc >> 3] |= 1 << (crc & 0xf);	}	return;}static void lance_set_multicast(struct net_device *dev){	struct lance_private *lp = (struct lance_private *) dev->priv;	volatile struct lance_init_block *ib;	volatile struct lance_regs *ll = lp->ll;	ib = (struct lance_init_block *) (dev->mem_start);	if (!netif_running(dev))		return;	if (lp->tx_old != lp->tx_new) {		mod_timer(&lp->multicast_timer, jiffies + 4);		netif_wake_queue(dev);		return;	}	netif_stop_queue(dev);	writereg(&ll->rap, LE_CSR0);	writereg(&ll->rdp, LE_C0_STOP);	lance_init_ring(dev);	if (dev->flags & IFF_PROMISC) {		ib->mode |= LE_MO_PROM;	} else {		ib->mode &= ~LE_MO_PROM;		lance_load_multicast(dev);	}	load_csrs(lp);	init_restart_lance(lp);	netif_wake_queue(dev);}static void lance_set_multicast_retry(unsigned long _opaque){	struct net_device *dev = (struct net_device *) _opaque;	lance_set_multicast(dev);}static int __init dec_lance_init(struct net_device *dev, const int type){	static unsigned version_printed;	struct net_device *dev;	struct lance_private *lp;	volatile struct lance_regs *ll;	int i, ret;	unsigned long esar_base;	unsigned char *esar;#ifndef CONFIG_TC	system_base = KN01_LANCE_BASE;#else	int slot;#endif	if (dec_lance_debug && version_printed++ == 0)		printk(version);	dev = init_etherdev(0, sizeof(struct lance_private));	if (!dev)		return -ENOMEM;	/* init_etherdev ensures the data structures used by the LANCE are aligned. */	lp = (struct lance_private *) dev->priv;	spin_lock_init(&lp->lock);	switch (type) {#ifdef CONFIG_TC	case ASIC_LANCE:		dev->base_addr = system_base + LANCE;		/* buffer space for the on-board LANCE shared memory */		/*		 * FIXME: ugly hack!		 */		dev->mem_start = KSEG1ADDR(0x00020000);		dev->mem_end = dev->mem_start + 0x00020000;		dev->irq = ETHER;		esar_base = system_base + ESAR;			/* Workaround crash with booting KN04 2.1k from Disk */		memset(dev->mem_start, 0, dev->mem_end - dev->mem_start);		/*		 * setup the pointer arrays, this sucks [tm] :-(		 */		for (i = 0; i < RX_RING_SIZE; i++) {			lp->rx_buf_ptr_cpu[i] = (char *) (dev->mem_start + BUF_OFFSET_CPU						 + 2 * i * RX_BUFF_SIZE);			lp->rx_buf_ptr_lnc[i] = (char *) (BUF_OFFSET_LNC						     + i * RX_BUFF_SIZE);		}		for (i = 0; i < TX_RING_SIZE; i++) {			lp->tx_buf_ptr_cpu[i] = (char *) (dev->mem_start + BUF_OFFSET_CPU					+ 2 * RX_RING_SIZE * RX_BUFF_SIZE						 + 2 * i * TX_BUFF_SIZE);			lp->tx_buf_ptr_lnc[i] = (char *) (BUF_OFFSET_LNC					    + RX_RING_SIZE * RX_BUFF_SIZE						     + i * TX_BUFF_SIZE);		}		/*		 * setup and enable IOASIC LANCE DMA		 */		lp->dma_ptr_reg = (unsigned long *) (system_base + IOCTL + LANCE_DMA_P);		*(lp->dma_ptr_reg) = PHYSADDR(dev->mem_start) << 3;		*(unsigned long *) (system_base + IOCTL + SSR) |= (1 << 16);		wbflush();		break;	case PMAD_LANCE:		slot = search_tc_card("PMAD-AA");		claim_tc_card(slot);		dev->mem_start = get_tc_base_addr(slot);		dev->base_addr = dev->mem_start + 0x100000;		dev->irq = get_tc_irq_nr(slot);		esar_base = dev->mem_start + 0x1c0002;		break;#endif	case PMAX_LANCE:		dev->irq = ETHER;		dev->base_addr = KN01_LANCE_BASE;		dev->mem_start = KN01_LANCE_BASE + 0x01000000;		esar_base = KN01_RTC_BASE + 1;		/*		 * setup the pointer arrays, this sucks [tm] :-(		 */		for (i = 0; i < RX_RING_SIZE; i++) {			lp->rx_buf_ptr_cpu[i] =			    (char *) (dev->mem_start + BUF_OFFSET_CPU				      + 2 * i * RX_BUFF_SIZE);			lp->rx_buf_ptr_lnc[i] =			    (char *) (BUF_OFFSET_LNC				      + i * RX_BUFF_SIZE);		}		for (i = 0; i < TX_RING_SIZE; i++) {			lp->tx_buf_ptr_cpu[i] =			    (char *) (dev->mem_start + BUF_OFFSET_CPU				      + 2 * RX_RING_SIZE * RX_BUFF_SIZE				      + 2 * i * TX_BUFF_SIZE);			lp->tx_buf_ptr_lnc[i] = (char *) (BUF_OFFSET_LNC					    + RX_RING_SIZE * RX_BUFF_SIZE						     + i * TX_BUFF_SIZE);		}		break;	default:		printk("declance_init called with unknown type\n");		ret = -ENODEV;		goto err_out;	}	ll = (struct lance_regs *) dev->base_addr;	esar = (unsigned char *) esar_base;	/* prom checks */	/* First, check for test pattern */	if (esar[0x60] != 0xff && esar[0x64] != 0x00 &&	    esar[0x68] != 0x55 && esar[0x6c] != 0xaa) {		printk("Ethernet station address prom not found!\n");		ret = -ENODEV;		goto err_out;	}	/* Check the prom contents */	for (i = 0; i < 8; i++) {		if (esar[i * 4] != esar[0x3c - i * 4] &&		    esar[i * 4] != esar[0x40 + i * 4] &&		    esar[0x3c - i * 4] != esar[0x40 + i * 4]) {			printk("Something is wrong with the ethernet "			       "station address prom!\n");			ret = -ENODEV;			goto err_out;		}	}	/* Copy the ethernet address to the device structure, later to the	 * lance initialization block so the lance gets it every time it's	 * (re)initialized.	 */	switch (type) {	case ASIC_LANCE:		printk("%s: IOASIC onboard LANCE, addr = ", dev->name);		break;	case PMAD_LANCE:		printk("%s: PMAD-AA, addr = ", dev->name);		break;	case PMAX_LANCE:		printk("%s: PMAX onboard LANCE, addr = ", dev->name);		break;	}	for (i = 0; i < 6; i++) {		dev->dev_addr[i] = esar[i * 4];		printk("%2.2x%c", dev->dev_addr[i], i == 5 ? ',' : ':');	}	printk(" irq = %d\n", dev->irq);	lp->dev = dev;	dev->open = &lance_open;	dev->stop = &lance_close;	dev->hard_start_xmit = &lance_start_xmit;	dev->tx_timeout = &lance_tx_timeout;	dev->watchdog_timeo = 5*HZ;	dev->get_stats = &lance_get_stats;	dev->set_multicast_list = &lance_set_multicast;	/* lp->ll is the location of the registers for lance card */	lp->ll = ll;	lp->name = lancestr;	/* busmaster_regval (CSR3) should be zero according to the PMAD-AA	 * specification.	 */	lp->busmaster_regval = 0;	dev->dma = 0;	ether_setup(dev);	/* We cannot sleep if the chip is busy during a	 * multicast list update event, because such events	 * can occur from interrupts (ex. IPv6).  So we	 * use a timer to try again later when necessary. -DaveM	 */	init_timer(&lp->multicast_timer);	lp->multicast_timer.data = (unsigned long) dev;	lp->multicast_timer.function = &lance_set_multicast_retry;#ifdef MODULE	dev->ifindex = dev_new_index();	lp->next_module = root_lance_dev;	root_lance_dev = lp;#endif	return 0;err_out:	unregister_netdev(dev);	kfree(dev);	return ret;}/* Find all the lance cards on the system and initialize them */static int __init dec_lance_probe(void){	struct net_device *dev = NULL;	static int called;#ifdef MODULE	root_lance_dev = NULL;#endif#ifdef CONFIG_TC	int slot = -1;	if (TURBOCHANNEL) {		if (IOASIC && !called) {			called = 1;			type = ASIC_LANCE;		} else {			if ((slot = search_tc_card("PMAD-AA")) >= 0) {				type = PMAD_LANCE;			} else {				return -ENODEV;			}		}	} else {		if (!called) {			called = 1;			type = PMAX_LANCE;		} else {			return -ENODEV;		}	}#else	if (!called && !TURBOCHANNEL) {		called = 1;		type = PMAX_LANCE;	} else {		return -ENODEV;	}#endif	return dec_lance_init(dev, type);}static void __exit dec_lance_cleanup(void){#ifdef MODULE   struct lance_private *lp;   while (root_lance_dev) {   lp = root_lance_dev->next_module;   unregister_netdev(root_lance_dev->dev);   kfree(root_lance_dev->dev);   root_lance_dev = lp;   }#endif /* MODULE */}module_init(dec_lance_probe);module_exit(dec_lance_cleanup);

⌨️ 快捷键说明

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