summaryrefslogtreecommitdiffstats
path: root/sys/dev/lnc
diff options
context:
space:
mode:
authorpaul <paul@FreeBSD.org>1995-02-02 04:07:45 +0000
committerpaul <paul@FreeBSD.org>1995-02-02 04:07:45 +0000
commit64b42948cbf0201fb76eb3e0f34cb3af72ba42a3 (patch)
treef126ae652cfc9b9ec3e6781d749db1c9c3a26d02 /sys/dev/lnc
parent7b026c1466277b9ee6b44a4e8d0e8f4dd96bba07 (diff)
downloadFreeBSD-src-64b42948cbf0201fb76eb3e0f34cb3af72ba42a3.zip
FreeBSD-src-64b42948cbf0201fb76eb3e0f34cb3af72ba42a3.tar.gz
Fixed problem passing received packets to bpf.
Implemented all the devconf code properly.
Diffstat (limited to 'sys/dev/lnc')
-rw-r--r--sys/dev/lnc/if_lnc.c127
1 files changed, 94 insertions, 33 deletions
diff --git a/sys/dev/lnc/if_lnc.c b/sys/dev/lnc/if_lnc.c
index 3f024e7..b482f5f 100644
--- a/sys/dev/lnc/if_lnc.c
+++ b/sys/dev/lnc/if_lnc.c
@@ -117,6 +117,7 @@ struct lnc_softc {
int initialised;
int rap;
int rdp;
+ struct kern_devconf kdc;
#ifdef DEBUG
int lnc_debug;
#endif
@@ -137,6 +138,16 @@ void lnc_dump_state(int);
struct isa_driver lncdriver = {lnc_probe, lnc_attach, "lnc"};
+static struct kern_devconf kdc_lnc = {
+ 0, 0, 0, /* filled in by dev_attach */
+ "lnc", 0, { MDDT_ISA, 0, "net" },
+ isa_generic_externalize, 0, 0, ISA_EXTERNALLEN,
+ &kdc_isa0, /* parent */
+ 0, /* parentdata */
+ DC_UNCONFIGURED,
+ ""
+};
+
inline void
write_csr(int unit, u_short port, u_short val)
{
@@ -151,6 +162,51 @@ read_csr(int unit, u_short port)
return (inw(lnc_softc[unit].rdp));
}
+static inline void
+lnc_registerdev(struct isa_device *isa_dev)
+{
+ struct lnc_softc *sc = &lnc_softc[isa_dev->id_unit];
+ struct kern_devconf *kdc = &sc->kdc;
+ *kdc = kdc_lnc;
+ kdc->kdc_unit = isa_dev->id_unit;
+ kdc->kdc_parentdata = isa_dev;
+
+ switch(sc->nic.ic) {
+ case LANCE:
+ if (sc->nic.ident == BICC)
+ kdc->kdc_description = "BICC (LANCE) Ethernet controller";
+ else if (sc->nic.ident == NE2100)
+ kdc->kdc_description = "NE2100 (LANCE) Ethernet controller";
+ else if (sc->nic.ident == DEPCA)
+ kdc->kdc_description = "DEPCA (LANCE) Ethernet controller";
+ break;
+ case C_LANCE:
+ if (sc->nic.ident == BICC)
+ kdc->kdc_description = "BICC (C-LANCE) Ethernet controller";
+ else if (sc->nic.ident == NE2100)
+ kdc->kdc_description = "NE2100 (C-LANCE) Ethernet controller";
+ else if (sc->nic.ident == DEPCA)
+ kdc->kdc_description = "DEPCA (C-LANCE) Ethernet controller";
+ break;
+ case PCnet_ISA:
+ kdc->kdc_description = "PCnet-ISA Ethernet controller";
+ break;
+ case PCnet_ISAplus:
+ kdc->kdc_description = "PCnet-ISA+ Ethernet controller";
+ break;
+ case PCnet_32:
+ kdc->kdc_description = "PCnet-32 VL-Bus Ethernet controller";
+ break;
+ case PCnet_PCI:
+ kdc->kdc_description = "PCnet-PCI Ethernet controller";
+ break;
+ default:
+ break;
+ }
+
+ dev_attach(kdc);
+}
+
void
lnc_setladrf(struct ifnet *ifp, struct lnc_softc *sc)
@@ -475,27 +531,37 @@ lnc_rint(int unit)
* ethernet and packet headers
*/
head->m_pkthdr.rcvif = &sc->arpcom.ac_if;
- head->m_pkthdr.len = pkt_len - sizeof(*eh);
+ head->m_pkthdr.len = pkt_len - sizeof *eh;
+
+ /*
+ * BPF expects the ether header to be in the first
+ * mbuf of the chain so point eh at the right place
+ * but don't increment the mbuf pointers before
+ * the bpf tap.
+ */
+
eh = (struct ether_header *) head->m_data;
- head->m_data += sizeof *eh;
- head->m_len -= sizeof *eh;
#if NBPFILTER > 0
if (sc->bpf)
bpf_mtap(sc->bpf, head);
/* Check this packet is really for us */
- /* XXX -- this doesn't look right */
if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) &&
+ !(eh->ether_dhost[0] & 1) && /* Broadcast and multicast */
(bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
- sizeof(eh->ether_dhost)) != 0) &&
- (bcmp(eh->ether_dhost, etherbroadcastaddr,
- sizeof(eh->ether_dhost)) != 0))
+ sizeof(eh->ether_dhost))))
m_freem(head);
else
#endif
- ether_input(&sc->arpcom.ac_if, eh, head);
+ {
+ /* Skip over the ether header */
+ head->m_data += sizeof *eh;
+ head->m_len -= sizeof *eh;
+
+ ether_input(&sc->arpcom.ac_if, eh, head);
+ }
} else {
log(LOG_ERR,"lnc%d: Packet dropped, no mbufs\n",unit);
@@ -750,26 +816,6 @@ lnc_tint(int unit)
}
-static struct kern_devconf kdc_lnc[NLNC] = { {
- 0, 0, 0, /* filled in by dev_attach */
- "lnc", 0, { MDDT_ISA, 0, "net" },
- isa_generic_externalize, 0, 0, ISA_EXTERNALLEN,
- &kdc_isa0, /* parent */
- 0, /* parentdata */
- DC_BUSY,
- "Generic LANCE-based Ethernet adapter"
-} };
-
-static inline void
-lnc_registerdev(struct isa_device *id)
-{
- if(id->id_unit)
- kdc_lnc[id->id_unit] = kdc_lnc[0];
- kdc_lnc[id->id_unit].kdc_unit = id->id_unit;
- kdc_lnc[id->id_unit].kdc_isa = id;
- dev_attach(&kdc_lnc[id->id_unit]);
-}
-
int
lnc_probe(struct isa_device * isa_dev)
{
@@ -781,6 +827,7 @@ int vsw;
printf("Vendor Specific Word = %x\n", vsw);
#endif
+
if (nports = bicc_probe(isa_dev))
return (nports);
if (nports = ne2100_probe(isa_dev))
@@ -788,6 +835,12 @@ int vsw;
if (nports = depca_probe(isa_dev))
return (nports);
+ /*
+ * Register device even though probe has
+ * failed so it can be reconfigured later.
+ */
+
+ lnc_registerdev(isa_dev);
return (0);
}
@@ -811,7 +864,7 @@ ne2100_probe(struct isa_device * isa_dev)
/* Extract MAC address from PROM */
for (i = 0; i < ETHER_ADDR_LEN; i++)
sc->arpcom.ac_enaddr[i] = inb(isa_dev->id_iobase + i);
-
+ lnc_registerdev(isa_dev);
return (NE2100_IOSIZE);
} else {
return (0);
@@ -847,6 +900,8 @@ int i;
/* Extract MAC address from PROM */
for (i = 0; i < ETHER_ADDR_LEN; i++)
sc->arpcom.ac_enaddr[i] = inb(isa_dev->id_iobase + (i * 2));
+
+ lnc_registerdev(isa_dev);
return (BICC_IOSIZE);
} else {
return (0);
@@ -902,8 +957,10 @@ depca_probe(struct isa_device * isa_dev)
/* Extract MAC address from PROM */
for (i = 0; i < DEPCA_ADDR_ROM_SIZE; i++)
maddr_ring[i] = inb(isa_dev->id_iobase + DEPCA_ADP);
- if (dec_macaddr_extract(maddr_ring, sc))
+ if (dec_macaddr_extract(maddr_ring, sc)) {
+ lnc_registerdev(isa_dev);
return (DEPCA_IOSIZE);
+ }
}
return (0);
}
@@ -1037,11 +1094,11 @@ lnc_attach(struct isa_device * isa_dev)
*/
if_attach(&sc->arpcom.ac_if);
+ sc->kdc.kdc_state = DC_IDLE;
- printf("lnc%d: %s, %s address %s\n",
+ printf("lnc%d: %s, address %s\n",
isa_dev->id_unit,
- nic_ident[sc->nic.ident],
- ic_ident[sc->nic.ic],
+ sc->kdc.kdc_description,
ether_sprintf(sc->arpcom.ac_enaddr));
#if NBPFILTER > 0
@@ -1523,6 +1580,8 @@ lnc_ioctl(struct ifnet * ifp, int command, caddr_t data)
switch (command) {
case SIOCSIFADDR:
ifp->if_flags |= IFF_UP;
+ sc->kdc.kdc_state = DC_BUSY;
+
switch (ifa->ifa_addr->sa_family) {
#ifdef INET
case AF_INET:
@@ -1568,6 +1627,8 @@ lnc_ioctl(struct ifnet * ifp, int command, caddr_t data)
*/
lnc_init(ifp->if_unit);
}
+ sc->kdc.kdc_state =
+ ((ifp->if_flags & IFF_UP) ? DC_BUSY : DC_IDLE);
break;
#ifdef notyet
case SIOCADDMULTI:
OpenPOWER on IntegriCloud