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

📄 8390.c

📁 Minix3.11的源码。[MINIX 3是一个为高可靠性应用而设计的自由且简洁的类UNIX系统。]
💻 C
📖 第 1 页 / 共 2 页
字号:
  unsigned pageno, curr, next;  vir_bytes length;  int packet_processed = FALSE;#ifdef ETH_IGN_PROTO  u16_t eth_type;#endif  pageno = inb_reg0(dep, DP_BNRY) + 1;  if (pageno == dep->de_stoppage) pageno = dep->de_startpage;  do {	/* */	outb_reg0(dep, DP_CR, CR_PS_P1);	curr = inb_reg1(dep, DP_CURR);	outb_reg0(dep, DP_CR, CR_PS_P0 | CR_NO_DMA | CR_STA);	if (curr == pageno) break;	(dep->de_getblockf) (dep, pageno * DP_PAGESIZE, sizeof(header), &header);#ifdef ETH_IGN_PROTO	(dep->de_getblockf) (dep, pageno * DP_PAGESIZE + sizeof(header) + 2 * sizeof(ether_addr_t), sizeof(eth_type), &eth_type);#endif	length = (header.dr_rbcl | (header.dr_rbch << 8)) - sizeof(dp_rcvhdr_t);	next = header.dr_next;	if (length < ETH_MIN_PACK_SIZE || length > ETH_MAX_PACK_SIZE) {		printf("%s: packet with strange length arrived: %d\n", dep->de_name, length);		dep->de_stat.ets_recvErr += 1;		next = curr;	} else if (next < dep->de_startpage || next >= dep->de_stoppage) {		printf("%s: strange next page\n", dep->de_name);		dep->de_stat.ets_recvErr += 1;		next = curr;#ifdef ETH_IGN_PROTO	} else if (eth_type == eth_ign_proto) {		/* Hack: ignore packets of a given protocol */		static int first = TRUE;		if (first) {			first = FALSE;			printf("%s: dropping proto %04x packet\n", dep->de_name, ntohs(eth_ign_proto));		}		next = curr;#endif	} else if (header.dr_status & RSR_FO) {		/* This is very serious, issue a warning and reset buffers */		printf("%s: fifo overrun, resetting receive buffer\n", dep->de_name);		dep->de_stat.ets_fifoOver += 1;		next = curr;	} else if ((header.dr_status & RSR_PRX) && (dep->de_flags & DEF_ENABLED)) {		if (!(dep->de_flags & DEF_READING)) break;		(dep->de_nic2userf) (dep, pageno, length);		dep->de_read_s = length;		dep->de_flags |= DEF_ACK_RECV;		dep->de_flags &= NOT(DEF_READING);		packet_processed = TRUE;	}	dep->bytes_Rx += (long) length;	dep->de_stat.ets_packetR += 1;	outb_reg0(dep, DP_BNRY, (next == dep->de_startpage ? dep->de_stoppage : next) - 1);	pageno = next;  } while (!packet_processed);#if 0  if ((dep->de_flags & (DEF_READING | DEF_STOPPED)) == (DEF_READING | DEF_STOPPED))	/* The chip is stopped, and all arrived packets delivered */	(*dep->de_resetf) (dep);  dep->de_flags &= NOT(DEF_STOPPED);#endif  return;}/***  Name:	void ns_interrupt(dpeth_t * dep)**  Function:	Handles interrupt.*/static void ns_interrupt(dpeth_t * dep){  int isr, tsr;  int size, queue;  while ((isr = inb_reg0(dep, DP_ISR)) != 0) {	outb_reg0(dep, DP_ISR, isr);	if (isr & (ISR_PTX | ISR_TXE)) {		tsr = inb_reg0(dep, DP_TSR);		if (tsr & TSR_PTX) {			dep->de_stat.ets_packetT++;		}		if (tsr & TSR_COL) dep->de_stat.ets_collision++;		if (tsr & (TSR_ABT | TSR_FU)) {			dep->de_stat.ets_fifoUnder++;		}		if ((isr & ISR_TXE) || (tsr & (TSR_CRS | TSR_CDH | TSR_OWC))) {			printf("%s: got send Error (0x%02X)\n", dep->de_name, tsr);			dep->de_stat.ets_sendErr++;		}		queue = dep->de_sendq_tail;		if (!(dep->de_sendq[queue].sq_filled)) {	/* Hardware bug? */			printf("%s: transmit interrupt, but not sending\n", dep->de_name);			continue;		}		dep->de_sendq[queue].sq_filled = FALSE;		if (++queue == dep->de_sendq_nr) queue = 0;		dep->de_sendq_tail = queue;		if (dep->de_sendq[queue].sq_filled) {			ns_start_xmit(dep, dep->de_sendq[queue].sq_size,				dep->de_sendq[queue].sq_sendpage);		}		if (dep->de_flags & DEF_SENDING) {			ns_send(dep, TRUE, dep->de_send_s);		}	}	if (isr & ISR_PRX) {		ns_recv(dep, TRUE, 0);	}	if (isr & ISR_RXE) {		printf("%s: got recv Error (0x%04X)\n", dep->de_name, inb_reg0(dep, DP_RSR));		dep->de_stat.ets_recvErr++;	}	if (isr & ISR_CNT) {		dep->de_stat.ets_CRCerr += inb_reg0(dep, DP_CNTR0);		dep->de_stat.ets_recvErr += inb_reg0(dep, DP_CNTR1);		dep->de_stat.ets_fifoOver += inb_reg0(dep, DP_CNTR2);	}	if (isr & ISR_OVW) {		printf("%s: got overwrite warning\n", dep->de_name);	}	if (isr & ISR_RDC) {		/* Nothing to do */	}	if (isr & ISR_RST) {		/* This means we got an interrupt but the ethernet		 * chip is shutdown. We set the flag DEF_STOPPED, and		 * continue processing arrived packets. When the		 * receive buffer is empty, we reset the dp8390. */		printf("%s: network interface stopped\n", dep->de_name);		dep->de_flags |= DEF_STOPPED;		break;	}  }  if ((dep->de_flags & (DEF_READING | DEF_STOPPED)) == (DEF_READING | DEF_STOPPED)) {	/* The chip is stopped, and all arrived packets delivered */	ns_reset(dep);	dep->de_flags &= NOT(DEF_STOPPED);  }  return;}/***  Name:	void ns_init(dpeth_t *dep)**  Function:	Initializes the NS 8390*/void ns_init(dpeth_t * dep){  int dp_reg;  int ix;  /* NS8390 initialization (as recommended in National Semiconductor specs) */  outb_reg0(dep, DP_CR, CR_PS_P0 | CR_STP | CR_NO_DMA);	/* 0x21 */#if PIO16 == 0  outb_reg0(dep, DP_DCR, (DCR_BYTEWIDE | DCR_LTLENDIAN | DCR_8BYTES | DCR_BMS));#else  outb_reg0(dep, DP_DCR, (((dep->de_16bit) ? DCR_WORDWIDE : DCR_BYTEWIDE) |			DCR_LTLENDIAN | DCR_8BYTES | DCR_BMS));#endif  outb_reg0(dep, DP_RBCR0, 0);  outb_reg0(dep, DP_RBCR1, 0);  outb_reg0(dep, DP_RCR, RCR_MON);	/* Sets Monitor mode */  outb_reg0(dep, DP_TCR, TCR_INTERNAL);	/* Sets Loopback mode 1 */  outb_reg0(dep, DP_PSTART, dep->de_startpage);  outb_reg0(dep, DP_PSTOP, dep->de_stoppage);  outb_reg0(dep, DP_BNRY, dep->de_stoppage - 1);  outb_reg0(dep, DP_ISR, 0xFF);	/* Clears Interrupt Status Register */  outb_reg0(dep, DP_IMR, 0);	/* Clears Interrupt Mask Register */  /* Copies station address in page 1 registers */  outb_reg0(dep, DP_CR, CR_PS_P1 | CR_NO_DMA);	/* Selects Page 1 */  for (ix = 0; ix < SA_ADDR_LEN; ix += 1)	/* Initializes address */	outb_reg1(dep, DP_PAR0 + ix, dep->de_address.ea_addr[ix]);  for (ix = DP_MAR0; ix <= DP_MAR7; ix += 1)	/* Initializes address */	outb_reg1(dep, ix, 0xFF);  outb_reg1(dep, DP_CURR, dep->de_startpage);  outb_reg1(dep, DP_CR, CR_PS_P0 | CR_NO_DMA);	/* Selects Page 0 */  inb_reg0(dep, DP_CNTR0);	/* Resets counters by reading them */  inb_reg0(dep, DP_CNTR1);  inb_reg0(dep, DP_CNTR2);  dp_reg = IMR_PRXE | IMR_PTXE | IMR_RXEE | IMR_TXEE | IMR_OVWE | IMR_CNTE;  outb_reg0(dep, DP_ISR, 0xFF);	/* Clears Interrupt Status Register */  outb_reg0(dep, DP_IMR, dp_reg);	/* Sets Interrupt Mask register */  dp_reg = 0;  if (dep->de_flags & DEF_PROMISC) dp_reg |= RCR_AB | RCR_PRO | RCR_AM;  if (dep->de_flags & DEF_BROAD) dp_reg |= RCR_AB;  if (dep->de_flags & DEF_MULTI) dp_reg |= RCR_AM;  outb_reg0(dep, DP_RCR, dp_reg);	/* Sets receive as requested */  outb_reg0(dep, DP_TCR, TCR_NORMAL);	/* Sets transmitter */  outb_reg0(dep, DP_CR, CR_STA | CR_NO_DMA);	/* Starts board */  /* Initializes the send queue. */  for (ix = 0; ix < dep->de_sendq_nr; ix += 1)	dep->de_sendq[ix].sq_filled = 0;  dep->de_sendq_head = dep->de_sendq_tail = 0;  /* Device specific functions */  if (!dep->de_prog_IO) {	dep->de_user2nicf = mem_user2nic;	dep->de_nic2userf = mem_nic2user;	dep->de_getblockf = mem_getblock;  } else {#if PIO16 == 0	dep->de_user2nicf = pio_user2nic;	dep->de_nic2userf = pio_nic2user;	dep->de_getblockf = pio_getblock;#else#error	Missing I/O functions for pio 16 bits#endif  }  dep->de_recvf = ns_recv;  dep->de_sendf = ns_send;  dep->de_flagsf = ns_reinit;  dep->de_resetf = ns_reset;  dep->de_getstatsf = ns_stats;  dep->de_dumpstatsf = ns_dodump;  dep->de_interruptf = ns_interrupt;  return;			/* Done */}#if PIO16 == 1/***  Name:	void dp_pio16_user2nic(dpeth_t *dep, int pageno, int pktsize)**  Function:	Copies a packet from user area to board (Prog. I/O, 16bits).*/static void dp_pio16_user2nic(dpeth_t *dep, int pageno, int pktsize){  u8_t two_bytes[2];  phys_bytes phys_user, phys_2bytes = vir2phys(two_bytes);  vir_bytes ecount = (pktsize + 1) & NOT(0x0001);  int bytes, ix = 0, odd_byte = 0;  iovec_dat_t *iovp = &dep->de_write_iovec;  outb_reg0(dep, DP_ISR, ISR_RDC);  dp_read_setup(dep, ecount, pageno * DP_PAGESIZE);  do {	bytes = iovp->iod_iovec[ix].iov_size;	if (bytes > pktsize) bytes = pktsize;	phys_user = numap(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_addr, bytes);	if (!phys_user) panic(dep->de_name, UmapErrMsg, NO_NUM);	if (odd_byte) {		phys_copy(phys_user, phys_2bytes + 1, (phys_bytes) 1);		out_word(dep->de_data_port, *(u16_t *)two_bytes);		pktsize--;		bytes--;		phys_user++;		odd_byte = 0;		if (!bytes) continue;	}	ecount = bytes & NOT(0x0001);	if (ecount != 0) {		phys_outsw(dep->de_data_port, phys_user, ecount);		pktsize -= ecount;		bytes -= ecount;		phys_user += ecount;	}	if (bytes) {		phys_copy(phys_user, phys_2bytes, (phys_bytes) 1);		pktsize--;		bytes--;		phys_user++;		odd_byte = 1;	}	if (++ix >= IOVEC_NR) {	/* Next buffer of I/O vector */		dp_next_iovec(iovp);		ix = 0;	}  }  while (bytes > 0);  if (odd_byte) out_word(dep->de_data_port, *(u16_t *) two_bytes);  for (ix = 0; ix < 100; ix++) {	if (inb_reg0(dep, DP_ISR) & ISR_RDC) break;  }  if (ix == 100) {	panic(dep->de_name, RdmaErrMsg, NO_NUM);  }  return;}/***  Name:	void dp_pio16_nic2user(dpeth_t *dep, int pageno, int pktsize)**  Function:	Copies a packet from board to user area (Prog. I/O, 16bits).*/static void dp_pio16_nic2user(dpeth_t * dep, int nic_addr, int count){  phys_bytes phys_user;  vir_bytes ecount;  int bytes, i;  u8_t two_bytes[2];  phys_bytes phys_2bytes;  int odd_byte;  ecount = (count + 1) & ~1;  phys_2bytes = vir2phys(two_bytes);  odd_byte = 0;  dp_read_setup(dep, ecount, nic_addr);  i = 0;  while (count > 0) {	if (i >= IOVEC_NR) {		dp_next_iovec(iovp);		i = 0;		continue;	}	bytes = iovp->iod_iovec[i].iov_size;	if (bytes > count) bytes = count;	phys_user = numap(iovp->iod_proc_nr,			  iovp->iod_iovec[i].iov_addr, bytes);	if (!phys_user) panic(dep->de_name, UmapErrMsg, NO_NUM);	if (odd_byte) {		phys_copy(phys_2bytes + 1, phys_user, (phys_bytes) 1);		count--;		bytes--;		phys_user++;		odd_byte = 0;		if (!bytes) continue;	}	ecount = bytes & ~1;	if (ecount != 0) {		phys_insw(dep->de_data_port, phys_user, ecount);		count -= ecount;		bytes -= ecount;		phys_user += ecount;	}	if (bytes) {		*(u16_t *) two_bytes = in_word(dep->de_data_port);		phys_copy(phys_2bytes, phys_user, (phys_bytes) 1);		count--;		bytes--;		phys_user++;		odd_byte = 1;	}  }  return;}#endif				/* PIO16 == 1 */#endif				/* ENABLE_DP8390 *//** end 8390.c **/

⌨️ 快捷键说明

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