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

📄 lin.c

📁 Java Op Processor java vhdl processor
💻 C
📖 第 1 页 / 共 2 页
字号:
			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);			*/						if (this_frame == rxing_page)	/* Read all the frames? */				break;				/* Done for now */						current_offset = this_frame << 8;			rdMem(current_offset, buf, 4);			int rx_frame_status = buf[0];			int rx_frame_next = buf[1];			int rx_frame_count = (buf[4]<<8) + buf[3];						pkt_len = rx_frame_count - 4;			pkt_stat = rx_frame_status;						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. */			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;			}			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) {				struct sk_buff *skb;								/* 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);for (int i=0; i<pkt_len; ++i) intVal(buf[i]);					// skb->protocol=eth_type_trans(skb,dev);					// netif_rx(skb);					// dev->last_rx = jiffies;					rx_packets++;					rx_bytes += pkt_len;					if (pkt_stat & ENRSR_PHY)						multicast++;				}			} else {				/*				if (ei_debug)					printk(KERN_DEBUG "%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n",						   dev->name, rx_frame_status, rx_frame_next,						   rx_frame_count);				*/				rx_errors++;				/* NB: The NIC counts CRC, frame and missed errors. */				if (pkt_stat & ENRSR_FO)					rx_fifo_errors++;			}			next_frame = rx_frame_next;						/* This _should_ never happen: it's here for avoiding bad clones. */			if (next_frame >= stop_page) {				/*				printk("%s: next frame inconsistency, %#2x\n", dev->name,					   next_frame);				*/				next_frame = rx_start_page;			}			current_page = next_frame;			wr(next_frame-1, EN0_BOUNDARY);		}		/* We used to also ack ENISR_OVER here, but that would sometimes mask		   a real overrun, leaving the 8390 in a stopped state with rec'vr off. */		wr(ENISR_RX+ENISR_RX_ERR, EN0_ISR);	}/** * rxOverrun - handle receiver overrun * * We have a receiver overrun: we have to kick the 8390 to get it started * again. Problem is that you have to kick it exactly as NS prescribes in * the updated datasheets, or "the NIC may act in an unpredictable manner." * This includes causing "the NIC to defer indefinitely when it is stopped * on a busy network."  Ugh. * Called with lock held. Don't call this with the interrupts off or your * computer will hate you - it takes 10ms or so.  */	private static void rxOverrun() {		boolean was_txing, must_resend = false;    		/*		 * Record whether a Tx was in progress and then issue the		 * stop command.		 */		was_txing = (rd(E8390_CMD) & E8390_TRANS) != 0;		wr(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD);    		/*		if (ei_debug > 1)			printk(KERN_DEBUG "%s: Receiver overrun.\n", dev->name);		*/		rx_over_errors++;    		/* 		 * Wait a full Tx time (1.2ms) + some guard time, NS says 1.6ms total.		 * Early datasheets said to poll the reset bit, but now they say that		 * it "is not a reliable indicator and subsequently should be ignored."		 * We wait at least 10ms.		 */		Timer.sleep(10);		/*		 * Reset RBCR[01] back to zero as per magic incantation.		 */		wr(0x00, EN0_RCNTLO);		wr(0x00, EN0_RCNTHI);		/*		 * See if any Tx was interrupted or not. According to NS, this		 * step is vital, and skipping it will cause no end of havoc.		 */		if (was_txing) { 			boolean tx_completed = (rd(EN0_ISR) & (ENISR_TX+ENISR_TX_ERR)) != 0;			if (!tx_completed)				must_resend = true;		}		/*		 * Have to enter loopback mode and then restart the NIC before		 * you are allowed to slurp packets up off the ring.		 */		wr(E8390_TXOFF, EN0_TXCR);		wr(E8390_NODMA + E8390_PAGE0 + E8390_START, E8390_CMD);		/*		 * Clear the Rx ring of all the debris, and ack the interrupt.		 */		receive();		wr(ENISR_OVER, EN0_ISR);		/*		 * Leave loopback mode, and resend any packet that got stopped.		 */		wr(E8390_TXCONFIG, EN0_TXCR); 		if (must_resend)    		wr(E8390_NODMA + E8390_PAGE0 + E8390_START + E8390_TRANS, E8390_CMD);}/**	Collect the stats.*/ 	public static void getStats() {		/* Read the counter registers, assuming we are in page 0. */		rx_frame_errors += rd(EN0_COUNTER0);		rx_crc_errors   += rd(EN0_COUNTER1);		rx_missed_errors+= rd(EN0_COUNTER2);    		// return &stat;	}/* * Update the given Autodin II CRC value with another data byte. */	private static int update_crc(int by, int current_crc) {		int bit;		int ah = 0;		for (bit=0; bit<8; bit++) 		{			int carry = (current_crc>>>31);			current_crc <<= 1;			ah = ((ah<<1) | carry) ^ by;			ah &= 0xff;			if ((ah&1) != 0)				current_crc ^= 0x04C11DB7;	/* CRC polynomial */			ah >>>= 1;			byte >>>= 1;		}		return current_crc;	}/* * Form the 64 bit 8390 multicast table from the linked list of addresses * associated with this dev structure. */ //static inline void make_mc_bits(u8 *bits, struct net_device *dev)//{//		struct dev_mc_list *dmi;////		for (dmi=dev->mc_list; dmi; dmi=dmi->next) //		{//			int i;//			u32 crc;//			if (dmi->dmi_addrlen != ETH_ALEN) //			{//				printk(KERN_INFO "%s: invalid multicast address length given.\n", dev->name);//				continue;//			}//			crc = 0xffffffff;	/* initial CRC value *///			for (i=0; i<ETH_ALEN; i++)//				crc = update_crc(dmi->dmi_addr[i], crc);//			/* //			 * The 8390 uses the 6 most significant bits of the//			 * CRC to index the multicast table.//			 *///			bits[crc>>29] |= (1<<((crc>>26)&7));//		}//}/////**// * do_set_multicast_list - set/clear multicast filter// * @dev: net device for which multicast filter is adjusted// *// *	Set or clear the multicast filter for this adaptor. May be called// *	from a BH in 2.1.x. Must be called with lock held. // */// //static void do_set_multicast_list(struct net_device *dev)//{//		int i;//		struct ei_device *ei_local = (struct ei_device*)dev->priv;////		if (!(dev->flags&(IFF_PROMISC|IFF_ALLMULTI))) //		{//			memset(mcfilter, 0, 8);//			if (dev->mc_list)//				make_mc_bits(mcfilter, dev);//		}//		else//			memset(mcfilter, 0xFF, 8);	/* mcast set to accept-all */////		/* //		 * DP8390 manuals don't specify any magic sequence for altering//		 * the multicast regs on an already running card. To be safe, we//		 * ensure multicast mode is off prior to loading up the new hash//		 * table. If this proves to be not enough, we can always resort//		 * to stopping the NIC, loading the table and then restarting.//		 *//		 * Bug Alert!  The MC regs on the SMC 83C690 (SMC Elite and SMC //		 * Elite16) appear to be write-only. The NS 8390 data sheet lists//		 * them as r/w so this is a bug.  The SMC 83C790 (SMC Ultra and//		 * Ultra32 EISA) appears to have this bug fixed.//		 *///		 //		if (netif_running(dev))//			wr(E8390_RXCONFIG, EN0_RXCR);//		wr(E8390_NODMA + E8390_PAGE1, E8390_CMD);//		for(i = 0; i < 8; i++) //		{//			wr(mcfilter[i], EN1_MULT_SHIFT(i));//#ifndef BUG_83C690//			if(rd(EN1_MULT_SHIFT(i))!=mcfilter[i])//				printk(KERN_ERR "Multicast filter read/write mismap %d\n",i);//#endif//		}//		wr(E8390_NODMA + E8390_PAGE0, E8390_CMD);////  	if(dev->flags&IFF_PROMISC)//  		wr(E8390_RXCONFIG | 0x18, EN0_RXCR);//		else if(dev->flags&IFF_ALLMULTI || dev->mc_list)//  		wr(E8390_RXCONFIG | 0x08, EN0_RXCR);//  	else//  		wr(E8390_RXCONFIG, EN0_RXCR);// }/////*// *	Called without lock held. This is invoked from user context and may// *	be parallel to just about everything else. Its also fairly quick and// *	not called too often. Must protect against both bh and irq users// */// //static void set_multicast_list(struct net_device *dev)//{//		struct ei_device *ei_local = (struct ei_device*)dev->priv;//		//		do_set_multicast_list(dev);//}	/*** Trigger a transmit start, assuming the length is valid. */   	private static void triggerSend(int length, int start_page) {		wr(E8390_NODMA+E8390_PAGE0, E8390_CMD);    		if (rd(E8390_CMD) & E8390_TRANS) {			// "trigger_send() called with the transmitter busy.\n",			return;		}		wr(length & 0xff, EN0_TCNTLO);		wr(length >> 8, EN0_TCNTHI);		wr(start_page, EN0_TPSR);		wr(E8390_NODMA+E8390_TRANS+E8390_START, E8390_CMD);	}

⌨️ 快捷键说明

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