Intel 8254x

From OSDev.wiki
Revision as of 13:12, 2 April 2013 by osdev>01000101
Jump to navigation Jump to search
This page is a work in progress.
This page may thus be incomplete. Its content may be changed in the near future.

The Intel 8254x series is comprised of: 82546GB/EB, 82545GM/EM, 82544GC/EI, 82541(PI/GI/EI), 82541ER, 82547GI/EI, and 82540EP/EM Gigabit Ethernet Controllers.

Intel 82540EM-based card

Overview

Intel 8254x-based cards come in 32-/64-bit, 33/66 MHz PCI and PCI-X flavors. The Intel 82547GI(EI) connects to the motherboard via a Communications Streaming Architecture (CSA) port instead of a PCI/PCI-X bus. The 82541xx and 82540EP/EM controllers do not support the PCI-X bus.

They are all high-performance, Gigabit-capable controllers and range from 1 to 4 ethernet/fiber ports per controller.

The Intel 8254x series heavily utilizes task offloading. Each controller has an "offloading engine" for tasks such as TCP/UDP/IP checksum calculations, packet filtering, and packet segmentation.

  • Jumbo packets are supported.
  • Wake on LAN (WoL) is supported.
  • A four wire serial EEPROM interface as well as a generic EEPROM "read" interface is implemented within the configuration registers.
  • D0 and D3 power states are supported through ACPI.

Programming

Detection

Section 5.2 in the 8254x Software Developer's Manual lists the Vendor and Device ID's of the various device in the 8254x series. These are used to detect devices on the PCI bus by looking in the PCI Configuration Space registers.

The device will also fill in the PCI Base Address Registers (BAR). BAR0 will either be a 64-bit or 32-bit MMIO address (checked by testing bits 2:1 to see if it's 00b (32-bit) or 10b (64-bit)) that points to the device's base register space. BAR0 should always be used to interface with the device via MMIO as the BAR number never changes in different devices in the series.

There is also a BAR that will contain an I/O base address, this can be detected by looking at each BAR and testing bit 1.

When using MMIO, reading/writing to/from registers is very straight-forward.

*(uint32_t *)(ioaddr + reg) = val; // writes "val" to an MMIO address
val = *(uint32_t *)(ioaddr + reg); // reads "val" from an MMIO address

When using IO, reading/writing to/from registers is a little more complicated as the IO address space for the 8254x is only 8 bytes wide. The register at offset 0x00 is the "IOADDR" window. The register at offset 0x04 is the "IODATA" window. IOADDR holds the IO address that the IODATA window operates on. So, basic operation is to set the IOADDR window and then the desired action using the IODATA window.

out32(ioaddr + 0x00, reg);  // set the IOADDR window
out32(ioaddr + 0x04, val);  // write the value to the IOADDR window which will end up in the register in IOADDR
in32(ioaddr + 0x04);        // read back the value

Emulation

  • VirtualBox (3.1 is all I can personally confirm) supports rather dodgy implementations of an Intel PRO/1000 MT Server (82545EM), Intel PRO/1000 MT Desktop (82540EM), and Intel PRO/1000 T Server (82543GC).
    • Bugs:
      • The EERD register is unimplemented (you *must* use the 4-wire access method if you want to read from the EEPROM). [01000101 - I had a patch committed to fix this. It will soon be mainstream]
  • VMWare Virtual Server 2 emulates/virtualizes an 82545EM-based card rather well.
  • QEMU (since 0.10.0) supports an 82540EM-based card and it seems to work OK. It is the default network card since 0.11.0.
    • Bugs:
      • QEMU does not properly handle the software reset operation (CTRL.RST) in builds prior to June 2009.
  • IIRC (needs confirmation) Microsoft's Hyper-V supports an 8254x-series card.

Documentation

Example driver