summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa
diff options
context:
space:
mode:
authorbrooks <brooks@FreeBSD.org>2005-06-10 16:49:24 +0000
committerbrooks <brooks@FreeBSD.org>2005-06-10 16:49:24 +0000
commit567ba9b00a248431e7c1147c4e079fd7a11b9ecf (patch)
treef65b6d7834b40dfcd48534829a0a1e9529ab87ee /sys/i386/isa
parent3eaa67c3ad947d85be5350e0e184cd6ee5b93a52 (diff)
downloadFreeBSD-src-567ba9b00a248431e7c1147c4e079fd7a11b9ecf.zip
FreeBSD-src-567ba9b00a248431e7c1147c4e079fd7a11b9ecf.tar.gz
Stop embedding struct ifnet at the top of driver softcs. Instead the
struct ifnet or the layer 2 common structure it was embedded in have been replaced with a struct ifnet pointer to be filled by a call to the new function, if_alloc(). The layer 2 common structure is also allocated via if_alloc() based on the interface type. It is hung off the new struct ifnet member, if_l2com. This change removes the size of these structures from the kernel ABI and will allow us to better manage them as interfaces come and go. Other changes of note: - Struct arpcom is no longer referenced in normal interface code. Instead the Ethernet address is accessed via the IFP2ENADDR() macro. To enforce this ac_enaddr has been renamed to _ac_enaddr. - The second argument to ether_ifattach is now always the mac address from driver private storage rather than sometimes being ac_enaddr. Reviewed by: sobomax, sam
Diffstat (limited to 'sys/i386/isa')
-rw-r--r--sys/i386/isa/if_el.c67
1 files changed, 37 insertions, 30 deletions
diff --git a/sys/i386/isa/if_el.c b/sys/i386/isa/if_el.c
index cea72ab..6ba3c0c 100644
--- a/sys/i386/isa/if_el.c
+++ b/sys/i386/isa/if_el.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <net/ethernet.h>
#include <net/if.h>
+#include <net/if_types.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
@@ -61,7 +62,8 @@ __FBSDID("$FreeBSD$");
/* el_softc: per line info and status */
struct el_softc {
- struct arpcom arpcom; /* Ethernet common */
+ struct ifnet *el_ifp;
+ u_char el_enaddr[6];
bus_space_handle_t el_bhandle;
bus_space_tag_t el_btag;
void *el_intrhand;
@@ -122,7 +124,6 @@ el_probe(device_t dev)
{
struct el_softc *sc;
u_short base; /* Just for convenience */
- u_char station_addr[ETHER_ADDR_LEN];
int i, rid;
/* Grab some info for our structure */
@@ -169,7 +170,7 @@ el_probe(device_t dev)
/* Now read the address */
for(i=0;i<ETHER_ADDR_LEN;i++) {
CSR_WRITE_1(sc,EL_GPBL,i);
- station_addr[i] = CSR_READ_1(sc,EL_EAW);
+ sc->el_enaddr[i] = CSR_READ_1(sc,EL_EAW);
}
/* Now release resources */
@@ -177,19 +178,17 @@ el_probe(device_t dev)
EL_UNLOCK(sc);
mtx_destroy(&sc->el_mtx);
- dprintf(("Address is %6D\n",station_addr, ":"));
+ dprintf(("Address is %6D\n",sc->el_enaddr, ":"));
/* If the vendor code is ok, return a 1. We'll assume that
* whoever configured this system is right about the IRQ.
*/
- if((station_addr[0] != 0x02) || (station_addr[1] != 0x60)
- || (station_addr[2] != 0x8c)) {
+ if((sc->el_enaddr[0] != 0x02) || (sc->el_enaddr[1] != 0x60)
+ || (sc->el_enaddr[2] != 0x8c)) {
dprintf(("Bad vendor code.\n"));
return(ENXIO);
} else {
dprintf(("Vendor code ok.\n"));
- /* Copy the station address into the arpcom structure */
- bcopy(station_addr,sc->arpcom.ac_enaddr,ETHER_ADDR_LEN);
}
device_set_desc(dev, "3Com 3c501 Ethernet");
@@ -214,7 +213,7 @@ el_hardreset(xsc)
* source code for this undocumented goodie...
*/
for(j=0;j<ETHER_ADDR_LEN;j++)
- CSR_WRITE_1(sc,j,sc->arpcom.ac_enaddr[j]);
+ CSR_WRITE_1(sc,j,IFP2ENADDR(sc->el_ifp)[j]);
}
/* Attach the interface to the kernel data structures. By the time
@@ -232,20 +231,26 @@ el_attach(device_t dev)
/* Get things pointing to the right places. */
sc = device_get_softc(dev);
- ifp = &sc->arpcom.ac_if;
+ ifp = sc->el_ifp = if_alloc(IFT_ETHER);
+
+ if (ifp == NULL)
+ return (ENOSPC);
rid = 0;
sc->el_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
0, ~0, EL_IOSIZ, RF_ACTIVE);
- if (sc->el_res == NULL)
+ if (sc->el_res == NULL) {
+ if_free(ifp);
return(ENXIO);
+ }
rid = 0;
sc->el_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE);
if (sc->el_irq == NULL) {
+ if_free(ifp);
bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->el_res);
return(ENXIO);
}
@@ -254,15 +259,12 @@ el_attach(device_t dev)
elintr, sc, &sc->el_intrhand);
if (error) {
+ if_free(ifp);
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->el_irq);
bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->el_res);
return(ENXIO);
}
- /* Now reset the board */
- dprintf(("Resetting board...\n"));
- el_hardreset(sc);
-
/* Initialize ifnet structure */
ifp->if_softc = sc;
if_initname(ifp, device_get_name(dev), device_get_unit(dev));
@@ -276,7 +278,11 @@ el_attach(device_t dev)
/* Now we can attach the interface */
dprintf(("Attaching interface...\n"));
- ether_ifattach(ifp, sc->arpcom.ac_enaddr);
+ ether_ifattach(ifp, sc->el_enaddr);
+
+ /* Now reset the board */
+ dprintf(("Resetting board...\n"));
+ el_hardreset(sc);
dprintf(("el_attach() finished.\n"));
return(0);
@@ -289,11 +295,12 @@ static int el_detach(dev)
struct ifnet *ifp;
sc = device_get_softc(dev);
- ifp = &sc->arpcom.ac_if;
+ ifp = sc->el_ifp;
el_stop(sc);
EL_LOCK(sc);
ether_ifdetach(ifp);
+ if_free(ifp);
bus_teardown_intr(dev, sc->el_irq, sc->el_intrhand);
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->el_irq);
bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->el_res);
@@ -346,7 +353,7 @@ el_init(xsc)
struct ifnet *ifp;
/* Set up pointers */
- ifp = &sc->arpcom.ac_if;
+ ifp = sc->el_ifp;
/* If address not known, do nothing. */
if(TAILQ_EMPTY(&ifp->if_addrhead)) /* XXX unlikely */
@@ -406,20 +413,20 @@ el_start(struct ifnet *ifp)
EL_LOCK(sc);
/* Don't do anything if output is active */
- if(sc->arpcom.ac_if.if_flags & IFF_OACTIVE)
+ if(sc->el_ifp->if_flags & IFF_OACTIVE)
return;
- sc->arpcom.ac_if.if_flags |= IFF_OACTIVE;
+ sc->el_ifp->if_flags |= IFF_OACTIVE;
/* The main loop. They warned me against endless loops, but
* would I listen? NOOO....
*/
while(1) {
/* Dequeue the next datagram */
- IF_DEQUEUE(&sc->arpcom.ac_if.if_snd,m0);
+ IF_DEQUEUE(&sc->el_ifp->if_snd,m0);
/* If there's nothing to send, return. */
if(m0 == NULL) {
- sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
+ sc->el_ifp->if_flags &= ~IFF_OACTIVE;
EL_UNLOCK(sc);
return;
}
@@ -441,7 +448,7 @@ el_start(struct ifnet *ifp)
len = max(len,ETHER_MIN_LEN);
/* Give the packet to the bpf, if any */
- BPF_TAP(&sc->arpcom.ac_if, sc->el_pktbuf, len);
+ BPF_TAP(sc->el_ifp, sc->el_pktbuf, len);
/* Transfer datagram to board */
dprintf(("el: xfr pkt length=%d...\n",len));
@@ -464,7 +471,7 @@ el_start(struct ifnet *ifp)
dprintf(("tx status=0x%x\n",i));
if(!(i & EL_TXS_READY)) {
dprintf(("el: err txs=%x\n",i));
- sc->arpcom.ac_if.if_oerrors++;
+ sc->el_ifp->if_oerrors++;
if(i & (EL_TXS_COLL|EL_TXS_COLL16)) {
if((!(i & EL_TXC_DCOLL16)) && retries < 15) {
retries++;
@@ -475,7 +482,7 @@ el_start(struct ifnet *ifp)
done = 1;
}
else {
- sc->arpcom.ac_if.if_opackets++;
+ sc->el_ifp->if_opackets++;
done = 1;
}
}
@@ -513,7 +520,7 @@ el_xmit(struct el_softc *sc,int len)
i--;
if(i == 0) {
dprintf(("tx not ready\n"));
- sc->arpcom.ac_if.if_oerrors++;
+ sc->el_ifp->if_oerrors++;
return(-1);
}
dprintf(("%d cycles.\n",(20000-i)));
@@ -524,7 +531,7 @@ el_xmit(struct el_softc *sc,int len)
static __inline void
elread(struct el_softc *sc,caddr_t buf,int len)
{
- struct ifnet *ifp = &sc->arpcom.ac_if;
+ struct ifnet *ifp = sc->el_ifp;
struct mbuf *m;
/*
@@ -574,7 +581,7 @@ elintr(void *xsc)
dprintf(("overflow.\n"));
el_hardreset(sc);
/* Put board back into receive mode */
- if(sc->arpcom.ac_if.if_flags & IFF_PROMISC)
+ if(sc->el_ifp->if_flags & IFF_PROMISC)
CSR_WRITE_1(sc,EL_RXC,
(EL_RXC_PROMISC|EL_RXC_ABROAD|
EL_RXC_AMULTI|EL_RXC_AGF|EL_RXC_DSHORT|
@@ -601,7 +608,7 @@ elintr(void *xsc)
/* If packet too short or too long, restore rx mode and return
*/
if((len <= sizeof(struct ether_header)) || (len > ETHER_MAX_LEN)) {
- if(sc->arpcom.ac_if.if_flags & IFF_PROMISC)
+ if(sc->el_ifp->if_flags & IFF_PROMISC)
CSR_WRITE_1(sc,EL_RXC,
(EL_RXC_PROMISC|EL_RXC_ABROAD|
EL_RXC_AMULTI|EL_RXC_AGF|EL_RXC_DSHORT|
@@ -619,7 +626,7 @@ elintr(void *xsc)
return;
}
- sc->arpcom.ac_if.if_ipackets++;
+ sc->el_ifp->if_ipackets++;
/* Copy the data into our buffer */
CSR_WRITE_1(sc,EL_GPBL,0);
OpenPOWER on IntegriCloud