Deleted Added
full compact
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 ---