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 --- |