2002-02-27 17:35:48 +00:00
|
|
|
/*-
|
|
|
|
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
2003-01-06 22:12:57 +00:00
|
|
|
* Copyright (c) 2001-2003 Thomas Moestl <tmm@FreeBSD.org>.
|
2002-02-27 17:35:48 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This code is derived from software contributed to The NetBSD Foundation
|
|
|
|
* by Paul Kranenburg.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
* This product includes software developed by the NetBSD
|
|
|
|
* Foundation, Inc. and its contributors.
|
|
|
|
* 4. Neither the name of The NetBSD Foundation nor the names of its
|
|
|
|
* contributors may be used to endorse or promote products derived
|
|
|
|
* from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
|
|
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
|
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
* from: NetBSD: hme.c,v 1.45 2005/02/18 00:22:11 heas Exp
|
2002-02-27 17:35:48 +00:00
|
|
|
*/
|
|
|
|
|
2003-08-24 17:55:58 +00:00
|
|
|
#include <sys/cdefs.h>
|
|
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
/*
|
|
|
|
* HME Ethernet module driver.
|
|
|
|
*
|
|
|
|
* The HME is e.g. part of the PCIO PCI multi function device.
|
|
|
|
* It supports TX gathering and TX and RX checksum offloading.
|
|
|
|
* RX buffers must be aligned at a programmable offset modulo 16. We choose 2
|
|
|
|
* for this offset: mbuf clusters are usually on about 2^11 boundaries, 2 bytes
|
|
|
|
* are skipped to make sure the header after the ethernet header is aligned on a
|
|
|
|
* natural boundary, so this ensures minimal wastage in the most common case.
|
|
|
|
*
|
|
|
|
* Also, apparently, the buffers must extend to a DMA burst boundary beyond the
|
|
|
|
* maximum packet size (this is not verified). Buffers starting on odd
|
|
|
|
* boundaries must be mapped so that the burst can start on a natural boundary.
|
|
|
|
*
|
2004-08-05 02:52:33 +00:00
|
|
|
* STP2002QFP-UG says that Ethernet hardware supports TCP checksum offloading.
|
|
|
|
* In reality, we can do the same technique for UDP datagram too. However,
|
|
|
|
* the hardware doesn't compensate the checksum for UDP datagram which can yield
|
|
|
|
* to 0x0. As a safe guard, UDP checksum offload is disabled by default. It
|
|
|
|
* can be reactivated by setting special link option link0 with ifconfig(8).
|
2002-02-27 17:35:48 +00:00
|
|
|
*/
|
2004-08-05 02:52:33 +00:00
|
|
|
#define HME_CSUM_FEATURES (CSUM_TCP)
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
#if 0
|
2002-02-27 17:35:48 +00:00
|
|
|
#define HMEDEBUG
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
#endif
|
2010-07-21 10:05:07 +00:00
|
|
|
#define KTR_HME KTR_SPARE2 /* XXX */
|
2002-02-27 17:35:48 +00:00
|
|
|
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/systm.h>
|
|
|
|
#include <sys/bus.h>
|
2002-04-26 22:48:23 +00:00
|
|
|
#include <sys/endian.h>
|
2002-02-27 17:35:48 +00:00
|
|
|
#include <sys/kernel.h>
|
2004-06-03 06:10:02 +00:00
|
|
|
#include <sys/module.h>
|
2002-02-27 17:35:48 +00:00
|
|
|
#include <sys/ktr.h>
|
|
|
|
#include <sys/mbuf.h>
|
|
|
|
#include <sys/malloc.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <sys/sockio.h>
|
|
|
|
|
2002-07-30 21:47:14 +00:00
|
|
|
#include <net/bpf.h>
|
2002-02-27 17:35:48 +00:00
|
|
|
#include <net/ethernet.h>
|
|
|
|
#include <net/if.h>
|
2013-10-26 17:58:36 +00:00
|
|
|
#include <net/if_var.h>
|
2002-02-27 17:35:48 +00:00
|
|
|
#include <net/if_arp.h>
|
|
|
|
#include <net/if_dl.h>
|
|
|
|
#include <net/if_media.h>
|
2005-06-10 16:49:24 +00:00
|
|
|
#include <net/if_types.h>
|
2004-05-06 13:38:19 +00:00
|
|
|
#include <net/if_vlan_var.h>
|
2002-02-27 17:35:48 +00:00
|
|
|
|
2004-08-05 02:52:33 +00:00
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <netinet/in_systm.h>
|
|
|
|
#include <netinet/ip.h>
|
|
|
|
#include <netinet/tcp.h>
|
|
|
|
#include <netinet/udp.h>
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
#include <dev/mii/mii.h>
|
|
|
|
#include <dev/mii/miivar.h>
|
|
|
|
|
|
|
|
#include <machine/bus.h>
|
|
|
|
|
2003-08-23 05:51:03 +00:00
|
|
|
#include <dev/hme/if_hmereg.h>
|
|
|
|
#include <dev/hme/if_hmevar.h>
|
2002-02-27 17:35:48 +00:00
|
|
|
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
CTASSERT(powerof2(HME_NRXDESC) && HME_NRXDESC >= 32 && HME_NRXDESC <= 256);
|
|
|
|
CTASSERT(HME_NTXDESC % 16 == 0 && HME_NTXDESC >= 16 && HME_NTXDESC <= 256);
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
static void hme_start(struct ifnet *);
|
2004-11-22 06:46:30 +00:00
|
|
|
static void hme_start_locked(struct ifnet *);
|
2002-02-27 17:35:48 +00:00
|
|
|
static void hme_stop(struct hme_softc *);
|
|
|
|
static int hme_ioctl(struct ifnet *, u_long, caddr_t);
|
|
|
|
static void hme_tick(void *);
|
2006-12-06 02:07:20 +00:00
|
|
|
static int hme_watchdog(struct hme_softc *);
|
2002-02-27 17:35:48 +00:00
|
|
|
static void hme_init(void *);
|
2005-06-10 16:49:24 +00:00
|
|
|
static void hme_init_locked(struct hme_softc *);
|
2002-02-27 17:35:48 +00:00
|
|
|
static int hme_add_rxbuf(struct hme_softc *, unsigned int, int);
|
|
|
|
static int hme_meminit(struct hme_softc *);
|
|
|
|
static int hme_mac_bitflip(struct hme_softc *, u_int32_t, u_int32_t,
|
|
|
|
u_int32_t, u_int32_t);
|
|
|
|
static void hme_mifinit(struct hme_softc *);
|
|
|
|
static void hme_setladrf(struct hme_softc *, int);
|
|
|
|
|
|
|
|
static int hme_mediachange(struct ifnet *);
|
2006-12-04 00:51:08 +00:00
|
|
|
static int hme_mediachange_locked(struct hme_softc *);
|
2002-02-27 17:35:48 +00:00
|
|
|
static void hme_mediastatus(struct ifnet *, struct ifmediareq *);
|
|
|
|
|
2005-10-25 03:56:21 +00:00
|
|
|
static int hme_load_txmbuf(struct hme_softc *, struct mbuf **);
|
2004-08-05 02:52:33 +00:00
|
|
|
static void hme_read(struct hme_softc *, int, int, u_int32_t);
|
2002-02-27 17:35:48 +00:00
|
|
|
static void hme_eint(struct hme_softc *, u_int);
|
|
|
|
static void hme_rint(struct hme_softc *);
|
|
|
|
static void hme_tint(struct hme_softc *);
|
2004-08-05 02:52:33 +00:00
|
|
|
static void hme_rxcksum(struct mbuf *, u_int32_t);
|
2002-02-27 17:35:48 +00:00
|
|
|
|
|
|
|
static void hme_cdma_callback(void *, bus_dma_segment_t *, int, int);
|
|
|
|
|
|
|
|
devclass_t hme_devclass;
|
|
|
|
|
|
|
|
static int hme_nerr;
|
|
|
|
|
|
|
|
DRIVER_MODULE(miibus, hme, miibus_driver, miibus_devclass, 0, 0);
|
2003-01-08 18:53:38 +00:00
|
|
|
MODULE_DEPEND(hme, miibus, 1, 1, 1);
|
2002-02-27 17:35:48 +00:00
|
|
|
|
|
|
|
#define HME_SPC_READ_4(spc, sc, offs) \
|
|
|
|
bus_space_read_4((sc)->sc_ ## spc ## t, (sc)->sc_ ## spc ## h, \
|
2004-08-12 20:37:02 +00:00
|
|
|
(offs))
|
2002-02-27 17:35:48 +00:00
|
|
|
#define HME_SPC_WRITE_4(spc, sc, offs, v) \
|
|
|
|
bus_space_write_4((sc)->sc_ ## spc ## t, (sc)->sc_ ## spc ## h, \
|
2004-08-12 20:37:02 +00:00
|
|
|
(offs), (v))
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
#define HME_SPC_BARRIER(spc, sc, offs, l, f) \
|
|
|
|
bus_space_barrier((sc)->sc_ ## spc ## t, (sc)->sc_ ## spc ## h, \
|
|
|
|
(offs), (l), (f))
|
2002-02-27 17:35:48 +00:00
|
|
|
|
|
|
|
#define HME_SEB_READ_4(sc, offs) HME_SPC_READ_4(seb, (sc), (offs))
|
|
|
|
#define HME_SEB_WRITE_4(sc, offs, v) HME_SPC_WRITE_4(seb, (sc), (offs), (v))
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
#define HME_SEB_BARRIER(sc, offs, l, f) \
|
|
|
|
HME_SPC_BARRIER(seb, (sc), (offs), (l), (f))
|
2002-02-27 17:35:48 +00:00
|
|
|
#define HME_ERX_READ_4(sc, offs) HME_SPC_READ_4(erx, (sc), (offs))
|
|
|
|
#define HME_ERX_WRITE_4(sc, offs, v) HME_SPC_WRITE_4(erx, (sc), (offs), (v))
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
#define HME_ERX_BARRIER(sc, offs, l, f) \
|
|
|
|
HME_SPC_BARRIER(erx, (sc), (offs), (l), (f))
|
2002-02-27 17:35:48 +00:00
|
|
|
#define HME_ETX_READ_4(sc, offs) HME_SPC_READ_4(etx, (sc), (offs))
|
|
|
|
#define HME_ETX_WRITE_4(sc, offs, v) HME_SPC_WRITE_4(etx, (sc), (offs), (v))
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
#define HME_ETX_BARRIER(sc, offs, l, f) \
|
|
|
|
HME_SPC_BARRIER(etx, (sc), (offs), (l), (f))
|
2002-02-27 17:35:48 +00:00
|
|
|
#define HME_MAC_READ_4(sc, offs) HME_SPC_READ_4(mac, (sc), (offs))
|
|
|
|
#define HME_MAC_WRITE_4(sc, offs, v) HME_SPC_WRITE_4(mac, (sc), (offs), (v))
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
#define HME_MAC_BARRIER(sc, offs, l, f) \
|
|
|
|
HME_SPC_BARRIER(mac, (sc), (offs), (l), (f))
|
2002-02-27 17:35:48 +00:00
|
|
|
#define HME_MIF_READ_4(sc, offs) HME_SPC_READ_4(mif, (sc), (offs))
|
|
|
|
#define HME_MIF_WRITE_4(sc, offs, v) HME_SPC_WRITE_4(mif, (sc), (offs), (v))
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
#define HME_MIF_BARRIER(sc, offs, l, f) \
|
|
|
|
HME_SPC_BARRIER(mif, (sc), (offs), (l), (f))
|
2002-02-27 17:35:48 +00:00
|
|
|
|
|
|
|
#define HME_MAXERR 5
|
|
|
|
#define HME_WHINE(dev, ...) do { \
|
|
|
|
if (hme_nerr++ < HME_MAXERR) \
|
|
|
|
device_printf(dev, __VA_ARGS__); \
|
|
|
|
if (hme_nerr == HME_MAXERR) { \
|
2006-05-27 09:28:59 +00:00
|
|
|
device_printf(dev, "too many errors; not reporting " \
|
|
|
|
"any more\n"); \
|
2002-02-27 17:35:48 +00:00
|
|
|
} \
|
|
|
|
} while(0)
|
|
|
|
|
2004-05-06 13:38:19 +00:00
|
|
|
/* Support oversized VLAN frames. */
|
|
|
|
#define HME_MAX_FRAMESIZE (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN)
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
int
|
|
|
|
hme_config(struct hme_softc *sc)
|
|
|
|
{
|
2005-06-10 16:49:24 +00:00
|
|
|
struct ifnet *ifp;
|
2002-02-27 17:35:48 +00:00
|
|
|
struct mii_softc *child;
|
|
|
|
bus_size_t size;
|
|
|
|
int error, rdesc, tdesc, i;
|
|
|
|
|
2005-06-10 16:49:24 +00:00
|
|
|
ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
|
|
|
|
if (ifp == NULL)
|
|
|
|
return (ENOSPC);
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
/*
|
|
|
|
* HME common initialization.
|
|
|
|
*
|
|
|
|
* hme_softc fields that must be initialized by the front-end:
|
|
|
|
*
|
2004-05-22 01:56:18 +00:00
|
|
|
* the DMA bus tag:
|
2002-02-27 17:35:48 +00:00
|
|
|
* sc_dmatag
|
|
|
|
*
|
2011-04-22 09:39:05 +00:00
|
|
|
* the bus handles, tags and offsets (splitted for SBus compatibility):
|
2002-02-27 17:35:48 +00:00
|
|
|
* sc_seb{t,h,o} (Shared Ethernet Block registers)
|
|
|
|
* sc_erx{t,h,o} (Receiver Unit registers)
|
|
|
|
* sc_etx{t,h,o} (Transmitter Unit registers)
|
|
|
|
* sc_mac{t,h,o} (MAC registers)
|
2004-05-22 01:56:18 +00:00
|
|
|
* sc_mif{t,h,o} (Management Interface registers)
|
2002-02-27 17:35:48 +00:00
|
|
|
*
|
|
|
|
* the maximum bus burst size:
|
|
|
|
* sc_burst
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2005-08-24 20:28:56 +00:00
|
|
|
callout_init_mtx(&sc->sc_tick_ch, &sc->sc_lock, 0);
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
/* Make sure the chip is stopped. */
|
2004-11-22 06:46:30 +00:00
|
|
|
HME_LOCK(sc);
|
2002-02-27 17:35:48 +00:00
|
|
|
hme_stop(sc);
|
2004-11-22 06:46:30 +00:00
|
|
|
HME_UNLOCK(sc);
|
2002-02-27 17:35:48 +00:00
|
|
|
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0,
|
|
|
|
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
|
|
|
|
BUS_SPACE_MAXSIZE_32BIT, 0, BUS_SPACE_MAXSIZE_32BIT, 0,
|
|
|
|
NULL, NULL, &sc->sc_pdmatag);
|
|
|
|
if (error)
|
|
|
|
goto fail_ifnet;
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
/*
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
* Create control, RX and TX mbuf DMA tags.
|
2002-02-27 17:35:48 +00:00
|
|
|
* Buffer descriptors must be aligned on a 2048 byte boundary;
|
|
|
|
* take this into account when calculating the size. Note that
|
|
|
|
* the maximum number of descriptors (256) occupies 2048 bytes,
|
|
|
|
* so we allocate that much regardless of HME_N*DESC.
|
|
|
|
*/
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
size = 4096;
|
2002-02-27 17:35:48 +00:00
|
|
|
error = bus_dma_tag_create(sc->sc_pdmatag, 2048, 0,
|
|
|
|
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, size,
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
1, size, 0, busdma_lock_mutex, &sc->sc_lock, &sc->sc_cdmatag);
|
2002-02-27 17:35:48 +00:00
|
|
|
if (error)
|
|
|
|
goto fail_ptag;
|
|
|
|
|
|
|
|
error = bus_dma_tag_create(sc->sc_pdmatag, max(0x10, sc->sc_burst), 0,
|
|
|
|
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
1, MCLBYTES, BUS_DMA_ALLOCNOW, NULL, NULL, &sc->sc_rdmatag);
|
2002-02-27 17:35:48 +00:00
|
|
|
if (error)
|
|
|
|
goto fail_ctag;
|
|
|
|
|
|
|
|
error = bus_dma_tag_create(sc->sc_pdmatag, max(0x10, sc->sc_burst), 0,
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
|
|
|
|
MCLBYTES * HME_NTXSEGS, HME_NTXSEGS, MCLBYTES, BUS_DMA_ALLOCNOW,
|
2003-07-01 15:52:06 +00:00
|
|
|
NULL, NULL, &sc->sc_tdmatag);
|
2002-02-27 17:35:48 +00:00
|
|
|
if (error)
|
|
|
|
goto fail_rtag;
|
|
|
|
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
/* Allocate the control DMA buffer. */
|
2002-02-27 17:35:48 +00:00
|
|
|
error = bus_dmamem_alloc(sc->sc_cdmatag, (void **)&sc->sc_rb.rb_membase,
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->sc_cdmamap);
|
2002-02-27 17:35:48 +00:00
|
|
|
if (error != 0) {
|
|
|
|
device_printf(sc->sc_dev, "DMA buffer alloc error %d\n", error);
|
|
|
|
goto fail_ttag;
|
|
|
|
}
|
|
|
|
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
/* Load the control DMA buffer. */
|
2002-02-27 17:35:48 +00:00
|
|
|
sc->sc_rb.rb_dmabase = 0;
|
|
|
|
if ((error = bus_dmamap_load(sc->sc_cdmatag, sc->sc_cdmamap,
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
sc->sc_rb.rb_membase, size, hme_cdma_callback, sc, 0)) != 0 ||
|
2002-02-27 17:35:48 +00:00
|
|
|
sc->sc_rb.rb_dmabase == 0) {
|
|
|
|
device_printf(sc->sc_dev, "DMA buffer map load error %d\n",
|
|
|
|
error);
|
|
|
|
goto fail_free;
|
|
|
|
}
|
|
|
|
CTR2(KTR_HME, "hme_config: dma va %p, pa %#lx", sc->sc_rb.rb_membase,
|
|
|
|
sc->sc_rb.rb_dmabase);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Prepare the RX descriptors. rdesc serves as marker for the last
|
|
|
|
* processed descriptor and may be used later on.
|
|
|
|
*/
|
|
|
|
for (rdesc = 0; rdesc < HME_NRXDESC; rdesc++) {
|
2002-07-14 12:09:48 +00:00
|
|
|
sc->sc_rb.rb_rxdesc[rdesc].hrx_m = NULL;
|
2002-02-27 17:35:48 +00:00
|
|
|
error = bus_dmamap_create(sc->sc_rdmatag, 0,
|
|
|
|
&sc->sc_rb.rb_rxdesc[rdesc].hrx_dmamap);
|
|
|
|
if (error != 0)
|
|
|
|
goto fail_rxdesc;
|
|
|
|
}
|
|
|
|
error = bus_dmamap_create(sc->sc_rdmatag, 0,
|
|
|
|
&sc->sc_rb.rb_spare_dmamap);
|
|
|
|
if (error != 0)
|
|
|
|
goto fail_rxdesc;
|
|
|
|
/* Same for the TX descs. */
|
2003-01-06 22:12:57 +00:00
|
|
|
for (tdesc = 0; tdesc < HME_NTXQ; tdesc++) {
|
2002-07-14 12:09:48 +00:00
|
|
|
sc->sc_rb.rb_txdesc[tdesc].htx_m = NULL;
|
2002-02-27 17:35:48 +00:00
|
|
|
error = bus_dmamap_create(sc->sc_tdmatag, 0,
|
|
|
|
&sc->sc_rb.rb_txdesc[tdesc].htx_dmamap);
|
|
|
|
if (error != 0)
|
|
|
|
goto fail_txdesc;
|
|
|
|
}
|
|
|
|
|
2004-08-05 02:52:33 +00:00
|
|
|
sc->sc_csum_features = HME_CSUM_FEATURES;
|
2002-02-27 17:35:48 +00:00
|
|
|
/* Initialize ifnet structure. */
|
|
|
|
ifp->if_softc = sc;
|
2003-10-31 18:32:15 +00:00
|
|
|
if_initname(ifp, device_get_name(sc->sc_dev),
|
|
|
|
device_get_unit(sc->sc_dev));
|
2004-11-22 06:46:30 +00:00
|
|
|
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
|
2002-02-27 17:35:48 +00:00
|
|
|
ifp->if_start = hme_start;
|
|
|
|
ifp->if_ioctl = hme_ioctl;
|
|
|
|
ifp->if_init = hme_init;
|
2004-08-01 23:58:04 +00:00
|
|
|
IFQ_SET_MAXLEN(&ifp->if_snd, HME_NTXQ);
|
|
|
|
ifp->if_snd.ifq_drv_maxlen = HME_NTXQ;
|
|
|
|
IFQ_SET_READY(&ifp->if_snd);
|
2002-02-27 17:35:48 +00:00
|
|
|
|
|
|
|
hme_mifinit(sc);
|
|
|
|
|
2010-10-15 14:52:11 +00:00
|
|
|
/*
|
|
|
|
* DP83840A used with HME chips don't advertise their media
|
|
|
|
* capabilities themselves properly so force writing the ANAR
|
|
|
|
* according to the BMSR in mii_phy_setmedia().
|
|
|
|
*/
|
|
|
|
error = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp, hme_mediachange,
|
|
|
|
hme_mediastatus, BMSR_DEFCAPMASK, HME_PHYAD_EXTERNAL,
|
|
|
|
MII_OFFSET_ANY, MIIF_FORCEANEG);
|
|
|
|
i = mii_attach(sc->sc_dev, &sc->sc_miibus, ifp, hme_mediachange,
|
|
|
|
hme_mediastatus, BMSR_DEFCAPMASK, HME_PHYAD_INTERNAL,
|
|
|
|
MII_OFFSET_ANY, MIIF_FORCEANEG);
|
|
|
|
if (error != 0 && i != 0) {
|
|
|
|
error = ENXIO;
|
|
|
|
device_printf(sc->sc_dev, "attaching PHYs failed\n");
|
2002-02-27 17:35:48 +00:00
|
|
|
goto fail_rxdesc;
|
|
|
|
}
|
|
|
|
sc->sc_mii = device_get_softc(sc->sc_miibus);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Walk along the list of attached MII devices and
|
2006-12-04 00:51:08 +00:00
|
|
|
* establish an `MII instance' to `PHY number'
|
|
|
|
* mapping. We'll use this mapping to enable the MII
|
|
|
|
* drivers of the external transceiver according to
|
|
|
|
* the currently selected media.
|
2002-02-27 17:35:48 +00:00
|
|
|
*/
|
2006-12-04 00:51:08 +00:00
|
|
|
sc->sc_phys[0] = sc->sc_phys[1] = -1;
|
|
|
|
LIST_FOREACH(child, &sc->sc_mii->mii_phys, mii_list) {
|
2002-02-27 17:35:48 +00:00
|
|
|
/*
|
|
|
|
* Note: we support just two PHYs: the built-in
|
|
|
|
* internal device and an external on the MII
|
|
|
|
* connector.
|
|
|
|
*/
|
2006-12-04 00:51:08 +00:00
|
|
|
if ((child->mii_phy != HME_PHYAD_EXTERNAL &&
|
|
|
|
child->mii_phy != HME_PHYAD_INTERNAL) ||
|
|
|
|
child->mii_inst > 1) {
|
2004-05-22 01:56:18 +00:00
|
|
|
device_printf(sc->sc_dev, "cannot accommodate "
|
2002-02-27 17:35:48 +00:00
|
|
|
"MII device %s at phy %d, instance %d\n",
|
|
|
|
device_get_name(child->mii_dev),
|
|
|
|
child->mii_phy, child->mii_inst);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
sc->sc_phys[child->mii_inst] = child->mii_phy;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Attach the interface. */
|
2005-06-10 16:49:24 +00:00
|
|
|
ether_ifattach(ifp, sc->sc_enaddr);
|
2002-02-27 17:35:48 +00:00
|
|
|
|
2004-05-06 13:38:19 +00:00
|
|
|
/*
|
2004-08-05 02:52:33 +00:00
|
|
|
* Tell the upper layer(s) we support long frames/checksum offloads.
|
2004-05-06 13:38:19 +00:00
|
|
|
*/
|
2014-08-30 19:55:54 +00:00
|
|
|
ifp->if_hdrlen = sizeof(struct ether_vlan_header);
|
2004-08-05 02:52:33 +00:00
|
|
|
ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_HWCSUM;
|
|
|
|
ifp->if_hwassist |= sc->sc_csum_features;
|
|
|
|
ifp->if_capenable |= IFCAP_VLAN_MTU | IFCAP_HWCSUM;
|
2002-02-27 17:35:48 +00:00
|
|
|
return (0);
|
|
|
|
|
|
|
|
fail_txdesc:
|
|
|
|
for (i = 0; i < tdesc; i++) {
|
|
|
|
bus_dmamap_destroy(sc->sc_tdmatag,
|
|
|
|
sc->sc_rb.rb_txdesc[i].htx_dmamap);
|
|
|
|
}
|
|
|
|
bus_dmamap_destroy(sc->sc_rdmatag, sc->sc_rb.rb_spare_dmamap);
|
|
|
|
fail_rxdesc:
|
|
|
|
for (i = 0; i < rdesc; i++) {
|
|
|
|
bus_dmamap_destroy(sc->sc_rdmatag,
|
|
|
|
sc->sc_rb.rb_rxdesc[i].hrx_dmamap);
|
|
|
|
}
|
|
|
|
bus_dmamap_unload(sc->sc_cdmatag, sc->sc_cdmamap);
|
|
|
|
fail_free:
|
|
|
|
bus_dmamem_free(sc->sc_cdmatag, sc->sc_rb.rb_membase, sc->sc_cdmamap);
|
|
|
|
fail_ttag:
|
|
|
|
bus_dma_tag_destroy(sc->sc_tdmatag);
|
|
|
|
fail_rtag:
|
|
|
|
bus_dma_tag_destroy(sc->sc_rdmatag);
|
|
|
|
fail_ctag:
|
|
|
|
bus_dma_tag_destroy(sc->sc_cdmatag);
|
|
|
|
fail_ptag:
|
|
|
|
bus_dma_tag_destroy(sc->sc_pdmatag);
|
2005-06-10 16:49:24 +00:00
|
|
|
fail_ifnet:
|
|
|
|
if_free(ifp);
|
2002-02-27 17:35:48 +00:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
2003-01-09 00:45:10 +00:00
|
|
|
void
|
|
|
|
hme_detach(struct hme_softc *sc)
|
|
|
|
{
|
2005-06-10 16:49:24 +00:00
|
|
|
struct ifnet *ifp = sc->sc_ifp;
|
2003-01-09 00:45:10 +00:00
|
|
|
int i;
|
|
|
|
|
2004-11-22 06:46:30 +00:00
|
|
|
HME_LOCK(sc);
|
2003-01-09 00:45:10 +00:00
|
|
|
hme_stop(sc);
|
2004-11-22 06:46:30 +00:00
|
|
|
HME_UNLOCK(sc);
|
2005-08-17 17:44:32 +00:00
|
|
|
callout_drain(&sc->sc_tick_ch);
|
2005-09-08 13:50:16 +00:00
|
|
|
ether_ifdetach(ifp);
|
|
|
|
if_free(ifp);
|
2003-01-09 00:45:10 +00:00
|
|
|
device_delete_child(sc->sc_dev, sc->sc_miibus);
|
|
|
|
|
|
|
|
for (i = 0; i < HME_NTXQ; i++) {
|
|
|
|
bus_dmamap_destroy(sc->sc_tdmatag,
|
|
|
|
sc->sc_rb.rb_txdesc[i].htx_dmamap);
|
|
|
|
}
|
|
|
|
bus_dmamap_destroy(sc->sc_rdmatag, sc->sc_rb.rb_spare_dmamap);
|
|
|
|
for (i = 0; i < HME_NRXDESC; i++) {
|
|
|
|
bus_dmamap_destroy(sc->sc_rdmatag,
|
|
|
|
sc->sc_rb.rb_rxdesc[i].hrx_dmamap);
|
|
|
|
}
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap,
|
|
|
|
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
|
2003-01-09 00:45:10 +00:00
|
|
|
bus_dmamap_unload(sc->sc_cdmatag, sc->sc_cdmamap);
|
|
|
|
bus_dmamem_free(sc->sc_cdmatag, sc->sc_rb.rb_membase, sc->sc_cdmamap);
|
|
|
|
bus_dma_tag_destroy(sc->sc_tdmatag);
|
|
|
|
bus_dma_tag_destroy(sc->sc_rdmatag);
|
|
|
|
bus_dma_tag_destroy(sc->sc_cdmatag);
|
|
|
|
bus_dma_tag_destroy(sc->sc_pdmatag);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
hme_suspend(struct hme_softc *sc)
|
|
|
|
{
|
|
|
|
|
2004-11-22 06:46:30 +00:00
|
|
|
HME_LOCK(sc);
|
2003-01-09 00:45:10 +00:00
|
|
|
hme_stop(sc);
|
2004-11-22 06:46:30 +00:00
|
|
|
HME_UNLOCK(sc);
|
2003-01-09 00:45:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
hme_resume(struct hme_softc *sc)
|
|
|
|
{
|
2005-06-10 16:49:24 +00:00
|
|
|
struct ifnet *ifp = sc->sc_ifp;
|
2003-01-09 00:45:10 +00:00
|
|
|
|
2004-11-22 06:46:30 +00:00
|
|
|
HME_LOCK(sc);
|
2003-01-09 00:45:10 +00:00
|
|
|
if ((ifp->if_flags & IFF_UP) != 0)
|
2005-06-10 16:49:24 +00:00
|
|
|
hme_init_locked(sc);
|
2004-11-22 06:46:30 +00:00
|
|
|
HME_UNLOCK(sc);
|
2003-01-09 00:45:10 +00:00
|
|
|
}
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
static void
|
|
|
|
hme_cdma_callback(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
|
|
|
|
{
|
|
|
|
struct hme_softc *sc = (struct hme_softc *)xsc;
|
|
|
|
|
|
|
|
if (error != 0)
|
|
|
|
return;
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
KASSERT(nsegs == 1,
|
|
|
|
("%s: too many DMA segments (%d)", __func__, nsegs));
|
2002-02-27 17:35:48 +00:00
|
|
|
sc->sc_rb.rb_dmabase = segs[0].ds_addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
hme_tick(void *arg)
|
|
|
|
{
|
|
|
|
struct hme_softc *sc = arg;
|
2005-10-25 03:56:21 +00:00
|
|
|
struct ifnet *ifp;
|
2002-02-27 17:35:48 +00:00
|
|
|
|
2005-08-10 20:12:25 +00:00
|
|
|
HME_LOCK_ASSERT(sc, MA_OWNED);
|
2005-10-25 03:56:21 +00:00
|
|
|
|
|
|
|
ifp = sc->sc_ifp;
|
|
|
|
/*
|
|
|
|
* Unload collision counters
|
|
|
|
*/
|
2014-09-18 21:07:05 +00:00
|
|
|
if_inc_counter(ifp, IFCOUNTER_COLLISIONS,
|
2005-10-25 03:56:21 +00:00
|
|
|
HME_MAC_READ_4(sc, HME_MACI_NCCNT) +
|
|
|
|
HME_MAC_READ_4(sc, HME_MACI_FCCNT) +
|
|
|
|
HME_MAC_READ_4(sc, HME_MACI_EXCNT) +
|
2014-09-18 21:07:05 +00:00
|
|
|
HME_MAC_READ_4(sc, HME_MACI_LTCNT));
|
2005-10-25 03:56:21 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* then clear the hardware counters.
|
|
|
|
*/
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_NCCNT, 0);
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_FCCNT, 0);
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_EXCNT, 0);
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_LTCNT, 0);
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
mii_tick(sc->sc_mii);
|
|
|
|
|
2006-12-06 02:07:20 +00:00
|
|
|
if (hme_watchdog(sc) == EJUSTRETURN)
|
|
|
|
return;
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
callout_reset(&sc->sc_tick_ch, hz, hme_tick, sc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
hme_stop(struct hme_softc *sc)
|
|
|
|
{
|
|
|
|
u_int32_t v;
|
|
|
|
int n;
|
|
|
|
|
|
|
|
callout_stop(&sc->sc_tick_ch);
|
2006-12-06 02:07:20 +00:00
|
|
|
sc->sc_wdog_timer = 0;
|
2005-08-10 20:12:25 +00:00
|
|
|
sc->sc_ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
sc->sc_flags &= ~HME_LINK;
|
2002-02-27 17:35:48 +00:00
|
|
|
|
2006-12-04 00:51:08 +00:00
|
|
|
/* Mask all interrupts */
|
|
|
|
HME_SEB_WRITE_4(sc, HME_SEBI_IMASK, 0xffffffff);
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
/* Reset transmitter and receiver */
|
|
|
|
HME_SEB_WRITE_4(sc, HME_SEBI_RESET, HME_SEB_RESET_ETX |
|
|
|
|
HME_SEB_RESET_ERX);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
HME_SEB_BARRIER(sc, HME_SEBI_RESET, 4,
|
|
|
|
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
|
2002-02-27 17:35:48 +00:00
|
|
|
for (n = 0; n < 20; n++) {
|
|
|
|
v = HME_SEB_READ_4(sc, HME_SEBI_RESET);
|
|
|
|
if ((v & (HME_SEB_RESET_ETX | HME_SEB_RESET_ERX)) == 0)
|
|
|
|
return;
|
|
|
|
DELAY(20);
|
|
|
|
}
|
|
|
|
|
|
|
|
device_printf(sc->sc_dev, "hme_stop: reset failed\n");
|
|
|
|
}
|
|
|
|
|
2002-07-14 12:09:48 +00:00
|
|
|
/*
|
|
|
|
* Discard the contents of an mbuf in the RX ring, freeing the buffer in the
|
|
|
|
* ring for subsequent use.
|
|
|
|
*/
|
2003-01-21 17:22:52 +00:00
|
|
|
static __inline void
|
|
|
|
hme_discard_rxbuf(struct hme_softc *sc, int ix)
|
2002-07-14 12:09:48 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Dropped a packet, reinitialize the descriptor and turn the
|
|
|
|
* ownership back to the hardware.
|
|
|
|
*/
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
HME_XD_SETFLAGS(sc->sc_flags & HME_PCI, sc->sc_rb.rb_rxd,
|
|
|
|
ix, HME_XD_OWN | HME_XD_ENCODE_RSIZE(HME_DESC_RXLEN(sc,
|
|
|
|
&sc->sc_rb.rb_rxdesc[ix])));
|
2002-07-14 12:09:48 +00:00
|
|
|
}
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
static int
|
|
|
|
hme_add_rxbuf(struct hme_softc *sc, unsigned int ri, int keepold)
|
|
|
|
{
|
|
|
|
struct hme_rxdesc *rd;
|
|
|
|
struct mbuf *m;
|
2005-01-15 22:05:59 +00:00
|
|
|
bus_dma_segment_t segs[1];
|
2002-02-27 17:35:48 +00:00
|
|
|
bus_dmamap_t map;
|
2003-01-06 22:12:57 +00:00
|
|
|
uintptr_t b;
|
2005-01-15 22:05:59 +00:00
|
|
|
int a, unmap, nsegs;
|
2002-02-27 17:35:48 +00:00
|
|
|
|
|
|
|
rd = &sc->sc_rb.rb_rxdesc[ri];
|
|
|
|
unmap = rd->hrx_m != NULL;
|
2002-07-14 12:09:48 +00:00
|
|
|
if (unmap && keepold) {
|
|
|
|
/*
|
|
|
|
* Reinitialize the descriptor flags, as they may have been
|
|
|
|
* altered by the hardware.
|
|
|
|
*/
|
2003-01-21 17:22:52 +00:00
|
|
|
hme_discard_rxbuf(sc, ri);
|
2002-02-27 17:35:48 +00:00
|
|
|
return (0);
|
2002-07-14 12:09:48 +00:00
|
|
|
}
|
2012-12-04 09:32:43 +00:00
|
|
|
if ((m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR)) == NULL)
|
2002-02-27 17:35:48 +00:00
|
|
|
return (ENOBUFS);
|
2003-01-06 22:12:57 +00:00
|
|
|
m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
|
|
|
|
b = mtod(m, uintptr_t);
|
2002-02-27 17:35:48 +00:00
|
|
|
/*
|
|
|
|
* Required alignment boundary. At least 16 is needed, but since
|
|
|
|
* the mapping must be done in a way that a burst can start on a
|
|
|
|
* natural boundary we might need to extend this.
|
|
|
|
*/
|
2005-10-25 03:56:21 +00:00
|
|
|
a = imax(HME_MINRXALIGN, sc->sc_burst);
|
2002-02-27 17:35:48 +00:00
|
|
|
/*
|
2003-01-06 22:12:57 +00:00
|
|
|
* Make sure the buffer suitably aligned. The 2 byte offset is removed
|
|
|
|
* when the mbuf is handed up. XXX: this ensures at least 16 byte
|
|
|
|
* alignment of the header adjacent to the ethernet header, which
|
|
|
|
* should be sufficient in all cases. Nevertheless, this second-guesses
|
|
|
|
* ALIGN().
|
2002-02-27 17:35:48 +00:00
|
|
|
*/
|
2003-01-06 22:12:57 +00:00
|
|
|
m_adj(m, roundup2(b, a) - b);
|
2005-01-15 22:05:59 +00:00
|
|
|
if (bus_dmamap_load_mbuf_sg(sc->sc_rdmatag, sc->sc_rb.rb_spare_dmamap,
|
|
|
|
m, segs, &nsegs, 0) != 0) {
|
2003-01-06 22:12:57 +00:00
|
|
|
m_freem(m);
|
|
|
|
return (ENOBUFS);
|
|
|
|
}
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
/* If nsegs is wrong then the stack is corrupt. */
|
|
|
|
KASSERT(nsegs == 1,
|
|
|
|
("%s: too many DMA segments (%d)", __func__, nsegs));
|
2002-02-27 17:35:48 +00:00
|
|
|
if (unmap) {
|
|
|
|
bus_dmamap_sync(sc->sc_rdmatag, rd->hrx_dmamap,
|
|
|
|
BUS_DMASYNC_POSTREAD);
|
|
|
|
bus_dmamap_unload(sc->sc_rdmatag, rd->hrx_dmamap);
|
|
|
|
}
|
|
|
|
map = rd->hrx_dmamap;
|
|
|
|
rd->hrx_dmamap = sc->sc_rb.rb_spare_dmamap;
|
|
|
|
sc->sc_rb.rb_spare_dmamap = map;
|
|
|
|
bus_dmamap_sync(sc->sc_rdmatag, rd->hrx_dmamap, BUS_DMASYNC_PREREAD);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
HME_XD_SETADDR(sc->sc_flags & HME_PCI, sc->sc_rb.rb_rxd, ri,
|
|
|
|
segs[0].ds_addr);
|
2002-02-27 17:35:48 +00:00
|
|
|
rd->hrx_m = m;
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
HME_XD_SETFLAGS(sc->sc_flags & HME_PCI, sc->sc_rb.rb_rxd, ri,
|
|
|
|
HME_XD_OWN | HME_XD_ENCODE_RSIZE(HME_DESC_RXLEN(sc, rd)));
|
2002-02-27 17:35:48 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
hme_meminit(struct hme_softc *sc)
|
|
|
|
{
|
|
|
|
struct hme_ring *hr = &sc->sc_rb;
|
|
|
|
struct hme_txdesc *td;
|
|
|
|
bus_addr_t dma;
|
|
|
|
caddr_t p;
|
|
|
|
unsigned int i;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
p = hr->rb_membase;
|
|
|
|
dma = hr->rb_dmabase;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocate transmit descriptors
|
|
|
|
*/
|
|
|
|
hr->rb_txd = p;
|
|
|
|
hr->rb_txddma = dma;
|
|
|
|
p += HME_NTXDESC * HME_XD_SIZE;
|
|
|
|
dma += HME_NTXDESC * HME_XD_SIZE;
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
/*
|
|
|
|
* We have reserved descriptor space until the next 2048 byte
|
|
|
|
* boundary.
|
|
|
|
*/
|
2002-02-27 17:35:48 +00:00
|
|
|
dma = (bus_addr_t)roundup((u_long)dma, 2048);
|
|
|
|
p = (caddr_t)roundup((u_long)p, 2048);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocate receive descriptors
|
|
|
|
*/
|
|
|
|
hr->rb_rxd = p;
|
|
|
|
hr->rb_rxddma = dma;
|
|
|
|
p += HME_NRXDESC * HME_XD_SIZE;
|
|
|
|
dma += HME_NRXDESC * HME_XD_SIZE;
|
|
|
|
/* Again move forward to the next 2048 byte boundary.*/
|
|
|
|
dma = (bus_addr_t)roundup((u_long)dma, 2048);
|
|
|
|
p = (caddr_t)roundup((u_long)p, 2048);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize transmit buffer descriptors
|
|
|
|
*/
|
|
|
|
for (i = 0; i < HME_NTXDESC; i++) {
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
HME_XD_SETADDR(sc->sc_flags & HME_PCI, hr->rb_txd, i, 0);
|
|
|
|
HME_XD_SETFLAGS(sc->sc_flags & HME_PCI, hr->rb_txd, i, 0);
|
2003-01-06 22:12:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
STAILQ_INIT(&sc->sc_rb.rb_txfreeq);
|
|
|
|
STAILQ_INIT(&sc->sc_rb.rb_txbusyq);
|
|
|
|
for (i = 0; i < HME_NTXQ; i++) {
|
|
|
|
td = &sc->sc_rb.rb_txdesc[i];
|
2002-02-27 17:35:48 +00:00
|
|
|
if (td->htx_m != NULL) {
|
2003-01-21 17:22:52 +00:00
|
|
|
bus_dmamap_sync(sc->sc_tdmatag, td->htx_dmamap,
|
|
|
|
BUS_DMASYNC_POSTWRITE);
|
2003-01-06 22:12:57 +00:00
|
|
|
bus_dmamap_unload(sc->sc_tdmatag, td->htx_dmamap);
|
2005-10-25 03:56:21 +00:00
|
|
|
m_freem(td->htx_m);
|
2002-02-27 17:35:48 +00:00
|
|
|
td->htx_m = NULL;
|
|
|
|
}
|
2003-01-06 22:12:57 +00:00
|
|
|
STAILQ_INSERT_TAIL(&sc->sc_rb.rb_txfreeq, td, htx_q);
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize receive buffer descriptors
|
|
|
|
*/
|
|
|
|
for (i = 0; i < HME_NRXDESC; i++) {
|
|
|
|
error = hme_add_rxbuf(sc, i, 1);
|
|
|
|
if (error != 0)
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap,
|
|
|
|
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
2002-07-14 12:09:48 +00:00
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
hr->rb_tdhead = hr->rb_tdtail = 0;
|
|
|
|
hr->rb_td_nbusy = 0;
|
|
|
|
hr->rb_rdtail = 0;
|
2002-07-14 12:09:48 +00:00
|
|
|
CTR2(KTR_HME, "hme_meminit: tx ring va %p, pa %#lx", hr->rb_txd,
|
2002-02-27 17:35:48 +00:00
|
|
|
hr->rb_txddma);
|
2002-07-14 12:09:48 +00:00
|
|
|
CTR2(KTR_HME, "hme_meminit: rx ring va %p, pa %#lx", hr->rb_rxd,
|
2002-02-27 17:35:48 +00:00
|
|
|
hr->rb_rxddma);
|
|
|
|
CTR2(KTR_HME, "rx entry 1: flags %x, address %x",
|
|
|
|
*(u_int32_t *)hr->rb_rxd, *(u_int32_t *)(hr->rb_rxd + 4));
|
|
|
|
CTR2(KTR_HME, "tx entry 1: flags %x, address %x",
|
|
|
|
*(u_int32_t *)hr->rb_txd, *(u_int32_t *)(hr->rb_txd + 4));
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
hme_mac_bitflip(struct hme_softc *sc, u_int32_t reg, u_int32_t val,
|
|
|
|
u_int32_t clr, u_int32_t set)
|
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
val &= ~clr;
|
|
|
|
val |= set;
|
|
|
|
HME_MAC_WRITE_4(sc, reg, val);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
HME_MAC_BARRIER(sc, reg, 4,
|
|
|
|
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
|
2002-02-27 17:35:48 +00:00
|
|
|
if (clr == 0 && set == 0)
|
|
|
|
return (1); /* just write, no bits to wait for */
|
|
|
|
do {
|
|
|
|
DELAY(100);
|
|
|
|
i++;
|
|
|
|
val = HME_MAC_READ_4(sc, reg);
|
|
|
|
if (i > 40) {
|
|
|
|
/* After 3.5ms, we should have been done. */
|
|
|
|
device_printf(sc->sc_dev, "timeout while writing to "
|
|
|
|
"MAC configuration register\n");
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
} while ((val & clr) != 0 && (val & set) != set);
|
|
|
|
return (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialization of interface; set up initialization block
|
|
|
|
* and transmit/receive descriptor rings.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
hme_init(void *xsc)
|
2004-11-22 06:46:30 +00:00
|
|
|
{
|
|
|
|
struct hme_softc *sc = (struct hme_softc *)xsc;
|
|
|
|
|
|
|
|
HME_LOCK(sc);
|
|
|
|
hme_init_locked(sc);
|
|
|
|
HME_UNLOCK(sc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2005-06-10 16:49:24 +00:00
|
|
|
hme_init_locked(struct hme_softc *sc)
|
2002-02-27 17:35:48 +00:00
|
|
|
{
|
2005-06-10 16:49:24 +00:00
|
|
|
struct ifnet *ifp = sc->sc_ifp;
|
2002-02-27 17:35:48 +00:00
|
|
|
u_int8_t *ea;
|
2004-08-05 02:52:33 +00:00
|
|
|
u_int32_t n, v;
|
2002-02-27 17:35:48 +00:00
|
|
|
|
2004-11-22 06:46:30 +00:00
|
|
|
HME_LOCK_ASSERT(sc, MA_OWNED);
|
2013-07-10 06:46:46 +00:00
|
|
|
|
|
|
|
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
|
|
|
|
return;
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
/*
|
|
|
|
* Initialization sequence. The numbered steps below correspond
|
|
|
|
* to the sequence outlined in section 6.3.5.1 in the Ethernet
|
|
|
|
* Channel Engine manual (part of the PCIO manual).
|
|
|
|
* See also the STP2002-STQ document from Sun Microsystems.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* step 1 & 2. Reset the Ethernet Channel */
|
|
|
|
hme_stop(sc);
|
|
|
|
|
|
|
|
/* Re-initialize the MIF */
|
|
|
|
hme_mifinit(sc);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/* Mask all MIF interrupts, just in case */
|
|
|
|
HME_MIF_WRITE_4(sc, HME_MIFI_IMASK, 0xffff);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* step 3. Setup data structures in host memory */
|
|
|
|
if (hme_meminit(sc) != 0) {
|
|
|
|
device_printf(sc->sc_dev, "out of buffers; init aborted.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* step 4. TX MAC registers & counters */
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_NCCNT, 0);
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_FCCNT, 0);
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_EXCNT, 0);
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_LTCNT, 0);
|
2004-05-06 13:38:19 +00:00
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_TXSIZE, HME_MAX_FRAMESIZE);
|
2002-02-27 17:35:48 +00:00
|
|
|
|
|
|
|
/* Load station MAC address */
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
ea = IF_LLADDR(ifp);
|
2002-02-27 17:35:48 +00:00
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_MACADDR0, (ea[0] << 8) | ea[1]);
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_MACADDR1, (ea[2] << 8) | ea[3]);
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_MACADDR2, (ea[4] << 8) | ea[5]);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Init seed for backoff
|
|
|
|
* (source suggested by manual: low 10 bits of MAC address)
|
|
|
|
*/
|
|
|
|
v = ((ea[4] << 8) | ea[5]) & 0x3fff;
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_RANDSEED, v);
|
|
|
|
|
|
|
|
/* Note: Accepting power-on default for other MAC registers here.. */
|
|
|
|
|
|
|
|
/* step 5. RX MAC registers & counters */
|
|
|
|
hme_setladrf(sc, 0);
|
|
|
|
|
|
|
|
/* step 6 & 7. Program Descriptor Ring Base Addresses */
|
|
|
|
HME_ETX_WRITE_4(sc, HME_ETXI_RING, sc->sc_rb.rb_txddma);
|
|
|
|
/* Transmit Descriptor ring size: in increments of 16 */
|
|
|
|
HME_ETX_WRITE_4(sc, HME_ETXI_RSIZE, HME_NTXDESC / 16 - 1);
|
|
|
|
|
|
|
|
HME_ERX_WRITE_4(sc, HME_ERXI_RING, sc->sc_rb.rb_rxddma);
|
2004-05-06 13:38:19 +00:00
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_RXSIZE, HME_MAX_FRAMESIZE);
|
2002-02-27 17:35:48 +00:00
|
|
|
|
|
|
|
/* step 8. Global Configuration & Interrupt Mask */
|
|
|
|
HME_SEB_WRITE_4(sc, HME_SEBI_IMASK,
|
|
|
|
~(/*HME_SEB_STAT_GOTFRAME | HME_SEB_STAT_SENTFRAME |*/
|
|
|
|
HME_SEB_STAT_HOSTTOTX |
|
|
|
|
HME_SEB_STAT_RXTOHOST |
|
|
|
|
HME_SEB_STAT_TXALL |
|
|
|
|
HME_SEB_STAT_TXPERR |
|
|
|
|
HME_SEB_STAT_RCNTEXP |
|
|
|
|
HME_SEB_STAT_ALL_ERRORS ));
|
|
|
|
|
|
|
|
switch (sc->sc_burst) {
|
|
|
|
default:
|
|
|
|
v = 0;
|
|
|
|
break;
|
|
|
|
case 16:
|
|
|
|
v = HME_SEB_CFG_BURST16;
|
|
|
|
break;
|
|
|
|
case 32:
|
|
|
|
v = HME_SEB_CFG_BURST32;
|
|
|
|
break;
|
|
|
|
case 64:
|
|
|
|
v = HME_SEB_CFG_BURST64;
|
|
|
|
break;
|
|
|
|
}
|
2004-08-05 02:52:33 +00:00
|
|
|
/*
|
|
|
|
* Blindly setting 64bit transfers may hang PCI cards(Cheerio?).
|
|
|
|
* Allowing 64bit transfers breaks TX checksum offload as well.
|
|
|
|
* Don't know this comes from hardware bug or driver's DMAing
|
|
|
|
* scheme.
|
|
|
|
*
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
* if (sc->sc_flags & HME_PCI == 0)
|
|
|
|
* v |= HME_SEB_CFG_64BIT;
|
2004-08-05 02:52:33 +00:00
|
|
|
*/
|
2002-02-27 17:35:48 +00:00
|
|
|
HME_SEB_WRITE_4(sc, HME_SEBI_CFG, v);
|
|
|
|
|
|
|
|
/* step 9. ETX Configuration: use mostly default values */
|
|
|
|
|
|
|
|
/* Enable DMA */
|
|
|
|
v = HME_ETX_READ_4(sc, HME_ETXI_CFG);
|
|
|
|
v |= HME_ETX_CFG_DMAENABLE;
|
|
|
|
HME_ETX_WRITE_4(sc, HME_ETXI_CFG, v);
|
|
|
|
|
|
|
|
/* step 10. ERX Configuration */
|
|
|
|
v = HME_ERX_READ_4(sc, HME_ERXI_CFG);
|
|
|
|
|
|
|
|
/* Encode Receive Descriptor ring size: four possible values */
|
|
|
|
v &= ~HME_ERX_CFG_RINGSIZEMSK;
|
|
|
|
switch (HME_NRXDESC) {
|
|
|
|
case 32:
|
|
|
|
v |= HME_ERX_CFG_RINGSIZE32;
|
|
|
|
break;
|
|
|
|
case 64:
|
|
|
|
v |= HME_ERX_CFG_RINGSIZE64;
|
|
|
|
break;
|
|
|
|
case 128:
|
|
|
|
v |= HME_ERX_CFG_RINGSIZE128;
|
|
|
|
break;
|
|
|
|
case 256:
|
|
|
|
v |= HME_ERX_CFG_RINGSIZE256;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
printf("hme: invalid Receive Descriptor ring size\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2003-01-06 22:12:57 +00:00
|
|
|
/* Enable DMA, fix RX first byte offset. */
|
2002-02-27 17:35:48 +00:00
|
|
|
v &= ~HME_ERX_CFG_FBO_MASK;
|
2003-01-06 22:12:57 +00:00
|
|
|
v |= HME_ERX_CFG_DMAENABLE | (HME_RXOFFS << HME_ERX_CFG_FBO_SHIFT);
|
2004-08-05 02:52:33 +00:00
|
|
|
/* RX TCP/UDP checksum offset */
|
|
|
|
n = (ETHER_HDR_LEN + sizeof(struct ip)) / 2;
|
|
|
|
n = (n << HME_ERX_CFG_CSUMSTART_SHIFT) & HME_ERX_CFG_CSUMSTART_MASK;
|
|
|
|
v |= n;
|
2002-02-27 17:35:48 +00:00
|
|
|
CTR1(KTR_HME, "hme_init: programming ERX_CFG to %x", (u_int)v);
|
|
|
|
HME_ERX_WRITE_4(sc, HME_ERXI_CFG, v);
|
|
|
|
|
|
|
|
/* step 11. XIF Configuration */
|
|
|
|
v = HME_MAC_READ_4(sc, HME_MACI_XIF);
|
|
|
|
v |= HME_MAC_XIF_OE;
|
|
|
|
CTR1(KTR_HME, "hme_init: programming XIF to %x", (u_int)v);
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_XIF, v);
|
|
|
|
|
|
|
|
/* step 12. RX_MAC Configuration Register */
|
|
|
|
v = HME_MAC_READ_4(sc, HME_MACI_RXCFG);
|
|
|
|
v |= HME_MAC_RXCFG_ENABLE;
|
|
|
|
v &= ~(HME_MAC_RXCFG_DCRCS);
|
|
|
|
CTR1(KTR_HME, "hme_init: programming RX_MAC to %x", (u_int)v);
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_RXCFG, v);
|
|
|
|
|
|
|
|
/* step 13. TX_MAC Configuration Register */
|
|
|
|
v = HME_MAC_READ_4(sc, HME_MACI_TXCFG);
|
|
|
|
v |= (HME_MAC_TXCFG_ENABLE | HME_MAC_TXCFG_DGIVEUP);
|
|
|
|
CTR1(KTR_HME, "hme_init: programming TX_MAC to %x", (u_int)v);
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_TXCFG, v);
|
|
|
|
|
|
|
|
/* step 14. Issue Transmit Pending command */
|
|
|
|
|
|
|
|
#ifdef HMEDEBUG
|
|
|
|
/* Debug: double-check. */
|
|
|
|
CTR4(KTR_HME, "hme_init: tx ring %#x, rsz %#x, rx ring %#x, "
|
|
|
|
"rxsize %#x", HME_ETX_READ_4(sc, HME_ETXI_RING),
|
|
|
|
HME_ETX_READ_4(sc, HME_ETXI_RSIZE),
|
|
|
|
HME_ERX_READ_4(sc, HME_ERXI_RING),
|
|
|
|
HME_MAC_READ_4(sc, HME_MACI_RXSIZE));
|
|
|
|
CTR3(KTR_HME, "hme_init: intr mask %#x, erx cfg %#x, etx cfg %#x",
|
|
|
|
HME_SEB_READ_4(sc, HME_SEBI_IMASK),
|
|
|
|
HME_ERX_READ_4(sc, HME_ERXI_CFG),
|
|
|
|
HME_ETX_READ_4(sc, HME_ETXI_CFG));
|
|
|
|
CTR2(KTR_HME, "hme_init: mac rxcfg %#x, maci txcfg %#x",
|
|
|
|
HME_MAC_READ_4(sc, HME_MACI_RXCFG),
|
|
|
|
HME_MAC_READ_4(sc, HME_MACI_TXCFG));
|
|
|
|
#endif
|
|
|
|
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
ifp->if_drv_flags |= IFF_DRV_RUNNING;
|
|
|
|
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
|
|
|
|
2004-05-29 18:29:53 +00:00
|
|
|
/* Set the current media. */
|
2006-12-04 00:51:08 +00:00
|
|
|
hme_mediachange_locked(sc);
|
2004-05-29 18:29:53 +00:00
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
/* Start the one second timer. */
|
2006-12-06 02:07:20 +00:00
|
|
|
sc->sc_wdog_timer = 0;
|
2002-02-27 17:35:48 +00:00
|
|
|
callout_reset(&sc->sc_tick_ch, hz, hme_tick, sc);
|
2004-08-05 02:52:33 +00:00
|
|
|
}
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
/*
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
* Routine to DMA map an mbuf chain, set up the descriptor rings
|
|
|
|
* accordingly and start the transmission.
|
|
|
|
* Returns 0 on success, -1 if there were not enough free descriptors
|
|
|
|
* to map the packet, or an errno otherwise.
|
2005-10-25 03:56:21 +00:00
|
|
|
*
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
* XXX: this relies on the fact that segments returned by
|
|
|
|
* bus_dmamap_load_mbuf_sg() are readable from the nearest burst
|
|
|
|
* boundary on (i.e. potentially before ds_addr) to the first
|
|
|
|
* boundary beyond the end. This is usually a safe assumption to
|
|
|
|
* make, but is not documented.
|
2002-02-27 17:35:48 +00:00
|
|
|
*/
|
|
|
|
static int
|
2005-10-25 03:56:21 +00:00
|
|
|
hme_load_txmbuf(struct hme_softc *sc, struct mbuf **m0)
|
2002-02-27 17:35:48 +00:00
|
|
|
{
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
bus_dma_segment_t segs[HME_NTXSEGS];
|
2005-10-25 03:56:21 +00:00
|
|
|
struct hme_txdesc *htx;
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
struct ip *ip;
|
|
|
|
struct mbuf *m;
|
2005-10-25 03:56:21 +00:00
|
|
|
caddr_t txd;
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
int error, i, nsegs, pci, ri, si;
|
|
|
|
uint32_t cflags, flags;
|
2002-02-27 17:35:48 +00:00
|
|
|
|
2005-10-25 03:56:21 +00:00
|
|
|
if ((htx = STAILQ_FIRST(&sc->sc_rb.rb_txfreeq)) == NULL)
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
return (ENOBUFS);
|
|
|
|
|
|
|
|
cflags = 0;
|
|
|
|
if (((*m0)->m_pkthdr.csum_flags & sc->sc_csum_features) != 0) {
|
|
|
|
if (M_WRITABLE(*m0) == 0) {
|
2012-12-04 09:32:43 +00:00
|
|
|
m = m_dup(*m0, M_NOWAIT);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
m_freem(*m0);
|
|
|
|
*m0 = m;
|
|
|
|
if (m == NULL)
|
|
|
|
return (ENOBUFS);
|
|
|
|
}
|
|
|
|
i = sizeof(struct ether_header);
|
|
|
|
m = m_pullup(*m0, i + sizeof(struct ip));
|
|
|
|
if (m == NULL) {
|
|
|
|
*m0 = NULL;
|
|
|
|
return (ENOBUFS);
|
|
|
|
}
|
|
|
|
ip = (struct ip *)(mtod(m, caddr_t) + i);
|
|
|
|
i += (ip->ip_hl << 2);
|
|
|
|
cflags = i << HME_XD_TXCKSUM_SSHIFT |
|
|
|
|
((i + m->m_pkthdr.csum_data) << HME_XD_TXCKSUM_OSHIFT) |
|
|
|
|
HME_XD_TXCKSUM;
|
|
|
|
*m0 = m;
|
|
|
|
}
|
|
|
|
|
2005-10-25 03:56:21 +00:00
|
|
|
error = bus_dmamap_load_mbuf_sg(sc->sc_tdmatag, htx->htx_dmamap,
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
*m0, segs, &nsegs, 0);
|
2005-10-25 03:56:21 +00:00
|
|
|
if (error == EFBIG) {
|
2012-12-04 09:32:43 +00:00
|
|
|
m = m_collapse(*m0, M_NOWAIT, HME_NTXSEGS);
|
2006-08-12 01:19:37 +00:00
|
|
|
if (m == NULL) {
|
|
|
|
m_freem(*m0);
|
|
|
|
*m0 = NULL;
|
2005-10-25 03:56:21 +00:00
|
|
|
return (ENOMEM);
|
|
|
|
}
|
2006-08-12 01:19:37 +00:00
|
|
|
*m0 = m;
|
2005-10-25 03:56:21 +00:00
|
|
|
error = bus_dmamap_load_mbuf_sg(sc->sc_tdmatag, htx->htx_dmamap,
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
*m0, segs, &nsegs, 0);
|
2005-10-25 03:56:21 +00:00
|
|
|
if (error != 0) {
|
2006-08-12 01:19:37 +00:00
|
|
|
m_freem(*m0);
|
|
|
|
*m0 = NULL;
|
2005-10-25 03:56:21 +00:00
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
} else if (error != 0)
|
|
|
|
return (error);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
/* If nsegs is wrong then the stack is corrupt. */
|
|
|
|
KASSERT(nsegs <= HME_NTXSEGS,
|
|
|
|
("%s: too many DMA segments (%d)", __func__, nsegs));
|
|
|
|
if (nsegs == 0) {
|
2006-08-12 01:19:37 +00:00
|
|
|
m_freem(*m0);
|
|
|
|
*m0 = NULL;
|
2005-10-25 03:56:21 +00:00
|
|
|
return (EIO);
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
if (sc->sc_rb.rb_td_nbusy + nsegs >= HME_NTXDESC) {
|
2005-10-25 03:56:21 +00:00
|
|
|
bus_dmamap_unload(sc->sc_tdmatag, htx->htx_dmamap);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
/* Retry with m_collapse(9)? */
|
|
|
|
return (ENOBUFS);
|
2005-10-25 03:56:21 +00:00
|
|
|
}
|
|
|
|
bus_dmamap_sync(sc->sc_tdmatag, htx->htx_dmamap, BUS_DMASYNC_PREWRITE);
|
|
|
|
|
|
|
|
si = ri = sc->sc_rb.rb_tdhead;
|
|
|
|
txd = sc->sc_rb.rb_txd;
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
pci = sc->sc_flags & HME_PCI;
|
2005-10-25 03:56:21 +00:00
|
|
|
CTR2(KTR_HME, "hme_load_mbuf: next desc is %d (%#x)", ri,
|
|
|
|
HME_XD_GETFLAGS(pci, txd, ri));
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
for (i = 0; i < nsegs; i++) {
|
2005-10-25 03:56:21 +00:00
|
|
|
/* Fill the ring entry. */
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
flags = HME_XD_ENCODE_TSIZE(segs[i].ds_len);
|
2005-10-25 03:56:21 +00:00
|
|
|
if (i == 0)
|
|
|
|
flags |= HME_XD_SOP | cflags;
|
|
|
|
else
|
|
|
|
flags |= HME_XD_OWN | cflags;
|
2002-02-27 17:35:48 +00:00
|
|
|
CTR3(KTR_HME, "hme_load_mbuf: activating ri %d, si %d (%#x)",
|
|
|
|
ri, si, flags);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
HME_XD_SETADDR(pci, txd, ri, segs[i].ds_addr);
|
2005-10-25 03:56:21 +00:00
|
|
|
HME_XD_SETFLAGS(pci, txd, ri, flags);
|
|
|
|
sc->sc_rb.rb_td_nbusy++;
|
|
|
|
htx->htx_lastdesc = ri;
|
|
|
|
ri = (ri + 1) % HME_NTXDESC;
|
|
|
|
}
|
|
|
|
sc->sc_rb.rb_tdhead = ri;
|
|
|
|
|
|
|
|
/* set EOP on the last descriptor */
|
|
|
|
ri = (ri + HME_NTXDESC - 1) % HME_NTXDESC;
|
|
|
|
flags = HME_XD_GETFLAGS(pci, txd, ri);
|
|
|
|
flags |= HME_XD_EOP;
|
|
|
|
CTR3(KTR_HME, "hme_load_mbuf: setting EOP ri %d, si %d (%#x)", ri, si,
|
|
|
|
flags);
|
|
|
|
HME_XD_SETFLAGS(pci, txd, ri, flags);
|
|
|
|
|
|
|
|
/* Turn the first descriptor ownership to the hme */
|
|
|
|
flags = HME_XD_GETFLAGS(pci, txd, si);
|
|
|
|
flags |= HME_XD_OWN;
|
|
|
|
CTR2(KTR_HME, "hme_load_mbuf: setting OWN for 1st desc ri %d, (%#x)",
|
|
|
|
ri, flags);
|
|
|
|
HME_XD_SETFLAGS(pci, txd, si, flags);
|
|
|
|
|
|
|
|
STAILQ_REMOVE_HEAD(&sc->sc_rb.rb_txfreeq, htx_q);
|
|
|
|
STAILQ_INSERT_TAIL(&sc->sc_rb.rb_txbusyq, htx, htx_q);
|
2006-08-12 01:19:37 +00:00
|
|
|
htx->htx_m = *m0;
|
2002-02-27 17:35:48 +00:00
|
|
|
|
|
|
|
/* start the transmission. */
|
|
|
|
HME_ETX_WRITE_4(sc, HME_ETXI_PENDING, HME_ETX_TP_DMAWAKEUP);
|
2005-10-25 03:56:21 +00:00
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Pass a packet to the higher levels.
|
|
|
|
*/
|
|
|
|
static void
|
2004-08-05 02:52:33 +00:00
|
|
|
hme_read(struct hme_softc *sc, int ix, int len, u_int32_t flags)
|
2002-02-27 17:35:48 +00:00
|
|
|
{
|
2005-06-10 16:49:24 +00:00
|
|
|
struct ifnet *ifp = sc->sc_ifp;
|
2002-02-27 17:35:48 +00:00
|
|
|
struct mbuf *m;
|
|
|
|
|
|
|
|
if (len <= sizeof(struct ether_header) ||
|
2004-05-06 13:38:19 +00:00
|
|
|
len > HME_MAX_FRAMESIZE) {
|
2002-02-27 17:35:48 +00:00
|
|
|
#ifdef HMEDEBUG
|
|
|
|
HME_WHINE(sc->sc_dev, "invalid packet size %d; dropping\n",
|
|
|
|
len);
|
|
|
|
#endif
|
2014-09-18 21:07:05 +00:00
|
|
|
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
|
2003-01-21 17:22:52 +00:00
|
|
|
hme_discard_rxbuf(sc, ix);
|
2002-07-14 12:09:48 +00:00
|
|
|
return;
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
m = sc->sc_rb.rb_rxdesc[ix].hrx_m;
|
2003-01-06 22:12:57 +00:00
|
|
|
CTR1(KTR_HME, "hme_read: len %d", len);
|
2002-02-27 17:35:48 +00:00
|
|
|
|
|
|
|
if (hme_add_rxbuf(sc, ix, 0) != 0) {
|
|
|
|
/*
|
|
|
|
* hme_add_rxbuf will leave the old buffer in the ring until
|
|
|
|
* it is sure that a new buffer can be mapped. If it can not,
|
|
|
|
* drop the packet, but leave the interface up.
|
|
|
|
*/
|
2014-09-18 21:07:05 +00:00
|
|
|
if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
|
2003-01-21 17:22:52 +00:00
|
|
|
hme_discard_rxbuf(sc, ix);
|
2002-07-14 12:09:48 +00:00
|
|
|
return;
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|
|
|
|
|
2014-09-18 21:07:05 +00:00
|
|
|
if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
|
2002-02-27 17:35:48 +00:00
|
|
|
|
|
|
|
m->m_pkthdr.rcvif = ifp;
|
2003-01-06 22:12:57 +00:00
|
|
|
m->m_pkthdr.len = m->m_len = len + HME_RXOFFS;
|
|
|
|
m_adj(m, HME_RXOFFS);
|
2004-08-05 02:52:33 +00:00
|
|
|
/* RX TCP/UDP checksum */
|
|
|
|
if (ifp->if_capenable & IFCAP_RXCSUM)
|
|
|
|
hme_rxcksum(m, flags);
|
2002-02-27 17:35:48 +00:00
|
|
|
/* Pass the packet up. */
|
2004-11-22 06:46:30 +00:00
|
|
|
HME_UNLOCK(sc);
|
2002-11-14 23:54:55 +00:00
|
|
|
(*ifp->if_input)(ifp, m);
|
2004-11-22 06:46:30 +00:00
|
|
|
HME_LOCK(sc);
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
hme_start(struct ifnet *ifp)
|
2004-11-22 06:46:30 +00:00
|
|
|
{
|
|
|
|
struct hme_softc *sc = ifp->if_softc;
|
|
|
|
|
|
|
|
HME_LOCK(sc);
|
|
|
|
hme_start_locked(ifp);
|
|
|
|
HME_UNLOCK(sc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
hme_start_locked(struct ifnet *ifp)
|
2002-02-27 17:35:48 +00:00
|
|
|
{
|
|
|
|
struct hme_softc *sc = (struct hme_softc *)ifp->if_softc;
|
|
|
|
struct mbuf *m;
|
|
|
|
int error, enq = 0;
|
|
|
|
|
2005-08-09 10:20:02 +00:00
|
|
|
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
IFF_DRV_RUNNING || (sc->sc_flags & HME_LINK) == 0)
|
2002-02-27 17:35:48 +00:00
|
|
|
return;
|
|
|
|
|
2005-10-25 03:56:21 +00:00
|
|
|
for (; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) &&
|
|
|
|
sc->sc_rb.rb_td_nbusy < HME_NTXDESC - 1;) {
|
2004-08-01 23:58:04 +00:00
|
|
|
IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
|
2002-02-27 17:35:48 +00:00
|
|
|
if (m == NULL)
|
|
|
|
break;
|
|
|
|
|
2005-10-25 03:56:21 +00:00
|
|
|
error = hme_load_txmbuf(sc, &m);
|
|
|
|
if (error != 0) {
|
|
|
|
if (m == NULL)
|
|
|
|
break;
|
2005-08-09 10:20:02 +00:00
|
|
|
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
2004-08-01 23:58:04 +00:00
|
|
|
IFQ_DRV_PREPEND(&ifp->if_snd, m);
|
2002-03-09 21:50:25 +00:00
|
|
|
break;
|
2002-07-30 21:47:14 +00:00
|
|
|
}
|
2005-10-25 03:56:21 +00:00
|
|
|
enq++;
|
|
|
|
BPF_MTAP(ifp, m);
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|
|
|
|
|
2005-10-25 03:56:21 +00:00
|
|
|
if (enq > 0) {
|
2003-01-21 17:22:52 +00:00
|
|
|
bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap,
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
2006-12-06 02:07:20 +00:00
|
|
|
sc->sc_wdog_timer = 5;
|
2003-01-21 17:22:52 +00:00
|
|
|
}
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Transmit interrupt.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
hme_tint(struct hme_softc *sc)
|
|
|
|
{
|
2005-10-25 03:56:21 +00:00
|
|
|
caddr_t txd;
|
2005-06-10 16:49:24 +00:00
|
|
|
struct ifnet *ifp = sc->sc_ifp;
|
2003-01-06 22:12:57 +00:00
|
|
|
struct hme_txdesc *htx;
|
2002-02-27 17:35:48 +00:00
|
|
|
unsigned int ri, txflags;
|
|
|
|
|
2005-10-25 03:56:21 +00:00
|
|
|
txd = sc->sc_rb.rb_txd;
|
2003-01-06 22:12:57 +00:00
|
|
|
htx = STAILQ_FIRST(&sc->sc_rb.rb_txbusyq);
|
2003-01-21 17:22:52 +00:00
|
|
|
bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, BUS_DMASYNC_POSTREAD);
|
2002-02-27 17:35:48 +00:00
|
|
|
/* Fetch current position in the transmit ring */
|
|
|
|
for (ri = sc->sc_rb.rb_tdtail;; ri = (ri + 1) % HME_NTXDESC) {
|
|
|
|
if (sc->sc_rb.rb_td_nbusy <= 0) {
|
|
|
|
CTR0(KTR_HME, "hme_tint: not busy!");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
txflags = HME_XD_GETFLAGS(sc->sc_flags & HME_PCI, txd, ri);
|
2002-02-27 17:35:48 +00:00
|
|
|
CTR2(KTR_HME, "hme_tint: index %d, flags %#x", ri, txflags);
|
|
|
|
|
|
|
|
if ((txflags & HME_XD_OWN) != 0)
|
|
|
|
break;
|
|
|
|
|
2003-01-06 22:12:57 +00:00
|
|
|
CTR0(KTR_HME, "hme_tint: not owned");
|
2002-02-27 17:35:48 +00:00
|
|
|
--sc->sc_rb.rb_td_nbusy;
|
2005-08-09 10:20:02 +00:00
|
|
|
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
2002-02-27 17:35:48 +00:00
|
|
|
|
|
|
|
/* Complete packet transmitted? */
|
|
|
|
if ((txflags & HME_XD_EOP) == 0)
|
|
|
|
continue;
|
|
|
|
|
2003-01-06 22:12:57 +00:00
|
|
|
KASSERT(htx->htx_lastdesc == ri,
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
("%s: ring indices skewed: %d != %d!",
|
|
|
|
__func__, htx->htx_lastdesc, ri));
|
2003-01-06 22:12:57 +00:00
|
|
|
bus_dmamap_sync(sc->sc_tdmatag, htx->htx_dmamap,
|
|
|
|
BUS_DMASYNC_POSTWRITE);
|
|
|
|
bus_dmamap_unload(sc->sc_tdmatag, htx->htx_dmamap);
|
|
|
|
|
2014-09-18 21:07:05 +00:00
|
|
|
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
|
2003-01-06 22:12:57 +00:00
|
|
|
m_freem(htx->htx_m);
|
|
|
|
htx->htx_m = NULL;
|
|
|
|
STAILQ_REMOVE_HEAD(&sc->sc_rb.rb_txbusyq, htx_q);
|
|
|
|
STAILQ_INSERT_TAIL(&sc->sc_rb.rb_txfreeq, htx, htx_q);
|
|
|
|
htx = STAILQ_FIRST(&sc->sc_rb.rb_txbusyq);
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|
2006-12-06 02:07:20 +00:00
|
|
|
sc->sc_wdog_timer = sc->sc_rb.rb_td_nbusy > 0 ? 5 : 0;
|
2002-02-27 17:35:48 +00:00
|
|
|
|
|
|
|
/* Update ring */
|
|
|
|
sc->sc_rb.rb_tdtail = ri;
|
|
|
|
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
hme_start_locked(ifp);
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|
|
|
|
|
2004-08-05 02:52:33 +00:00
|
|
|
/*
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
* RX TCP/UDP checksum
|
2004-08-05 02:52:33 +00:00
|
|
|
*/
|
|
|
|
static void
|
|
|
|
hme_rxcksum(struct mbuf *m, u_int32_t flags)
|
|
|
|
{
|
|
|
|
struct ether_header *eh;
|
|
|
|
struct ip *ip;
|
|
|
|
struct udphdr *uh;
|
|
|
|
int32_t hlen, len, pktlen;
|
|
|
|
u_int16_t cksum, *opts;
|
|
|
|
u_int32_t temp32;
|
|
|
|
|
|
|
|
pktlen = m->m_pkthdr.len;
|
|
|
|
if (pktlen < sizeof(struct ether_header) + sizeof(struct ip))
|
|
|
|
return;
|
|
|
|
eh = mtod(m, struct ether_header *);
|
|
|
|
if (eh->ether_type != htons(ETHERTYPE_IP))
|
|
|
|
return;
|
|
|
|
ip = (struct ip *)(eh + 1);
|
|
|
|
if (ip->ip_v != IPVERSION)
|
|
|
|
return;
|
|
|
|
|
|
|
|
hlen = ip->ip_hl << 2;
|
|
|
|
pktlen -= sizeof(struct ether_header);
|
|
|
|
if (hlen < sizeof(struct ip))
|
|
|
|
return;
|
|
|
|
if (ntohs(ip->ip_len) < hlen)
|
|
|
|
return;
|
|
|
|
if (ntohs(ip->ip_len) != pktlen)
|
|
|
|
return;
|
|
|
|
if (ip->ip_off & htons(IP_MF | IP_OFFMASK))
|
|
|
|
return; /* can't handle fragmented packet */
|
|
|
|
|
|
|
|
switch (ip->ip_p) {
|
|
|
|
case IPPROTO_TCP:
|
|
|
|
if (pktlen < (hlen + sizeof(struct tcphdr)))
|
|
|
|
return;
|
|
|
|
break;
|
|
|
|
case IPPROTO_UDP:
|
|
|
|
if (pktlen < (hlen + sizeof(struct udphdr)))
|
|
|
|
return;
|
|
|
|
uh = (struct udphdr *)((caddr_t)ip + hlen);
|
|
|
|
if (uh->uh_sum == 0)
|
|
|
|
return; /* no checksum */
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-03-21 12:21:51 +00:00
|
|
|
cksum = ~(flags & HME_XD_RXCKSUM);
|
2004-08-05 02:52:33 +00:00
|
|
|
/* checksum fixup for IP options */
|
|
|
|
len = hlen - sizeof(struct ip);
|
|
|
|
if (len > 0) {
|
|
|
|
opts = (u_int16_t *)(ip + 1);
|
|
|
|
for (; len > 0; len -= sizeof(u_int16_t), opts++) {
|
|
|
|
temp32 = cksum - *opts;
|
|
|
|
temp32 = (temp32 >> 16) + (temp32 & 65535);
|
|
|
|
cksum = temp32 & 65535;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m->m_pkthdr.csum_flags |= CSUM_DATA_VALID;
|
|
|
|
m->m_pkthdr.csum_data = cksum;
|
|
|
|
}
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
/*
|
|
|
|
* Receive interrupt.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
hme_rint(struct hme_softc *sc)
|
|
|
|
{
|
|
|
|
caddr_t xdr = sc->sc_rb.rb_rxd;
|
2005-06-10 16:49:24 +00:00
|
|
|
struct ifnet *ifp = sc->sc_ifp;
|
2002-02-27 17:35:48 +00:00
|
|
|
unsigned int ri, len;
|
2003-01-21 17:22:52 +00:00
|
|
|
int progress = 0;
|
2002-02-27 17:35:48 +00:00
|
|
|
u_int32_t flags;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Process all buffers with valid data.
|
|
|
|
*/
|
2003-01-21 17:22:52 +00:00
|
|
|
bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap, BUS_DMASYNC_POSTREAD);
|
2002-02-27 17:35:48 +00:00
|
|
|
for (ri = sc->sc_rb.rb_rdtail;; ri = (ri + 1) % HME_NRXDESC) {
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
flags = HME_XD_GETFLAGS(sc->sc_flags & HME_PCI, xdr, ri);
|
2002-02-27 17:35:48 +00:00
|
|
|
CTR2(KTR_HME, "hme_rint: index %d, flags %#x", ri, flags);
|
|
|
|
if ((flags & HME_XD_OWN) != 0)
|
|
|
|
break;
|
|
|
|
|
2003-01-21 17:22:52 +00:00
|
|
|
progress++;
|
2002-02-27 17:35:48 +00:00
|
|
|
if ((flags & HME_XD_OFL) != 0) {
|
|
|
|
device_printf(sc->sc_dev, "buffer overflow, ri=%d; "
|
|
|
|
"flags=0x%x\n", ri, flags);
|
2014-09-18 21:07:05 +00:00
|
|
|
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
|
2003-01-21 17:22:52 +00:00
|
|
|
hme_discard_rxbuf(sc, ri);
|
2002-02-27 17:35:48 +00:00
|
|
|
} else {
|
|
|
|
len = HME_XD_DECODE_RSIZE(flags);
|
2004-08-05 02:52:33 +00:00
|
|
|
hme_read(sc, ri, len, flags);
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|
|
|
|
}
|
2003-01-21 17:22:52 +00:00
|
|
|
if (progress) {
|
|
|
|
bus_dmamap_sync(sc->sc_cdmatag, sc->sc_cdmamap,
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
2003-01-21 17:22:52 +00:00
|
|
|
}
|
2002-02-27 17:35:48 +00:00
|
|
|
sc->sc_rb.rb_rdtail = ri;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
hme_eint(struct hme_softc *sc, u_int status)
|
|
|
|
{
|
|
|
|
|
|
|
|
if ((status & HME_SEB_STAT_MIFIRQ) != 0) {
|
2006-12-04 00:51:08 +00:00
|
|
|
device_printf(sc->sc_dev, "XXXlink status changed: "
|
|
|
|
"cfg=%#x, stat=%#x, sm=%#x\n",
|
|
|
|
HME_MIF_READ_4(sc, HME_MIFI_CFG),
|
|
|
|
HME_MIF_READ_4(sc, HME_MIFI_STAT),
|
|
|
|
HME_MIF_READ_4(sc, HME_MIFI_SM));
|
2002-02-27 17:35:48 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-10-25 03:56:21 +00:00
|
|
|
/* check for fatal errors that needs reset to unfreeze DMA engine */
|
|
|
|
if ((status & HME_SEB_STAT_FATAL_ERRORS) != 0) {
|
|
|
|
HME_WHINE(sc->sc_dev, "error signaled, status=%#x\n", status);
|
2013-07-10 06:46:46 +00:00
|
|
|
sc->sc_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
2005-10-25 03:56:21 +00:00
|
|
|
hme_init_locked(sc);
|
|
|
|
}
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
hme_intr(void *v)
|
|
|
|
{
|
|
|
|
struct hme_softc *sc = (struct hme_softc *)v;
|
|
|
|
u_int32_t status;
|
|
|
|
|
2004-11-22 06:46:30 +00:00
|
|
|
HME_LOCK(sc);
|
2002-02-27 17:35:48 +00:00
|
|
|
status = HME_SEB_READ_4(sc, HME_SEBI_STAT);
|
|
|
|
CTR1(KTR_HME, "hme_intr: status %#x", (u_int)status);
|
|
|
|
|
|
|
|
if ((status & HME_SEB_STAT_ALL_ERRORS) != 0)
|
|
|
|
hme_eint(sc, status);
|
|
|
|
|
|
|
|
if ((status & HME_SEB_STAT_RXTOHOST) != 0)
|
|
|
|
hme_rint(sc);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
|
|
|
|
if ((status & (HME_SEB_STAT_TXALL | HME_SEB_STAT_HOSTTOTX)) != 0)
|
|
|
|
hme_tint(sc);
|
2004-11-22 06:46:30 +00:00
|
|
|
HME_UNLOCK(sc);
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|
|
|
|
|
2006-12-06 02:07:20 +00:00
|
|
|
static int
|
|
|
|
hme_watchdog(struct hme_softc *sc)
|
2002-02-27 17:35:48 +00:00
|
|
|
{
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
struct ifnet *ifp = sc->sc_ifp;
|
2002-02-27 17:35:48 +00:00
|
|
|
|
2006-12-06 02:07:20 +00:00
|
|
|
HME_LOCK_ASSERT(sc, MA_OWNED);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
|
2004-11-22 06:46:30 +00:00
|
|
|
#ifdef HMEDEBUG
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
CTR1(KTR_HME, "hme_watchdog: status %x",
|
|
|
|
(u_int)HME_SEB_READ_4(sc, HME_SEBI_STAT));
|
2002-02-27 17:35:48 +00:00
|
|
|
#endif
|
2006-12-06 02:07:20 +00:00
|
|
|
|
|
|
|
if (sc->sc_wdog_timer == 0 || --sc->sc_wdog_timer != 0)
|
|
|
|
return (0);
|
|
|
|
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
if ((sc->sc_flags & HME_LINK) != 0)
|
|
|
|
device_printf(sc->sc_dev, "device timeout\n");
|
|
|
|
else if (bootverbose)
|
|
|
|
device_printf(sc->sc_dev, "device timeout (no link)\n");
|
2014-09-18 21:07:05 +00:00
|
|
|
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
|
2002-02-27 17:35:48 +00:00
|
|
|
|
2013-07-10 06:46:46 +00:00
|
|
|
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
2005-08-10 20:12:25 +00:00
|
|
|
hme_init_locked(sc);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
hme_start_locked(ifp);
|
2006-12-06 02:07:20 +00:00
|
|
|
return (EJUSTRETURN);
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize the MII Management Interface
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
hme_mifinit(struct hme_softc *sc)
|
|
|
|
{
|
|
|
|
u_int32_t v;
|
|
|
|
|
2006-12-04 00:51:08 +00:00
|
|
|
/*
|
|
|
|
* Configure the MIF in frame mode, polling disabled, internal PHY
|
|
|
|
* selected.
|
|
|
|
*/
|
|
|
|
HME_MIF_WRITE_4(sc, HME_MIFI_CFG, 0);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the currently selected media uses the external transceiver,
|
|
|
|
* enable its MII drivers (which basically isolates the internal
|
|
|
|
* one and vice versa). In case the current media hasn't been set,
|
|
|
|
* yet, we default to the internal transceiver.
|
|
|
|
*/
|
|
|
|
v = HME_MAC_READ_4(sc, HME_MACI_XIF);
|
|
|
|
if (sc->sc_mii != NULL && sc->sc_mii->mii_media.ifm_cur != NULL &&
|
|
|
|
sc->sc_phys[IFM_INST(sc->sc_mii->mii_media.ifm_cur->ifm_media)] ==
|
|
|
|
HME_PHYAD_EXTERNAL)
|
|
|
|
v |= HME_MAC_XIF_MIIENABLE;
|
|
|
|
else
|
|
|
|
v &= ~HME_MAC_XIF_MIIENABLE;
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_XIF, v);
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* MII interface
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
hme_mii_readreg(device_t dev, int phy, int reg)
|
|
|
|
{
|
2006-12-04 00:51:08 +00:00
|
|
|
struct hme_softc *sc;
|
2002-02-27 17:35:48 +00:00
|
|
|
int n;
|
|
|
|
u_int32_t v;
|
|
|
|
|
2006-12-04 00:51:08 +00:00
|
|
|
sc = device_get_softc(dev);
|
2002-02-27 17:35:48 +00:00
|
|
|
/* Select the desired PHY in the MIF configuration register */
|
|
|
|
v = HME_MIF_READ_4(sc, HME_MIFI_CFG);
|
|
|
|
if (phy == HME_PHYAD_EXTERNAL)
|
|
|
|
v |= HME_MIF_CFG_PHY;
|
2006-12-04 00:51:08 +00:00
|
|
|
else
|
|
|
|
v &= ~HME_MIF_CFG_PHY;
|
2002-02-27 17:35:48 +00:00
|
|
|
HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v);
|
|
|
|
|
|
|
|
/* Construct the frame command */
|
|
|
|
v = (MII_COMMAND_START << HME_MIF_FO_ST_SHIFT) |
|
|
|
|
HME_MIF_FO_TAMSB |
|
|
|
|
(MII_COMMAND_READ << HME_MIF_FO_OPC_SHIFT) |
|
|
|
|
(phy << HME_MIF_FO_PHYAD_SHIFT) |
|
|
|
|
(reg << HME_MIF_FO_REGAD_SHIFT);
|
|
|
|
|
|
|
|
HME_MIF_WRITE_4(sc, HME_MIFI_FO, v);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
HME_MIF_BARRIER(sc, HME_MIFI_FO, 4,
|
|
|
|
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
|
2002-02-27 17:35:48 +00:00
|
|
|
for (n = 0; n < 100; n++) {
|
|
|
|
DELAY(1);
|
|
|
|
v = HME_MIF_READ_4(sc, HME_MIFI_FO);
|
2006-12-04 00:51:08 +00:00
|
|
|
if (v & HME_MIF_FO_TALSB)
|
2002-02-27 17:35:48 +00:00
|
|
|
return (v & HME_MIF_FO_DATA);
|
|
|
|
}
|
|
|
|
|
|
|
|
device_printf(sc->sc_dev, "mii_read timeout\n");
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
hme_mii_writereg(device_t dev, int phy, int reg, int val)
|
|
|
|
{
|
2006-12-04 00:51:08 +00:00
|
|
|
struct hme_softc *sc;
|
2002-02-27 17:35:48 +00:00
|
|
|
int n;
|
|
|
|
u_int32_t v;
|
|
|
|
|
2006-12-04 00:51:08 +00:00
|
|
|
sc = device_get_softc(dev);
|
2002-02-27 17:35:48 +00:00
|
|
|
/* Select the desired PHY in the MIF configuration register */
|
|
|
|
v = HME_MIF_READ_4(sc, HME_MIFI_CFG);
|
|
|
|
if (phy == HME_PHYAD_EXTERNAL)
|
|
|
|
v |= HME_MIF_CFG_PHY;
|
2006-12-04 00:51:08 +00:00
|
|
|
else
|
|
|
|
v &= ~HME_MIF_CFG_PHY;
|
2002-02-27 17:35:48 +00:00
|
|
|
HME_MIF_WRITE_4(sc, HME_MIFI_CFG, v);
|
|
|
|
|
|
|
|
/* Construct the frame command */
|
|
|
|
v = (MII_COMMAND_START << HME_MIF_FO_ST_SHIFT) |
|
|
|
|
HME_MIF_FO_TAMSB |
|
|
|
|
(MII_COMMAND_WRITE << HME_MIF_FO_OPC_SHIFT) |
|
|
|
|
(phy << HME_MIF_FO_PHYAD_SHIFT) |
|
|
|
|
(reg << HME_MIF_FO_REGAD_SHIFT) |
|
|
|
|
(val & HME_MIF_FO_DATA);
|
|
|
|
|
|
|
|
HME_MIF_WRITE_4(sc, HME_MIFI_FO, v);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
HME_MIF_BARRIER(sc, HME_MIFI_FO, 4,
|
|
|
|
BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
|
2002-02-27 17:35:48 +00:00
|
|
|
for (n = 0; n < 100; n++) {
|
|
|
|
DELAY(1);
|
|
|
|
v = HME_MIF_READ_4(sc, HME_MIFI_FO);
|
2005-08-10 20:12:25 +00:00
|
|
|
if (v & HME_MIF_FO_TALSB)
|
2002-02-27 17:35:48 +00:00
|
|
|
return (1);
|
|
|
|
}
|
|
|
|
|
|
|
|
device_printf(sc->sc_dev, "mii_write timeout\n");
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
hme_mii_statchg(device_t dev)
|
|
|
|
{
|
2006-12-04 00:51:08 +00:00
|
|
|
struct hme_softc *sc;
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
uint32_t rxcfg, txcfg;
|
2002-02-27 17:35:48 +00:00
|
|
|
|
2006-12-04 00:51:08 +00:00
|
|
|
sc = device_get_softc(dev);
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
#ifdef HMEDEBUG
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
if ((sc->sc_ifp->if_flags & IFF_DEBUG) != 0)
|
2006-12-04 00:51:08 +00:00
|
|
|
device_printf(sc->sc_dev, "hme_mii_statchg: status change\n");
|
2002-02-27 17:35:48 +00:00
|
|
|
#endif
|
|
|
|
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
if ((sc->sc_mii->mii_media_status & IFM_ACTIVE) != 0 &&
|
|
|
|
IFM_SUBTYPE(sc->sc_mii->mii_media_active) != IFM_NONE)
|
|
|
|
sc->sc_flags |= HME_LINK;
|
|
|
|
else
|
|
|
|
sc->sc_flags &= ~HME_LINK;
|
|
|
|
|
|
|
|
txcfg = HME_MAC_READ_4(sc, HME_MACI_TXCFG);
|
|
|
|
if (!hme_mac_bitflip(sc, HME_MACI_TXCFG, txcfg,
|
|
|
|
HME_MAC_TXCFG_ENABLE, 0))
|
|
|
|
device_printf(sc->sc_dev, "cannot disable TX MAC\n");
|
|
|
|
rxcfg = HME_MAC_READ_4(sc, HME_MACI_RXCFG);
|
|
|
|
if (!hme_mac_bitflip(sc, HME_MACI_RXCFG, rxcfg,
|
|
|
|
HME_MAC_RXCFG_ENABLE, 0))
|
|
|
|
device_printf(sc->sc_dev, "cannot disable RX MAC\n");
|
|
|
|
|
|
|
|
/* Set the MAC Full Duplex bit appropriately. */
|
2002-02-27 17:35:48 +00:00
|
|
|
if ((IFM_OPTIONS(sc->sc_mii->mii_media_active) & IFM_FDX) != 0)
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
txcfg |= HME_MAC_TXCFG_FULLDPLX;
|
2002-02-27 17:35:48 +00:00
|
|
|
else
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
txcfg &= ~HME_MAC_TXCFG_FULLDPLX;
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_TXCFG, txcfg);
|
|
|
|
|
|
|
|
if ((sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
|
|
|
|
(sc->sc_flags & HME_LINK) != 0) {
|
|
|
|
if (!hme_mac_bitflip(sc, HME_MACI_TXCFG, txcfg, 0,
|
|
|
|
HME_MAC_TXCFG_ENABLE))
|
|
|
|
device_printf(sc->sc_dev, "cannot enable TX MAC\n");
|
|
|
|
if (!hme_mac_bitflip(sc, HME_MACI_RXCFG, rxcfg, 0,
|
|
|
|
HME_MAC_RXCFG_ENABLE))
|
|
|
|
device_printf(sc->sc_dev, "cannot enable RX MAC\n");
|
|
|
|
}
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
hme_mediachange(struct ifnet *ifp)
|
|
|
|
{
|
|
|
|
struct hme_softc *sc = ifp->if_softc;
|
2005-08-10 20:12:25 +00:00
|
|
|
int error;
|
2002-02-27 17:35:48 +00:00
|
|
|
|
2005-08-10 20:12:25 +00:00
|
|
|
HME_LOCK(sc);
|
2006-12-04 00:51:08 +00:00
|
|
|
error = hme_mediachange_locked(sc);
|
2005-08-10 20:12:25 +00:00
|
|
|
HME_UNLOCK(sc);
|
|
|
|
return (error);
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|
|
|
|
|
2006-12-04 00:51:08 +00:00
|
|
|
static int
|
|
|
|
hme_mediachange_locked(struct hme_softc *sc)
|
|
|
|
{
|
|
|
|
struct mii_softc *child;
|
|
|
|
|
|
|
|
HME_LOCK_ASSERT(sc, MA_OWNED);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
|
2006-12-04 00:51:08 +00:00
|
|
|
#ifdef HMEDEBUG
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
if ((sc->sc_ifp->if_flags & IFF_DEBUG) != 0)
|
2006-12-04 00:51:08 +00:00
|
|
|
device_printf(sc->sc_dev, "hme_mediachange_locked");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
hme_mifinit(sc);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If both PHYs are present reset them. This is required for
|
|
|
|
* unisolating the previously isolated PHY when switching PHYs.
|
|
|
|
* As the above hme_mifinit() call will set the MII drivers in
|
2011-04-22 09:39:05 +00:00
|
|
|
* the XIF configuration register according to the currently
|
2006-12-04 00:51:08 +00:00
|
|
|
* selected media, there should be no window during which the
|
|
|
|
* data paths of both transceivers are open at the same time,
|
|
|
|
* even if the PHY device drivers use MIIF_NOISOLATE.
|
|
|
|
*/
|
|
|
|
if (sc->sc_phys[0] != -1 && sc->sc_phys[1] != -1)
|
|
|
|
LIST_FOREACH(child, &sc->sc_mii->mii_phys, mii_list)
|
- Remove attempts to implement setting of BMCR_LOOP/MIIF_NOLOOP
(reporting IFM_LOOP based on BMCR_LOOP is left in place though as
it might provide useful for debugging). For most mii(4) drivers it
was unclear whether the PHYs driven by them actually support
loopback or not. Moreover, typically loopback mode also needs to
be activated on the MAC, which none of the Ethernet drivers using
mii(4) implements. Given that loopback media has no real use (and
obviously hardly had a chance to actually work) besides for driver
development (which just loopback mode should be sufficient for
though, i.e one doesn't necessary need support for loopback media)
support for it is just dropped as both NetBSD and OpenBSD already
did quite some time ago.
- Let mii_phy_add_media() also announce the support of IFM_NONE.
- Restructure the PHY entry points to use a structure of entry points
instead of discrete function pointers, and extend this to include
a "reset" entry point. Make sure any PHY-specific reset routine is
always used, and provide one for lxtphy(4) which disables MII
interrupts (as is done for a few other PHYs we have drivers for).
This includes changing NIC drivers which previously just called the
generic mii_phy_reset() to now actually call the PHY-specific reset
routine, which might be crucial in some cases. While at it, the
redundant checks in these NIC drivers for mii->mii_instance not being
zero before calling the reset routines were removed because as soon
as one PHY driver attaches mii->mii_instance is incremented and we
hardly can end up in their media change callbacks etc if no PHY driver
has attached as mii_attach() would have failed in that case and not
attach a miibus(4) instance.
Consequently, NIC drivers now no longer should call mii_phy_reset()
directly, so it was removed from EXPORT_SYMS.
- Add a mii_phy_dev_attach() as a companion helper to mii_phy_dev_probe().
The purpose of that function is to perform the common steps to attach
a PHY driver instance and to hook it up to the miibus(4) instance and to
optionally also handle the probing, addition and initialization of the
supported media. So all a PHY driver without any special requirements
has to do in its bus attach method is to call mii_phy_dev_attach()
along with PHY-specific MIIF_* flags, a pointer to its PHY functions
and the add_media set to one. All PHY drivers were updated to take
advantage of mii_phy_dev_attach() as appropriate. Along with these
changes the capability mask was added to the mii_softc structure so
PHY drivers taking advantage of mii_phy_dev_attach() but still
handling media on their own do not need to fiddle with the MII attach
arguments anyway.
- Keep track of the PHY offset in the mii_softc structure. This is done
for compatibility with NetBSD/OpenBSD.
- Keep track of the PHY's OUI, model and revision in the mii_softc
structure. Several PHY drivers require this information also after
attaching and previously had to wrap their own softc around mii_softc.
NetBSD/OpenBSD also keep track of the model and revision on their
mii_softc structure. All PHY drivers were updated to take advantage
as appropriate.
- Convert the mebers of the MII data structure to unsigned where
appropriate. This is partly inspired by NetBSD/OpenBSD.
- According to IEEE 802.3-2002 the bits actually have to be reversed
when mapping an OUI to the MII ID registers. All PHY drivers and
miidevs where changed as necessary. Actually this now again allows to
largely share miidevs with NetBSD, which fixed this problem already
9 years ago. Consequently miidevs was synced as far as possible.
- Add MIIF_NOMANPAUSE and mii_phy_flowstatus() calls to drivers that
weren't explicitly converted to support flow control before. It's
unclear whether flow control actually works with these but typically
it should and their net behavior should be more correct with these
changes in place than without if the MAC driver sets MIIF_DOPAUSE.
Obtained from: NetBSD (partially)
Reviewed by: yongari (earlier version), silence on arch@ and net@
2011-05-03 19:51:29 +00:00
|
|
|
PHY_RESET(child);
|
2006-12-04 00:51:08 +00:00
|
|
|
return (mii_mediachg(sc->sc_mii));
|
|
|
|
}
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
static void
|
|
|
|
hme_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
|
|
|
|
{
|
|
|
|
struct hme_softc *sc = ifp->if_softc;
|
|
|
|
|
2004-11-22 06:46:30 +00:00
|
|
|
HME_LOCK(sc);
|
|
|
|
if ((ifp->if_flags & IFF_UP) == 0) {
|
|
|
|
HME_UNLOCK(sc);
|
2002-02-27 17:35:48 +00:00
|
|
|
return;
|
2004-11-22 06:46:30 +00:00
|
|
|
}
|
2002-02-27 17:35:48 +00:00
|
|
|
|
|
|
|
mii_pollstat(sc->sc_mii);
|
|
|
|
ifmr->ifm_active = sc->sc_mii->mii_media_active;
|
|
|
|
ifmr->ifm_status = sc->sc_mii->mii_media_status;
|
2004-11-22 06:46:30 +00:00
|
|
|
HME_UNLOCK(sc);
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Process an ioctl request.
|
|
|
|
*/
|
|
|
|
static int
|
|
|
|
hme_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
|
|
|
{
|
|
|
|
struct hme_softc *sc = ifp->if_softc;
|
|
|
|
struct ifreq *ifr = (struct ifreq *)data;
|
2005-08-10 20:12:25 +00:00
|
|
|
int error = 0;
|
2002-02-27 17:35:48 +00:00
|
|
|
|
|
|
|
switch (cmd) {
|
|
|
|
case SIOCSIFFLAGS:
|
2005-08-10 20:12:25 +00:00
|
|
|
HME_LOCK(sc);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
if ((ifp->if_flags & IFF_UP) != 0) {
|
|
|
|
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
|
|
|
|
((ifp->if_flags ^ sc->sc_ifflags) &
|
|
|
|
(IFF_ALLMULTI | IFF_PROMISC)) != 0)
|
|
|
|
hme_setladrf(sc, 1);
|
|
|
|
else
|
|
|
|
hme_init_locked(sc);
|
|
|
|
} else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
|
2002-02-27 17:35:48 +00:00
|
|
|
hme_stop(sc);
|
2004-08-05 02:52:33 +00:00
|
|
|
if ((ifp->if_flags & IFF_LINK0) != 0)
|
|
|
|
sc->sc_csum_features |= CSUM_UDP;
|
|
|
|
else
|
|
|
|
sc->sc_csum_features &= ~CSUM_UDP;
|
|
|
|
if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
|
|
|
|
ifp->if_hwassist = sc->sc_csum_features;
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
sc->sc_ifflags = ifp->if_flags;
|
2005-08-10 20:12:25 +00:00
|
|
|
HME_UNLOCK(sc);
|
2002-02-27 17:35:48 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case SIOCADDMULTI:
|
|
|
|
case SIOCDELMULTI:
|
2005-08-10 20:12:25 +00:00
|
|
|
HME_LOCK(sc);
|
2002-02-27 17:35:48 +00:00
|
|
|
hme_setladrf(sc, 1);
|
2005-08-10 20:12:25 +00:00
|
|
|
HME_UNLOCK(sc);
|
2002-02-27 17:35:48 +00:00
|
|
|
error = 0;
|
|
|
|
break;
|
|
|
|
case SIOCGIFMEDIA:
|
|
|
|
case SIOCSIFMEDIA:
|
|
|
|
error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii->mii_media, cmd);
|
|
|
|
break;
|
2004-08-05 02:52:33 +00:00
|
|
|
case SIOCSIFCAP:
|
2005-08-10 20:12:25 +00:00
|
|
|
HME_LOCK(sc);
|
2004-08-05 02:52:33 +00:00
|
|
|
ifp->if_capenable = ifr->ifr_reqcap;
|
|
|
|
if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
|
|
|
|
ifp->if_hwassist = sc->sc_csum_features;
|
|
|
|
else
|
|
|
|
ifp->if_hwassist = 0;
|
2005-08-10 20:12:25 +00:00
|
|
|
HME_UNLOCK(sc);
|
2004-08-05 02:52:33 +00:00
|
|
|
break;
|
2002-02-27 17:35:48 +00:00
|
|
|
default:
|
2002-11-14 23:54:55 +00:00
|
|
|
error = ether_ioctl(ifp, cmd, data);
|
2002-02-27 17:35:48 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set up the logical address filter.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
hme_setladrf(struct hme_softc *sc, int reenable)
|
|
|
|
{
|
2005-06-10 16:49:24 +00:00
|
|
|
struct ifnet *ifp = sc->sc_ifp;
|
2002-02-27 17:35:48 +00:00
|
|
|
struct ifmultiaddr *inm;
|
|
|
|
u_int32_t crc;
|
|
|
|
u_int32_t hash[4];
|
|
|
|
u_int32_t macc;
|
|
|
|
|
2004-11-22 06:46:30 +00:00
|
|
|
HME_LOCK_ASSERT(sc, MA_OWNED);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
/* Clear the hash table. */
|
2002-02-27 17:35:48 +00:00
|
|
|
hash[3] = hash[2] = hash[1] = hash[0] = 0;
|
|
|
|
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
/* Get the current RX configuration. */
|
2002-02-27 17:35:48 +00:00
|
|
|
macc = HME_MAC_READ_4(sc, HME_MACI_RXCFG);
|
|
|
|
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
/*
|
|
|
|
* Turn off promiscuous mode, promiscuous group mode (all multicast),
|
|
|
|
* and hash filter. Depending on the case, the right bit will be
|
|
|
|
* enabled.
|
|
|
|
*/
|
|
|
|
macc &= ~(HME_MAC_RXCFG_PGRP | HME_MAC_RXCFG_PMISC);
|
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
/*
|
|
|
|
* Disable the receiver while changing it's state as the documentation
|
|
|
|
* mandates.
|
|
|
|
* We then must wait until the bit clears in the register. This should
|
|
|
|
* take at most 3.5ms.
|
|
|
|
*/
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
if (!hme_mac_bitflip(sc, HME_MACI_RXCFG, macc,
|
|
|
|
HME_MAC_RXCFG_ENABLE, 0))
|
|
|
|
device_printf(sc->sc_dev, "cannot disable RX MAC\n");
|
2002-02-27 17:35:48 +00:00
|
|
|
/* Disable the hash filter before writing to the filter registers. */
|
|
|
|
if (!hme_mac_bitflip(sc, HME_MACI_RXCFG, macc,
|
|
|
|
HME_MAC_RXCFG_HENABLE, 0))
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
device_printf(sc->sc_dev, "cannot disable hash filter\n");
|
2002-02-27 17:35:48 +00:00
|
|
|
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
/* Make the RX MAC really SIMPLEX. */
|
2005-05-23 05:45:36 +00:00
|
|
|
macc |= HME_MAC_RXCFG_ME;
|
2002-02-27 17:35:48 +00:00
|
|
|
if (reenable)
|
|
|
|
macc |= HME_MAC_RXCFG_ENABLE;
|
|
|
|
else
|
|
|
|
macc &= ~HME_MAC_RXCFG_ENABLE;
|
|
|
|
|
|
|
|
if ((ifp->if_flags & IFF_PROMISC) != 0) {
|
|
|
|
macc |= HME_MAC_RXCFG_PMISC;
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
goto chipit;
|
|
|
|
}
|
|
|
|
if ((ifp->if_flags & IFF_ALLMULTI) != 0) {
|
|
|
|
macc |= HME_MAC_RXCFG_PGRP;
|
2002-02-27 17:35:48 +00:00
|
|
|
goto chipit;
|
|
|
|
}
|
|
|
|
|
|
|
|
macc |= HME_MAC_RXCFG_HENABLE;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set up multicast address filter by passing all multicast addresses
|
|
|
|
* through a crc generator, and then using the high order 6 bits as an
|
|
|
|
* index into the 64 bit logical address filter. The high order bit
|
|
|
|
* selects the word, while the rest of the bits select the bit within
|
|
|
|
* the word.
|
|
|
|
*/
|
|
|
|
|
2009-06-26 11:45:06 +00:00
|
|
|
if_maddr_rlock(ifp);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
TAILQ_FOREACH(inm, &ifp->if_multiaddrs, ifma_link) {
|
2002-02-27 17:35:48 +00:00
|
|
|
if (inm->ifma_addr->sa_family != AF_LINK)
|
|
|
|
continue;
|
2004-06-10 00:06:04 +00:00
|
|
|
crc = ether_crc32_le(LLADDR((struct sockaddr_dl *)
|
|
|
|
inm->ifma_addr), ETHER_ADDR_LEN);
|
2004-06-09 14:34:04 +00:00
|
|
|
|
2002-02-27 17:35:48 +00:00
|
|
|
/* Just want the 6 most significant bits. */
|
|
|
|
crc >>= 26;
|
|
|
|
|
|
|
|
/* Set the corresponding bit in the filter. */
|
|
|
|
hash[crc >> 4] |= 1 << (crc & 0xf);
|
|
|
|
}
|
2009-06-26 11:45:06 +00:00
|
|
|
if_maddr_runlock(ifp);
|
2002-02-27 17:35:48 +00:00
|
|
|
|
|
|
|
chipit:
|
|
|
|
/* Now load the hash table into the chip */
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_HASHTAB0, hash[0]);
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_HASHTAB1, hash[1]);
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_HASHTAB2, hash[2]);
|
|
|
|
HME_MAC_WRITE_4(sc, HME_MACI_HASHTAB3, hash[3]);
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
if (!hme_mac_bitflip(sc, HME_MACI_RXCFG, macc, 0,
|
2005-05-23 05:45:36 +00:00
|
|
|
macc & (HME_MAC_RXCFG_ENABLE | HME_MAC_RXCFG_HENABLE |
|
o Disable HMEDEBUG by default.
o Add CTASSERTs ensuring that HME_NRXDESC and HME_NTXDESC are set to
legal values.
o Use appropriate maxsize, nsegments and maxsegsize parameters when
creating DMA tags and correct some comments related to them.
o The FreeBSD bus_dmamap_sync(9) supports ored together flags for quite
some time now so collapse calls accordingly.
o Add missing BUS_DMASYNC_PREREAD when syncing the control DMA maps in
hme_rint() and hme_start_locked().
o Keep state of the link state and use it to enable or disable the MAC
in hme_mii_statchg() accordingly as well as to return early from
hme_start_locked() in case the link is down.
o Introduce a sc_flags and use it to replace individual members like
sc_pci.
o Add bus_barrier(9) calls to hme_mac_bitflip(), hme_mii_readreg(),
hme_mii_writereg() and hme_stop() to ensure the respective bit
has been written before we starting polling on it and for the right
bits to change.
o Rather just returning in case hme_mac_bitflip() fails and leaving us
in an undefined state report the problem and move on; chances are
the requested configuration will become active shortly after.
o Don't call hme_start_locked() in hme_init_locked() unconditionally
but only after calls to hme_init_locked() when it's appropriate, i.e.
in hme_watchdog().
o Add a KASSERT which asserts nsegs is valid also to hme_load_txmbuf().
o In hme_load_txmbuf():
- use a maximum of the newly introduced HME_NTXSEGS segments instead
of the incorrect HME_NTXQ, which reflects the maximum TX queue
length, for loading the mbufs and put the DMA segments back onto
the stack instead of the softc as 16 should be ok there.
- use the common errno(2) return values instead of homegrown ones,
- given that hme_load_txmbuf() is allowed to fail resulting in a
packet drop for quite some time now implement the functionality of
hme_txcksum() by means of m_pullup(9), which de-obfuscates the code
and allows to always retrieve the correct length of the IP header, [1]
- also add a KASSERT which asserts nsegs is valid,
- take advantage of m_collapse(9) instead of m_defrag(9) for
performance reasons.
o Don't bother to check whether the interface is running or whether its
queue is empty before calling hme_start_locked() in hme_tint(), the
former will check these anyway.
o In hme_intr() call hme_rint() before hme_tint() as gem_tint() may
take quite a while to return when it calls hme_start_locked().
o Get rid of sc_debug and just check if_flags for IFF_DEBUG directly.
o Add a shadow sc_ifflags so we don't reset the chip when unnecessary.
o Handle IFF_ALLMULTI correctly. [2]
o Use PCIR_BAR instead of a homegrown macro.
o Replace sc_enaddr[6] with sc_enaddr[ETHER_ADDR_LEN].
o Use the maximum of 256 TX descriptors for better performance as using
all of them has no additional static cost rather than using just half
of them.
Reported by: rwatson [2]
Suggested by: yongari [1]
Reviewed by: yongari
MFC after: 1 month
2008-04-24 23:12:03 +00:00
|
|
|
HME_MAC_RXCFG_ME)))
|
|
|
|
device_printf(sc->sc_dev, "cannot configure RX MAC\n");
|
2002-02-27 17:35:48 +00:00
|
|
|
}
|