summaryrefslogtreecommitdiff
path: root/sys/dev/gem
diff options
context:
space:
mode:
authorMarius Strobl <marius@FreeBSD.org>2005-09-14 21:23:50 +0000
committerMarius Strobl <marius@FreeBSD.org>2005-09-14 21:23:50 +0000
commitf3aa5b8c3685f8c053c98c979acf2390e15b4a5d (patch)
treef0bc960ba0c5a7e92e4b20f1dfe8cb6c224e0bcf /sys/dev/gem
parent96f922a3aa8e797284802d7d4d74138e1836a570 (diff)
Notes
Diffstat (limited to 'sys/dev/gem')
-rw-r--r--sys/dev/gem/if_gem.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/sys/dev/gem/if_gem.c b/sys/dev/gem/if_gem.c
index 36297d1b819a..b6b4de9e38b4 100644
--- a/sys/dev/gem/if_gem.c
+++ b/sys/dev/gem/if_gem.c
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
#include <net/if_dl.h>
#include <net/if_media.h>
#include <net/if_types.h>
+#include <net/if_vlan_var.h>
#include <machine/bus.h>
@@ -324,6 +325,14 @@ gem_attach(sc)
#ifdef GEM_RINT_TIMEOUT
callout_init(&sc->sc_rx_ch, 0);
#endif
+
+ /*
+ * Tell the upper layer(s) we support long frames.
+ */
+ ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
+ ifp->if_capabilities |= IFCAP_VLAN_MTU;
+ ifp->if_capenable |= IFCAP_VLAN_MTU;
+
return (0);
/*
@@ -407,6 +416,11 @@ gem_resume(sc)
{
struct ifnet *ifp = sc->sc_ifp;
+ /*
+ * On resume all registers have to be initialized again like
+ * after power-on.
+ */
+ sc->sc_inited = 0;
if (ifp->if_flags & IFF_UP)
gem_init(ifp);
}
@@ -755,7 +769,6 @@ gem_meminit(sc)
/*
* Initialize the transmit descriptor ring.
*/
- memset((void *)sc->sc_txdescs, 0, sizeof(sc->sc_txdescs));
for (i = 0; i < GEM_NTXDESC; i++) {
sc->sc_txdescs[i].gd_flags = 0;
sc->sc_txdescs[i].gd_addr = 0;
@@ -875,9 +888,6 @@ gem_init(xsc)
/* step 4. TX MAC registers & counters */
gem_init_regs(sc);
- /* XXX: VLAN code from NetBSD temporarily removed. */
- bus_space_write_4(t, h, GEM_MAC_MAC_MAX_FRAME,
- (ETHER_MAX_LEN + sizeof(struct ether_header)) | (0x2000<<16));
/* step 5. RX MAC registers & counters */
gem_setladrf(sc);
@@ -1028,7 +1038,8 @@ gem_init_regs(sc)
bus_space_write_4(t, h, GEM_MAC_MAC_MIN_FRAME, ETHER_MIN_LEN);
/* Max frame and max burst size */
bus_space_write_4(t, h, GEM_MAC_MAC_MAX_FRAME,
- ETHER_MAX_LEN | (0x2000<<16));
+ (ETHER_MAX_LEN + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN) |
+ (0x2000 << 16));
bus_space_write_4(t, h, GEM_MAC_PREAMBLE_LEN, 0x7);
bus_space_write_4(t, h, GEM_MAC_JAM_SIZE, 0x4);
@@ -1554,11 +1565,15 @@ gem_intr(v)
}
if (status & GEM_INTR_RX_MAC) {
int rxstat = bus_space_read_4(t, seb, GEM_MAC_RX_STATUS);
- if (rxstat & ~(GEM_MAC_RX_DONE | GEM_MAC_RX_FRAME_CNT))
+ /*
+ * On some chip revisions GEM_MAC_RX_OVERFLOW happen often
+ * due to a silicon bug so handle them silently.
+ */
+ if (rxstat & GEM_MAC_RX_OVERFLOW)
+ gem_init(sc);
+ else if (rxstat & ~(GEM_MAC_RX_DONE | GEM_MAC_RX_FRAME_CNT))
device_printf(sc->sc_dev, "MAC rx fault, status %x\n",
rxstat);
- if ((rxstat & GEM_MAC_RX_OVERFLOW) != 0)
- gem_init(sc);
}
}