PERFORCE change 140397 for review
John Birrell
jb at FreeBSD.org
Tue Apr 22 09:53:36 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=140397
Change 140397 by jb at freebsd3 on 2008/04/22 09:52:57
IF7
Affected files ...
.. //depot/projects/dtrace7/src/lib/libc/stdlib/strfmon.c#2 integrate
.. //depot/projects/dtrace7/src/lib/libthr/thread/thr_mutexattr.c#2 integrate
.. //depot/projects/dtrace7/src/share/man/man4/nfe.4#3 integrate
.. //depot/projects/dtrace7/src/sys/dev/mii/ip1000phy.c#2 integrate
.. //depot/projects/dtrace7/src/sys/dev/mii/ip1000phyreg.h#2 integrate
.. //depot/projects/dtrace7/src/sys/dev/mii/miidevs#3 integrate
.. //depot/projects/dtrace7/src/sys/dev/mii/rgephy.c#2 integrate
.. //depot/projects/dtrace7/src/sys/dev/re/if_re.c#6 integrate
.. //depot/projects/dtrace7/src/sys/pci/if_rl.c#5 integrate
.. //depot/projects/dtrace7/src/sys/pci/if_rlreg.h#4 integrate
Differences ...
==== //depot/projects/dtrace7/src/lib/libc/stdlib/strfmon.c#2 (text+ko) ====
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/stdlib/strfmon.c,v 1.15 2005/09/12 19:52:42 stefanf Exp $");
+__FBSDID("$FreeBSD: src/lib/libc/stdlib/strfmon.c,v 1.15.2.1 2008/04/22 08:05:38 ru Exp $");
#include <sys/types.h>
#include <ctype.h>
@@ -67,6 +67,8 @@
while (isdigit((unsigned char)*fmt)) { \
VAR *= 10; \
VAR += *fmt - '0'; \
+ if (VAR < 0) \
+ goto e2big_error; \
fmt++; \
} \
} while (0)
@@ -187,7 +189,7 @@
/* Do we have enough space to put number with
* required width ?
*/
- if (dst + width >= s + maxsize)
+ if ((unsigned int)width >= maxsize - (dst - s))
goto e2big_error;
}
@@ -196,6 +198,8 @@
if (!isdigit((unsigned char)*++fmt))
goto format_error;
GET_NUMBER(left_prec);
+ if ((unsigned int)left_prec >= maxsize - (dst - s))
+ goto e2big_error;
}
/* Right precision */
@@ -203,6 +207,9 @@
if (!isdigit((unsigned char)*++fmt))
goto format_error;
GET_NUMBER(right_prec);
+ if ((unsigned int)right_prec >= maxsize - (dst - s) -
+ left_prec)
+ goto e2big_error;
}
/* Conversion Characters */
@@ -218,6 +225,8 @@
goto format_error;
}
+ if (currency_symbol != NULL)
+ free(currency_symbol);
if (flags & USE_INTL_CURRENCY) {
currency_symbol = strdup(lc->int_curr_symbol);
if (currency_symbol != NULL)
@@ -246,6 +255,8 @@
pad_size = 0;
}
+ if (asciivalue != NULL)
+ free(asciivalue);
asciivalue = __format_grouped_double(value, &flags,
left_prec, right_prec, pad_char);
if (asciivalue == NULL)
@@ -535,12 +546,11 @@
/* make sure that we've enough space for result string */
bufsize = strlen(avalue)*2+1;
- rslt = malloc(bufsize);
+ rslt = calloc(1, bufsize);
if (rslt == NULL) {
free(avalue);
return (NULL);
}
- memset(rslt, 0, bufsize);
bufend = rslt + bufsize - 1; /* reserve space for trailing '\0' */
/* skip spaces at beggining */
==== //depot/projects/dtrace7/src/lib/libthr/thread/thr_mutexattr.c#2 (text+ko) ====
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/lib/libthr/thread/thr_mutexattr.c,v 1.7 2007/01/12 07:26:20 imp Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_mutexattr.c,v 1.7.2.1 2008/04/22 01:28:15 davidxu Exp $
*/
/*
@@ -132,8 +132,7 @@
{
int ret;
if (attr == NULL || *attr == NULL || type >= PTHREAD_MUTEX_TYPE_MAX) {
- errno = EINVAL;
- ret = -1;
+ ret = EINVAL;
} else {
(*attr)->m_type = type;
ret = 0;
==== //depot/projects/dtrace7/src/share/man/man4/nfe.4#3 (text+ko) ====
@@ -14,9 +14,9 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.\" $FreeBSD: src/share/man/man4/nfe.4,v 1.8.2.1 2007/12/02 08:45:57 remko Exp $
+.\" $FreeBSD: src/share/man/man4/nfe.4,v 1.8.2.2 2008/04/22 06:19:29 yongari Exp $
.\"
-.Dd Nov 27, 2007
+.Dd April 16, 2008
.Dt NFE 4
.Os
.Sh NAME
@@ -43,7 +43,7 @@
driver supports PCI Ethernet adapters based on the NVIDIA
nForce Media and Communications Processors (MCP), such as
the nForce, nForce 2, nForce 3, CK804, MCP04, MCP51, MCP55,
-MCP61, MCP65 and MCP67 Ethernet controller chips.
+MCP61, MCP65, MCP67 and MCP73 Ethernet controller chips.
.Pp
Supported features include (hardware support provided):
.Pp
@@ -116,6 +116,8 @@
.It
NVIDIA nForce MCP67 Networking Adapter
.It
+NVIDIA nForce MCP73 Networking Adapter
+.It
NVIDIA nForce2 MCP2 Networking Adapter
.It
NVIDIA nForce2 400 MCP4 Networking Adapter
==== //depot/projects/dtrace7/src/sys/dev/mii/ip1000phy.c#2 (text+ko) ====
@@ -27,10 +27,10 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mii/ip1000phy.c,v 1.2 2006/12/02 15:32:33 marius Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/mii/ip1000phy.c,v 1.2.2.1 2008/04/22 06:35:37 yongari Exp $");
/*
- * Driver for the IC Plus IP1000A 10/100/1000 PHY.
+ * Driver for the IC Plus IP1000A/IP1001 10/100/1000 PHY.
*/
#include <sys/param.h>
@@ -57,6 +57,12 @@
static int ip1000phy_probe(device_t);
static int ip1000phy_attach(device_t);
+struct ip1000phy_softc {
+ struct mii_softc mii_sc;
+ int model;
+ int revision;
+};
+
static device_method_t ip1000phy_methods[] = {
/* device interface */
DEVMETHOD(device_probe, ip1000phy_probe),
@@ -82,6 +88,7 @@
static const struct mii_phydesc ip1000phys[] = {
MII_PHY_DESC(ICPLUS, IP1000A),
+ MII_PHY_DESC(ICPLUS, IP1001),
MII_PHY_END
};
@@ -95,11 +102,13 @@
static int
ip1000phy_attach(device_t dev)
{
+ struct ip1000phy_softc *isc;
struct mii_softc *sc;
struct mii_attach_args *ma;
struct mii_data *mii;
- sc = device_get_softc(dev);
+ isc = device_get_softc(dev);
+ sc = &isc->mii_sc;
ma = device_get_ivars(dev);
sc->mii_dev = device_get_parent(dev);
mii = device_get_softc(sc->mii_dev);
@@ -114,6 +123,9 @@
mii->mii_instance++;
+ isc->model = MII_MODEL(ma->mii_id2);
+ isc->revision = MII_REV(ma->mii_id2);
+
device_printf(dev, " ");
#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
@@ -302,10 +314,13 @@
static void
ip1000phy_status(struct mii_softc *sc)
{
+ struct ip1000phy_softc *isc;
struct mii_data *mii = sc->mii_pdata;
uint32_t bmsr, bmcr, stat;
uint32_t ar, lpar;
+ isc = (struct ip1000phy_softc *)sc;
+
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
@@ -326,25 +341,44 @@
}
}
- stat = PHY_READ(sc, STGE_PhyCtrl);
- switch (PC_LinkSpeed(stat)) {
- case PC_LinkSpeed_Down:
- mii->mii_media_active |= IFM_NONE;
- return;
- case PC_LinkSpeed_10:
- mii->mii_media_active |= IFM_10_T;
- break;
- case PC_LinkSpeed_100:
- mii->mii_media_active |= IFM_100_TX;
- break;
- case PC_LinkSpeed_1000:
- mii->mii_media_active |= IFM_1000_T;
- break;
+ if (isc->model == MII_MODEL_ICPLUS_IP1001) {
+ stat = PHY_READ(sc, IP1000PHY_LSR);
+ switch (stat & IP1000PHY_LSR_SPEED_MASK) {
+ case IP1000PHY_LSR_SPEED_10:
+ mii->mii_media_active |= IFM_10_T;
+ break;
+ case IP1000PHY_LSR_SPEED_100:
+ mii->mii_media_active |= IFM_100_TX;
+ break;
+ case IP1000PHY_LSR_SPEED_1000:
+ mii->mii_media_active |= IFM_1000_T;
+ break;
+ }
+ if ((stat & IP1000PHY_LSR_FULL_DUPLEX) != 0)
+ mii->mii_media_active |= IFM_FDX;
+ else
+ mii->mii_media_active |= IFM_HDX;
+ } else {
+ stat = PHY_READ(sc, STGE_PhyCtrl);
+ switch (PC_LinkSpeed(stat)) {
+ case PC_LinkSpeed_Down:
+ mii->mii_media_active |= IFM_NONE;
+ return;
+ case PC_LinkSpeed_10:
+ mii->mii_media_active |= IFM_10_T;
+ break;
+ case PC_LinkSpeed_100:
+ mii->mii_media_active |= IFM_100_TX;
+ break;
+ case PC_LinkSpeed_1000:
+ mii->mii_media_active |= IFM_1000_T;
+ break;
+ }
+ if ((stat & PC_PhyDuplexStatus) != 0)
+ mii->mii_media_active |= IFM_FDX;
+ else
+ mii->mii_media_active |= IFM_HDX;
}
- if ((stat & PC_PhyDuplexStatus) != 0)
- mii->mii_media_active |= IFM_FDX;
- else
- mii->mii_media_active |= IFM_HDX;
ar = PHY_READ(sc, IP1000PHY_MII_ANAR);
lpar = PHY_READ(sc, IP1000PHY_MII_ANLPAR);
@@ -410,10 +444,12 @@
static void
ip1000phy_reset(struct mii_softc *sc)
{
+ struct ip1000phy_softc *isc;
struct stge_softc *stge_sc;
struct mii_data *mii;
uint32_t reg;
+ isc = (struct ip1000phy_softc *)sc;
mii_phy_reset(sc);
/* clear autoneg/full-duplex as we don't want it after reset */
@@ -426,7 +462,8 @@
* XXX There should be more general way to pass PHY specific
* data via mii interface.
*/
- if (strcmp(mii->mii_ifp->if_dname, "stge") == 0) {
+ if (isc->model == MII_MODEL_ICPLUS_IP1000A &&
+ strcmp(mii->mii_ifp->if_dname, "stge") == 0) {
stge_sc = mii->mii_ifp->if_softc;
if (stge_sc->sc_rev >= 0x40 && stge_sc->sc_rev <= 0x4e)
ip1000phy_load_dspcode(sc);
==== //depot/projects/dtrace7/src/sys/dev/mii/ip1000phyreg.h#2 (text+ko) ====
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/sys/dev/mii/ip1000phyreg.h,v 1.1 2006/07/25 00:16:09 yongari Exp $
+ * $FreeBSD: src/sys/dev/mii/ip1000phyreg.h,v 1.1.4.1 2008/04/22 06:35:37 yongari Exp $
*/
#ifndef _DEV_MII_IP1000PHYREG_H_
@@ -138,4 +138,49 @@
#define IP1000PHY_EXTSTS_1000X 0x4000
#define IP1000PHY_EXTSTS_1000X_FDX 0x8000
+/* PHY specific control & status register. IP1001 only. */
+#define IP1000PHY_SCSR 0x10
+#define IP1000PHY_SCSR_RXPHASE_SEL 0x0001
+#define IP1000PHY_SCSR_TXPHASE_SEL 0x0002
+#define IP1000PHY_SCSR_REPEATOR_MODE 0x0004
+#define IP1000PHY_SCSR_RESERVED1_DEF 0x0008
+#define IP1000PHY_SCSR_RXCLK_DRV_MASK 0x0060
+#define IP1000PHY_SCSR_RXCLK_DRV_DEF 0x0040
+#define IP1000PHY_SCSR_RXD_DRV_MASK 0x0180
+#define IP1000PHY_SCSR_RXD_DRV_DEF 0x0100
+#define IP1000PHY_SCSR_JABBER_ENB 0x0200
+#define IP1000PHY_SCSR_HEART_BEAT_ENB 0x0400
+#define IP1000PHY_SCSR_DOWNSHIFT_ENB 0x0800
+#define IP1000PHY_SCSR_RESERVED2_DEF 0x1000
+#define IP1000PHY_SCSR_LED_DRV_4MA 0x0000
+#define IP1000PHY_SCSR_LED_DRV_8MA 0x2000
+#define IP1000PHY_SCSR_LED_MODE_MASK 0xC000
+#define IP1000PHY_SCSR_LED_MODE_DEF 0x0000
+
+/* PHY link status register. IP1001 only. */
+#define IP1000PHY_LSR 0x11
+#define IP1000PHY_LSR_JABBER_DET 0x0200
+#define IP1000PHY_LSR_APS_SLEEP 0x0400
+#define IP1000PHY_LSR_MDIX 0x0800
+#define IP1000PHY_LSR_FULL_DUPLEX 0x1000
+#define IP1000PHY_LSR_SPEED_10 0x0000
+#define IP1000PHY_LSR_SPEED_100 0x2000
+#define IP1000PHY_LSR_SPEED_1000 0x4000
+#define IP1000PHY_LSR_SPEED_MASK 0x6000
+#define IP1000PHY_LSR_LINKUP 0x8000
+
+/* PHY specific control register 2. IP1001 only. */
+#define IP1000PHY_SCR
+#define IP1000PHY_SCR_SEW_RATE_MASK 0x0003
+#define IP1000PHY_SCR_SEW_RATE_DEF 0x0003
+#define IP1000PHY_SCR_AUTO_XOVER 0x0004
+#define IP1000PHY_SCR_SPEED_10_100_ENB 0x0040
+#define IP1000PHY_SCR_FIFO_LATENCY_2 0x0000
+#define IP1000PHY_SCR_FIFO_LATENCY_3 0x0080
+#define IP1000PHY_SCR_FIFO_LATENCY_4 0x0100
+#define IP1000PHY_SCR_FIFO_LATENCY_5 0x0180
+#define IP1000PHY_SCR_MDIX_ENB 0x0200
+#define IP1000PHY_SCR_RESERVED_DEF 0x0400
+#define IP1000PHY_SCR_APS_ON 0x0800
+
#endif /* _DEV_MII_IP1000PHYREG_H_ */
==== //depot/projects/dtrace7/src/sys/dev/mii/miidevs#3 (text+ko) ====
@@ -1,4 +1,4 @@
-$FreeBSD: src/sys/dev/mii/miidevs,v 1.46.2.3 2008/03/17 18:23:44 jhb Exp $
+$FreeBSD: src/sys/dev/mii/miidevs,v 1.46.2.4 2008/04/22 06:35:37 yongari Exp $
/*$NetBSD: miidevs,v 1.6 1999/05/14 11:37:30 drochner Exp $*/
/*-
@@ -156,6 +156,7 @@
/* IC Plus Corp. PHYs */
model ICPLUS IP101 0x0005 IC Plus 10/100 PHY
model ICPLUS IP1000A 0x0008 IC Plus 10/100/1000 media interface
+model ICPLUS IP1001 0x0019 IC Plus IP1001 10/100/1000 media interface
/* Intel PHYs */
model xxINTEL I82553AB 0x0000 i83553 10/100 media interface
==== //depot/projects/dtrace7/src/sys/dev/mii/rgephy.c#2 (text+ko) ====
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/mii/rgephy.c,v 1.15.2.2 2007/11/05 01:39:25 yongari Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/mii/rgephy.c,v 1.15.2.3 2008/04/22 06:25:11 yongari Exp $");
/*
* Driver for the RealTek 8169S/8110S/8211B internal 10/100/1000 PHY.
@@ -367,6 +367,11 @@
bmsr = PHY_READ(sc, RGEPHY_MII_BMSR);
bmcr = PHY_READ(sc, RGEPHY_MII_BMCR);
+ if (bmcr & RGEPHY_BMCR_ISO) {
+ mii->mii_media_active |= IFM_NONE;
+ mii->mii_media_status = 0;
+ return;
+ }
if (bmcr & RGEPHY_BMCR_LOOP)
mii->mii_media_active |= IFM_LOOP;
==== //depot/projects/dtrace7/src/sys/dev/re/if_re.c#6 (text+ko) ====
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/re/if_re.c,v 1.95.2.5 2008/03/13 07:50:47 yongari Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/re/if_re.c,v 1.95.2.18 2008/04/22 06:14:56 yongari Exp $");
/*
* RealTek 8139C+/8169/8169S/8110S/8168/8111/8101E PCI NIC driver
@@ -146,6 +146,8 @@
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
+#include <pci/if_rlreg.h>
+
MODULE_DEPEND(re, pci, 1, 1, 1);
MODULE_DEPEND(re, ether, 1, 1, 1);
MODULE_DEPEND(re, miibus, 1, 1, 1);
@@ -158,10 +160,8 @@
*/
#define RE_USEIOSPACE
-#include <pci/if_rlreg.h>
-
/* Tunables. */
-static int msi_disable = 0;
+static int msi_disable = 1;
TUNABLE_INT("hw.re.msi_disable", &msi_disable);
#define RE_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP)
@@ -201,8 +201,7 @@
{ LINKSYS_VENDORID, LINKSYS_DEVICEID_EG1032, RL_HWREV_8169S,
"Linksys EG1032 (RTL8169S) Gigabit Ethernet" },
{ USR_VENDORID, USR_DEVICEID_997902, RL_HWREV_8169S,
- "US Robotics 997902 (RTL8169S) Gigabit Ethernet" },
- { 0, 0, 0, NULL }
+ "US Robotics 997902 (RTL8169S) Gigabit Ethernet" }
};
static struct rl_hwrev re_hwrevs[] = {
@@ -233,13 +232,13 @@
static int re_attach (device_t);
static int re_detach (device_t);
-static int re_encap (struct rl_softc *, struct mbuf **, int *);
+static int re_encap (struct rl_softc *, struct mbuf **);
static void re_dma_map_addr (void *, bus_dma_segment_t *, int, int);
-static void re_dma_map_desc (void *, bus_dma_segment_t *, int,
- bus_size_t, int);
static int re_allocmem (device_t, struct rl_softc *);
-static int re_newbuf (struct rl_softc *, int, struct mbuf *);
+static __inline void re_discard_rxbuf
+ (struct rl_softc *, int);
+static int re_newbuf (struct rl_softc *, int);
static int re_rx_list_init (struct rl_softc *);
static int re_tx_list_init (struct rl_softc *);
#ifdef RE_FIXUP_RX
@@ -280,6 +279,8 @@
static void re_setmulti (struct rl_softc *);
static void re_reset (struct rl_softc *);
+static void re_setwol (struct rl_softc *);
+static void re_clrwol (struct rl_softc *);
#ifdef RE_DIAG
static int re_diag (struct rl_softc *);
@@ -849,14 +850,14 @@
bus_dmamap_sync(sc->rl_ldata.rl_rx_list_tag,
sc->rl_ldata.rl_rx_list_map,
BUS_DMASYNC_POSTREAD);
- bus_dmamap_sync(sc->rl_ldata.rl_mtag,
- sc->rl_ldata.rl_rx_dmamap[0],
- BUS_DMASYNC_POSTWRITE);
- bus_dmamap_unload(sc->rl_ldata.rl_mtag,
- sc->rl_ldata.rl_rx_dmamap[0]);
+ bus_dmamap_sync(sc->rl_ldata.rl_rx_mtag,
+ sc->rl_ldata.rl_rx_desc[0].rx_dmamap,
+ BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->rl_ldata.rl_rx_mtag,
+ sc->rl_ldata.rl_rx_desc[0].rx_dmamap);
- m0 = sc->rl_ldata.rl_rx_mbuf[0];
- sc->rl_ldata.rl_rx_mbuf[0] = NULL;
+ m0 = sc->rl_ldata.rl_rx_desc[0].rx_m;
+ sc->rl_ldata.rl_rx_desc[0].rx_m = NULL;
eh = mtod(m0, struct ether_header *);
cur_rx = &sc->rl_ldata.rl_rx_list[0];
@@ -916,133 +917,41 @@
device_t dev;
{
struct rl_type *t;
- struct rl_softc *sc;
- int rid;
- u_int32_t hwrev;
+ uint16_t devid, vendor;
+ uint16_t revid, sdevid;
+ int i;
+
+ vendor = pci_get_vendor(dev);
+ devid = pci_get_device(dev);
+ revid = pci_get_revid(dev);
+ sdevid = pci_get_subdevice(dev);
- t = re_devs;
- sc = device_get_softc(dev);
-
- while (t->rl_name != NULL) {
- if ((pci_get_vendor(dev) == t->rl_vid) &&
- (pci_get_device(dev) == t->rl_did)) {
+ if (vendor == LINKSYS_VENDORID && devid == LINKSYS_DEVICEID_EG1032) {
+ if (sdevid != LINKSYS_SUBDEVICE_EG1032_REV3) {
/*
* Only attach to rev. 3 of the Linksys EG1032 adapter.
- * Rev. 2 i supported by sk(4).
+ * Rev. 2 is supported by sk(4).
*/
- if ((t->rl_vid == LINKSYS_VENDORID) &&
- (t->rl_did == LINKSYS_DEVICEID_EG1032) &&
- (pci_get_subdevice(dev) !=
- LINKSYS_SUBDEVICE_EG1032_REV3)) {
- t++;
- continue;
- }
-
- /*
- * Temporarily map the I/O space
- * so we can read the chip ID register.
- */
- rid = RL_RID;
- sc->rl_res = bus_alloc_resource_any(dev, RL_RES, &rid,
- RF_ACTIVE);
- if (sc->rl_res == NULL) {
- device_printf(dev,
- "couldn't map ports/memory\n");
- return (ENXIO);
- }
- sc->rl_btag = rman_get_bustag(sc->rl_res);
- sc->rl_bhandle = rman_get_bushandle(sc->rl_res);
- hwrev = CSR_READ_4(sc, RL_TXCFG) & RL_TXCFG_HWREV;
- bus_release_resource(dev, RL_RES,
- RL_RID, sc->rl_res);
- if (t->rl_basetype == hwrev) {
- device_set_desc(dev, t->rl_name);
- return (BUS_PROBE_DEFAULT);
- }
+ return (ENXIO);
}
- t++;
}
- return (ENXIO);
-}
-
-/*
- * This routine takes the segment list provided as the result of
- * a bus_dma_map_load() operation and assigns the addresses/lengths
- * to RealTek DMA descriptors. This can be called either by the RX
- * code or the TX code. In the RX case, we'll probably wind up mapping
- * at most one segment. For the TX case, there could be any number of
- * segments since TX packets may span multiple mbufs. In either case,
- * if the number of segments is larger than the rl_maxsegs limit
- * specified by the caller, we abort the mapping operation. Sadly,
- * whoever designed the buffer mapping API did not provide a way to
- * return an error from here, so we have to fake it a bit.
- */
-
-static void
-re_dma_map_desc(arg, segs, nseg, mapsize, error)
- void *arg;
- bus_dma_segment_t *segs;
- int nseg;
- bus_size_t mapsize;
- int error;
-{
- struct rl_dmaload_arg *ctx;
- struct rl_desc *d = NULL;
- int i = 0, idx;
- u_int32_t cmdstat;
- int totlen = 0;
-
- if (error)
- return;
-
- ctx = arg;
-
- /* Signal error to caller if there's too many segments */
- if (nseg > ctx->rl_maxsegs) {
- ctx->rl_maxsegs = 0;
- return;
+ if (vendor == RT_VENDORID && devid == RT_DEVICEID_8139) {
+ if (revid != 0x20) {
+ /* 8139, let rl(4) take care of this device. */
+ return (ENXIO);
+ }
}
- /*
- * Map the segment array into descriptors. Note that we set the
- * start-of-frame and end-of-frame markers for either TX or RX, but
- * they really only have meaning in the TX case. (In the RX case,
- * it's the chip that tells us where packets begin and end.)
- * We also keep track of the end of the ring and set the
- * end-of-ring bits as needed, and we set the ownership bits
- * in all except the very first descriptor. (The caller will
- * set this descriptor later when it start transmission or
- * reception.)
- */
- idx = ctx->rl_idx;
- for (;;) {
- d = &ctx->rl_ring[idx];
- if (le32toh(d->rl_cmdstat) & RL_RDESC_STAT_OWN) {
- ctx->rl_maxsegs = 0;
- return;
+ t = re_devs;
+ for (i = 0; i < sizeof(re_devs) / sizeof(re_devs[0]); i++, t++) {
+ if (vendor == t->rl_vid && devid == t->rl_did) {
+ device_set_desc(dev, t->rl_name);
+ return (BUS_PROBE_DEFAULT);
}
- cmdstat = segs[i].ds_len;
- totlen += segs[i].ds_len;
- d->rl_vlanctl = 0;
- d->rl_bufaddr_lo = htole32(RL_ADDR_LO(segs[i].ds_addr));
- d->rl_bufaddr_hi = htole32(RL_ADDR_HI(segs[i].ds_addr));
- if (i == 0)
- cmdstat |= RL_TDESC_CMD_SOF;
- else
- cmdstat |= RL_TDESC_CMD_OWN;
- if (idx == (RL_RX_DESC_CNT - 1))
- cmdstat |= RL_TDESC_CMD_EOR;
- d->rl_cmdstat = htole32(cmdstat | ctx->rl_flags);
- i++;
- if (i == nseg)
- break;
- RL_DESC_INC(idx);
}
- d->rl_cmdstat |= htole32(RL_TDESC_CMD_EOF);
- ctx->rl_maxsegs = nseg;
- ctx->rl_idx = idx;
+ return (ENXIO);
}
/*
@@ -1071,21 +980,52 @@
device_t dev;
struct rl_softc *sc;
{
+ bus_size_t rx_list_size, tx_list_size;
int error;
- int nseg;
int i;
+ rx_list_size = sc->rl_ldata.rl_rx_desc_cnt * sizeof(struct rl_desc);
+ tx_list_size = sc->rl_ldata.rl_tx_desc_cnt * sizeof(struct rl_desc);
+
+ /*
+ * Allocate the parent bus DMA tag appropriate for PCI.
+ * In order to use DAC, RL_CPLUSCMD_PCI_DAC bit of RL_CPLUS_CMD
+ * register should be set. However some RealTek chips are known
+ * to be buggy on DAC handling, therefore disable DAC by limiting
+ * DMA address space to 32bit. PCIe variants of RealTek chips
+ * may not have the limitation but I took safer path.
+ */
+ error = bus_dma_tag_create(bus_get_dma_tag(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->rl_parent_tag);
+ if (error) {
+ device_printf(dev, "could not allocate parent DMA tag\n");
+ return (error);
+ }
+
/*
+ * Allocate map for TX mbufs.
+ */
+ error = bus_dma_tag_create(sc->rl_parent_tag, 1, 0,
+ BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL,
+ NULL, MCLBYTES * RL_NTXSEGS, RL_NTXSEGS, 4096, 0,
+ NULL, NULL, &sc->rl_ldata.rl_tx_mtag);
+ if (error) {
+ device_printf(dev, "could not allocate TX DMA tag\n");
+ return (error);
+ }
+
+ /*
* Allocate map for RX mbufs.
*/
- nseg = 32;
- error = bus_dma_tag_create(sc->rl_parent_tag, ETHER_ALIGN, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL,
- NULL, MCLBYTES * nseg, nseg, MCLBYTES, BUS_DMA_ALLOCNOW,
- NULL, NULL, &sc->rl_ldata.rl_mtag);
+
+ error = bus_dma_tag_create(sc->rl_parent_tag, sizeof(uint64_t), 0,
+ BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
+ MCLBYTES, 1, MCLBYTES, 0, NULL, NULL, &sc->rl_ldata.rl_rx_mtag);
if (error) {
- device_printf(dev, "could not allocate dma tag\n");
- return (ENOMEM);
+ device_printf(dev, "could not allocate RX DMA tag\n");
+ return (error);
}
/*
@@ -1093,36 +1033,44 @@
*/
error = bus_dma_tag_create(sc->rl_parent_tag, RL_RING_ALIGN,
0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL,
- NULL, RL_TX_LIST_SZ, 1, RL_TX_LIST_SZ, 0,
+ NULL, tx_list_size, 1, tx_list_size, 0,
NULL, NULL, &sc->rl_ldata.rl_tx_list_tag);
if (error) {
- device_printf(dev, "could not allocate dma tag\n");
- return (ENOMEM);
+ device_printf(dev, "could not allocate TX DMA ring tag\n");
+ return (error);
}
/* Allocate DMA'able memory for the TX ring */
error = bus_dmamem_alloc(sc->rl_ldata.rl_tx_list_tag,
- (void **)&sc->rl_ldata.rl_tx_list, BUS_DMA_NOWAIT | BUS_DMA_ZERO,
+ (void **)&sc->rl_ldata.rl_tx_list,
+ BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO,
&sc->rl_ldata.rl_tx_list_map);
- if (error)
- return (ENOMEM);
+ if (error) {
+ device_printf(dev, "could not allocate TX DMA ring\n");
+ return (error);
+ }
/* Load the map for the TX ring. */
+ sc->rl_ldata.rl_tx_list_addr = 0;
error = bus_dmamap_load(sc->rl_ldata.rl_tx_list_tag,
sc->rl_ldata.rl_tx_list_map, sc->rl_ldata.rl_tx_list,
- RL_TX_LIST_SZ, re_dma_map_addr,
+ tx_list_size, re_dma_map_addr,
&sc->rl_ldata.rl_tx_list_addr, BUS_DMA_NOWAIT);
+ if (error != 0 || sc->rl_ldata.rl_tx_list_addr == 0) {
+ device_printf(dev, "could not load TX DMA ring\n");
+ return (ENOMEM);
+ }
/* Create DMA maps for TX buffers */
- for (i = 0; i < RL_TX_DESC_CNT; i++) {
- error = bus_dmamap_create(sc->rl_ldata.rl_mtag, 0,
- &sc->rl_ldata.rl_tx_dmamap[i]);
+ for (i = 0; i < sc->rl_ldata.rl_tx_desc_cnt; i++) {
+ error = bus_dmamap_create(sc->rl_ldata.rl_tx_mtag, 0,
+ &sc->rl_ldata.rl_tx_desc[i].tx_dmamap);
if (error) {
- device_printf(dev, "can't create DMA map for TX\n");
- return (ENOMEM);
+ device_printf(dev, "could not create DMA map for TX\n");
+ return (error);
}
}
@@ -1131,36 +1079,50 @@
*/
error = bus_dma_tag_create(sc->rl_parent_tag, RL_RING_ALIGN,
0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL,
- NULL, RL_RX_LIST_SZ, 1, RL_RX_LIST_SZ, 0,
+ NULL, rx_list_size, 1, rx_list_size, 0,
NULL, NULL, &sc->rl_ldata.rl_rx_list_tag);
if (error) {
- device_printf(dev, "could not allocate dma tag\n");
- return (ENOMEM);
+ device_printf(dev, "could not create RX DMA ring tag\n");
+ return (error);
}
/* Allocate DMA'able memory for the RX ring */
error = bus_dmamem_alloc(sc->rl_ldata.rl_rx_list_tag,
- (void **)&sc->rl_ldata.rl_rx_list, BUS_DMA_NOWAIT | BUS_DMA_ZERO,
+ (void **)&sc->rl_ldata.rl_rx_list,
+ BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO,
&sc->rl_ldata.rl_rx_list_map);
- if (error)
- return (ENOMEM);
+ if (error) {
+ device_printf(dev, "could not allocate RX DMA ring\n");
+ return (error);
+ }
/* Load the map for the RX ring. */
+ sc->rl_ldata.rl_rx_list_addr = 0;
error = bus_dmamap_load(sc->rl_ldata.rl_rx_list_tag,
sc->rl_ldata.rl_rx_list_map, sc->rl_ldata.rl_rx_list,
- RL_RX_LIST_SZ, re_dma_map_addr,
+ rx_list_size, re_dma_map_addr,
&sc->rl_ldata.rl_rx_list_addr, BUS_DMA_NOWAIT);
+ if (error != 0 || sc->rl_ldata.rl_rx_list_addr == 0) {
+ device_printf(dev, "could not load RX DMA ring\n");
+ return (ENOMEM);
+ }
/* Create DMA maps for RX buffers */
- for (i = 0; i < RL_RX_DESC_CNT; i++) {
- error = bus_dmamap_create(sc->rl_ldata.rl_mtag, 0,
- &sc->rl_ldata.rl_rx_dmamap[i]);
+ error = bus_dmamap_create(sc->rl_ldata.rl_rx_mtag, 0,
+ &sc->rl_ldata.rl_rx_sparemap);
+ if (error) {
+ device_printf(dev, "could not create spare DMA map for RX\n");
+ return (error);
+ }
+ for (i = 0; i < sc->rl_ldata.rl_rx_desc_cnt; i++) {
+ error = bus_dmamap_create(sc->rl_ldata.rl_rx_mtag, 0,
+ &sc->rl_ldata.rl_rx_desc[i].rx_dmamap);
if (error) {
- device_printf(dev, "can't create DMA map for RX\n");
- return (ENOMEM);
+ device_printf(dev, "could not create DMA map for RX\n");
+ return (error);
}
}
@@ -1184,6 +1146,7 @@
u_int16_t re_did = 0;
int error = 0, rid, i;
int msic, reg;
+ uint8_t cfg;
sc = device_get_softc(dev);
sc->rl_dev = dev;
@@ -1222,6 +1185,12 @@
device_printf(dev, "Using %d MSI messages\n",
msic);
sc->rl_msi = 1;
+ /* Explicitly set MSI enable bit. */
+ CSR_WRITE_1(sc, RL_EECMD, RL_EE_MODE);
+ cfg = CSR_READ_1(sc, RL_CFG2);
+ cfg |= RL_CFG2_MSI;
+ CSR_WRITE_1(sc, RL_CFG2, cfg);
+ CSR_WRITE_1(sc, RL_EECMD, 0);
} else
pci_release_msi(dev);
}
@@ -1265,6 +1234,11 @@
}
hw_rev++;
}
+ if (hw_rev->rl_desc == NULL) {
+ device_printf(dev, "Unknown H/W revision: %08x\n", hwrev);
+ error = ENXIO;
+ goto fail;
+ }
sc->rl_eewidth = RL_9356_ADDR_LEN;
re_read_eeprom(sc, (caddr_t)&re_did, 0, 1);
@@ -1280,28 +1254,25 @@
bcopy(as, eaddr, sizeof(eaddr));
if (sc->rl_type == RL_8169) {
- /* Set RX length mask */
+ /* Set RX length mask and number of descriptors. */
sc->rl_rxlenmask = RL_RDESC_STAT_GFRAGLEN;
sc->rl_txstart = RL_GTXSTART;
+ sc->rl_ldata.rl_tx_desc_cnt = RL_8169_TX_DESC_CNT;
+ sc->rl_ldata.rl_rx_desc_cnt = RL_8169_RX_DESC_CNT;
} else {
- /* Set RX length mask */
+ /* Set RX length mask and number of descriptors. */
sc->rl_rxlenmask = RL_RDESC_STAT_FRAGLEN;
sc->rl_txstart = RL_TXSTART;
+ sc->rl_ldata.rl_tx_desc_cnt = RL_8139_TX_DESC_CNT;
+ sc->rl_ldata.rl_rx_desc_cnt = RL_8139_RX_DESC_CNT;
}
-
- /*
- * Allocate the parent bus DMA tag appropriate for PCI.
- */
-#define RL_NSEG_NEW 32
- error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
- BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
- MAXBSIZE, RL_NSEG_NEW, BUS_SPACE_MAXSIZE_32BIT, 0,
- NULL, NULL, &sc->rl_parent_tag);
- if (error)
+ if (hw_rev->rl_desc == NULL) {
+ device_printf(dev, "Unsupported revision : 0x%08x\n", hwrev);
+ error = ENXIO;
goto fail;
+ }
error = re_allocmem(dev, sc);
-
if (error)
goto fail;
@@ -1348,8 +1319,8 @@
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
ifp->if_ioctl = re_ioctl;
ifp->if_start = re_start;
- ifp->if_hwassist = RE_CSUM_FEATURES;
- ifp->if_capabilities = IFCAP_HWCSUM;
+ ifp->if_hwassist = RE_CSUM_FEATURES | CSUM_TSO;
+ ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_TSO4;
ifp->if_capenable = ifp->if_capabilities;
ifp->if_init = re_init;
IFQ_SET_MAXLEN(&ifp->if_snd, RL_IFQ_MAXLEN);
@@ -1368,6 +1339,9 @@
ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING;
if (ifp->if_capabilities & IFCAP_HWCSUM)
ifp->if_capabilities |= IFCAP_VLAN_HWCSUM;
+ /* Enable WOL if PM is supported. */
+ if (pci_find_extcap(sc->rl_dev, PCIY_PMG, ®) == 0)
+ ifp->if_capabilities |= IFCAP_WOL;
ifp->if_capenable = ifp->if_capabilities;
#ifdef DEVICE_POLLING
ifp->if_capabilities |= IFCAP_POLLING;
@@ -1534,14 +1508,20 @@
/* Destroy all the RX and TX buffer maps */
- if (sc->rl_ldata.rl_mtag) {
- for (i = 0; i < RL_TX_DESC_CNT; i++)
- bus_dmamap_destroy(sc->rl_ldata.rl_mtag,
- sc->rl_ldata.rl_tx_dmamap[i]);
- for (i = 0; i < RL_RX_DESC_CNT; i++)
- bus_dmamap_destroy(sc->rl_ldata.rl_mtag,
- sc->rl_ldata.rl_rx_dmamap[i]);
- bus_dma_tag_destroy(sc->rl_ldata.rl_mtag);
+ if (sc->rl_ldata.rl_tx_mtag) {
+ for (i = 0; i < sc->rl_ldata.rl_tx_desc_cnt; i++)
+ bus_dmamap_destroy(sc->rl_ldata.rl_tx_mtag,
+ sc->rl_ldata.rl_tx_desc[i].tx_dmamap);
+ bus_dma_tag_destroy(sc->rl_ldata.rl_tx_mtag);
+ }
+ if (sc->rl_ldata.rl_rx_mtag) {
+ for (i = 0; i < sc->rl_ldata.rl_rx_desc_cnt; i++)
+ bus_dmamap_destroy(sc->rl_ldata.rl_rx_mtag,
+ sc->rl_ldata.rl_rx_desc[i].rx_dmamap);
+ if (sc->rl_ldata.rl_rx_sparemap)
+ bus_dmamap_destroy(sc->rl_ldata.rl_rx_mtag,
+ sc->rl_ldata.rl_rx_sparemap);
+ bus_dma_tag_destroy(sc->rl_ldata.rl_rx_mtag);
}
/* Unload and free the stats buffer and map */
@@ -1563,23 +1543,40 @@
return (0);
}
+static __inline void
+re_discard_rxbuf(sc, idx)
+ struct rl_softc *sc;
+ int idx;
+{
+ struct rl_desc *desc;
+ struct rl_rxdesc *rxd;
+ uint32_t cmdstat;
+
+ rxd = &sc->rl_ldata.rl_rx_desc[idx];
+ desc = &sc->rl_ldata.rl_rx_list[idx];
+ desc->rl_vlanctl = 0;
+ cmdstat = rxd->rx_size;
+ if (idx == sc->rl_ldata.rl_rx_desc_cnt - 1)
+ cmdstat |= RL_RDESC_CMD_EOR;
+ desc->rl_cmdstat = htole32(cmdstat | RL_RDESC_CMD_OWN);
+}
+
static int
-re_newbuf(sc, idx, m)
+re_newbuf(sc, idx)
struct rl_softc *sc;
int idx;
+{
struct mbuf *m;
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list