NetBSD Documentation: Converting ancient BSD Ethernet drivers to NetBSD
Preface
With NetBSD-1.2D and later, the traditional IPv4-over-Ethernet-only ARP subsystem was modified to allow IPv4 over any hardware medium. While all NetBSD Ethernet drivers were converted, you might want to contribute a new one, based on some other BSD's code who did not yet make this change. This document outlines the steps necessary to convert your driver to NetBSD.
Naming Conventions
Throughout this document,
struct ifnet *ifp;
is a pointer to the interface structure of "our" device and
struct foo_softc *sc;
is a pointer to our softc structure.
Include Files Needed
Instead of
#include <netinet/if_ether.h>
use
#include <net/if_dl.h> /* for the LLADDR macro */ #include <net/if_ether.h> /* for real Ethernet stuff */ #include <netinet/if_inarp.h> /* for IP-specific ARP stuff. */
Sometimes you also need
#include <net/if_arp.h>
Softc Structure
-
Remove
struct arpcom
from the beginning of the softc definition. In most drivers it is calledstruct arpcom sc_ac;
or
struct arpcom sc_arpcom;
Throughout this text, we assume the former.
-
Add
struct ethercom
instead. Throughout this text, we assume you called itstruct ethercom sc_ec;
-
In all references to the multicast list, use the struct ethercom, that is replace
sc->sc_ac
bysc->sc_ec
. -
Replace all reference to
sc_ac.ac_if
bysc_ec.ec_if
.
[While you are here: I've seen lots of places, where, at the beginning of a function, a struct ifnet * parameter is converted to a struct foo_softc *, and later there are lots of sc->sc_if.bar or &sc->sc_if accesses. This is ugly, confusing and unnecessary. Depending on the nature of the driver you might want to change this while you're at it.]
Changed functions
-
arp_ifinit()
(there is a man page on this) takes astruct ifnet *
as the first parameter, instead of astruct arpcom *
.
You may have noticed by now, that you don't have a hardware address any longer in the softc.
There are two types of accesses to it. One is initialization, in the
foo_attach()
function (if this is done in the
fooprobe()/foomatch()
function,
your driver is broken for other reasons and should be fixed); the
other is runtime reads, and for less common protocols like XNS, OSI, DECnet,
even writes
-
Initialization: you call
ether_ifattach()
(there should be a man page on this) with a 2nd parameter, au_int8_t *
pointing to the address.ether_ifattach()
will create (as before) astruct sockaddr_dl
in the interface address list, copy (among other initialization) the address there, and makesifp->if_sadl
point to it. -
Run-time: use
LLADDR(ifp->if_sadl)
as a caddr_t pointing to our Ethernet address. If you need the address length, you should probably useETHER_ADDR_LEN
.
Back to NetBSD Documentation: Kernel