diff --git a/sys/dev/tx/if_tx.c b/sys/dev/tx/if_tx.c index 93c715b3253f..f7610c713a41 100644 --- a/sys/dev/tx/if_tx.c +++ b/sys/dev/tx/if_tx.c @@ -54,6 +54,8 @@ #if defined(__FreeBSD__) #define NBPFILTER 1 +#include "vlan.h" + #include <net/if.h> #include <net/if_arp.h> #include <net/ethernet.h> @@ -61,6 +63,10 @@ #include <net/bpf.h> +#if NVLAN > 0 +#include <net/if_vlan_var.h> +#endif + #include <vm/vm.h> /* for vtophys */ #include <vm/pmap.h> /* for vtophys */ #include <machine/bus_memio.h> @@ -85,6 +91,8 @@ #else /* __OpenBSD__ */ #include "bpfilter.h" +#define NVLAN 0 /* not sure if/how OpenBSD supports VLANs */ + #include <sys/device.h> #include <net/if.h> @@ -555,6 +563,9 @@ epic_freebsd_attach(dev) /* Attach to OS's managers */ ether_ifattach(ifp, ETHER_BPF_SUPPORTED); +#if NVLAN > 0 + ifp->if_hdrlen = sizeof(struct ether_vlan_header); +#endif callout_handle_init(&sc->stat_ch); fail: @@ -642,9 +653,25 @@ epic_ifioctl(ifp, command, data) #if defined(__FreeBSD__) case SIOCSIFADDR: case SIOCGIFADDR: - case SIOCSIFMTU: error = ether_ioctl(ifp, command, data); break; + case SIOCSIFMTU: + if (ifp->if_mtu == ifr->ifr_mtu) + break; + + /* XXX Though the datasheet doesn't imply any + * limitations on RX and TX sizes beside max 64Kb + * DMA transfer, seems we can't send more then 1600 + * data bytes per ethernet packet. (Transmitter hangs + * up if more data is sent) + */ + if (ifr->ifr_mtu + ifp->if_hdrlen <= EPIC_MAX_MTU) { + ifp->if_mtu = ifr->ifr_mtu; + epic_stop(sc); + epic_init(sc); + } else + error = EINVAL; + break; #else /* __OpenBSD__ */ case SIOCSIFADDR: { struct ifaddr *ifa = (struct ifaddr *)data; @@ -1746,9 +1773,8 @@ epic_init_rings(sc) } desc->bufaddr = vtophys( mtod(buf->mbuf,caddr_t) ); - desc->buflength = ETHER_MAX_FRAME_LEN; - desc->status = 0x8000; /* Give to EPIC */ - + desc->buflength = MCLBYTES; /* Max RX buffer length */ + desc->status = 0x8000; /* Set owner bit to NIC */ } for (i = 0; i < TX_RING_SIZE; i++) { diff --git a/sys/dev/tx/if_txreg.h b/sys/dev/tx/if_txreg.h index a9ec762161fa..7a5c82b78ee6 100644 --- a/sys/dev/tx/if_txreg.h +++ b/sys/dev/tx/if_txreg.h @@ -50,6 +50,8 @@ #define RX_RING_MASK (RX_RING_SIZE - 1) #define ETHER_MAX_FRAME_LEN (ETHER_MAX_LEN + ETHER_CRC_LEN) +#define EPIC_MAX_MTU 1600 /* This is experiment-derived value */ + /* PCI aux configuration registers */ #if defined(__FreeBSD__) #define PCIR_BASEIO (PCIR_MAPS + 0x0) /* Base IO Address */ diff --git a/sys/dev/tx/if_txvar.h b/sys/dev/tx/if_txvar.h index a9ec762161fa..7a5c82b78ee6 100644 --- a/sys/dev/tx/if_txvar.h +++ b/sys/dev/tx/if_txvar.h @@ -50,6 +50,8 @@ #define RX_RING_MASK (RX_RING_SIZE - 1) #define ETHER_MAX_FRAME_LEN (ETHER_MAX_LEN + ETHER_CRC_LEN) +#define EPIC_MAX_MTU 1600 /* This is experiment-derived value */ + /* PCI aux configuration registers */ #if defined(__FreeBSD__) #define PCIR_BASEIO (PCIR_MAPS + 0x0) /* Base IO Address */ diff --git a/sys/modules/tx/Makefile b/sys/modules/tx/Makefile index c1c1dfa0c684..b9fdd6d18e64 100644 --- a/sys/modules/tx/Makefile +++ b/sys/modules/tx/Makefile @@ -4,6 +4,10 @@ KMOD= if_tx SRCS= if_tx.c opt_bdg.h device_if.h bus_if.h pci_if.h -SRCS+= miibus_if.h +SRCS+= miibus_if.h vlan.h +CLEANFILES = vlan.h + +vlan.h: + touch vlan.h .include <bsd.kmod.mk> diff --git a/sys/pci/if_tx.c b/sys/pci/if_tx.c index 93c715b3253f..f7610c713a41 100644 --- a/sys/pci/if_tx.c +++ b/sys/pci/if_tx.c @@ -54,6 +54,8 @@ #if defined(__FreeBSD__) #define NBPFILTER 1 +#include "vlan.h" + #include <net/if.h> #include <net/if_arp.h> #include <net/ethernet.h> @@ -61,6 +63,10 @@ #include <net/bpf.h> +#if NVLAN > 0 +#include <net/if_vlan_var.h> +#endif + #include <vm/vm.h> /* for vtophys */ #include <vm/pmap.h> /* for vtophys */ #include <machine/bus_memio.h> @@ -85,6 +91,8 @@ #else /* __OpenBSD__ */ #include "bpfilter.h" +#define NVLAN 0 /* not sure if/how OpenBSD supports VLANs */ + #include <sys/device.h> #include <net/if.h> @@ -555,6 +563,9 @@ epic_freebsd_attach(dev) /* Attach to OS's managers */ ether_ifattach(ifp, ETHER_BPF_SUPPORTED); +#if NVLAN > 0 + ifp->if_hdrlen = sizeof(struct ether_vlan_header); +#endif callout_handle_init(&sc->stat_ch); fail: @@ -642,9 +653,25 @@ epic_ifioctl(ifp, command, data) #if defined(__FreeBSD__) case SIOCSIFADDR: case SIOCGIFADDR: - case SIOCSIFMTU: error = ether_ioctl(ifp, command, data); break; + case SIOCSIFMTU: + if (ifp->if_mtu == ifr->ifr_mtu) + break; + + /* XXX Though the datasheet doesn't imply any + * limitations on RX and TX sizes beside max 64Kb + * DMA transfer, seems we can't send more then 1600 + * data bytes per ethernet packet. (Transmitter hangs + * up if more data is sent) + */ + if (ifr->ifr_mtu + ifp->if_hdrlen <= EPIC_MAX_MTU) { + ifp->if_mtu = ifr->ifr_mtu; + epic_stop(sc); + epic_init(sc); + } else + error = EINVAL; + break; #else /* __OpenBSD__ */ case SIOCSIFADDR: { struct ifaddr *ifa = (struct ifaddr *)data; @@ -1746,9 +1773,8 @@ epic_init_rings(sc) } desc->bufaddr = vtophys( mtod(buf->mbuf,caddr_t) ); - desc->buflength = ETHER_MAX_FRAME_LEN; - desc->status = 0x8000; /* Give to EPIC */ - + desc->buflength = MCLBYTES; /* Max RX buffer length */ + desc->status = 0x8000; /* Set owner bit to NIC */ } for (i = 0; i < TX_RING_SIZE; i++) { diff --git a/sys/pci/if_txvar.h b/sys/pci/if_txvar.h index a9ec762161fa..7a5c82b78ee6 100644 --- a/sys/pci/if_txvar.h +++ b/sys/pci/if_txvar.h @@ -50,6 +50,8 @@ #define RX_RING_MASK (RX_RING_SIZE - 1) #define ETHER_MAX_FRAME_LEN (ETHER_MAX_LEN + ETHER_CRC_LEN) +#define EPIC_MAX_MTU 1600 /* This is experiment-derived value */ + /* PCI aux configuration registers */ #if defined(__FreeBSD__) #define PCIR_BASEIO (PCIR_MAPS + 0x0) /* Base IO Address */