_3c90xcore.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 640 行 · 第 1/2 页

JAVA
640
字号
			} else {
				log.debug("Unknown IntStatus flags set on " + flags.getName() + ": IntStatus=0x" + NumberUtils.hex(intStatus, 4));
				issueCommand(cmdAcknowledgeInterrupt, intStatus & ~INT_WINDOWNUMBER, 0);
			}
			intStatus = getReg16(regCommandIntStatus_w);
		}

		//issueCommand(cmdAcknowledgeInterrupt, INT_INTERRUPTLATCH, 0);

		//log.debug("Done IRQ on " + flags.getName() + ": 0x" + NumberUtils.hex(intStatus, 4));
	}
	
	/**
	 * Process a TxComplete interrupt
	 */
	private final void processTxComplete() {
		tx_active = false;
		notifyAll();
		setReg8(regTxStatus_b, 0xFF); // Ack TxComplete, by writing any value
	}
	
	/**
	 * Process an UpdateStats interrupt
	 */
	private final void processUpdateStats() {
		// TODO Implement update stats
	}
	
	/**
	 * Process a LinkEvent interrupt
	 */
	private final void processLinkEvent() {
		// Read IntStatusAuto ack. the interrupt
		//getReg16(regIntStatusAuto_w);
		issueCommand(cmdAcknowledgeInterrupt, 0x02, 0);
		//issueCommand(cmdRxEnable, 0, 0);
	}
	
	/**
	 * Process an UpComplete interrupt
	 */
	private final void processUpComplete() {
		// Read all packets
		final int nrFrames = rxRing.getNrFrames();
		
		// Stall uploading first
		issueCommand(cmdStallCtl, 0x00, 1);
		
		for (int i = 0; i < nrFrames; i++) {
			final int pktStatus = rxRing.getPktStatus(i);
			if (pktStatus != 0) {
				//log.debug("PktStatus[" + NumberUtils.hex(i, 2) + "]=0x" + NumberUtils.hex(pktStatus));
				if ((pktStatus & upComplete) != 0) {
					final SocketBuffer skbuf = rxRing.getPacket(i);
					try {
						//log.debug("Read packet at index 0x" + NumberUtils.hex(i));
						driver.onReceive(skbuf);
					} catch (NetworkException ex) {
						log.debug("Error in onReceive", ex);
					} finally {
						rxRing.setPktStatus(i, 0);
					}
				}
			}
		}
		
		// UnStall uploading
		issueCommand(cmdStallCtl, 0x01, 0);
		
		// Ack interrupt
		issueCommand(cmdAcknowledgeInterrupt, INT_UPCOMPLETE, 0);
	}
	
	/**
	 * Reset this device
	 */
	private void reset() {
		issueCommand(cmdGlobalReset, 0xff, 10);

		/** global reset command resets station mask, non-B revision cards
		 ** require explicit reset of values
		 **/
		setWindow(winAddressing2);
		setReg16(regStationAddress_2_3w+0, 0);
		setReg16(regStationAddress_2_3w+2, 0);
		setReg16(regStationAddress_2_3w+4, 0);

		/** Issue transmit reset, wait for command completion **/
		issueCommand(cmdTxReset, 0, 10);
		issueCommand(cmdRxReset, 0, 10);
		issueCommand(cmdSetInterruptEnable, 0, 0);
		/** enable rxComplete and txComplete **/
		issueCommand(cmdSetIndicationEnable, 0x0014, 0);
		/** acknowledge any pending status flags **/
		issueCommand(cmdAcknowledgeInterrupt, 0x661, 0);
	}

	/**
	 * Gets the first IO-Address used by the given device
	 * @param device
	 * @param flags
	 */
	protected int getIOBase(Device device, _3c90xFlags flags) 
	throws DriverException {
		final PCIDeviceConfig config = ((PCIDevice)device).getConfig();
		final PCIBaseAddress[] addrs = config.getBaseAddresses();
		if (addrs.length < 1) {
			throw new DriverException("Cannot find iobase: not base addresses");
		}
		if (!addrs[0].isIOSpace()) {
			throw new DriverException("Cannot find iobase: first address is not I/O");
		}
		return addrs[0].getIOBase();
	}

	/**
	 * Gets the number of IO-Addresses used by the given device
	 * @param device
	 * @param flags
	 */
	protected int getIOLength(Device device, _3c90xFlags flags)
	throws DriverException {
		final PCIDeviceConfig config = ((PCIDevice)device).getConfig();
		final PCIBaseAddress[] addrs = config.getBaseAddresses();
		if (addrs.length < 1) {
			throw new DriverException("Cannot find iobase: not base addresses");
		}
		if (!addrs[0].isIOSpace()) {
			throw new DriverException("Cannot find iobase: first address is not I/O");
		}
		return addrs[0].getSize();
	}

	/**
	 * Gets the IRQ used by the given device
	 * @param device
	 * @param flags
	 */
	protected int getIRQ(Device device, _3c90xFlags flags) 
	throws DriverException {
		final PCIDeviceConfig config = ((PCIDevice)device).getConfig();
		return config.getInterruptLine();
	}
	
	/**
	 * Determine which connectors are physically available on the device.
	 * Determine the link type based on that.
	 * @param connectors
	 */
	private final int determineLinkType(Collection connectors) {
		/** Read the media options register, print a message and set default
		 ** xcvr.
		 **
		 ** Uses Media Option command on B revision, Reset Option on non-B
		 ** revision cards -- same register address
		 **/
		setWindow(winTxRxOptions3);
		int mopt = getReg16(regResetMediaOptions_3_w);

		/* mask out VCO bit that is defined as 10baseFL bit on B-rev cards */
		if (!Brev) {
			mopt &= 0x7F;
		}
		//log.debug("mopt=0x" + NumberUtils.hex(mopt));
		
		int linktype = 0x0008;
		if ((mopt & 0x01) != 0) {
			connectors.add("100Base-T4");
			linktype = 0x0006;
		}
		if ((mopt & 0x04) != 0) {
			connectors.add("100Base-FX");
			linktype = 0x0005;
		}
		if ((mopt & 0x10) != 0) {
			connectors.add("10Base-2");
			linktype = 0x0003;
		}
		if ((mopt & 0x20) != 0) {
			connectors.add("AUI");
			linktype = 0x0001;
		}
		if ((mopt & 0x40) != 0) {
			connectors.add("MII");
			linktype = 0x0006;
		}
		if ((mopt & 0xA) == 0xA) {
			connectors.add("10Base-T / 100Base-TX");
			linktype = 0x0008;
		} else if ((mopt & 0xA) == 0x2) {
			connectors.add("100Base-TX");
			linktype = 0x0008;
		} else if ((mopt & 0xA) == 0x8) {
			connectors.add("10Base-T");
			linktype = 0x0008;
		}
		
		return linktype;		
	}
	
	/**
	 * Execute a command on the NIC
	 * @param command
	 * @param param
	 */
	private final void issueCommand(int command, int param, long sleep) {
		// Calculate the complete command + param value
		final int v = (command << 11) | (param & 0x7FF);
		// Wait for the previous command to complete
		while ((getReg16(regCommandIntStatus_w) & INT_CMDINPROGRESS) != 0) {
			/* loop */
		}
		// Send the command
		setReg16(regCommandIntStatus_w, v);
		if (sleep > 0) {
			// Sleep for long commands
			try {
				Thread.sleep(sleep);
			} catch (InterruptedException ex) {
				// Ignore
			}
		}
		// Wait for the command to complete
		int loops = 0;
		while ((getReg16(regCommandIntStatus_w) & INT_CMDINPROGRESS) != 0) {
			/* loop */
			loops++;
		}
		//log.debug("Loops=" + loops + ", cmd=0x" + NumberUtils.hex(v));
	}

	/**
	 * Read data from the serial eeprom
	 * @param address
	 */
	private int readEEProm(int address) {
		/** Select correct window **/
		setWindow(winEepromBios0);

		/** Make sure the eeprom isn't busy **/
		while (((1<<15) & getReg16(regEepromCommand_0_w)) != 0) {
			/* Loop */
		}

		/** Read the value. **/
		setReg16(regEepromCommand_0_w, address + ((0x02)<<6));
		try {
			Thread.sleep(2);
		} catch (InterruptedException ex) {
			// Ignore
		}
		while (((1<<15) & getReg16(regEepromCommand_0_w)) != 0) {
			/* Loop */
		}
		
		return getReg16(regEepromData_0_w) & 0xFFFF;
	}
	
	/**
	 * Sets the current register window
	 * @param w
	 */
	private final void setWindow(int w) {
		if (reg_window != w) {
			issueCommand(cmdSelectRegisterWindow, w, 0);
			reg_window = w; 
		}
	}
	
	/**
	 * Reads a 8-bit NIC register
	 * @param reg
	 */
	/*private final int getReg8(int reg) {
		return io.inPortByte(iobase + reg);
	}*/
	
	/**
	 * Reads a 16-bit NIC register
	 * @param reg
	 */
	private final int getReg16(int reg) {
		return io.inPortWord(iobase + reg);
	}
	
	/**
	 * Reads a 32-bit NIC register
	 * @param reg
	 */
	private final int getReg32(int reg) {
		return io.inPortDword(iobase + reg);
	}
	
	/**
	 * Writes a 8-bit NIC register
	 * @param reg
	 * @param value
	 */
	private final void setReg8(int reg, int value) {
		io.outPortByte(iobase + reg, value);
	}
	/**
	 * Writes a 16-bit NIC register
	 * @param reg
	 * @param value
	 */
	private final void setReg16(int reg, int value) {
		io.outPortWord(iobase + reg, value);
	}

	/**
	 * Writes a 32-bit NIC register
	 * @param reg
	 * @param value
	 */
	private final void setReg32(int reg, int value) {
		io.outPortDword(iobase + reg, value);
	}
}

⌨️ 快捷键说明

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