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

📄 eth.java

📁 Java Op Processor java vhdl processor
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
			buf[i] = rd(NE_DATAPORT);		}// is used in block_input and get header, do I need this?		wr(ENISR_RDC, EN0_ISR);	/* Ack intr. */	}/***	DMA write to card memory.*	uses page numbers instead of addr!*/	private static void wrMem(int page, int[] buf, int cnt) {		int i;		/* We should already be in page 0, but to be safe... */		wr(E8390_PAGE0+E8390_START+E8390_NODMA, E8390_CMD);//#ifdef NE8390_RW_BUGFIX//	/* Handle the read-before-write bug the same way as the//	   Crynwr packet driver -- the NatSemi method doesn't work.//	   Actually this doesn't always work either, but if you have//	   problems with your NEx000 this is better than nothing! */////	wr(0x42, EN0_RCNTLO);//	wr(0x00,   EN0_RCNTHI);//	wr(0x42, EN0_RSARLO);//	wr(0x00, EN0_RSARHI);//	wr(E8390_RREAD+E8390_START, E8390_CMD);//	/* Make certain that the dummy read has occurred. *///	udelay(6);//#endif////	wr(ENISR_RDC, EN0_ISR); // one more acc ???	/* Now the normal output. */		wr(cnt & 0xff, EN0_RCNTLO);		wr(cnt >>> 8,  EN0_RCNTHI);		wr(0x00, EN0_RSARLO);	/* DMA start */		wr(page, EN0_RSARHI);		wr(E8390_RWRITE+E8390_START, E8390_CMD);	    		for(i = 0; i<cnt; ++i) {			wr(buf[i], NE_DATAPORT);		}/******	dma_start = jiffies;	while ((rd(EN0_ISR) & ENISR_RDC) == 0)		if (jiffies - dma_start > 2*HZ/100) {		// 20ms			printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name);			ne_reset_8390(dev);			NS8390_init(dev,1);			break;		}*/// do I need this???		wr(ENISR_RDC, EN0_ISR);	/* Ack intr. */	}/** * txTimeout - handle transmit time out condition * * Called by kernel when device never acknowledges a transmit has * completed (or failed) - i.e. never posted a Tx related interrupt. */	public static void txTimeout() {		int txsr, isr;		// int tickssofar = jiffies - dev->trans_start;		tx_errors++;		txsr = rd(EN0_TSR);		isr = rd(EN0_ISR);/*		printk(KERN_DEBUG "%s: Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n",			dev->name, (txsr & ENTSR_ABT) ? "excess collisions." :			(isr) ? "lost interrupt?" : "cable problem?", txsr, isr, tickssofar);*///		if (!isr && !tx_packets) {			/* The 8390 probably hasn't gotten on the cable yet. *///			interface_num ^= 1;   /* Try a different xcvr.  *///		}					/* Try to restart the card.  Perhaps the user has fixed something. */		init();					// netif_wake_queue(dev);	}    /*** Sends a packet to an 8390 network device.old ret was 0 if ok, now true if ok!*/	public static boolean startXmit(int[] buf, int length) {		int send_length, output_page;		wr(0x00, EN0_IMR);				send_length = ETH_ZLEN < length ? length : ETH_ZLEN;    		/*		 * We have two Tx slots available for use. Find the first free		 * slot, and then perform some sanity checks. With two Tx bufs,		 * you get very close to transmitting back-to-back packets. With		 * only one Tx buf, the transmitter sits idle while you reload the		 * card, leaving a substantial gap between each transmitted packet.		 */		if (tx1 == 0) {			output_page = tx_start_page;			tx1 = send_length;		} else if (tx2 == 0) {			output_page = tx_start_page + TX_PAGES/2;	// second buffer			tx2 = send_length;		} else {	/* We should never get here. */			// No Tx buffers free!			// netif_stop_queue(dev);			wr(ENISR_ALL, EN0_IMR);			tx_errors++;			return false;		}		/*		 * Okay, now upload the packet and trigger a send if the transmitter		 * isn't already sending. If it is busy, the interrupt handler will		 * trigger the send later, upon receiving a Tx done interrupt.		 */		wrMem(output_page, buf, length);		if (!txing) {			txing = true;			triggerSend(send_length, output_page);			// dev->trans_start = jiffies;			if (output_page == tx_start_page) {				tx1 = -1;			} else {				tx2 = -1;			}		}		/*		if (tx1!=0  &&  tx2!=0)			netif_stop_queue(dev);		else			netif_start_queue(dev);		*/		/* Turn 8390 interrupts back on. */		wr(ENISR_ALL, EN0_IMR);				tx_bytes += send_length;    		return true;}/*** Handle the ether interface interrupts. We pull packets from* the 8390 via the card specific functions and fire them at the networking* stack. We also handle transmit completions and wake the transmit path if* neccessary. We also update the counters and do other housekeeping as* needed.*/// when will this be called on my polling version!!!	public static void interrupt() {		int interrupts, nr_serviced;    		/* Change to page 0 and read the intr status reg. */		wr(E8390_NODMA+E8390_PAGE0, E8390_CMD);	// no START means STOP ?    		/* !!Assumption!! -- we stay in page 0.	 Don't break this. */		for (nr_serviced=0; (interrupts = rd(EN0_ISR)) != 0 && nr_serviced<MAX_SERVICE; ++nr_serviced) {hexVal(interrupts);			/* Push the next to-transmit packet through. */			if ((interrupts & ENISR_TX)!=0) {				txIntr();			} else if ((interrupts & ENISR_TX_ERR)!=0) {				txErr();			}			if ((interrupts & ENISR_OVER)!=0) {				rxOverrun();			} else if ((interrupts & (ENISR_RX+ENISR_RX_ERR))!=0) {				/* Got a good (?) packet. */				receive();			}			if ((interrupts & ENISR_COUNTERS)!=0) {				rx_frame_errors += rd(EN0_COUNTER0);				rx_crc_errors   += rd(EN0_COUNTER1);				rx_missed_errors+= rd(EN0_COUNTER2);				wr(ENISR_COUNTERS, EN0_ISR); /* Ack intr. */			}						/* Ignore any RDC interrupts that make it back to here. */			if ((interrupts & ENISR_RDC)!=0) 			{				wr(ENISR_RDC, EN0_ISR);			}			wr(E8390_NODMA+E8390_PAGE0+E8390_START, E8390_CMD);		}    //		if (interrupts && ei_debug) //		{//			wr(E8390_NODMA+E8390_PAGE0+E8390_START, E8390_CMD);//			if (nr_serviced >= MAX_SERVICE) //			{//				/* 0xFF is valid for a card removal *///				if(interrupts!=0xFF)//					printk(KERN_WARNING "%s: Too much work at interrupt, status %#2.2x\n",//					   dev->name, interrupts);//				wr(ENISR_ALL, EN0_ISR); /* Ack. most intrs. *///			} else {//				printk(KERN_WARNING "%s: unknown interrupt %#2x\n", dev->name, interrupts);//				wr(0xff, EN0_ISR); /* Ack. all intrs. *///			}//		}	}/*** txErr - handle transmitter error** A transmitter error has happened. Most likely excess collisions (which* is a fairly normal condition). If the error is one where the Tx will* have been aborted, we try and send another one right away, instead of* letting the failed packet sit and collect dust in the Tx buffer. This* is a much better solution as it avoids kernel based Tx timeouts, and* an unnecessary card reset.**/	private static void txErr() {		int txsr = rd(EN0_TSR);		boolean tx_was_aborted = (txsr & (ENTSR_ABT+ENTSR_FU))!=0;/*#ifdef VERBOSE_ERROR_DUMP		printk(KERN_DEBUG "%s: transmitter error (%#2x): ", dev->name, txsr);		if (txsr & ENTSR_ABT)			printk("excess-collisions ");		if (txsr & ENTSR_ND)			printk("non-deferral ");		if (txsr & ENTSR_CRS)			printk("lost-carrier ");		if (txsr & ENTSR_FU)			printk("FIFO-underrun ");		if (txsr & ENTSR_CDH)			printk("lost-heartbeat ");		printk("\n");#endif*/		wr(ENISR_TX_ERR, EN0_ISR); /* Ack intr. */		if (tx_was_aborted) {			txIntr();		} else {			tx_errors++;			if ((txsr & ENTSR_CRS)!=0) tx_carrier_errors++;			if ((txsr & ENTSR_CDH)!=0) tx_heartbeat_errors++;			if ((txsr & ENTSR_OWC)!=0) tx_window_errors++;		}	}/*** txIntr - transmit interrupt handler** We have finished a transmit: check for errors and then trigger the next* packet to be sent.*/	private static void txIntr() {		int status = rd(EN0_TSR);    		wr(ENISR_TX, EN0_ISR); /* Ack intr. */		/*		 * There are two Tx buffers, see which one finished, and trigger		 * the send of another one if it exists.		 */		if (tx1 < 0) {			tx1 = 0;			if (tx2 > 0) {				txing = true;				triggerSend(tx2, tx_start_page + TX_PAGES/2);	// second buffer				// dev->trans_start = jiffies;				tx2 = -1;			} else {				txing = false;				}		} else if (tx2 < 0) {			tx2 = 0;			if (tx1 > 0) {				txing = true;				triggerSend(tx1, tx_start_page);				// dev->trans_start = jiffies;				tx1 = -1;			} else {				txing = false;			}		}		/* Minimize Tx latency: update the statistics after we restart TXing. */		if ((status & ENTSR_COL)!=0) collisions++;		if ((status & ENTSR_PTX)!=0) {			tx_packets++;		} else {			tx_errors++;			if ((status & ENTSR_ABT)!=0) 			{				tx_aborted_errors++;				collisions += 16;			}			if ((status & ENTSR_CRS)!=0) tx_carrier_errors++;			if ((status & ENTSR_FU)!=0) tx_fifo_errors++;			if ((status & ENTSR_CDH)!=0) tx_heartbeat_errors++;			if ((status & ENTSR_OWC)!=0) tx_window_errors++;		}		// netif_wake_queue(dev);	}/** * We have a good packet(s), get it/them out of the buffers.  * Called with lock held. */	private static void receive() {		int rxing_page, this_frame, next_frame;		int current_offset;		int rx_pkt_count = 0;		// int num_rx_pages = stop_page-rx_start_page;    wrSer('r');		//while (++rx_pkt_count < 10) {		{	// only one packet for now!!!			int pkt_len, pkt_stat;						/* Get the rx page (incoming packet pointer). */			wr(E8390_NODMA+E8390_PAGE1, E8390_CMD);			rxing_page = rd(EN1_CURPAG);			wr(E8390_NODMA+E8390_PAGE0, E8390_CMD);						/* Remove one frame from the ring.  Boundary is always a page behind. */			this_frame = rd(EN0_BOUNDARY) + 1;			if (this_frame >= stop_page)				this_frame = rx_start_page;						/* Someday we'll omit the previous, iff we never get this message.			   (There is at least one clone claimed to have a problem.)  			   			   Keep quiet if it looks like a card removal. One problem here			   is that some clones crash in roughly the same way.			 */			/*			if (ei_debug > 0  &&  this_frame != current_page && (this_frame!=0x0 || rxing_page!=0xFF))				printk(KERN_ERR "%s: mismatched read page pointers %2x vs %2x.\n",					   dev->name, this_frame, current_page);			*/			// no while loop!			// if (this_frame == rxing_page)	/* Read all the frames? */			//	break;				/* Done for now */						current_offset = this_frame << 8;			rdMem(current_offset, buf, 4);			pkt_stat = buf[0];			int rx_frame_next = buf[1];			pkt_len = (buf[3]<<8) + buf[2] - 4;// intVal(pkt_len);						next_frame = this_frame + 1 + ((pkt_len+4)>>8);						/* Check for bogosity warned by 3c503 book: the status byte is never			   written.  This happened a lot during testing! This code should be			   cleaned up someday. *//* strange!!!			if (rx_frame_next != next_frame				&& rx_frame_next != next_frame + 1				&& rx_frame_next != next_frame - num_rx_pages				&& rx_frame_next != next_frame + 1 - num_rx_pages) {				current_page = rxing_page;				wr(current_page-1, EN0_BOUNDARY);				rx_errors++;				continue;			}*//* I don't care for now			if (pkt_len < 60  ||  pkt_len > 1518) {				if (ei_debug)					printk(KERN_DEBUG "%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n",						   dev->name, rx_frame_count, rx_frame_status,						   rx_frame_next);				rx_errors++;				rx_length_errors++;			} else if ((pkt_stat & 0x0F) == ENRSR_RXOK) {*/			if ((pkt_stat & 0x0F) == ENRSR_RXOK) {				/* no buffer available -> drop				skb = dev_alloc_skb(pkt_len+2);				if (skb == NULL) 				{					if (ei_debug > 1)						printk(KERN_DEBUG "%s: Couldn't allocate a sk_buff of size %d.\n",							   dev->name, pkt_len);					rx_dropped++;					break;				}				else				*/				{					// whou cares about ring buffer bounderies!!!!					rdMem(current_offset + 4 /* sizeof(rx_frame)*/, buf, pkt_len);					// rcv_len is the 'signal' for the loop					rcv_len = pkt_len;/*wrSer('\n');wrSer('p');wrSer(' ');for (int i=0; i<pkt_len; ++i) hexVal(buf[i]);wrSer('\n');*/					// skb->protocol=eth_type_trans(skb,dev);

⌨️ 快捷键说明

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