Beispiel #1
0
/*
**  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;
}
Beispiel #2
0
/*
**  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;
}
Beispiel #3
0
/*===========================================================================*
 *				dp8390_dump				     *
 *===========================================================================*/
void dp8390_dump()
{
	dpeth_t *dep;
	int i, isr;

	printf("\n");
	for (i= 0, dep = &de_table[0]; i<DE_PORT_NR; i++, dep++)
	{
#if XXX
		if (dep->de_mode == DEM_DISABLED)
			printf("dp8390 port %d is disabled\n", i);
		else if (dep->de_mode == DEM_SINK)
			printf("dp8390 port %d is in sink mode\n", i);
#endif

		if (dep->de_mode != DEM_ENABLED)
			continue;

		printf("dp8390 statistics of port %d:\n", i);

		printf("recvErr    :%8ld\t", dep->de_stat.ets_recvErr);
		printf("sendErr    :%8ld\t", dep->de_stat.ets_sendErr);
		printf("OVW        :%8ld\n", dep->de_stat.ets_OVW);

		printf("CRCerr     :%8ld\t", dep->de_stat.ets_CRCerr);
		printf("frameAll   :%8ld\t", dep->de_stat.ets_frameAll);
		printf("missedP    :%8ld\n", dep->de_stat.ets_missedP);

		printf("packetR    :%8ld\t", dep->de_stat.ets_packetR);
		printf("packetT    :%8ld\t", dep->de_stat.ets_packetT);
		printf("transDef   :%8ld\n", dep->de_stat.ets_transDef);

		printf("collision  :%8ld\t", dep->de_stat.ets_collision);
		printf("transAb    :%8ld\t", dep->de_stat.ets_transAb);
		printf("carrSense  :%8ld\n", dep->de_stat.ets_carrSense);

		printf("fifoUnder  :%8ld\t", dep->de_stat.ets_fifoUnder);
		printf("fifoOver   :%8ld\t", dep->de_stat.ets_fifoOver);
		printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat);

		printf("OWC        :%8ld\t", dep->de_stat.ets_OWC);

		isr= inb_reg0(dep, DP_ISR);
		printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr,
					inb_reg0(dep, DP_ISR), dep->de_flags);

		if (debug)
		{
			dep->de_int_pending= 1;
			interrupt(dpeth_tasknr);
		}
	}
}
Beispiel #4
0
/*
**  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)
{
  iovec_dat_s_t *iovp = &dep->de_write_iovec;
  int r, 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;
	r= sys_safe_outsb(dep->de_data_port, iovp->iod_proc_nr,
	      iovp->iod_iovec[ix].iov_grant, 0, bytes);
	if (r != OK)
		panic("pio_user2nic: sys_safe_outsb failed: %d", r);

	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(RdmaErrMsg);
  }
  return;
}
Beispiel #5
0
/*===========================================================================*
 *				dp8390_dump				     *
 *===========================================================================*/
void dp8390_dump()
{
	dpeth_t *dep;
	int isr;

	dep = &de_state;

	printf("\n");
#if XXX
	if (dep->de_mode == DEM_DISABLED)
		printf("dp8390 instance %d is disabled\n", de_instance);
	else if (dep->de_mode == DEM_SINK)
		printf("dp8390 instance %d is in sink mode\n", de_instance);
#endif

	if (dep->de_mode != DEM_ENABLED)
		return;

	printf("dp8390 statistics of instance %d:\n", de_instance);

	printf("recvErr    :%8ld\t", dep->de_stat.ets_recvErr);
	printf("sendErr    :%8ld\t", dep->de_stat.ets_sendErr);
	printf("OVW        :%8ld\n", dep->de_stat.ets_OVW);

	printf("CRCerr     :%8ld\t", dep->de_stat.ets_CRCerr);
	printf("frameAll   :%8ld\t", dep->de_stat.ets_frameAll);
	printf("missedP    :%8ld\n", dep->de_stat.ets_missedP);

	printf("packetR    :%8ld\t", dep->de_stat.ets_packetR);
	printf("packetT    :%8ld\t", dep->de_stat.ets_packetT);
	printf("transDef   :%8ld\n", dep->de_stat.ets_transDef);

	printf("collision  :%8ld\t", dep->de_stat.ets_collision);
	printf("transAb    :%8ld\t", dep->de_stat.ets_transAb);
	printf("carrSense  :%8ld\n", dep->de_stat.ets_carrSense);

	printf("fifoUnder  :%8ld\t", dep->de_stat.ets_fifoUnder);
	printf("fifoOver   :%8ld\t", dep->de_stat.ets_fifoOver);
	printf("CDheartbeat:%8ld\n", dep->de_stat.ets_CDheartbeat);

	printf("OWC        :%8ld\t", dep->de_stat.ets_OWC);

	isr= inb_reg0(dep, DP_ISR);
	printf("dp_isr = 0x%x + 0x%x, de_flags = 0x%x\n", isr,
				inb_reg0(dep, DP_ISR), dep->de_flags);
}
Beispiel #6
0
/*
**  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(UmapErrMsg);

	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(RdmaErrMsg);
  }
  return;
}
Beispiel #7
0
/*===========================================================================*
 *				ne_probe				     *
 *===========================================================================*/
int ne_probe(dpeth_t *dep)
{
	int byte;
	int i;
	int loc1, loc2;
	testf_t f;

	dep->de_dp8390_port= dep->de_base_port + NE_DP8390;

	/* We probe for an ne1000 or an ne2000 by testing whether the
	 * on board is reachable through the dp8390. Note that the
	 * ne1000 is an 8bit card and has a memory region distict from
	 * the 16bit ne2000
	 */

	for (dep->de_16bit= 0; dep->de_16bit < 2; dep->de_16bit++)
	{
		/* Reset the ethernet card */
		byte= inb_ne(dep, NE_RESET);
		milli_delay(2);
		outb_ne(dep, NE_RESET, byte);
		milli_delay(2);

		/* Reset the dp8390 */
		outb_reg0(dep, DP_CR, CR_STP | CR_DM_ABORT);
		for (i= 0; i < 0x1000 && ((inb_reg0(dep, DP_ISR) & ISR_RST) == 0); i++)
			; /* Do nothing */

		/* Check if the dp8390 is really there */
		if ((inb_reg0(dep, DP_CR) & (CR_STP|CR_DM_ABORT)) !=
			(CR_STP|CR_DM_ABORT))
		{
			return 0;
		}

		/* Disable the receiver and init TCR and DCR. */
		outb_reg0(dep, DP_RCR, RCR_MON);
		outb_reg0(dep, DP_TCR, TCR_NORMAL);
		if (dep->de_16bit)
		{
			outb_reg0(dep, DP_DCR, DCR_WORDWIDE | DCR_8BYTES |
				DCR_BMS);
		}
		else
		{
			outb_reg0(dep, DP_DCR, DCR_BYTEWIDE | DCR_8BYTES |
				DCR_BMS);
		}

		if (dep->de_16bit)
		{
			loc1= NE2000_START;
			loc2= NE2000_START + NE2000_SIZE - 4;
			f= test_16;
		}
		else
		{
			loc1= NE1000_START;
			loc2= NE1000_START + NE1000_SIZE - 4;
			f= test_8;
		}
		if (f(dep, loc1, pat0) && f(dep, loc1, pat1) &&
			f(dep, loc1, pat2) && f(dep, loc1, pat3) &&
			f(dep, loc2, pat0) && f(dep, loc2, pat1) &&
			f(dep, loc2, pat2) && f(dep, loc2, pat3))
		{
			/* We don't need a memory segment */
			dep->de_linmem= 0;
			if (!dep->de_pci)
				dep->de_initf= ne_init;
			dep->de_stopf= ne_stop;
			dep->de_prog_IO= 1;
			return 1;
		}
	}
	return 0;
}
Beispiel #8
0
/*
**  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 */
}
Beispiel #9
0
/*
**  Name:	void ns_interrupt(dpeth_t * dep)
**  Function:	Handles interrupt.
*/
static void ns_interrupt(dpeth_t * dep)
{
  int isr, tsr;
  int 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;
}
Beispiel #10
0
/*
**  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;
  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;
}