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

📄 declance.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 3 页
字号:
			*tp++ = *fp++;			*tp++ = *fp++;			*tp++ = *fp++;			fp += 8;		}		/*		 * do the rest, if any.		 */		clen = len & 15;		rtp = (unsigned char *) tp;		rfp = (unsigned char *) fp;		while (clen--) {			*rtp++ = *rfp++;		}	}}/* Setup the Lance Rx and Tx rings */static void lance_init_ring(struct net_device *dev){	struct lance_private *lp = (struct lance_private *) dev->priv;	volatile struct lance_init_block *ib;	int leptr;	int i;	ib = (struct lance_init_block *) (dev->mem_start);	/* Lock out other processes while setting up hardware */	netif_stop_queue(dev);	lp->rx_new = lp->tx_new = 0;	lp->rx_old = lp->tx_old = 0;	/* Copy the ethernet address to the lance init block.	 * XXX bit 0 of the physical address registers has to be zero	 */	ib->phys_addr[0] = dev->dev_addr[0];	ib->phys_addr[1] = dev->dev_addr[1];	ib->phys_addr[4] = dev->dev_addr[2];	ib->phys_addr[5] = dev->dev_addr[3];	ib->phys_addr[8] = dev->dev_addr[4];	ib->phys_addr[9] = dev->dev_addr[5];	/* Setup the initialization block */	/* Setup rx descriptor pointer */	leptr = LANCE_ADDR(libdesc_offset(brx_ring, 0));	ib->rx_len = (LANCE_LOG_RX_BUFFERS << 13) | (leptr >> 16);	ib->rx_ptr = leptr;	if (ZERO)		printk("RX ptr: %8.8x(%8.8x)\n", leptr, libdesc_offset(brx_ring, 0));	/* Setup tx descriptor pointer */	leptr = LANCE_ADDR(libdesc_offset(btx_ring, 0));	ib->tx_len = (LANCE_LOG_TX_BUFFERS << 13) | (leptr >> 16);	ib->tx_ptr = leptr;	if (ZERO)		printk("TX ptr: %8.8x(%8.8x)\n", leptr, libdesc_offset(btx_ring, 0));	if (ZERO)		printk("TX rings:\n");	/* Setup the Tx ring entries */	for (i = 0; i < TX_RING_SIZE; i++) {		leptr = (int) lp->tx_buf_ptr_lnc[i];		ib->btx_ring[i].tmd0 = leptr;		ib->btx_ring[i].tmd1_hadr = leptr >> 16;		ib->btx_ring[i].tmd1_bits = 0;		ib->btx_ring[i].length = 0xf000;	/* The ones required by tmd2 */		ib->btx_ring[i].misc = 0;		if (i < 3 && ZERO)			printk("%d: 0x%8.8x(0x%8.8x)\n", i, leptr, (int) lp->tx_buf_ptr_cpu[i]);	}	/* Setup the Rx ring entries */	if (ZERO)		printk("RX rings:\n");	for (i = 0; i < RX_RING_SIZE; i++) {		leptr = (int) lp->rx_buf_ptr_lnc[i];		ib->brx_ring[i].rmd0 = leptr;		ib->brx_ring[i].rmd1_hadr = leptr >> 16;		ib->brx_ring[i].rmd1_bits = LE_R1_OWN;		ib->brx_ring[i].length = -RX_BUFF_SIZE | 0xf000;		ib->brx_ring[i].mblength = 0;		if (i < 3 && ZERO)			printk("%d: 0x%8.8x(0x%8.8x)\n", i, leptr, (int) lp->rx_buf_ptr_cpu[i]);	}	wbflush();}static int init_restart_lance(struct lance_private *lp){	volatile struct lance_regs *ll = lp->ll;	int i;	writereg(&ll->rap, LE_CSR0);	writereg(&ll->rdp, LE_C0_INIT);	/* Wait for the lance to complete initialization */	for (i = 0; (i < 100) && !(ll->rdp & LE_C0_IDON); i++) {		udelay(10);	}	if ((i == 100) || (ll->rdp & LE_C0_ERR)) {		printk("LANCE unopened after %d ticks, csr0=%4.4x.\n", i, ll->rdp);		return -1;	}	if ((ll->rdp & LE_C0_ERR)) {		printk("LANCE unopened after %d ticks, csr0=%4.4x.\n", i, ll->rdp);		return -1;	}	writereg(&ll->rdp, LE_C0_IDON);	writereg(&ll->rdp, LE_C0_STRT);	writereg(&ll->rdp, LE_C0_INEA);	return 0;}static int lance_rx(struct net_device *dev){	struct lance_private *lp = (struct lance_private *) dev->priv;	volatile struct lance_init_block *ib;	volatile struct lance_rx_desc *rd = 0;	unsigned char bits;	int len = 0;	struct sk_buff *skb = 0;	ib = (struct lance_init_block *) (dev->mem_start);#ifdef TEST_HITS	{	int i;	printk("[");	for (i = 0; i < RX_RING_SIZE; i++) {		if (i == lp->rx_new)			printk("%s",			       ib->brx_ring[i].rmd1_bits & LE_R1_OWN ? "_" : "X");		else			printk("%s",			       ib->brx_ring[i].rmd1_bits & LE_R1_OWN ? "." : "1");	}	printk("]");	}#endif	for (rd = &ib->brx_ring[lp->rx_new];	     !((bits = rd->rmd1_bits) & LE_R1_OWN);	     rd = &ib->brx_ring[lp->rx_new]) {		/* We got an incomplete frame? */		if ((bits & LE_R1_POK) != LE_R1_POK) {			lp->stats.rx_over_errors++;			lp->stats.rx_errors++;		} else if (bits & LE_R1_ERR) {			/* Count only the end frame as a rx error,			 * not the beginning			 */			if (bits & LE_R1_BUF)				lp->stats.rx_fifo_errors++;			if (bits & LE_R1_CRC)				lp->stats.rx_crc_errors++;			if (bits & LE_R1_OFL)				lp->stats.rx_over_errors++;			if (bits & LE_R1_FRA)				lp->stats.rx_frame_errors++;			if (bits & LE_R1_EOP)				lp->stats.rx_errors++;		} else {			len = (rd->mblength & 0xfff) - 4;			skb = dev_alloc_skb(len + 2);			if (skb == 0) {				printk("%s: Memory squeeze, deferring packet.\n",				       dev->name);				lp->stats.rx_dropped++;				rd->mblength = 0;				rd->rmd1_bits = LE_R1_OWN;				lp->rx_new = (lp->rx_new + 1) & RX_RING_MOD_MASK;				return 0;			}			lp->stats.rx_bytes += len;			skb->dev = dev;			skb_reserve(skb, 2);	/* 16 byte align */			skb_put(skb, len);	/* make room */			cp_from_buf(skb->data,				 (char *) lp->rx_buf_ptr_cpu[lp->rx_new],				    len);			skb->protocol = eth_type_trans(skb, dev);			netif_rx(skb);			dev->last_rx = jiffies;			lp->stats.rx_packets++;		}		/* Return the packet to the pool */		rd->mblength = 0;		rd->length = -RX_BUFF_SIZE | 0xf000;		rd->rmd1_bits = LE_R1_OWN;		lp->rx_new = (lp->rx_new + 1) & RX_RING_MOD_MASK;	}	return 0;}static void lance_tx(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;	volatile struct lance_tx_desc *td;	int i, j;	int status;	ib = (struct lance_init_block *) (dev->mem_start);	j = lp->tx_old;	spin_lock(&lp->lock);	for (i = j; i != lp->tx_new; i = j) {		td = &ib->btx_ring[i];		/* If we hit a packet not owned by us, stop */		if (td->tmd1_bits & LE_T1_OWN)			break;		if (td->tmd1_bits & LE_T1_ERR) {			status = td->misc;			lp->stats.tx_errors++;			if (status & LE_T3_RTY)				lp->stats.tx_aborted_errors++;			if (status & LE_T3_LCOL)				lp->stats.tx_window_errors++;			if (status & LE_T3_CLOS) {				lp->stats.tx_carrier_errors++;				printk("%s: Carrier Lost\n", dev->name);				/* Stop the lance */				writereg(&ll->rap, LE_CSR0);				writereg(&ll->rdp, LE_C0_STOP);				lance_init_ring(dev);				load_csrs(lp);				init_restart_lance(lp);				goto out;			}			/* Buffer errors and underflows turn off the			 * transmitter, restart the adapter.			 */			if (status & (LE_T3_BUF | LE_T3_UFL)) {				lp->stats.tx_fifo_errors++;				printk("%s: Tx: ERR_BUF|ERR_UFL, restarting\n",				       dev->name);				/* Stop the lance */				writereg(&ll->rap, LE_CSR0);				writereg(&ll->rdp, LE_C0_STOP);				lance_init_ring(dev);				load_csrs(lp);				init_restart_lance(lp);				goto out;			}		} else if ((td->tmd1_bits & LE_T1_POK) == LE_T1_POK) {			/*			 * So we don't count the packet more than once.			 */			td->tmd1_bits &= ~(LE_T1_POK);			/* One collision before packet was sent. */			if (td->tmd1_bits & LE_T1_EONE)				lp->stats.collisions++;			/* More than one collision, be optimistic. */			if (td->tmd1_bits & LE_T1_EMORE)				lp->stats.collisions += 2;			lp->stats.tx_packets++;		}		j = (j + 1) & TX_RING_MOD_MASK;	}	lp->tx_old = j;out:	if (netif_queue_stopped(dev) &&	    TX_BUFFS_AVAIL > 0)		netif_wake_queue(dev);	spin_unlock(&lp->lock);}static void lance_interrupt(const int irq, void *dev_id, struct pt_regs *regs){	struct net_device *dev = (struct net_device *) dev_id;	struct lance_private *lp = (struct lance_private *) dev->priv;	volatile struct lance_regs *ll = lp->ll;	int csr0;	writereg(&ll->rap, LE_CSR0);	csr0 = ll->rdp;	/* Acknowledge all the interrupt sources ASAP */	writereg(&ll->rdp, csr0 & (LE_C0_INTR | LE_C0_TINT | LE_C0_RINT));	if ((csr0 & LE_C0_ERR)) {		/* Clear the error condition */		writereg(&ll->rdp, LE_C0_BABL | LE_C0_ERR | LE_C0_MISS |			 LE_C0_CERR | LE_C0_MERR);	}	if (csr0 & LE_C0_RINT)		lance_rx(dev);	if (csr0 & LE_C0_TINT)		lance_tx(dev);	if (csr0 & LE_C0_BABL)		lp->stats.tx_errors++;	if (csr0 & LE_C0_MISS)		lp->stats.rx_errors++;	if (csr0 & LE_C0_MERR) {		volatile unsigned long int_stat = *(unsigned long *) (system_base + IOCTL + SIR);		printk("%s: Memory error, status %04x\n", dev->name, csr0);		if (int_stat & LANCE_DMA_MEMRDERR) {			printk("%s: DMA error\n", dev->name);			int_stat |= LANCE_DMA_MEMRDERR;			/*			 * re-enable LANCE DMA			 */			*(unsigned long *) (system_base + IOCTL + SSR) |= (1 << 16);			wbflush();		}		writereg(&ll->rdp, LE_C0_STOP);		lance_init_ring(dev);		load_csrs(lp);		init_restart_lance(lp);		netif_wake_queue(dev);	}	writereg(&ll->rdp, LE_C0_INEA);	writereg(&ll->rdp, LE_C0_INEA);}struct net_device *last_dev = 0;static int lance_open(struct net_device *dev){	volatile struct lance_init_block *ib = (struct lance_init_block *) (dev->mem_start);	struct lance_private *lp = (struct lance_private *) dev->priv;	volatile struct lance_regs *ll = lp->ll;	int status = 0;	last_dev = dev;	/* Stop the Lance */	writereg(&ll->rap, LE_CSR0);	writereg(&ll->rdp, LE_C0_STOP);	/* Set mode and clear multicast filter only at device open,	 * so that lance_init_ring() called at any error will not	 * forget multicast filters.	 *	 * BTW it is common bug in all lance drivers! --ANK	 */	ib->mode = 0;	ib->filter [0] = 0;	ib->filter [2] = 0;	lance_init_ring(dev);	load_csrs(lp);	netif_start_queue(dev);	/* Associate IRQ with lance_interrupt */	if (request_irq(dev->irq, &lance_interrupt, 0, lp->name, dev)) {		printk("Lance: Can't get irq %d\n", dev->irq);		return -EAGAIN;	}	status = init_restart_lance(lp);	/*	 * if (!status)	 *      MOD_INC_USE_COUNT;	 */	return status;}static int lance_close(struct net_device *dev){	struct lance_private *lp = (struct lance_private *) dev->priv;	volatile struct lance_regs *ll = lp->ll;	netif_stop_queue(dev);	del_timer_sync(&lp->multicast_timer);	/* Stop the card */	writereg(&ll->rap, LE_CSR0);	writereg(&ll->rdp, LE_C0_STOP);	free_irq(dev->irq, (void *) dev);	/*	   MOD_DEC_USE_COUNT;	 */	return 0;}static inline int lance_reset(struct net_device *dev){	struct lance_private *lp = (struct lance_private *) dev->priv;	volatile struct lance_regs *ll = lp->ll;	int status;	/* Stop the lance */	writereg(&ll->rap, LE_CSR0);	writereg(&ll->rdp, LE_C0_STOP);	lance_init_ring(dev);	load_csrs(lp);	dev->trans_start = jiffies;	status = init_restart_lance(lp);	return status;}

⌨️ 快捷键说明

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