A quick and dirty summary: miibus

(Robert Watson and Warner Losh)

The IEEE 802.3 standard defines a separation of function within any network attached device. The simplest of these separations was introduced for the 100Base standards. Among other things, it defined a standard connection and protocol between a MAC (a computer device that produced and consumed packets) and a PHY (a chip that converted the digital packet streams into some encoded analog network media such as 10BaseT, 100BaseTx, etc). The connection between these two layers is named MII. Later versions of the standard defined other classes of connection. Gigabit Ethernet added GMII. 10G Ethernet added XAUI. For the purpose of this document, MII will refer to all of these technologies.

The Media Independent Interface (MII) layer defines a standard interface connecting network interface MACs with PHYs. It defines a protocol to represent information about the device regarding device capabilities, link status, identity etc. MII is a simple bus protocol driven by the MAC, but exposed via PCI (or similar) to the OS device driver.

Several devices (typically PHYs) may be present on an MII bus, each addressed using a 5-bit device ID. Further, each device can expose several registers, which may be set or retrieved, identified by a 5-bit register IDs. This allows addressing requests to specific devices, as well as enumerating devices through standard interpretations of registers. On a boring NIC, you might have a single MAC hooked up to one PHY (a 10Mbps/100Mbps/1Gbps RJ-45 UTP port) via MII, but on an embedded board, multiply PHYs might appear on the same MII bus, each with its own address.

Because MII and friends exist in most (all) network interface devices, and is functionally extremely similar across devices, FreeBSD provides an abstraction, miibus(4), used by most device drivers. Device drivers implement MII register read and write methods on their device_t, mapping operations into device driver-specific I/O, such as PCI reads and writes. As PHYs vary, different PHY drivers may attach, based on its OUI returned during enumeration. Device drivers can then map network ioctls, such as media requests, into MII operations, which miibus(4) will arrange to be handled appropriately.

Simplified world view: MAC, MII, and PHY

The world of NICs (Network Interface Controllers) is full of sometimes ambiguously used terminology; for our purposes, a MAC (Media Access Controller) is, effectively, the logic implementing an ethernet network interface, and the PHY is the physical component implementing the network physical layer. They are linked by several communication channels, including MII data, MII clock, as well as data send and receive channels carrying network data.

                 +-------+       MII           +-------+
                 |       | === MII DATA ====== |       |
                 |       | === MII CLOCK ===== |       |
 ... === PCI === |  MAC  |                     |  PHY  | === (real fibre and copper and stuff) ...
                 |       | === DATA RECEIVE == |       |
                 |       | === DATA SEND ===== |       |
                 +-------+                     +-------+

Simplified world view: MII communication traces

Typical MII communications register read:

   T     NIC                                       PHY
   i         --- start read/write --------------->
   m         --- 5-bit device, 5-bit register --->
   e         <-- 16-bits of register data -------

Typical MII communications register write:

   T     NIC                                       PHY
   i         --- start read/write --------------->
   m         --- 5-bit device, 5-bit register --->
   e         --- 16-bits of register data ------->

Useful constants may be found in http://fxr.watson.org/fxr/source/dev/mii/mii.h.

A list of MII device OUIs may be found in http://fxr.watson.org/fxr/source/dev/mii/miidevs.

Device drivers

In FreeBSD, device drivers indicate that they support MII by implementing device_t methods for reading and writing registers. The MII device methods are defined in http://fxr.watson.org/fxr/source/dev/mii/miibus_if.m.

         DEVMETHOD(miibus_readreg,       foo_miibus_readreg),
         DEVMETHOD(miibus_writereg,      foo_miibus_writereg),

In this case, the device driver implements two functions, foo_miibus_readreg and foo_miibus_writereg, providing device-specific methods for accessing the device's MII bus. For example, for a PCI-connected device, these might generate PCI read and write operations.

In addition, a device driver might want to override certain default methods, such as link state change, that involve more complex NIC/driver logic:

         DEVMETHOD(miibus_statchg,       vr_miibus_statchg),

Finally, the device driver itself may need to use this MII information, such as when implementing the ifmedia ioctl()'s that allow the network stack to query link state and configuration. For example, this code comes from the if_vr driver:

 * Report current media status.
static void
vr_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
        struct vr_softc         *sc;
        struct mii_data         *mii;
        sc = ifp->if_softc;
        mii = device_get_softc(sc->vr_miibus);
        ifmr->ifm_active = mii->mii_media_active;
        ifmr->ifm_status = mii->mii_media_status;

More information

Further information may be found in IEEE 802.3, and on Wikipedia: http://en.wikipedia.org/wiki/Media_Independent_Interface.

The miibus(4) man page is the authoritative reference on the API.

The IEEE 802.3 standard has good information about this. Here's the download page: http://standards.ieee.org/getieee802/802.3.html.

MIIBUS (last edited 2010-03-14T04:06:40+0000 by WarnerLosh)