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

📄 8390.c

📁 Minix3.11的源码。[MINIX 3是一个为高可靠性应用而设计的自由且简洁的类UNIX系统。]
💻 C
📖 第 1 页 / 共 2 页
字号:
/***  File:	8390.c		May  02, 2000****  Author:	Giovanni Falzoni <gfalzoni@inwind.it>****  This file contains an ethernet device driver for NICs**  equipped with the National Semiconductor NS 8390 chip.**  It has to be associated with the board specific driver.**  Rewritten from Minix 2.0.0 ethernet driver dp8390.c**  to extract the NS 8390 common functions.****  $Id: 8390.c,v 1.4 2005/09/04 18:52:16 beng Exp $*/#include "drivers.h"#include <minix/com.h>#include <net/hton.h>#include <net/gen/ether.h>#include <net/gen/eth_io.h>#include "dp.h"#if (ENABLE_DP8390 == 1)#define PIO16	0	/* NOTE: pio 16 functions missing */#include "8390.h"#define	sys_nic2mem(srcOffs,dstProc,dstOffs,length) \	sys_vircopy(SELF,dep->de_memsegm,(vir_bytes)(srcOffs),\		    (dstProc),D,(vir_bytes)(dstOffs),length)#define	sys_user2nic(srcProc,srcOffs,dstOffs,length) \	sys_vircopy((srcProc),D,(vir_bytes)(srcOffs),\		    SELF,dep->de_memsegm,(vir_bytes)(dstOffs),length)static const char RdmaErrMsg[] = "remote dma failed to complete";/***  Name:	void ns_rw_setup(dpeth_t *dep, int mode, int size, u16_t offset);**  Function:	Sets the board for reading/writing.*/static void ns_rw_setup(dpeth_t *dep, int mode, int size, u16_t offset){  if (mode == CR_DM_RW) outb_reg0(dep, DP_ISR, ISR_RDC);  outb_reg0(dep, DP_RBCR0, size & 0xFF);  outb_reg0(dep, DP_RBCR1, (size >> 8) & 0xFF);  outb_reg0(dep, DP_RSAR0, offset & 0xFF);  outb_reg0(dep, DP_RSAR1, (offset >> 8) & 0xFF);  mode |= (CR_PS_P0 | CR_STA);  outb_reg0(dep, DP_CR, mode);  return;}/***  Name:	void ns_start_xmit(dpeth_t *dep, int size, int pageno);**  Function:	Sets the board for for transmitting and fires it.*/static void ns_start_xmit(dpeth_t * dep, int size, int pageno){  outb_reg0(dep, DP_TPSR, pageno);  outb_reg0(dep, DP_TBCR1, size >> 8);  outb_reg0(dep, DP_TBCR0, size & 0xFF);  outb_reg0(dep, DP_CR, CR_NO_DMA | CR_STA | CR_TXP);	/* Fires transmission */  return;}/***  Name:	void mem_getblock(dpeth_t *dep, u16_t offset,**  				int size, void *dst)**  Function:	Reads a block of packet from board (shared memory).*/static void mem_getblock(dpeth_t *dep, u16_t offset, int size, void *dst){  sys_nic2mem(dep->de_linmem + offset, SELF, dst, size);  return;}/***  Name:	void mem_nic2user(dpeth_t *dep, int pageno, int pktsize);**  Function:	Copies a packet from board to user area (shared memory).*/static void mem_nic2user(dpeth_t * dep, int pageno, int pktsize){  phys_bytes offset, phys_user;  iovec_dat_t *iovp = &dep->de_read_iovec;  int bytes, ix = 0;  /* Computes shared memory address (skipping receive header) */  offset = pageno * DP_PAGESIZE + sizeof(dp_rcvhdr_t);  do {				/* Reads chuncks of packet into user area */	bytes = iovp->iod_iovec[ix].iov_size;	/* Size of a chunck */	if (bytes > pktsize) bytes = pktsize;	/* Reads from board to user area */	if ((offset + bytes) > (dep->de_stoppage * DP_PAGESIZE)) {		/* Circular buffer wrap-around */		bytes = dep->de_stoppage * DP_PAGESIZE - offset;		sys_nic2mem(dep->de_linmem + offset, iovp->iod_proc_nr,			    iovp->iod_iovec[ix].iov_addr, bytes);		pktsize -= bytes;		phys_user += bytes;		bytes = iovp->iod_iovec[ix].iov_size - bytes;		if (bytes > pktsize) bytes = pktsize;		offset = dep->de_startpage * DP_PAGESIZE;	}	sys_nic2mem(dep->de_linmem + offset, iovp->iod_proc_nr,		    iovp->iod_iovec[ix].iov_addr, bytes);	offset += bytes;	if (++ix >= IOVEC_NR) {	/* Next buffer of IO vector */		dp_next_iovec(iovp);		ix = 0;	}	/* Till packet done */  } while ((pktsize -= bytes) > 0);  return;}/***  Name:	void mem_user2nic(dpeth_t *dep, int pageno, int pktsize)**  Function:	Copies a packet from user area to board (shared memory).*/static void mem_user2nic(dpeth_t *dep, int pageno, int pktsize){  phys_bytes offset, phys_user;  iovec_dat_t *iovp = &dep->de_write_iovec;  int bytes, ix = 0;  /* Computes shared memory address */  offset = pageno * DP_PAGESIZE;  do {				/* Reads chuncks of packet from user area */	bytes = iovp->iod_iovec[ix].iov_size;	/* Size of chunck */	if (bytes > pktsize) bytes = pktsize;	/* Reads from user area to board (shared memory) */	sys_user2nic(iovp->iod_proc_nr, iovp->iod_iovec[ix].iov_addr, 		     dep->de_linmem + offset, bytes);	offset += bytes;	if (++ix >= IOVEC_NR) {	/* Next buffer of IO vector */		dp_next_iovec(iovp);		ix = 0;	}	/* Till packet done */  } while ((pktsize -= bytes) > 0);  return;}/***  Name:	void pio_getblock(dpeth_t *dep, u16_t offset,**  				int size, void *dst)**  Function:	Reads a block of packet from board (Prog. I/O).*/static void pio_getblock(dpeth_t *dep, u16_t offset, int size, void *dst){  /* Sets up board for reading */  ns_rw_setup(dep, CR_DM_RR, size, offset);#if PIO16 == 0  insb(dep->de_data_port, SELF, dst, size);#else  if (dep->de_16bit == TRUE) {	insw(dep->de_data_port, dst, size);  } else {	insb(dep->de_data_port, dst, size);  }#endif  return;}/***  Name:	void pio_nic2user(dpeth_t *dep, int pageno, int pktsize)**  Function:	Copies a packet from board to user area (Prog. I/O).*/static void pio_nic2user(dpeth_t *dep, int pageno, int pktsize){  phys_bytes phys_user;  iovec_dat_t *iovp = &dep->de_read_iovec;  unsigned offset; int bytes, ix = 0;  /* Computes memory address (skipping receive header) */  offset = pageno * DP_PAGESIZE + sizeof(dp_rcvhdr_t);  /* Sets up board for reading */  ns_rw_setup(dep, CR_DM_RR, ((offset + pktsize) > (dep->de_stoppage * DP_PAGESIZE)) ?	(dep->de_stoppage * DP_PAGESIZE) - offset : pktsize, offset);  do {				/* Reads chuncks of packet into user area */	bytes = iovp->iod_iovec[ix].iov_size;	/* Size of a chunck */	if (bytes > pktsize) bytes = pktsize;	if ((offset + bytes) > (dep->de_stoppage * DP_PAGESIZE)) {		/* Circular buffer wrap-around */		bytes = dep->de_stoppage * DP_PAGESIZE - offset;		insb(dep->de_data_port, iovp->iod_proc_nr, (void*)(iovp->iod_iovec[ix].iov_addr), bytes);		pktsize -= bytes;		iovp->iod_iovec[ix].iov_addr += bytes;		bytes = iovp->iod_iovec[ix].iov_size - bytes;		if (bytes > pktsize) bytes = pktsize;		offset = dep->de_startpage * DP_PAGESIZE;  		ns_rw_setup(dep, CR_DM_RR, pktsize, offset);	}	insb(dep->de_data_port, iovp->iod_proc_nr, (void*)(iovp->iod_iovec[ix].iov_addr), bytes);	offset += bytes;	if (++ix >= IOVEC_NR) {	/* Next buffer of IO vector */		dp_next_iovec(iovp);		ix = 0;	}	/* Till packet done */  } while ((pktsize -= bytes) > 0);  return;}/***  Name:	void pio_user2nic(dpeth_t *dep, int pageno, int pktsize)**  Function:	Copies a packet from user area to board (Prog. I/O).*/static void pio_user2nic(dpeth_t *dep, int pageno, int pktsize){  phys_bytes phys_user;  iovec_dat_t *iovp = &dep->de_write_iovec;  int bytes, ix = 0;  /* Sets up board for writing */  ns_rw_setup(dep, CR_DM_RW, pktsize, pageno * DP_PAGESIZE);    do {				/* Reads chuncks of packet from user area */	bytes = iovp->iod_iovec[ix].iov_size;	/* Size of chunck */	if (bytes > pktsize) bytes = pktsize;	outsb(dep->de_data_port, iovp->iod_proc_nr,	      (void*)(iovp->iod_iovec[ix].iov_addr), bytes);	if (++ix >= IOVEC_NR) {	/* Next buffer of I/O vector */		dp_next_iovec(iovp);		ix = 0;	}	/* Till packet done */  } while ((pktsize -= bytes) > 0);  for (ix = 0; ix < 100; ix += 1) {	if (inb_reg0(dep, DP_ISR) & ISR_RDC) break;  }  if (ix == 100) {	panic(dep->de_name, RdmaErrMsg, NO_NUM);  }  return;}/***  Name:	void ns_stats(dpeth_t * dep)**  Function:	Updates counters reading from device*/static void ns_stats(dpeth_t * dep){  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);  return;}/***  Name:	void ns_dodump(dpeth_t * dep)**  Function:	Displays statistics (a request from F5 key).*/static void ns_dodump(dpeth_t * dep){  ns_stats(dep);		/* Forces reading fo counters from board */  return;}/***  Name:	void ns_reinit(dpeth_t *dep)**  Function:	Updates receiver configuration.*/static void ns_reinit(dpeth_t * dep){  int 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_CR, CR_PS_P0);  outb_reg0(dep, DP_RCR, dp_reg);  return;}/***  Name:	void ns_send(dpeth_t * dep, int from_int, int size)**  Function:	Transfers packet to device and starts sending.*/static void ns_send(dpeth_t * dep, int from_int, int size){  int queue;  if (queue = dep->de_sendq_head, dep->de_sendq[queue].sq_filled) {	if (from_int) panic(dep->de_name, "should not be sending ", NO_NUM);	dep->de_send_s = size;	return;  }  (dep->de_user2nicf) (dep, dep->de_sendq[queue].sq_sendpage, size);  dep->bytes_Tx += (long) size;  dep->de_sendq[queue].sq_filled = TRUE;  dep->de_flags |= (DEF_XMIT_BUSY | DEF_ACK_SEND);  if (dep->de_sendq_tail == queue) {	/* there it goes.. */	ns_start_xmit(dep, size, dep->de_sendq[queue].sq_sendpage);  } else	dep->de_sendq[queue].sq_size = size;  if (++queue == dep->de_sendq_nr) queue = 0;  dep->de_sendq_head = queue;  dep->de_flags &= NOT(DEF_SENDING);  return;}/***  Name:	void ns_reset(dpeth_t *dep)**  Function:	Resets device.*/static void ns_reset(dpeth_t * dep){  int ix;  /* Stop chip */  outb_reg0(dep, DP_CR, CR_STP | CR_NO_DMA);  outb_reg0(dep, DP_RBCR0, 0);  outb_reg0(dep, DP_RBCR1, 0);  for (ix = 0; ix < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); ix += 1)	 /* Do nothing */ ;  outb_reg0(dep, DP_TCR, TCR_1EXTERNAL | TCR_OFST);  outb_reg0(dep, DP_CR, CR_STA | CR_NO_DMA);  outb_reg0(dep, DP_TCR, TCR_NORMAL | TCR_OFST);  /* Acknowledge the ISR_RDC (remote dma) interrupt. */  for (ix = 0; ix < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RDC) == 0); ix += 1)	 /* Do nothing */ ;  outb_reg0(dep, DP_ISR, inb_reg0(dep, DP_ISR) & NOT(ISR_RDC));  /* Reset the transmit ring. If we were transmitting a packet, we   * pretend that the packet is processed. Higher layers will   * retransmit if the packet wasn't actually sent. */  dep->de_sendq_head = dep->de_sendq_tail = 0;  for (ix = 0; ix < dep->de_sendq_nr; ix++)	dep->de_sendq[ix].sq_filled = FALSE;  ns_send(dep, TRUE, dep->de_send_s);  return;}/***  Name:	void ns_recv(dpeth_t *dep, int fromint, int size)**  Function:	Gets a packet from device*/static void ns_recv(dpeth_t *dep, int fromint, int size){  dp_rcvhdr_t header;  dp_rcvhdr_t dummy;

⌨️ 快捷键说明

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