if_hme.c (146513) | if_hme.c (147256) |
---|---|
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 146513 2005-05-23 05:45:36Z yongari $"); | 41__FBSDID("$FreeBSD: head/sys/dev/hme/if_hme.c 147256 2005-06-10 16:49:24Z brooks $"); |
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 --- 27 unchanged lines hidden (view full) --- 77#include <sys/sockio.h> 78 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> | 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 --- 27 unchanged lines hidden (view full) --- 77#include <sys/sockio.h> 78 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_types.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 --- 7 unchanged lines hidden (view full) --- 100 101static void hme_start(struct ifnet *); 102static void hme_start_locked(struct ifnet *); 103static void hme_stop(struct hme_softc *); 104static int hme_ioctl(struct ifnet *, u_long, caddr_t); 105static void hme_tick(void *); 106static void hme_watchdog(struct ifnet *); 107static void hme_init(void *); | 86#include <net/if_vlan_var.h> 87 88#include <netinet/in.h> 89#include <netinet/in_systm.h> 90#include <netinet/ip.h> 91#include <netinet/tcp.h> 92#include <netinet/udp.h> 93 --- 7 unchanged lines hidden (view full) --- 101 102static void hme_start(struct ifnet *); 103static void hme_start_locked(struct ifnet *); 104static void hme_stop(struct hme_softc *); 105static int hme_ioctl(struct ifnet *, u_long, caddr_t); 106static void hme_tick(void *); 107static void hme_watchdog(struct ifnet *); 108static void hme_init(void *); |
108static void hme_init_locked(void *); | 109static void hme_init_locked(struct hme_softc *); |
109static int hme_add_rxbuf(struct hme_softc *, unsigned int, int); 110static int hme_meminit(struct hme_softc *); 111static int hme_mac_bitflip(struct hme_softc *, u_int32_t, u_int32_t, 112 u_int32_t, u_int32_t); 113static void hme_mifinit(struct hme_softc *); 114static void hme_reset(struct hme_softc *); 115static void hme_setladrf(struct hme_softc *, int); 116 --- 48 unchanged lines hidden (view full) --- 165} while(0) 166 167/* Support oversized VLAN frames. */ 168#define HME_MAX_FRAMESIZE (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN) 169 170int 171hme_config(struct hme_softc *sc) 172{ | 110static int hme_add_rxbuf(struct hme_softc *, unsigned int, int); 111static int hme_meminit(struct hme_softc *); 112static int hme_mac_bitflip(struct hme_softc *, u_int32_t, u_int32_t, 113 u_int32_t, u_int32_t); 114static void hme_mifinit(struct hme_softc *); 115static void hme_reset(struct hme_softc *); 116static void hme_setladrf(struct hme_softc *, int); 117 --- 48 unchanged lines hidden (view full) --- 166} while(0) 167 168/* Support oversized VLAN frames. */ 169#define HME_MAX_FRAMESIZE (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN) 170 171int 172hme_config(struct hme_softc *sc) 173{ |
173 struct ifnet *ifp = &sc->sc_arpcom.ac_if; | 174 struct ifnet *ifp; |
174 struct mii_softc *child; 175 bus_size_t size; 176 int error, rdesc, tdesc, i; 177 | 175 struct mii_softc *child; 176 bus_size_t size; 177 int error, rdesc, tdesc, i; 178 |
179 ifp = sc->sc_ifp = if_alloc(IFT_ETHER); 180 if (ifp == NULL) 181 return (ENOSPC); 182 |
|
178 /* 179 * HME common initialization. 180 * 181 * hme_softc fields that must be initialized by the front-end: 182 * 183 * the DMA bus tag: 184 * sc_dmatag 185 * --- 23 unchanged lines hidden (view full) --- 209 * so we allocate that much regardless of HME_N*DESC. 210 */ 211 size = 4096; 212 213 error = bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT, 214 BUS_SPACE_MAXADDR, NULL, NULL, size, HME_NTXDESC + HME_NRXDESC + 1, 215 BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL, &sc->sc_pdmatag); 216 if (error) | 183 /* 184 * HME common initialization. 185 * 186 * hme_softc fields that must be initialized by the front-end: 187 * 188 * the DMA bus tag: 189 * sc_dmatag 190 * --- 23 unchanged lines hidden (view full) --- 214 * so we allocate that much regardless of HME_N*DESC. 215 */ 216 size = 4096; 217 218 error = bus_dma_tag_create(NULL, 1, 0, BUS_SPACE_MAXADDR_32BIT, 219 BUS_SPACE_MAXADDR, NULL, NULL, size, HME_NTXDESC + HME_NRXDESC + 1, 220 BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL, &sc->sc_pdmatag); 221 if (error) |
217 return (error); | 222 goto fail_ifnet; |
218 219 error = bus_dma_tag_create(sc->sc_pdmatag, 2048, 0, 220 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size, 221 1, BUS_SPACE_MAXSIZE_32BIT, BUS_DMA_ALLOCNOW, busdma_lock_mutex, 222 &Giant, &sc->sc_cdmatag); 223 if (error) 224 goto fail_ptag; 225 --- 102 unchanged lines hidden (view full) --- 328 child->mii_phy, child->mii_inst); 329 continue; 330 } 331 332 sc->sc_phys[child->mii_inst] = child->mii_phy; 333 } 334 335 /* Attach the interface. */ | 223 224 error = bus_dma_tag_create(sc->sc_pdmatag, 2048, 0, 225 BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size, 226 1, BUS_SPACE_MAXSIZE_32BIT, BUS_DMA_ALLOCNOW, busdma_lock_mutex, 227 &Giant, &sc->sc_cdmatag); 228 if (error) 229 goto fail_ptag; 230 --- 102 unchanged lines hidden (view full) --- 333 child->mii_phy, child->mii_inst); 334 continue; 335 } 336 337 sc->sc_phys[child->mii_inst] = child->mii_phy; 338 } 339 340 /* Attach the interface. */ |
336 ether_ifattach(ifp, sc->sc_arpcom.ac_enaddr); | 341 ether_ifattach(ifp, sc->sc_enaddr); |
337 338 /* 339 * Tell the upper layer(s) we support long frames/checksum offloads. 340 */ 341 ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); 342 ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_HWCSUM; 343 ifp->if_hwassist |= sc->sc_csum_features; 344 ifp->if_capenable |= IFCAP_VLAN_MTU | IFCAP_HWCSUM; --- 18 unchanged lines hidden (view full) --- 363fail_ttag: 364 bus_dma_tag_destroy(sc->sc_tdmatag); 365fail_rtag: 366 bus_dma_tag_destroy(sc->sc_rdmatag); 367fail_ctag: 368 bus_dma_tag_destroy(sc->sc_cdmatag); 369fail_ptag: 370 bus_dma_tag_destroy(sc->sc_pdmatag); | 342 343 /* 344 * Tell the upper layer(s) we support long frames/checksum offloads. 345 */ 346 ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); 347 ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_HWCSUM; 348 ifp->if_hwassist |= sc->sc_csum_features; 349 ifp->if_capenable |= IFCAP_VLAN_MTU | IFCAP_HWCSUM; --- 18 unchanged lines hidden (view full) --- 368fail_ttag: 369 bus_dma_tag_destroy(sc->sc_tdmatag); 370fail_rtag: 371 bus_dma_tag_destroy(sc->sc_rdmatag); 372fail_ctag: 373 bus_dma_tag_destroy(sc->sc_cdmatag); 374fail_ptag: 375 bus_dma_tag_destroy(sc->sc_pdmatag); |
376fail_ifnet: 377 if_free(ifp); |
|
371 return (error); 372} 373 374void 375hme_detach(struct hme_softc *sc) 376{ | 378 return (error); 379} 380 381void 382hme_detach(struct hme_softc *sc) 383{ |
377 struct ifnet *ifp = &sc->sc_arpcom.ac_if; | 384 struct ifnet *ifp = sc->sc_ifp; |
378 int i; 379 380 HME_LOCK_ASSERT(sc, MA_NOTOWNED); 381 382 ether_ifdetach(ifp); | 385 int i; 386 387 HME_LOCK_ASSERT(sc, MA_NOTOWNED); 388 389 ether_ifdetach(ifp); |
390 if_free(ifp); |
|
383 HME_LOCK(sc); 384 hme_stop(sc); 385 HME_UNLOCK(sc); 386 device_delete_child(sc->sc_dev, sc->sc_miibus); 387 388 for (i = 0; i < HME_NTXQ; i++) { 389 bus_dmamap_destroy(sc->sc_tdmatag, 390 sc->sc_rb.rb_txdesc[i].htx_dmamap); --- 20 unchanged lines hidden (view full) --- 411 HME_LOCK(sc); 412 hme_stop(sc); 413 HME_UNLOCK(sc); 414} 415 416void 417hme_resume(struct hme_softc *sc) 418{ | 391 HME_LOCK(sc); 392 hme_stop(sc); 393 HME_UNLOCK(sc); 394 device_delete_child(sc->sc_dev, sc->sc_miibus); 395 396 for (i = 0; i < HME_NTXQ; i++) { 397 bus_dmamap_destroy(sc->sc_tdmatag, 398 sc->sc_rb.rb_txdesc[i].htx_dmamap); --- 20 unchanged lines hidden (view full) --- 419 HME_LOCK(sc); 420 hme_stop(sc); 421 HME_UNLOCK(sc); 422} 423 424void 425hme_resume(struct hme_softc *sc) 426{ |
419 struct ifnet *ifp = &sc->sc_arpcom.ac_if; | 427 struct ifnet *ifp = sc->sc_ifp; |
420 421 HME_LOCK(sc); 422 if ((ifp->if_flags & IFF_UP) != 0) | 428 429 HME_LOCK(sc); 430 if ((ifp->if_flags & IFF_UP) != 0) |
423 hme_init_locked(ifp); | 431 hme_init_locked(sc); |
424 HME_UNLOCK(sc); 425} 426 427static void 428hme_cdma_callback(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) 429{ 430 struct hme_softc *sc = (struct hme_softc *)xsc; 431 --- 245 unchanged lines hidden (view full) --- 677 struct hme_softc *sc = (struct hme_softc *)xsc; 678 679 HME_LOCK(sc); 680 hme_init_locked(sc); 681 HME_UNLOCK(sc); 682} 683 684static void | 432 HME_UNLOCK(sc); 433} 434 435static void 436hme_cdma_callback(void *xsc, bus_dma_segment_t *segs, int nsegs, int error) 437{ 438 struct hme_softc *sc = (struct hme_softc *)xsc; 439 --- 245 unchanged lines hidden (view full) --- 685 struct hme_softc *sc = (struct hme_softc *)xsc; 686 687 HME_LOCK(sc); 688 hme_init_locked(sc); 689 HME_UNLOCK(sc); 690} 691 692static void |
685hme_init_locked(void *xsc) | 693hme_init_locked(struct hme_softc *sc) |
686{ | 694{ |
687 struct hme_softc *sc = (struct hme_softc *)xsc; 688 struct ifnet *ifp = &sc->sc_arpcom.ac_if; | 695 struct ifnet *ifp = sc->sc_ifp; |
689 u_int8_t *ea; 690 u_int32_t n, v; 691 692 HME_LOCK_ASSERT(sc, MA_OWNED); 693 /* 694 * Initialization sequence. The numbered steps below correspond 695 * to the sequence outlined in section 6.3.5.1 in the Ethernet 696 * Channel Engine manual (part of the PCIO manual). --- 20 unchanged lines hidden (view full) --- 717 /* step 4. TX MAC registers & counters */ 718 HME_MAC_WRITE_4(sc, HME_MACI_NCCNT, 0); 719 HME_MAC_WRITE_4(sc, HME_MACI_FCCNT, 0); 720 HME_MAC_WRITE_4(sc, HME_MACI_EXCNT, 0); 721 HME_MAC_WRITE_4(sc, HME_MACI_LTCNT, 0); 722 HME_MAC_WRITE_4(sc, HME_MACI_TXSIZE, HME_MAX_FRAMESIZE); 723 724 /* Load station MAC address */ | 696 u_int8_t *ea; 697 u_int32_t n, v; 698 699 HME_LOCK_ASSERT(sc, MA_OWNED); 700 /* 701 * Initialization sequence. The numbered steps below correspond 702 * to the sequence outlined in section 6.3.5.1 in the Ethernet 703 * Channel Engine manual (part of the PCIO manual). --- 20 unchanged lines hidden (view full) --- 724 /* step 4. TX MAC registers & counters */ 725 HME_MAC_WRITE_4(sc, HME_MACI_NCCNT, 0); 726 HME_MAC_WRITE_4(sc, HME_MACI_FCCNT, 0); 727 HME_MAC_WRITE_4(sc, HME_MACI_EXCNT, 0); 728 HME_MAC_WRITE_4(sc, HME_MACI_LTCNT, 0); 729 HME_MAC_WRITE_4(sc, HME_MACI_TXSIZE, HME_MAX_FRAMESIZE); 730 731 /* Load station MAC address */ |
725 ea = sc->sc_arpcom.ac_enaddr; | 732 ea = IFP2ENADDR(sc->sc_ifp); |
726 HME_MAC_WRITE_4(sc, HME_MACI_MACADDR0, (ea[0] << 8) | ea[1]); 727 HME_MAC_WRITE_4(sc, HME_MACI_MACADDR1, (ea[2] << 8) | ea[3]); 728 HME_MAC_WRITE_4(sc, HME_MACI_MACADDR2, (ea[4] << 8) | ea[5]); 729 730 /* 731 * Init seed for backoff 732 * (source suggested by manual: low 10 bits of MAC address) 733 */ --- 302 unchanged lines hidden (view full) --- 1036} 1037 1038/* 1039 * Pass a packet to the higher levels. 1040 */ 1041static void 1042hme_read(struct hme_softc *sc, int ix, int len, u_int32_t flags) 1043{ | 733 HME_MAC_WRITE_4(sc, HME_MACI_MACADDR0, (ea[0] << 8) | ea[1]); 734 HME_MAC_WRITE_4(sc, HME_MACI_MACADDR1, (ea[2] << 8) | ea[3]); 735 HME_MAC_WRITE_4(sc, HME_MACI_MACADDR2, (ea[4] << 8) | ea[5]); 736 737 /* 738 * Init seed for backoff 739 * (source suggested by manual: low 10 bits of MAC address) 740 */ --- 302 unchanged lines hidden (view full) --- 1043} 1044 1045/* 1046 * Pass a packet to the higher levels. 1047 */ 1048static void 1049hme_read(struct hme_softc *sc, int ix, int len, u_int32_t flags) 1050{ |
1044 struct ifnet *ifp = &sc->sc_arpcom.ac_if; | 1051 struct ifnet *ifp = sc->sc_ifp; |
1045 struct mbuf *m; 1046 1047 if (len <= sizeof(struct ether_header) || 1048 len > HME_MAX_FRAMESIZE) { 1049#ifdef HMEDEBUG 1050 HME_WHINE(sc->sc_dev, "invalid packet size %d; dropping\n", 1051 len); 1052#endif --- 81 unchanged lines hidden (view full) --- 1134} 1135 1136/* 1137 * Transmit interrupt. 1138 */ 1139static void 1140hme_tint(struct hme_softc *sc) 1141{ | 1052 struct mbuf *m; 1053 1054 if (len <= sizeof(struct ether_header) || 1055 len > HME_MAX_FRAMESIZE) { 1056#ifdef HMEDEBUG 1057 HME_WHINE(sc->sc_dev, "invalid packet size %d; dropping\n", 1058 len); 1059#endif --- 81 unchanged lines hidden (view full) --- 1141} 1142 1143/* 1144 * Transmit interrupt. 1145 */ 1146static void 1147hme_tint(struct hme_softc *sc) 1148{ |
1142 struct ifnet *ifp = &sc->sc_arpcom.ac_if; | 1149 struct ifnet *ifp = sc->sc_ifp; |
1143 struct hme_txdesc *htx; 1144 unsigned int ri, txflags; 1145 1146 /* 1147 * Unload collision counters 1148 */ 1149 ifp->if_collisions += 1150 HME_MAC_READ_4(sc, HME_MACI_NCCNT) + --- 126 unchanged lines hidden (view full) --- 1277 1278/* 1279 * Receive interrupt. 1280 */ 1281static void 1282hme_rint(struct hme_softc *sc) 1283{ 1284 caddr_t xdr = sc->sc_rb.rb_rxd; | 1150 struct hme_txdesc *htx; 1151 unsigned int ri, txflags; 1152 1153 /* 1154 * Unload collision counters 1155 */ 1156 ifp->if_collisions += 1157 HME_MAC_READ_4(sc, HME_MACI_NCCNT) + --- 126 unchanged lines hidden (view full) --- 1284 1285/* 1286 * Receive interrupt. 1287 */ 1288static void 1289hme_rint(struct hme_softc *sc) 1290{ 1291 caddr_t xdr = sc->sc_rb.rb_rxd; |
1285 struct ifnet *ifp = &sc->sc_arpcom.ac_if; | 1292 struct ifnet *ifp = sc->sc_ifp; |
1286 unsigned int ri, len; 1287 int progress = 0; 1288 u_int32_t flags; 1289 1290 /* 1291 * Process all buffers with valid data. 1292 */ 1293 bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, BUS_DMASYNC_POSTREAD); --- 320 unchanged lines hidden (view full) --- 1614} 1615 1616/* 1617 * Set up the logical address filter. 1618 */ 1619static void 1620hme_setladrf(struct hme_softc *sc, int reenable) 1621{ | 1293 unsigned int ri, len; 1294 int progress = 0; 1295 u_int32_t flags; 1296 1297 /* 1298 * Process all buffers with valid data. 1299 */ 1300 bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, BUS_DMASYNC_POSTREAD); --- 320 unchanged lines hidden (view full) --- 1621} 1622 1623/* 1624 * Set up the logical address filter. 1625 */ 1626static void 1627hme_setladrf(struct hme_softc *sc, int reenable) 1628{ |
1622 struct ifnet *ifp = &sc->sc_arpcom.ac_if; | 1629 struct ifnet *ifp = sc->sc_ifp; |
1623 struct ifmultiaddr *inm; 1624 u_int32_t crc; 1625 u_int32_t hash[4]; 1626 u_int32_t macc; 1627 1628 HME_LOCK_ASSERT(sc, MA_OWNED); 1629 /* Clear hash table */ 1630 hash[3] = hash[2] = hash[1] = hash[0] = 0; --- 36 unchanged lines hidden (view full) --- 1667 /* 1668 * Set up multicast address filter by passing all multicast addresses 1669 * through a crc generator, and then using the high order 6 bits as an 1670 * index into the 64 bit logical address filter. The high order bit 1671 * selects the word, while the rest of the bits select the bit within 1672 * the word. 1673 */ 1674 | 1630 struct ifmultiaddr *inm; 1631 u_int32_t crc; 1632 u_int32_t hash[4]; 1633 u_int32_t macc; 1634 1635 HME_LOCK_ASSERT(sc, MA_OWNED); 1636 /* Clear hash table */ 1637 hash[3] = hash[2] = hash[1] = hash[0] = 0; --- 36 unchanged lines hidden (view full) --- 1674 /* 1675 * Set up multicast address filter by passing all multicast addresses 1676 * through a crc generator, and then using the high order 6 bits as an 1677 * index into the 64 bit logical address filter. The high order bit 1678 * selects the word, while the rest of the bits select the bit within 1679 * the word. 1680 */ 1681 |
1675 TAILQ_FOREACH(inm, &sc->sc_arpcom.ac_if.if_multiaddrs, ifma_link) { | 1682 TAILQ_FOREACH(inm, &sc->sc_ifp->if_multiaddrs, ifma_link) { |
1676 if (inm->ifma_addr->sa_family != AF_LINK) 1677 continue; 1678 crc = ether_crc32_le(LLADDR((struct sockaddr_dl *) 1679 inm->ifma_addr), ETHER_ADDR_LEN); 1680 1681 /* Just want the 6 most significant bits. */ 1682 crc >>= 26; 1683 --- 16 unchanged lines hidden --- | 1683 if (inm->ifma_addr->sa_family != AF_LINK) 1684 continue; 1685 crc = ether_crc32_le(LLADDR((struct sockaddr_dl *) 1686 inm->ifma_addr), ETHER_ADDR_LEN); 1687 1688 /* Just want the 6 most significant bits. */ 1689 crc >>= 26; 1690 --- 16 unchanged lines hidden --- |