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