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

📄 3c509.c

📁 Minix3.11的源码。[MINIX 3是一个为高可靠性应用而设计的自由且简洁的类UNIX系统。]
💻 C
📖 第 1 页 / 共 2 页
字号:
	outw_el3(dep, REG_CmdStatus, CMD_StopIntXcvr);	/* milli_delay(5); */  } else if (dep->de_if_port == TP_XCVR) {	SetWindow(WNO_Diagnostics);	outw_el3(dep, REG_MediaStatus, inw_el3(dep, REG_MediaStatus) &		 NOT((MediaLBeatEnable | MediaJabberEnable)));	/* milli_delay(5); */  }  DEBUG(printf("%s: stopping Etherlink ... \n", dep->de_name));  /* Issues a global reset  outw_el3(dep, REG_CmdStatus, CMD_GlobalReset); */  sys_irqdisable(&dep->de_hook);	/* Disable interrupt */   return;}/***  Name:	void el3_interrupt(dpeth_t *dep)**  Function:	Interrupt handler.  Acknwledges transmit interrupts**  		or unloads receive buffer to memory queue.*/static void el3_interrupt(dpeth_t * dep){  int loop;  unsigned short isr;  for (loop = 5; loop > 0 && ((isr = inw_el3(dep, REG_CmdStatus)) &         (INT_Latch | INT_RxComplete | INT_UpdateStats)); loop -= 1) {	if (isr & INT_RxComplete)	/* Got a new packet */		el3_rx_complete(dep);	if (isr & INT_TxAvailable) {	/* Tx has room for big packets */		DEBUG(printf("3c509: got Tx interrupt, Status=0x%04x\n", isr);)		dep->de_flags &= NOT(DEF_XMIT_BUSY);		outw_el3(dep, REG_CmdStatus, CMD_Acknowledge | INT_TxAvailable);		if (dep->de_flags & DEF_SENDING)	/* Send pending */			el3_send(dep, TRUE, dep->de_send_s);	}	if (isr & (INT_AdapterFail | INT_RxEarly | INT_UpdateStats)) {		if (isr & INT_UpdateStats)	/* Empties statistics */			el3_getstats(dep);		if (isr & INT_RxEarly)	/* Not really used. Do nothing */			outw_el3(dep, REG_CmdStatus, CMD_Acknowledge | (INT_RxEarly));		if (isr & INT_AdapterFail) {			/* Adapter error. Reset and re-enable receiver */			DEBUG(printf("3c509: got Rx fail interrupt, Status=0x%04x\n", isr);)			el3_rx_mode(dep);			outw_el3(dep, REG_CmdStatus, CMD_Acknowledge | INT_AdapterFail);		}	}	/* Acknowledge interrupt */	outw_el3(dep, REG_CmdStatus, CMD_Acknowledge | (INT_Latch | INT_Requested));  }  return;}/***  Name:	unsigned el3_read_eeprom(port_t port, unsigned address);**  Function:	Reads the EEPROM at specified address*/static unsigned el3_read_eeprom(port_t port, unsigned address){  unsigned int result;  int bit;  address |= EL3_READ_EEPROM;  outb(port, address);  milli_delay(5);		/* Allows EEPROM reads */  for (result = 0, bit = 16; bit > 0; bit -= 1) {	result = (result << 1) | (inb(port) & 0x0001);  }  return result;}/***  Name:	void el3_read_StationAddress(dpeth_t *dep)**  Function:	Reads station address from board*/static void el3_read_StationAddress(dpeth_t * dep){  unsigned int ix, rc;  for (ix = EE_3COM_NODE_ADDR; ix < SA_ADDR_LEN;) {	/* Accesses with word No. */	rc = el3_read_eeprom(dep->de_id_port, ix / 2);	/* Swaps bytes of word */	dep->de_address.ea_addr[ix++] = (rc >> 8) & 0xFF;	dep->de_address.ea_addr[ix++] = rc & 0xFF;  }  return;}/***  Name:	void el3_open(dpeth_t *dep)**  Function:	Initalizes board hardware and driver data structures.*/static void el3_open(dpeth_t * dep){  unsigned int AddrCfgReg, ResCfgReg;  unsigned int ix;  el3_read_StationAddress(dep);	/* Get ethernet address */  /* Get address and resource configurations */  AddrCfgReg = el3_read_eeprom(dep->de_id_port, EE_ADDR_CFG);  ResCfgReg = el3_read_eeprom(dep->de_id_port, EE_RESOURCE_CFG);  outb(dep->de_id_port, EL3_ACTIVATE);	/* Activate the board */  /* Gets xcvr configuration */  dep->de_if_port = AddrCfgReg & EL3_CONFIG_XCVR_MASK;  AddrCfgReg = ((AddrCfgReg & EL3_CONFIG_IOBASE_MASK) << 4) + EL3_IO_BASE_ADDR;  if (AddrCfgReg != dep->de_base_port)	panic(dep->de_name, "Bad I/O port for Etherlink board", NO_NUM);  ResCfgReg >>= 12;  dep->de_irq &= NOT(DEI_DEFAULT);	/* Strips the default flag */  if (ResCfgReg != dep->de_irq) panic(dep->de_name, "Bad IRQ for Etherlink board", NO_NUM);  SetWindow(WNO_Setup);  /* Reset transmitter and receiver */  outw_el3(dep, REG_CmdStatus, CMD_TxReset);  outw_el3(dep, REG_CmdStatus, CMD_RxReset);  /* Enable the adapter */  outb_el3(dep, REG_CfgControl, EL3_EnableAdapter);  /* Disable Status bits */  outw_el3(dep, REG_CmdStatus, CMD_SetStatusEnab + 0x00);  /* Set "my own" address */  SetWindow(WNO_StationAddress);  for (ix = 0; ix < 6; ix += 1)	outb_el3(dep, REG_SA0_1 + ix, dep->de_address.ea_addr[ix]);  /* Start Transceivers as required */  if (dep->de_if_port == BNC_XCVR) {	/* Start internal transceiver for Coaxial cable */	outw_el3(dep, REG_CmdStatus, CMD_StartIntXcvr);	milli_delay(5);  } else if (dep->de_if_port == TP_XCVR) {	/* Start internal transceiver for Twisted pair cable */	SetWindow(WNO_Diagnostics);	outw_el3(dep, REG_MediaStatus,		 inw_el3(dep, REG_MediaStatus) | (MediaLBeatEnable | MediaJabberEnable));  }  /* Switch to the statistic window, and clear counts (by reading) */  SetWindow(WNO_Statistics);  for (ix = REG_TxCarrierLost; ix <= REG_TxDefer; ix += 1) inb_el3(dep, ix);  inw_el3(dep, REG_RxBytes);  inw_el3(dep, REG_TxBytes);  /* Switch to operating window for normal use */  SetWindow(WNO_Operating);  /* Receive individual address & broadcast. (Mofified later by rx_mode) */  outw_el3(dep, REG_CmdStatus, CMD_SetRxFilter |	 (FilterIndividual | FilterBroadcast));  /* Turn on statistics */  outw_el3(dep, REG_CmdStatus, CMD_StatsEnable);  /* Enable transmitter and receiver */  outw_el3(dep, REG_CmdStatus, CMD_TxEnable);  outw_el3(dep, REG_CmdStatus, CMD_RxEnable);  /* Enable all the status bits */  outw_el3(dep, REG_CmdStatus, CMD_SetStatusEnab | 0xFF);  /* Acknowledge all interrupts to clear adapter. Enable interrupts */  outw_el3(dep, REG_CmdStatus, CMD_Acknowledge | 0xFF);  outw_el3(dep, REG_CmdStatus, CMD_SetIntMask |    (INT_Latch | INT_TxAvailable | INT_RxComplete | INT_UpdateStats));  /* Ready to operate, sets the environment for eth_task */  dep->de_data_port = dep->de_base_port;  /* Allocates Rx/Tx buffers */  init_buff(dep, NULL);  /* Device specific functions */  dep->de_recvf = el3_recv;  dep->de_sendf = el3_send;  dep->de_flagsf = el3_rx_mode;  dep->de_resetf = el3_reset;  dep->de_getstatsf = el3_getstats;  dep->de_dumpstatsf = el3_dodump;  dep->de_interruptf = el3_interrupt;  printf("%s: Etherlink III (%s) at %X:%d, %s port - ",         dep->de_name, "3c509", dep->de_base_port, dep->de_irq,         IfNamesMsg[dep->de_if_port >> 14]);  for (ix = 0; ix < SA_ADDR_LEN; ix += 1)	printf("%02X%c", dep->de_address.ea_addr[ix],	       ix < SA_ADDR_LEN - 1 ? ':' : '\n');  return;			/* Done */}/***  Name:	unsigned int el3_checksum(port_t port);**  Function:	Reads EEPROM and computes checksum.*/static unsigned short el3_checksum(port_t port){  unsigned short rc, checksum, address;  unsigned char lo, hi;  for (checksum = address = 0; address < 15; address += 1) {	rc = el3_read_eeprom(port, address);	lo = rc & 0xFF;	hi = (rc >> 8) & 0xFF;	if ((address == EE_PROD_ID && (rc & EE_PROD_ID_MASK) != EL3_PRODUCT_ID) ||	    (address == EE_3COM_CODE && rc != EL3_3COM_CODE))		return address;	if (address == EE_ADDR_CFG ||	    address == EE_RESOURCE_CFG ||	    address == EE_SW_CONFIG_INFO) {		lo ^= hi;		hi = 0;	} else {		hi ^= lo;		lo = 0;	}	rc = ((unsigned) hi << 8) + lo;	checksum ^= rc;  }  rc = el3_read_eeprom(port, address);  return(checksum ^= rc);	/* If OK checksum is 0 */}/***  Name:	void el3_write_id(port_t port);**  Function:	Writes the ID sequence to the board.*/static void el3_write_id(port_t port){  int ix, pattern;  outb(port, 0);		/* Selects the ID port */  outb(port, 0);		/* Resets hardware pattern generator */  for (pattern = ix = 0x00FF; ix > 0; ix -= 1) {	outb(port, pattern);	pattern <<= 1;	pattern = (pattern & 0x0100) ? pattern ^ 0xCF : pattern;  }  return;}/***  Name:	int el3_probe(dpeth_t *dep)**  Function:	Checks for presence of the board.*/PUBLIC int el3_probe(dpeth_t * dep){  port_t id_port;  /* Don't ask me what is this for !! */  outb(0x0279, 0x02);	/* Select PnP config control register. */  outb(0x0A79, 0x02);	/* Return to WaitForKey state. */  /* Tests I/O ports in the 0x1xF range for a valid ID port */  for (id_port = 0x110; id_port < 0x200; id_port += 0x10) {	outb(id_port, 0x00);	outb(id_port, 0xFF);	if (inb(id_port) & 0x01) break;  }  if (id_port == 0x200) return 0;	/* No board responding */  el3_write_id(id_port);  outb(id_port, EL3_ID_GLOBAL_RESET);	/* Reset the board */  milli_delay(5);		/* Technical reference says 162 micro sec. */  el3_write_id(id_port);  outb(id_port, EL3_SET_TAG_REGISTER);  milli_delay(5);  dep->de_id_port = id_port;	/* Stores ID port No. */  dep->de_ramsize =		/* RAM size is meaningless */	dep->de_offset_page = 0;  dep->de_linmem = 0L;		/* Access is via I/O port  */  /* Device specific functions */  dep->de_initf = el3_open;  dep->de_stopf = el3_close;  return(el3_checksum(id_port) == 0);	/* Etherlink board found/not found */}#endif				/* ENABLE_3C509 *//** 3c509.c **/

⌨️ 快捷键说明

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