Deleted Added
full compact
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>
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 *);
108static void hme_init_locked(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{
173 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
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)
217 return (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. */
336 ether_ifattach(ifp, sc->sc_arpcom.ac_enaddr);
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{
377 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
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{
419 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
427 struct ifnet *ifp = sc->sc_ifp;
428
429 HME_LOCK(sc);
430 if ((ifp->if_flags & IFF_UP) != 0)
423 hme_init_locked(ifp);
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
685hme_init_locked(void *xsc)
693hme_init_locked(struct hme_softc *sc)
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;
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);
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;
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;
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;
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;
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) {
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 ---