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 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> |
85#include <net/if_types.h> |
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 *); |
109static void hme_init_locked(struct hme_softc *); |
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{ |
174 struct ifnet *ifp; |
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 |
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) |
222 goto fail_ifnet; |
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. */ |
341 ether_ifattach(ifp, sc->sc_enaddr); |
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); |
378 return (error); 379} 380 381void 382hme_detach(struct hme_softc *sc) 383{ |
384 struct ifnet *ifp = sc->sc_ifp; |
385 int i; 386 387 HME_LOCK_ASSERT(sc, MA_NOTOWNED); 388 389 ether_ifdetach(ifp); |
390 if_free(ifp); |
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{ |
427 struct ifnet *ifp = sc->sc_ifp; |
428 429 HME_LOCK(sc); 430 if ((ifp->if_flags & IFF_UP) != 0) |
431 hme_init_locked(sc); |
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 |
693hme_init_locked(struct hme_softc *sc) |
694{ |
695 struct ifnet *ifp = sc->sc_ifp; |
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 */ |
732 ea = IFP2ENADDR(sc->sc_ifp); |
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{ |
1051 struct ifnet *ifp = sc->sc_ifp; |
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{ |
1149 struct ifnet *ifp = sc->sc_ifp; |
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; |
1292 struct ifnet *ifp = sc->sc_ifp; |
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{ |
1629 struct ifnet *ifp = sc->sc_ifp; |
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 |
1682 TAILQ_FOREACH(inm, &sc->sc_ifp->if_multiaddrs, ifma_link) { |
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 --- |