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

📄 lin.c

📁 Java Op Processor java vhdl processor
💻 C
📖 第 1 页 / 共 2 页
字号:
//**************** ne.c//**************** 8390.c/** * txTimeout - handle transmit time out condition * @dev: network device which has apparently fallen asleep * * 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;				lasttx = -1;			} else {				tx2 = -1;				lasttx = -2;			}		}		/*		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 = 0;    		/* 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. */		while ((interrupts = rd(EN0_ISR)) != 0 && ++nr_serviced < MAX_SERVICE) {			if (interrupts & ENISR_OVER) {				rxOverrun();			} else if (interrupts & (ENISR_RX+ENISR_RX_ERR)) {				/* Got a good (?) packet. */				receive();			}			/* Push the next to-transmit packet through. */			if (interrupts & ENISR_TX) {				txIntr();			} else if (interrupts & ENISR_TX_ERR) {				txErr();			}			if (interrupts & ENISR_COUNTERS) {				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) 			{				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);		int tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU);/*#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) tx_carrier_errors++;			if (txsr & ENTSR_CDH) tx_heartbeat_errors++;			if (txsr & ENTSR_OWC) 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) {/*			if (lasttx != 1 && lasttx != -1)				printk(KERN_ERR "%s: bogus last_tx_buffer %d, tx1=%d.\n",					name, lasttx, tx1);*/			tx1 = 0;			if (tx2 > 0) {				txing = true;				triggerSend(tx2, tx_start_page + TX_PAGES/2);	// second buffer				// dev->trans_start = jiffies;				tx2 = -1,				lasttx = 2;			} else {				lasttx = 20;				txing = 0;				}		} else if (tx2 < 0) {/*			if (lasttx != 2  &&  lasttx != -2)				printk("%s: bogus last_tx_buffer %d, tx2=%d.\n",					name, lasttx, tx2);*/			tx2 = 0;			if (tx1 > 0) {				txing = 1;				triggerSend(tx1, tx_start_page);				// dev->trans_start = jiffies;				tx1 = -1;				lasttx = 1;			} else {				lasttx = 10;				txing = 0;			}		}//	else printk(KERN_WARNING "%s: unexpected TX-done interrupt, lasttx=%d.\n",//			dev->name, lasttx);		/* Minimize Tx latency: update the statistics after we restart TXing. */		if (status & ENTSR_COL) collisions++;		if (status & ENTSR_PTX) {			tx_packets++;		} else {			tx_errors++;			if (status & ENTSR_ABT) 			{				tx_aborted_errors++;				collisions += 16;			}			if (status & ENTSR_CRS) tx_carrier_errors++;			if (status & ENTSR_FU) tx_fifo_errors++;			if (status & ENTSR_CDH) tx_heartbeat_errors++;			if (status & ENTSR_OWC) 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;    		while (++rx_pkt_count < 10) {			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.			 */			/*

⌨️ 快捷键说明

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