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

📄 rtl8139core.java

📁 纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * $Id: RTL8139Core.java,v 1.2 2004/02/25 06:50:39 epr Exp $
 */

package org.jnode.driver.net.rtl8139;

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.net.ethernet.Flags;
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;

/**
 * 
 * Build with help of the donation from WebSprocket LLC
 * 
 * @author Martin Husted Hartvig
 */

public class RTL8139Core extends AbstractDeviceCore implements RTL8139Constants, 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 = null;
	/** flags needed to setup device */
	private final RTL8139Flags flags;
	/** main driver this belongs to */
	private final RTL8139Driver driver;
	/** The receive buffer ring */
	private final RTL8139RxRing rxRing;
	/** The transmit buffer */
	private final RTL8139TxBuffer[] txBuffers = new RTL8139TxBuffer[4];
	/** Is a transmission active? */
	//private boolean tx_active;
	private int txIndex;
	private int txAborted;
	private int txNumberOfPackets;
	private int txPending;

	/**
	 * Create a new instance
	 * 
	 * @param flags
	 */
	public RTL8139Core(RTL8139Driver driver, ResourceOwner owner, PCIDevice device, Flags flags) throws DriverException, ResourceNotFreeException {
		if (!(flags instanceof RTL8139Flags))
			throw new DriverException("Wrong flags to the RTL8139 driver");

		this.driver = driver;
		this.flags = (RTL8139Flags) flags;

		final int irq = getIRQ(device, this.flags);

		// Get the start of the IO address space
		this.iobase = getIOBase(device, this.flags);

		final int iolength = getIOLength(device, this.flags);
		//    log.debug("RTL8139 driver iobase "+iobase+" irq "+irq);

		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 RTL8139RxRing(RX_FRAMES, rm);

		for (int i = 0; i < txBuffers.length; i++) {
			txBuffers[i] = new RTL8139TxBuffer(rm);
			setReg32(REG_TX_ADDR0 + (4 * i), Address.as32bit(txBuffers[i].getFirstDPDAddress()));
		}

		powerUpDevice();
		reset();

		byte[] adr1 = i2bsLoHi(getReg32(REG_MAC0));
		byte[] adr2 = i2bsLoHi(getReg32(REG_MAC0 + 4));

		final byte[] hwAddrArr = new byte[ETH_ALEN];

		hwAddrArr[0] = adr1[0];
		hwAddrArr[1] = adr1[1];
		hwAddrArr[2] = adr1[2];
		hwAddrArr[3] = adr1[3];
		hwAddrArr[4] = adr2[0];
		hwAddrArr[5] = adr2[1];

		this.hwAddress = new EthernetAddress(hwAddrArr, 0);

		// disable multicast
		setReg32(REG_MAR0, 0);
		setReg32(REG_MAR0 + 4, 0);

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

	private void powerUpDevice() {
		setReg8(REG_CFG9346, CFG9346_WE);

		setReg8(REG_CONFIG1, 0);
		setReg8(REG_CFG9346, 0);
	}

	private void reset() {
		txIndex = 0;

		int i;

		setReg8(REG_CHIPCMD, CMD_RESET);

		try {
			Thread.sleep(200);
		} catch (InterruptedException ex) {
		}

		for (i = 0; i < REPEAT_TIMEOUT_COUNT; i++) {
			try {
				Thread.sleep(GENERIC_WAIT_TIME);
			} catch (InterruptedException ex) {
			}

			if ((getReg8(REG_CHIPCMD) & CMD_RESET) == 0)
				break;
		}

		if (i == REPEAT_TIMEOUT_COUNT)
			log.debug("Ethernet card: Chip Reset incomplete");

		setReg16(BMCR, BMCR_RESET);

		try {
			Thread.sleep(200);
		} catch (InterruptedException ex) {
		}

		for (i = 0; i < REPEAT_TIMEOUT_COUNT; i++) {
			try {
				Thread.sleep(GENERIC_WAIT_TIME);
			} catch (InterruptedException ex) {
			}

			if ((getReg16(BMCR) & BMCR_RESET) == 0)
				break;
		}

		if (i == REPEAT_TIMEOUT_COUNT)
			log.debug("Ethernet card: BMCR Reset incomplete");

		// Autoload from the eeprom
		setReg8(REG_CFG9346, CFG9346_AUTOLOAD);

		try {
			Thread.sleep(200);
		} catch (InterruptedException ex) {
		}

		for (i = 0; i < REPEAT_TIMEOUT_COUNT; i++) {
			try {
				Thread.sleep(GENERIC_WAIT_TIME);
			} catch (InterruptedException ex) {
			}

			if ((getReg8(REG_CFG9346) & 0xc0) == 0)
				break;
		}
		if (i == REPEAT_TIMEOUT_COUNT)
			log.debug("Ethernet card: Autoload incomplete");
	}

	private byte[] i2bsLoHi(int _i) {
		int shiftL = 24, shiftH = shiftL;

		byte[] bs = new byte[4];

		for (int i = 0; i < 4; i++) {
			bs[i] = (byte) ((_i << shiftH) >>> shiftL);
			shiftH = shiftH - 8;
		}
		return bs;
	}

	private void autoNegotiate() {

		//boolean fullDuplex = false;

		// start auto negotiating
		setReg16(REG_INTR_MASK, INTR_MASK);

		int status = getReg16(REG_INTR_STATUS);

		if ((status & INTR_LNKCHG) != 0) {
			log.debug("AN: link changed! " + Integer.toHexString(status));

			setReg16(REG_INTR_STATUS, status);
		}

		setReg8(REG_CFG9346, 0xC0);
		setReg16(BMCR, 0x1200);

		status = getReg16(BMSR);

		int bogusCount = 0;
		while ((status & 0x30) == 0) {

			try {
				Thread.sleep(1000);
			} catch (InterruptedException ex) {
			}

			bogusCount++;
			if (bogusCount >= AUTO_NEGOTIATE_TIMEOUT) {
				log.debug("Bogus count: autonegotiating taking too long: " + Integer.toHexString(status));
				break;
			}
			status = getReg16(BMSR);
		}

		log.debug("autonegotiating status: " + Integer.toHexString(status));

		if ((status & 0x20) != 0)
			log.debug("autonegotiating complete");
		if ((status & 0x10) != 0)
			log.debug("remote fault detected");
		if ((status & 0x4) != 0)
			log.debug("link valid");

		/* int lpar = */
		getReg16(NWAY_LPAR);

		log.debug("MSR: " + Integer.toHexString(getReg8(MSR)) + " BMCR: " + Integer.toHexString(getReg16(BMCR)) + " LPAR: " + Integer.toHexString(getReg16(NWAY_LPAR)));

		// 	if (lpar == 0xffff) {
		// 	} else if (((lpar & 0x0100) == 0x0100) || ((lpar & 0x00C0) == 0x0040)) {
		// 	    fullDuplex = true;
		// 	}

		// 	if (fullDuplex) rtl8139.write8(REG_CONFIG1, 0x60); // check
		// 	else rtl8139.write8(REG_CONFIG1, 0x20);

		setReg8(REG_CFG9346, 0x00);

		// 	if (fullDuplex) System.out.print("AutoNegotiation: Full Duplex ");
		// 	else System.out.print("AutoNegotiation: Half Duplex ");

		// 	if ((lpar & 0x0180) != 0) System.out.println("100 Mbps Mode");
		// 	else System.out.println("10 Mbps Mode");

		return;
	}

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

	/**
	 * Initialize the device
	 */
	public void initialize() {
		// reset the device
		reset();

		// initialize our buffer
		rxRing.initialize();

		setReg32(REG_RX_BUF, Address.as32bit(rxRing.getFirstUPDAddress()));

		autoNegotiate();

		// enable tx/rx
		enableTxRx();

		// setup tx configuration
		setReg32(REG_TX_CONFIG, txConfig);
		// setup rx configuration
		setReg32(REG_RX_CONFIG, rxConfig);

		// unlock config registers
		setReg8(REG_CFG9346, 0xc0);

		// setups up LED pin defs, vital product data, and power management
		int reg = getReg8(REG_CONFIG1);

		// disable power management
		reg &= 0xfe;
		reg |= 0xc0;
		setReg8(REG_CONFIG1, reg);

		// setup config3
		setReg8(REG_CONFIG3, 0x40);
		// Setup config4
		setReg8(REG_CONFIG4, 0x2);
		setReg8(REG_CFG9346, 0);

		// clear rx missed
		setReg16(REG_RX_MISSED, 0x00000000);

		// enable tx/rx
		enableTxRx();
		// Enable interrupts
		setReg16(REG_INTR_MASK, INTR_MASK);
	}

	private void enableTxRx() {
		setReg8(REG_CHIPCMD, CMD_TX_ENABLE | CMD_RX_ENABLE);
	}

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

⌨️ 快捷键说明

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