Deleted Added
full compact
if_hme.c (132986) if_hme.c (133149)
1/*-
2 * Copyright (c) 1999 The NetBSD Foundation, Inc.
3 * Copyright (c) 2001-2003 Thomas Moestl <tmm@FreeBSD.org>.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Paul Kranenburg.
8 *

--- 24 unchanged lines hidden (view full) ---

33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 * from: NetBSD: hme.c,v 1.29 2002/05/05 03:02:38 thorpej Exp
38 */
39
40#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1999 The NetBSD Foundation, Inc.
3 * Copyright (c) 2001-2003 Thomas Moestl <tmm@FreeBSD.org>.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Paul Kranenburg.
8 *

--- 24 unchanged lines hidden (view full) ---

33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 *
37 * from: NetBSD: hme.c,v 1.29 2002/05/05 03:02:38 thorpej Exp
38 */
39
40#include <sys/cdefs.h>
41__FBSDID("$FreeBSD: head/sys/dev/hme/if_hme.c 132986 2004-08-01 23:58:04Z mlaier $");
41__FBSDID("$FreeBSD: head/sys/dev/hme/if_hme.c 133149 2004-08-05 02:52:33Z yongari $");
42
43/*
44 * HME Ethernet module driver.
45 *
46 * The HME is e.g. part of the PCIO PCI multi function device.
47 * It supports TX gathering and TX and RX checksum offloading.
48 * RX buffers must be aligned at a programmable offset modulo 16. We choose 2
49 * for this offset: mbuf clusters are usually on about 2^11 boundaries, 2 bytes
50 * are skipped to make sure the header after the ethernet header is aligned on a
51 * natural boundary, so this ensures minimal wastage in the most common case.
52 *
53 * Also, apparently, the buffers must extend to a DMA burst boundary beyond the
54 * maximum packet size (this is not verified). Buffers starting on odd
55 * boundaries must be mapped so that the burst can start on a natural boundary.
56 *
42
43/*
44 * HME Ethernet module driver.
45 *
46 * The HME is e.g. part of the PCIO PCI multi function device.
47 * It supports TX gathering and TX and RX checksum offloading.
48 * RX buffers must be aligned at a programmable offset modulo 16. We choose 2
49 * for this offset: mbuf clusters are usually on about 2^11 boundaries, 2 bytes
50 * are skipped to make sure the header after the ethernet header is aligned on a
51 * natural boundary, so this ensures minimal wastage in the most common case.
52 *
53 * Also, apparently, the buffers must extend to a DMA burst boundary beyond the
54 * maximum packet size (this is not verified). Buffers starting on odd
55 * boundaries must be mapped so that the burst can start on a natural boundary.
56 *
57 * Checksumming is not yet supported.
57 * STP2002QFP-UG says that Ethernet hardware supports TCP checksum offloading.
58 * In reality, we can do the same technique for UDP datagram too. However,
59 * the hardware doesn't compensate the checksum for UDP datagram which can yield
60 * to 0x0. As a safe guard, UDP checksum offload is disabled by default. It
61 * can be reactivated by setting special link option link0 with ifconfig(8).
58 */
62 */
59
63#define HME_CSUM_FEATURES (CSUM_TCP)
60#define HMEDEBUG
61#define KTR_HME KTR_CT2 /* XXX */
62
63#include <sys/param.h>
64#include <sys/systm.h>
65#include <sys/bus.h>
66#include <sys/endian.h>
67#include <sys/kernel.h>

--- 7 unchanged lines hidden (view full) ---

75#include <net/bpf.h>
76#include <net/ethernet.h>
77#include <net/if.h>
78#include <net/if_arp.h>
79#include <net/if_dl.h>
80#include <net/if_media.h>
81#include <net/if_vlan_var.h>
82
64#define HMEDEBUG
65#define KTR_HME KTR_CT2 /* XXX */
66
67#include <sys/param.h>
68#include <sys/systm.h>
69#include <sys/bus.h>
70#include <sys/endian.h>
71#include <sys/kernel.h>

--- 7 unchanged lines hidden (view full) ---

79#include <net/bpf.h>
80#include <net/ethernet.h>
81#include <net/if.h>
82#include <net/if_arp.h>
83#include <net/if_dl.h>
84#include <net/if_media.h>
85#include <net/if_vlan_var.h>
86
87#include <netinet/in.h>
88#include <netinet/in_systm.h>
89#include <netinet/ip.h>
90#include <netinet/tcp.h>
91#include <netinet/udp.h>
92
83#include <dev/mii/mii.h>
84#include <dev/mii/miivar.h>
85
86#include <machine/bus.h>
87
88#include <dev/hme/if_hmereg.h>
89#include <dev/hme/if_hmevar.h>
90

--- 10 unchanged lines hidden (view full) ---

101static void hme_mifinit(struct hme_softc *);
102static void hme_reset(struct hme_softc *);
103static void hme_setladrf(struct hme_softc *, int);
104
105static int hme_mediachange(struct ifnet *);
106static void hme_mediastatus(struct ifnet *, struct ifmediareq *);
107
108static int hme_load_txmbuf(struct hme_softc *, struct mbuf *);
93#include <dev/mii/mii.h>
94#include <dev/mii/miivar.h>
95
96#include <machine/bus.h>
97
98#include <dev/hme/if_hmereg.h>
99#include <dev/hme/if_hmevar.h>
100

--- 10 unchanged lines hidden (view full) ---

111static void hme_mifinit(struct hme_softc *);
112static void hme_reset(struct hme_softc *);
113static void hme_setladrf(struct hme_softc *, int);
114
115static int hme_mediachange(struct ifnet *);
116static void hme_mediastatus(struct ifnet *, struct ifmediareq *);
117
118static int hme_load_txmbuf(struct hme_softc *, struct mbuf *);
109static void hme_read(struct hme_softc *, int, int);
119static void hme_read(struct hme_softc *, int, int, u_int32_t);
110static void hme_eint(struct hme_softc *, u_int);
111static void hme_rint(struct hme_softc *);
112static void hme_tint(struct hme_softc *);
120static void hme_eint(struct hme_softc *, u_int);
121static void hme_rint(struct hme_softc *);
122static void hme_tint(struct hme_softc *);
123static void hme_txcksum(struct mbuf *, u_int32_t *);
124static void hme_rxcksum(struct mbuf *, u_int32_t);
113
114static void hme_cdma_callback(void *, bus_dma_segment_t *, int, int);
115static void hme_rxdma_callback(void *, bus_dma_segment_t *, int,
116 bus_size_t, int);
117static void hme_txdma_callback(void *, bus_dma_segment_t *, int,
118 bus_size_t, int);
119
120devclass_t hme_devclass;

--- 140 unchanged lines hidden (view full) ---

261 for (tdesc = 0; tdesc < HME_NTXQ; tdesc++) {
262 sc->sc_rb.rb_txdesc[tdesc].htx_m = NULL;
263 error = bus_dmamap_create(sc->sc_tdmatag, 0,
264 &sc->sc_rb.rb_txdesc[tdesc].htx_dmamap);
265 if (error != 0)
266 goto fail_txdesc;
267 }
268
125
126static void hme_cdma_callback(void *, bus_dma_segment_t *, int, int);
127static void hme_rxdma_callback(void *, bus_dma_segment_t *, int,
128 bus_size_t, int);
129static void hme_txdma_callback(void *, bus_dma_segment_t *, int,
130 bus_size_t, int);
131
132devclass_t hme_devclass;

--- 140 unchanged lines hidden (view full) ---

273 for (tdesc = 0; tdesc < HME_NTXQ; tdesc++) {
274 sc->sc_rb.rb_txdesc[tdesc].htx_m = NULL;
275 error = bus_dmamap_create(sc->sc_tdmatag, 0,
276 &sc->sc_rb.rb_txdesc[tdesc].htx_dmamap);
277 if (error != 0)
278 goto fail_txdesc;
279 }
280
281 sc->sc_csum_features = HME_CSUM_FEATURES;
269 /* Initialize ifnet structure. */
270 ifp->if_softc = sc;
271 if_initname(ifp, device_get_name(sc->sc_dev),
272 device_get_unit(sc->sc_dev));
273 ifp->if_mtu = ETHERMTU;
274 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
275 ifp->if_start = hme_start;
276 ifp->if_ioctl = hme_ioctl;

--- 36 unchanged lines hidden (view full) ---

313
314 sc->sc_phys[child->mii_inst] = child->mii_phy;
315 }
316
317 /* Attach the interface. */
318 ether_ifattach(ifp, sc->sc_arpcom.ac_enaddr);
319
320 /*
282 /* Initialize ifnet structure. */
283 ifp->if_softc = sc;
284 if_initname(ifp, device_get_name(sc->sc_dev),
285 device_get_unit(sc->sc_dev));
286 ifp->if_mtu = ETHERMTU;
287 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
288 ifp->if_start = hme_start;
289 ifp->if_ioctl = hme_ioctl;

--- 36 unchanged lines hidden (view full) ---

326
327 sc->sc_phys[child->mii_inst] = child->mii_phy;
328 }
329
330 /* Attach the interface. */
331 ether_ifattach(ifp, sc->sc_arpcom.ac_enaddr);
332
333 /*
321 * Tell the upper layer(s) we support long frames.
334 * Tell the upper layer(s) we support long frames/checksum offloads.
322 */
323 ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
335 */
336 ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
324 ifp->if_capabilities |= IFCAP_VLAN_MTU;
325 ifp->if_capenable |= IFCAP_VLAN_MTU;
337 ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_HWCSUM;
338 ifp->if_hwassist |= sc->sc_csum_features;
339 ifp->if_capenable |= IFCAP_VLAN_MTU | IFCAP_HWCSUM;
326
327 callout_init(&sc->sc_tick_ch, 0);
328 return (0);
329
330fail_txdesc:
331 for (i = 0; i < tdesc; i++) {
332 bus_dmamap_destroy(sc->sc_tdmatag,
333 sc->sc_rb.rb_txdesc[i].htx_dmamap);

--- 319 unchanged lines hidden (view full) ---

653 * and transmit/receive descriptor rings.
654 */
655static void
656hme_init(void *xsc)
657{
658 struct hme_softc *sc = (struct hme_softc *)xsc;
659 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
660 u_int8_t *ea;
340
341 callout_init(&sc->sc_tick_ch, 0);
342 return (0);
343
344fail_txdesc:
345 for (i = 0; i < tdesc; i++) {
346 bus_dmamap_destroy(sc->sc_tdmatag,
347 sc->sc_rb.rb_txdesc[i].htx_dmamap);

--- 319 unchanged lines hidden (view full) ---

667 * and transmit/receive descriptor rings.
668 */
669static void
670hme_init(void *xsc)
671{
672 struct hme_softc *sc = (struct hme_softc *)xsc;
673 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
674 u_int8_t *ea;
661 u_int32_t v;
675 u_int32_t n, v;
662
663 /*
664 * Initialization sequence. The numbered steps below correspond
665 * to the sequence outlined in section 6.3.5.1 in the Ethernet
666 * Channel Engine manual (part of the PCIO manual).
667 * See also the STP2002-STQ document from Sun Microsystems.
668 */
669

--- 67 unchanged lines hidden (view full) ---

737 break;
738 case 32:
739 v = HME_SEB_CFG_BURST32;
740 break;
741 case 64:
742 v = HME_SEB_CFG_BURST64;
743 break;
744 }
676
677 /*
678 * Initialization sequence. The numbered steps below correspond
679 * to the sequence outlined in section 6.3.5.1 in the Ethernet
680 * Channel Engine manual (part of the PCIO manual).
681 * See also the STP2002-STQ document from Sun Microsystems.
682 */
683

--- 67 unchanged lines hidden (view full) ---

751 break;
752 case 32:
753 v = HME_SEB_CFG_BURST32;
754 break;
755 case 64:
756 v = HME_SEB_CFG_BURST64;
757 break;
758 }
759 /*
760 * Blindly setting 64bit transfers may hang PCI cards(Cheerio?).
761 * Allowing 64bit transfers breaks TX checksum offload as well.
762 * Don't know this comes from hardware bug or driver's DMAing
763 * scheme.
764 *
765 * if (sc->sc_pci == 0)
766 * v |= HME_SEB_CFG_64BIT;
767 */
745 HME_SEB_WRITE_4(sc, HME_SEBI_CFG, v);
746
747 /* step 9. ETX Configuration: use mostly default values */
748
749 /* Enable DMA */
750 v = HME_ETX_READ_4(sc, HME_ETXI_CFG);
751 v |= HME_ETX_CFG_DMAENABLE;
752 HME_ETX_WRITE_4(sc, HME_ETXI_CFG, v);

--- 19 unchanged lines hidden (view full) ---

772 default:
773 printf("hme: invalid Receive Descriptor ring size\n");
774 break;
775 }
776
777 /* Enable DMA, fix RX first byte offset. */
778 v &= ~HME_ERX_CFG_FBO_MASK;
779 v |= HME_ERX_CFG_DMAENABLE | (HME_RXOFFS << HME_ERX_CFG_FBO_SHIFT);
768 HME_SEB_WRITE_4(sc, HME_SEBI_CFG, v);
769
770 /* step 9. ETX Configuration: use mostly default values */
771
772 /* Enable DMA */
773 v = HME_ETX_READ_4(sc, HME_ETXI_CFG);
774 v |= HME_ETX_CFG_DMAENABLE;
775 HME_ETX_WRITE_4(sc, HME_ETXI_CFG, v);

--- 19 unchanged lines hidden (view full) ---

795 default:
796 printf("hme: invalid Receive Descriptor ring size\n");
797 break;
798 }
799
800 /* Enable DMA, fix RX first byte offset. */
801 v &= ~HME_ERX_CFG_FBO_MASK;
802 v |= HME_ERX_CFG_DMAENABLE | (HME_RXOFFS << HME_ERX_CFG_FBO_SHIFT);
803 /* RX TCP/UDP checksum offset */
804 n = (ETHER_HDR_LEN + sizeof(struct ip)) / 2;
805 n = (n << HME_ERX_CFG_CSUMSTART_SHIFT) & HME_ERX_CFG_CSUMSTART_MASK;
806 v |= n;
780 CTR1(KTR_HME, "hme_init: programming ERX_CFG to %x", (u_int)v);
781 HME_ERX_WRITE_4(sc, HME_ERXI_CFG, v);
782
783 /* step 11. XIF Configuration */
784 v = HME_MAC_READ_4(sc, HME_MACI_XIF);
785 v |= HME_MAC_XIF_OE;
786 /* If an external transceiver is connected, enable its MII drivers */
787 if ((HME_MIF_READ_4(sc, HME_MIFI_CFG) & HME_MIF_CFG_MDI1) != 0)

--- 102 unchanged lines hidden (view full) ---

890 tdhead = (tdhead + 1) % HME_NTXDESC;
891 len += segs[i].ds_len;
892 }
893 ta->hta_sc->sc_rb.rb_tdhead = tdhead;
894 KASSERT((flags & HME_XD_EOP) != 0,
895 ("hme_txdma_callback: missed end of packet!"));
896}
897
807 CTR1(KTR_HME, "hme_init: programming ERX_CFG to %x", (u_int)v);
808 HME_ERX_WRITE_4(sc, HME_ERXI_CFG, v);
809
810 /* step 11. XIF Configuration */
811 v = HME_MAC_READ_4(sc, HME_MACI_XIF);
812 v |= HME_MAC_XIF_OE;
813 /* If an external transceiver is connected, enable its MII drivers */
814 if ((HME_MIF_READ_4(sc, HME_MIFI_CFG) & HME_MIF_CFG_MDI1) != 0)

--- 102 unchanged lines hidden (view full) ---

917 tdhead = (tdhead + 1) % HME_NTXDESC;
918 len += segs[i].ds_len;
919 }
920 ta->hta_sc->sc_rb.rb_tdhead = tdhead;
921 KASSERT((flags & HME_XD_EOP) != 0,
922 ("hme_txdma_callback: missed end of packet!"));
923}
924
925/* TX TCP/UDP checksum */
926static void
927hme_txcksum(struct mbuf *m, u_int32_t *cflags)
928{
929 struct ip *ip;
930 u_int32_t offset, offset2;
931 caddr_t p;
932
933 for(; m && m->m_len == 0; m = m->m_next)
934 ;
935 if (m == NULL || m->m_len < ETHER_HDR_LEN) {
936 printf("hme_txcksum: m_len < ETHER_HDR_LEN\n");
937 return; /* checksum will be corrupted */
938 }
939 if (m->m_len < ETHER_HDR_LEN + sizeof(u_int32_t)) {
940 if (m->m_len != ETHER_HDR_LEN) {
941 printf("hme_txcksum: m_len != ETHER_HDR_LEN\n");
942 return; /* checksum will be corrupted */
943 }
944 /* XXX */
945 for(m = m->m_next; m && m->m_len == 0; m = m->m_next)
946 ;
947 if (m == NULL)
948 return; /* checksum will be corrupted */
949 ip = mtod(m, struct ip *);
950 } else {
951 p = mtod(m, caddr_t);
952 p += ETHER_HDR_LEN;
953 ip = (struct ip *)p;
954 }
955 offset2 = m->m_pkthdr.csum_data;
956 offset = (ip->ip_hl << 2) + ETHER_HDR_LEN;
957 *cflags = offset << HME_XD_TXCKSUM_SSHIFT;
958 *cflags |= ((offset + offset2) << HME_XD_TXCKSUM_OSHIFT);
959 *cflags |= HME_XD_TXCKSUM;
960}
961
898/*
899 * Routine to dma map an mbuf chain, set up the descriptor rings accordingly and
900 * start the transmission.
901 * Returns 0 on success, -1 if there were not enough free descriptors to map
902 * the packet, or an errno otherwise.
903 */
904static int
905hme_load_txmbuf(struct hme_softc *sc, struct mbuf *m0)
906{
907 struct hme_txdma_arg cba;
908 struct hme_txdesc *td;
909 int error, si, ri;
962/*
963 * Routine to dma map an mbuf chain, set up the descriptor rings accordingly and
964 * start the transmission.
965 * Returns 0 on success, -1 if there were not enough free descriptors to map
966 * the packet, or an errno otherwise.
967 */
968static int
969hme_load_txmbuf(struct hme_softc *sc, struct mbuf *m0)
970{
971 struct hme_txdma_arg cba;
972 struct hme_txdesc *td;
973 int error, si, ri;
910 u_int32_t flags;
974 u_int32_t flags, cflags = 0;
911
912 si = sc->sc_rb.rb_tdhead;
913 if ((td = STAILQ_FIRST(&sc->sc_rb.rb_txfreeq)) == NULL)
914 return (-1);
975
976 si = sc->sc_rb.rb_tdhead;
977 if ((td = STAILQ_FIRST(&sc->sc_rb.rb_txfreeq)) == NULL)
978 return (-1);
979 if ((m0->m_pkthdr.csum_flags & sc->sc_csum_features) != 0)
980 hme_txcksum(m0, &cflags);
915 td->htx_m = m0;
916 cba.hta_sc = sc;
917 cba.hta_htx = td;
918 if ((error = bus_dmamap_load_mbuf(sc->sc_tdmatag, td->htx_dmamap,
919 m0, hme_txdma_callback, &cba, 0)) != 0)
920 goto fail;
921 if (cba.hta_ndescs == -1) {
922 error = -1;

--- 7 unchanged lines hidden (view full) ---

930
931 /* Turn descriptor ownership to the hme, back to forth. */
932 ri = sc->sc_rb.rb_tdhead;
933 CTR2(KTR_HME, "hme_load_mbuf: next desc is %d (%#x)",
934 ri, HME_XD_GETFLAGS(sc->sc_pci, sc->sc_rb.rb_txd, ri));
935 do {
936 ri = (ri + HME_NTXDESC - 1) % HME_NTXDESC;
937 flags = HME_XD_GETFLAGS(sc->sc_pci, sc->sc_rb.rb_txd, ri) |
981 td->htx_m = m0;
982 cba.hta_sc = sc;
983 cba.hta_htx = td;
984 if ((error = bus_dmamap_load_mbuf(sc->sc_tdmatag, td->htx_dmamap,
985 m0, hme_txdma_callback, &cba, 0)) != 0)
986 goto fail;
987 if (cba.hta_ndescs == -1) {
988 error = -1;

--- 7 unchanged lines hidden (view full) ---

996
997 /* Turn descriptor ownership to the hme, back to forth. */
998 ri = sc->sc_rb.rb_tdhead;
999 CTR2(KTR_HME, "hme_load_mbuf: next desc is %d (%#x)",
1000 ri, HME_XD_GETFLAGS(sc->sc_pci, sc->sc_rb.rb_txd, ri));
1001 do {
1002 ri = (ri + HME_NTXDESC - 1) % HME_NTXDESC;
1003 flags = HME_XD_GETFLAGS(sc->sc_pci, sc->sc_rb.rb_txd, ri) |
938 HME_XD_OWN;
1004 HME_XD_OWN | cflags;
939 CTR3(KTR_HME, "hme_load_mbuf: activating ri %d, si %d (%#x)",
940 ri, si, flags);
941 HME_XD_SETFLAGS(sc->sc_pci, sc->sc_rb.rb_txd, ri, flags);
942 } while (ri != si);
943
944 /* start the transmission. */
945 HME_ETX_WRITE_4(sc, HME_ETXI_PENDING, HME_ETX_TP_DMAWAKEUP);
946 return (0);
947fail:
948 bus_dmamap_unload(sc->sc_tdmatag, td->htx_dmamap);
949 return (error);
950}
951
952/*
953 * Pass a packet to the higher levels.
954 */
955static void
1005 CTR3(KTR_HME, "hme_load_mbuf: activating ri %d, si %d (%#x)",
1006 ri, si, flags);
1007 HME_XD_SETFLAGS(sc->sc_pci, sc->sc_rb.rb_txd, ri, flags);
1008 } while (ri != si);
1009
1010 /* start the transmission. */
1011 HME_ETX_WRITE_4(sc, HME_ETXI_PENDING, HME_ETX_TP_DMAWAKEUP);
1012 return (0);
1013fail:
1014 bus_dmamap_unload(sc->sc_tdmatag, td->htx_dmamap);
1015 return (error);
1016}
1017
1018/*
1019 * Pass a packet to the higher levels.
1020 */
1021static void
956hme_read(struct hme_softc *sc, int ix, int len)
1022hme_read(struct hme_softc *sc, int ix, int len, u_int32_t flags)
957{
958 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
959 struct mbuf *m;
960
961 if (len <= sizeof(struct ether_header) ||
962 len > HME_MAX_FRAMESIZE) {
963#ifdef HMEDEBUG
964 HME_WHINE(sc->sc_dev, "invalid packet size %d; dropping\n",

--- 18 unchanged lines hidden (view full) ---

983 return;
984 }
985
986 ifp->if_ipackets++;
987
988 m->m_pkthdr.rcvif = ifp;
989 m->m_pkthdr.len = m->m_len = len + HME_RXOFFS;
990 m_adj(m, HME_RXOFFS);
1023{
1024 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1025 struct mbuf *m;
1026
1027 if (len <= sizeof(struct ether_header) ||
1028 len > HME_MAX_FRAMESIZE) {
1029#ifdef HMEDEBUG
1030 HME_WHINE(sc->sc_dev, "invalid packet size %d; dropping\n",

--- 18 unchanged lines hidden (view full) ---

1049 return;
1050 }
1051
1052 ifp->if_ipackets++;
1053
1054 m->m_pkthdr.rcvif = ifp;
1055 m->m_pkthdr.len = m->m_len = len + HME_RXOFFS;
1056 m_adj(m, HME_RXOFFS);
1057 /* RX TCP/UDP checksum */
1058 if (ifp->if_capenable & IFCAP_RXCSUM)
1059 hme_rxcksum(m, flags);
991 /* Pass the packet up. */
992 (*ifp->if_input)(ifp, m);
993}
994
995static void
996hme_start(struct ifnet *ifp)
997{
998 struct hme_softc *sc = (struct hme_softc *)ifp->if_softc;

--- 106 unchanged lines hidden (view full) ---

1105
1106 hme_start(ifp);
1107
1108 if (sc->sc_rb.rb_td_nbusy == 0)
1109 ifp->if_timer = 0;
1110}
1111
1112/*
1060 /* Pass the packet up. */
1061 (*ifp->if_input)(ifp, m);
1062}
1063
1064static void
1065hme_start(struct ifnet *ifp)
1066{
1067 struct hme_softc *sc = (struct hme_softc *)ifp->if_softc;

--- 106 unchanged lines hidden (view full) ---

1174
1175 hme_start(ifp);
1176
1177 if (sc->sc_rb.rb_td_nbusy == 0)
1178 ifp->if_timer = 0;
1179}
1180
1181/*
1182 * RX TCP/UDP checksum
1183 */
1184static void
1185hme_rxcksum(struct mbuf *m, u_int32_t flags)
1186{
1187 struct ether_header *eh;
1188 struct ip *ip;
1189 struct udphdr *uh;
1190 int32_t hlen, len, pktlen;
1191 u_int16_t cksum, *opts;
1192 u_int32_t temp32;
1193
1194 pktlen = m->m_pkthdr.len;
1195 if (pktlen < sizeof(struct ether_header) + sizeof(struct ip))
1196 return;
1197 eh = mtod(m, struct ether_header *);
1198 if (eh->ether_type != htons(ETHERTYPE_IP))
1199 return;
1200 ip = (struct ip *)(eh + 1);
1201 if (ip->ip_v != IPVERSION)
1202 return;
1203
1204 hlen = ip->ip_hl << 2;
1205 pktlen -= sizeof(struct ether_header);
1206 if (hlen < sizeof(struct ip))
1207 return;
1208 if (ntohs(ip->ip_len) < hlen)
1209 return;
1210 if (ntohs(ip->ip_len) != pktlen)
1211 return;
1212 if (ip->ip_off & htons(IP_MF | IP_OFFMASK))
1213 return; /* can't handle fragmented packet */
1214
1215 switch (ip->ip_p) {
1216 case IPPROTO_TCP:
1217 if (pktlen < (hlen + sizeof(struct tcphdr)))
1218 return;
1219 break;
1220 case IPPROTO_UDP:
1221 if (pktlen < (hlen + sizeof(struct udphdr)))
1222 return;
1223 uh = (struct udphdr *)((caddr_t)ip + hlen);
1224 if (uh->uh_sum == 0)
1225 return; /* no checksum */
1226 break;
1227 default:
1228 return;
1229 }
1230
1231 cksum = ~(flags & HME_XD_RXCKSUM);
1232 /* checksum fixup for IP options */
1233 len = hlen - sizeof(struct ip);
1234 if (len > 0) {
1235 opts = (u_int16_t *)(ip + 1);
1236 for (; len > 0; len -= sizeof(u_int16_t), opts++) {
1237 temp32 = cksum - *opts;
1238 temp32 = (temp32 >> 16) + (temp32 & 65535);
1239 cksum = temp32 & 65535;
1240 }
1241 }
1242 m->m_pkthdr.csum_flags |= CSUM_DATA_VALID;
1243 m->m_pkthdr.csum_data = cksum;
1244}
1245
1246/*
1113 * Receive interrupt.
1114 */
1115static void
1116hme_rint(struct hme_softc *sc)
1117{
1118 caddr_t xdr = sc->sc_rb.rb_rxd;
1119 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1120 unsigned int ri, len;

--- 13 unchanged lines hidden (view full) ---

1134 progress++;
1135 if ((flags & HME_XD_OFL) != 0) {
1136 device_printf(sc->sc_dev, "buffer overflow, ri=%d; "
1137 "flags=0x%x\n", ri, flags);
1138 ifp->if_ierrors++;
1139 hme_discard_rxbuf(sc, ri);
1140 } else {
1141 len = HME_XD_DECODE_RSIZE(flags);
1247 * Receive interrupt.
1248 */
1249static void
1250hme_rint(struct hme_softc *sc)
1251{
1252 caddr_t xdr = sc->sc_rb.rb_rxd;
1253 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
1254 unsigned int ri, len;

--- 13 unchanged lines hidden (view full) ---

1268 progress++;
1269 if ((flags & HME_XD_OFL) != 0) {
1270 device_printf(sc->sc_dev, "buffer overflow, ri=%d; "
1271 "flags=0x%x\n", ri, flags);
1272 ifp->if_ierrors++;
1273 hme_discard_rxbuf(sc, ri);
1274 } else {
1275 len = HME_XD_DECODE_RSIZE(flags);
1142 hme_read(sc, ri, len);
1276 hme_read(sc, ri, len, flags);
1143 }
1144 }
1145 if (progress) {
1146 bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap,
1147 BUS_DMASYNC_PREWRITE);
1148 }
1149 sc->sc_rb.rb_rdtail = ri;
1150}

--- 219 unchanged lines hidden (view full) ---

1370 hme_init(sc);
1371 } else if ((ifp->if_flags & IFF_UP) != 0) {
1372 /*
1373 * Reset the interface to pick up changes in any other
1374 * flags that affect hardware registers.
1375 */
1376 hme_init(sc);
1377 }
1277 }
1278 }
1279 if (progress) {
1280 bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap,
1281 BUS_DMASYNC_PREWRITE);
1282 }
1283 sc->sc_rb.rb_rdtail = ri;
1284}

--- 219 unchanged lines hidden (view full) ---

1504 hme_init(sc);
1505 } else if ((ifp->if_flags & IFF_UP) != 0) {
1506 /*
1507 * Reset the interface to pick up changes in any other
1508 * flags that affect hardware registers.
1509 */
1510 hme_init(sc);
1511 }
1512 if ((ifp->if_flags & IFF_LINK0) != 0)
1513 sc->sc_csum_features |= CSUM_UDP;
1514 else
1515 sc->sc_csum_features &= ~CSUM_UDP;
1516 if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
1517 ifp->if_hwassist = sc->sc_csum_features;
1378#ifdef HMEDEBUG
1379 sc->sc_debug = (ifp->if_flags & IFF_DEBUG) != 0 ? 1 : 0;
1380#endif
1381 break;
1382
1383 case SIOCADDMULTI:
1384 case SIOCDELMULTI:
1385 hme_setladrf(sc, 1);
1386 error = 0;
1387 break;
1388 case SIOCGIFMEDIA:
1389 case SIOCSIFMEDIA:
1390 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii->mii_media, cmd);
1391 break;
1518#ifdef HMEDEBUG
1519 sc->sc_debug = (ifp->if_flags & IFF_DEBUG) != 0 ? 1 : 0;
1520#endif
1521 break;
1522
1523 case SIOCADDMULTI:
1524 case SIOCDELMULTI:
1525 hme_setladrf(sc, 1);
1526 error = 0;
1527 break;
1528 case SIOCGIFMEDIA:
1529 case SIOCSIFMEDIA:
1530 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii->mii_media, cmd);
1531 break;
1532 case SIOCSIFCAP:
1533 ifp->if_capenable = ifr->ifr_reqcap;
1534 if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
1535 ifp->if_hwassist = sc->sc_csum_features;
1536 else
1537 ifp->if_hwassist = 0;
1538 break;
1392 default:
1393 error = ether_ioctl(ifp, cmd, data);
1394 break;
1395 }
1396
1397 splx(s);
1398 return (error);
1399}

--- 81 unchanged lines hidden ---
1539 default:
1540 error = ether_ioctl(ifp, cmd, data);
1541 break;
1542 }
1543
1544 splx(s);
1545 return (error);
1546}

--- 81 unchanged lines hidden ---