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

📄 _3c90xcore.java

📁 纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * $Id: _3c90xCore.java,v 1.1 2003/11/25 11:52:22 epr Exp $
 */
package org.jnode.driver.net._3c90x;

import java.util.ArrayList;
import java.util.Collection;

import javax.naming.NameNotFoundException;

import org.jnode.driver.Device;
import org.jnode.driver.DriverException;
import org.jnode.driver.net.AbstractDeviceCore;
import org.jnode.driver.net.NetworkException;
import org.jnode.driver.pci.PCIBaseAddress;
import org.jnode.driver.pci.PCIDevice;
import org.jnode.driver.pci.PCIDeviceConfig;
import org.jnode.naming.InitialNaming;
import org.jnode.net.HardwareAddress;
import org.jnode.net.SocketBuffer;
import org.jnode.net.ethernet.EthernetAddress;
import org.jnode.net.ethernet.EthernetConstants;
import org.jnode.system.IOResource;
import org.jnode.system.IRQHandler;
import org.jnode.system.IRQResource;
import org.jnode.system.ResourceManager;
import org.jnode.system.ResourceNotFreeException;
import org.jnode.system.ResourceOwner;
import org.jnode.util.NumberUtils;
import org.jnode.util.TimeoutException;
import org.jnode.vm.Address;

/**
 * @author epr
 */
public class _3c90xCore extends AbstractDeviceCore implements _3c90xConstants, IRQHandler, EthernetConstants {

	/** Start of IO address space */
	private final int iobase;
	/** IO address space */
	private final IOResource io;
	/** IRQ */
	private final IRQResource irq;
	/** My ethernet address */
	private EthernetAddress hwAddress;
	/** The driver i'm a part of */
	private final _3c90xDriver driver;
	/** My flags */
	private final _3c90xFlags flags;
	/** Is a transmission active? */
	private boolean tx_active;
	/** Active register window */
	private int reg_window = 0xff;
	/** The receive buffer ring */
	private final _3c90xRxRing rxRing;
	/** The transmit buffer */
	private final _3c90xTxBuffer txBuffer;
	/** Is the device a B revision */
	private final boolean Brev;
	
	/**
	 * Create a new instance
	 * @param flags
	 */
	public _3c90xCore(
		_3c90xDriver driver,
		ResourceOwner owner,
		PCIDevice device,
		_3c90xFlags flags)
	throws DriverException, ResourceNotFreeException {
		final int irq = getIRQ(device, flags);
		this.driver = driver;
		this.flags = flags;
		this.tx_active = false;

		// Get the start of the IO address space
		this.iobase = getIOBase(device, flags);
		final int iolength = getIOLength(device, flags);
		final ResourceManager rm;
		try {
			rm = (ResourceManager)InitialNaming.lookup(ResourceManager.NAME);
		} catch (NameNotFoundException ex) {
			throw new DriverException("Cannot find ResourceManager");
		}
		this.irq = rm.claimIRQ(owner, irq, this, true);
		try {
			io = rm.claimIOResource(owner, iobase, iolength);
		} catch (ResourceNotFreeException ex) {
			this.irq.release();
			throw ex;
		}
		this.rxRing = new _3c90xRxRing(RX_FRAMES, rm);
		this.txBuffer = new _3c90xTxBuffer(rm);

		// Reset the device
		reset();
		
		// Determine Brev flag
		switch (readEEProm(0x03)) {
			case 0x9000: /** 10 Base TPO             **/
			case 0x9001: /** 10/100 T4               **/
			case 0x9050: /** 10/100 TPO              **/
			case 0x9051: /** 10 Base Combo           **/
			//case 0x9200: /** 3Com905C-TXM            **/
				Brev = false;
				break;

			case 0x9004: /** 10 Base TPO             **/
			case 0x9005: /** 10 Base Combo           **/
			case 0x9006: /** 10 Base TPO and Base2   **/
			case 0x900A: /** 10 Base FL              **/
			case 0x9055: /** 10/100 TPO              **/
			case 0x9056: /** 10/100 T4               **/
			case 0x905A: /** 10 Base FX              **/
			default:
				Brev = true;
				break;
		}

		// Read the eeprom
		final int[] eeprom = new int[0x21];
		for (int i = 0; i < 0x17; i++) {
			eeprom[i] = readEEProm(i);
			//Syslog.debug("eeprom[" + NumberUtils.hex(i, 2) + "]=" + NumberUtils.hex(eeprom[i], 4));
		}
		final byte[] hwAddrArr = new byte[ETH_ALEN];
		hwAddrArr[0] = (byte)(eeprom[0x0a]>>8);
		hwAddrArr[1] = (byte)(eeprom[0x0a]&0xFF);
		hwAddrArr[2] = (byte)(eeprom[0x0b]>>8);
		hwAddrArr[3] = (byte)(eeprom[0x0b]&0xFF);
		hwAddrArr[4] = (byte)(eeprom[0x0c]>>8);
		hwAddrArr[5] = (byte)(eeprom[0x0c]&0xFF);
		this.hwAddress = new EthernetAddress(hwAddrArr, 0);

		log.debug(
			"Found "
				+ flags.getName()
				+ " IRQ="
				+ irq
				+ ", IOBase=0x"
				+ NumberUtils.hex(iobase)
				+ ", MAC Address="
				+ hwAddress);		
	}

	/**
	 * Gets the ethernet address of this device
	 */
	public HardwareAddress getHwAddress() {
		return hwAddress;
	}

	/**
	 * Initialize the device
	 */
	public synchronized void initialize() {
		// First reset the device
		reset();
		
		// Now initialize our buffers
		rxRing.initialize();
		
		/** Program the MAC address into the station address registers **/
		setWindow(winAddressing2);
		final int a0 = ((hwAddress.get(1) & 0xFF) << 8) | (hwAddress.get(0) & 0xFF);
		final int a1 = ((hwAddress.get(3) & 0xFF) << 8) | (hwAddress.get(2) & 0xFF);
		final int a2 = ((hwAddress.get(5) & 0xFF) << 8) | (hwAddress.get(4) & 0xFF);
		setReg16(regStationAddress_2_3w+0, a0);
		setReg16(regStationAddress_2_3w+2, a1);
		setReg16(regStationAddress_2_3w+4, a2);
		setReg16(regStationMask_2_3w+0, 0);
		setReg16(regStationMask_2_3w+2, 0);
		setReg16(regStationMask_2_3w+4, 0);
		
		// Determine the link type
		final ArrayList connectors = new ArrayList();
		final int linktype = determineLinkType(connectors);
		log.debug("Found connectors " + connectors);

		/** enable DC converter for 10-Base-T **/
		if (linktype == 0x0003) {
			issueCommand(cmdEnableDcConverter, 0, 0);
		}

		/** Set the link to the type we just determined. **/
		setWindow(winTxRxOptions3);
		int cfg = getReg32(regInternalConfig_3_l);
		cfg &= ~(0xF<<20);
		cfg |= (linktype<<20);
		setReg32(regInternalConfig_3_l, cfg);
		//log.debug("Setting linktype to 0x" + NumberUtils.hex(linktype));

		/** Now that we set the xcvr type, reset the Tx and Rx, re-enable. **/
		issueCommand(cmdTxReset, 0x00, 10);
		while ((getReg16(regCommandIntStatus_w) & INT_CMDINPROGRESS) != 0) {
			/* loop */ 
		}

		if (!Brev) {
			setReg8(regTxFreeThresh_b, 0x01);
		}

		issueCommand(cmdTxEnable, 0, 0);

		/**
		 ** reset of the receiver on B-revision cards re-negotiates the link
		 ** takes several seconds (a computer eternity)
		 **/
		if (Brev) {
			issueCommand(cmdRxReset, 0x04, 10);
		} else {
			issueCommand(cmdRxReset, 0x00, 10);
		}
		while ((getReg16(regCommandIntStatus_w) & INT_CMDINPROGRESS) != 0) {
			/* loop */
		}

		/** Set the RX filter = receive only individual pkts & bcast. **/
		issueCommand(cmdSetRxFilter, 0x01 + 0x04, 0);
		//issueCommand(cmdSetRxFilter, 0x1F, 0);
		issueCommand(cmdRxEnable, 0, 0);
		setReg32(regUpListPtr_l, Address.as32bit(rxRing.getFirstUPDAddress()));

		/**
		 ** set Indication and Interrupt flags , acknowledge any IRQ's
		 **/
		final int intMask = INT_HOSTERROR | INT_TXCOMPLETE | INT_RXCOMPLETE | INT_UPDATESTATS | INT_LINKEVENT | INT_UPCOMPLETE | INT_INTREQUESTED;
		issueCommand(cmdSetInterruptEnable, /*0x7FF*/intMask, 0);
		issueCommand(cmdSetIndicationEnable, 0x7FF, 0);
		issueCommand(cmdAcknowledgeInterrupt, 0x661, 0);
		
		log.debug("initialize done");
	}

	/**
	 * Disable the device
	 */
	public synchronized void disable() {
		reset();
	}

	/**
	 * Release all resources
	 */
	public synchronized void release() {
		log.debug("io.release");
		io.release();
		log.debug("irq.release");
		irq.release();
	}

	/**
	 * Transmit the given buffer
	 * @param buf
	 * @param timeout
	 * @throws InterruptedException
	 * @throws TimeoutException
	 */
	public synchronized void transmit(SocketBuffer buf, long timeout)
	throws InterruptedException, TimeoutException {
		// Set the source address
		hwAddress.writeTo(buf, 6);

		//final int txStatus = getReg8(regTxStatus_b);
		//log.debug("Waiting for transmit txStatus=0x" + NumberUtils.hex(txStatus, 2));

		// Wait until we can start transmitting
		final long start = System.currentTimeMillis();
		while (tx_active) {
			final long now = System.currentTimeMillis();
			if (now-start > timeout) {
				throw new TimeoutException("Timeout in claiming transmitter");
			}
			wait(timeout);
		}
		tx_active = true;
		//log.debug("Going for transmit");

		txBuffer.initialize(buf);
		
		// Stall the download engine
		issueCommand(cmdStallCtl, 2, 1);
		
		// Set the address of the txBuffer
		setReg32(regDnListPtr_l, Address.as32bit(txBuffer.getFirstDPDAddress()));

		// UnStall the download engine
		issueCommand(cmdStallCtl, 3, 1);
		//log.debug("Leaving transmit txStatus=0x" + NumberUtils.hex(getReg8(regTxStatus_b), 2));
	}

	/**
	 * @see org.jnode.system.IRQHandler#handleInterrupt(int)
	 */
	public synchronized void handleInterrupt(int irq) {
		
		int intStatus = getReg16(regCommandIntStatus_w);
		int loops = 0;
		while ((intStatus & ~INT_WINDOWNUMBER) != 0) {
			//log.debug("IntStatus flags on " + flags.getName() + ": 0x" + NumberUtils.hex(intStatus, 4));
			loops++;
			if (loops > MAX_SERVICE) {
				log.error("Too much work in intterupt, IntStatus=0x" + NumberUtils.hex(intStatus));
				//issueCommand(cmdAcknowledgeInterrupt, intStatus & ~INT_WINDOWNUMBER, 0);
				return;
			}
			if ((intStatus & INT_TXCOMPLETE) != 0) {
				//log.debug("TxComplete on " + flags.getName());
				processTxComplete(); 
			} else if ((intStatus & INT_UPDATESTATS) != 0) {
				log.debug("UpdateStats on " + flags.getName());
				processUpdateStats();
			} else if ((intStatus & INT_LINKEVENT) != 0) {
				//log.debug("LinkEvent on " + flags.getName());
				processLinkEvent();
			} else if ((intStatus & INT_UPCOMPLETE) != 0) {
				//log.debug("UpComplete on " + flags.getName());
				processUpComplete();
			} else if ((intStatus & INT_INTERRUPTLATCH) != 0) {
				issueCommand(cmdAcknowledgeInterrupt, INT_INTERRUPTLATCH, 0);

⌨️ 快捷键说明

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