📄 rtl8139core.java
字号:
/*
* $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 + -