* Network driver for DEC/21143 and K° ("dc") ported from FreeBSD 8.2;
* Network drivers for 3com, ipro100, rtl8139 are updated from FreeBSD 8.2 Release branch; * Some functions, defines and typedef required by updated and fresh ported FreeBSD drivers were added into freebsd_compat layer. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42393 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
eb5c4b0745
commit
698b6790bc
@ -169,7 +169,7 @@ SYSTEM_ADD_ONS_DRIVERS_GRAPHICS = $(X86_ONLY)radeon $(X86_ONLY)nvidia
|
||||
SYSTEM_ADD_ONS_DRIVERS_MIDI = emuxki usb_midi ;
|
||||
SYSTEM_ADD_ONS_DRIVERS_NET = $(X86_ONLY)3com $(X86_ONLY)atheros813x
|
||||
$(X86_ONLY)ar81xx $(X86_ONLY)attansic_l1 $(X86_ONLY)attansic_l2
|
||||
$(X86_ONLY)broadcom440x $(X86_ONLY)broadcom570x etherpci
|
||||
$(X86_ONLY)broadcom440x $(X86_ONLY)broadcom570x $(X86_ONLY)dec21xxx etherpci
|
||||
$(X86_ONLY)ipro100 $(X86_ONLY)ipro1000 $(X86_ONLY)jmicron2x0
|
||||
$(X86_ONLY)marvell_yukon $(X86_ONLY)nforce $(X86_ONLY)pcnet pegasus
|
||||
$(X86_ONLY)rtl8139 $(X86_ONLY)rtl81xx sis900
|
||||
|
@ -1,4 +1,3 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel drivers network 3com ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network 3com dev ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network 3com pci ;
|
||||
|
@ -1,3 +1,4 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel drivers network 3com dev ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network 3com dev mii ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network 3com dev xl ;
|
||||
|
@ -14,13 +14,6 @@
|
||||
* 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
|
||||
@ -46,11 +39,6 @@
|
||||
* 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 Manuel Bouyer.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
@ -68,7 +56,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/dev/mii/bmtphy.c,v 1.9.2.1 2006/08/08 04:37:18 yongari Exp $");
|
||||
__FBSDID("$FreeBSD: src/sys/dev/mii/bmtphy.c,v 1.12.10.8.2.1 2010/12/21 17:09:25 kensmith Exp $");
|
||||
|
||||
/*
|
||||
* Driver for the Broadcom BCM5201/BCM5202 "Mini-Theta" PHYs. This also
|
||||
@ -97,6 +85,11 @@ __FBSDID("$FreeBSD: src/sys/dev/mii/bmtphy.c,v 1.9.2.1 2006/08/08 04:37:18 yonga
|
||||
static int bmtphy_probe(device_t);
|
||||
static int bmtphy_attach(device_t);
|
||||
|
||||
struct bmtphy_softc {
|
||||
struct mii_softc mii_sc;
|
||||
int mii_model;
|
||||
};
|
||||
|
||||
static device_method_t bmtphy_methods[] = {
|
||||
/* Device interface */
|
||||
DEVMETHOD(device_probe, bmtphy_probe),
|
||||
@ -112,81 +105,73 @@ static devclass_t bmtphy_devclass;
|
||||
static driver_t bmtphy_driver = {
|
||||
"bmtphy",
|
||||
bmtphy_methods,
|
||||
sizeof(struct mii_softc)
|
||||
sizeof(struct bmtphy_softc)
|
||||
};
|
||||
|
||||
DRIVER_MODULE(bmtphy, miibus, bmtphy_driver, bmtphy_devclass, 0, 0);
|
||||
|
||||
static int bmtphy_service(struct mii_softc *, struct mii_data *, int);
|
||||
static void bmtphy_status(struct mii_softc *);
|
||||
static void bmtphy_reset(struct mii_softc *);
|
||||
|
||||
static const struct mii_phydesc bmtphys_dp[] = {
|
||||
MII_PHY_DESC(BROADCOM, BCM4401),
|
||||
MII_PHY_DESC(BROADCOM, BCM5201),
|
||||
MII_PHY_DESC(BROADCOM, BCM5214),
|
||||
MII_PHY_DESC(BROADCOM, BCM5221),
|
||||
MII_PHY_DESC(BROADCOM, BCM5222),
|
||||
MII_PHY_END
|
||||
};
|
||||
|
||||
static const struct mii_phydesc bmtphys_lp[] = {
|
||||
MII_PHY_DESC(BROADCOM, 3C905B),
|
||||
MII_PHY_DESC(BROADCOM, 3C905C),
|
||||
MII_PHY_END
|
||||
};
|
||||
|
||||
static int
|
||||
bmtphy_probe(device_t dev)
|
||||
{
|
||||
struct mii_attach_args *ma;
|
||||
int rval;
|
||||
|
||||
ma = device_get_ivars(dev);
|
||||
rval = BUS_PROBE_DEFAULT;
|
||||
/* Let exphy(4) take precedence for these. */
|
||||
rval = mii_phy_dev_probe(dev, bmtphys_lp, BUS_PROBE_LOW_PRIORITY);
|
||||
if (rval <= 0)
|
||||
return (rval);
|
||||
|
||||
if (MII_OUI(ma->mii_id1, ma->mii_id2) != MII_OUI_BROADCOM)
|
||||
return (ENXIO);
|
||||
|
||||
switch (MII_MODEL(ma->mii_id2)) {
|
||||
case MII_MODEL_BROADCOM_3C905B:
|
||||
device_set_desc(dev, MII_STR_BROADCOM_3C905B);
|
||||
rval = BUS_PROBE_LOW_PRIORITY; /* Let exphy take precedence. */
|
||||
break;
|
||||
case MII_MODEL_BROADCOM_3C905C:
|
||||
device_set_desc(dev, MII_STR_BROADCOM_3C905C);
|
||||
rval = BUS_PROBE_LOW_PRIORITY; /* Let exphy take precedence. */
|
||||
break;
|
||||
case MII_MODEL_BROADCOM_BCM5201:
|
||||
device_set_desc(dev, MII_STR_BROADCOM_BCM5201);
|
||||
break;
|
||||
case MII_MODEL_BROADCOM_BCM5221:
|
||||
device_set_desc(dev, MII_STR_BROADCOM_BCM5221);
|
||||
break;
|
||||
case MII_MODEL_BROADCOM_BCM4401:
|
||||
device_set_desc(dev, MII_STR_BROADCOM_BCM4401);
|
||||
break;
|
||||
default:
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
return (rval);
|
||||
return (mii_phy_dev_probe(dev, bmtphys_dp, BUS_PROBE_DEFAULT));
|
||||
}
|
||||
|
||||
static int
|
||||
bmtphy_attach(device_t dev)
|
||||
{
|
||||
struct mii_softc *sc;
|
||||
struct mii_attach_args *ma;
|
||||
struct mii_data *mii;
|
||||
struct bmtphy_softc *bsc;
|
||||
struct mii_softc *sc;
|
||||
struct mii_attach_args *ma;
|
||||
struct mii_data *mii;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
bsc = device_get_softc(dev);
|
||||
sc = &bsc->mii_sc;
|
||||
ma = device_get_ivars(dev);
|
||||
sc->mii_dev = device_get_parent(dev);
|
||||
mii = device_get_softc(sc->mii_dev);
|
||||
mii = ma->mii_data;
|
||||
LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);
|
||||
|
||||
sc->mii_inst = mii->mii_instance;
|
||||
sc->mii_flags = miibus_get_flags(dev);
|
||||
sc->mii_inst = mii->mii_instance++;
|
||||
sc->mii_phy = ma->mii_phyno;
|
||||
sc->mii_service = bmtphy_service;
|
||||
sc->mii_pdata = mii;
|
||||
|
||||
mii_phy_reset(sc);
|
||||
sc->mii_flags |= MIIF_NOMANPAUSE;
|
||||
|
||||
mii->mii_instance++;
|
||||
bsc->mii_model = MII_MODEL(ma->mii_id2);
|
||||
|
||||
sc->mii_capabilities =
|
||||
PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
|
||||
bmtphy_reset(sc);
|
||||
|
||||
sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
|
||||
device_printf(dev, " ");
|
||||
if ((sc->mii_capabilities & BMSR_MEDIAMASK) == 0)
|
||||
printf("no media present");
|
||||
else
|
||||
mii_phy_add_media(sc);
|
||||
|
||||
mii_phy_add_media(sc);
|
||||
printf("\n");
|
||||
|
||||
MIIBUS_MEDIAINIT(sc->mii_dev);
|
||||
@ -197,31 +182,12 @@ bmtphy_attach(device_t dev)
|
||||
static int
|
||||
bmtphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
|
||||
{
|
||||
struct ifmedia_entry *ife;
|
||||
int reg;
|
||||
|
||||
ife = mii->mii_media.ifm_cur;
|
||||
|
||||
switch (cmd) {
|
||||
case MII_POLLSTAT:
|
||||
/*
|
||||
* If we're not polling our PHY instance, just return.
|
||||
*/
|
||||
if (IFM_INST(ife->ifm_media) != sc->mii_inst)
|
||||
return (0);
|
||||
break;
|
||||
|
||||
case MII_MEDIACHG:
|
||||
/*
|
||||
* If the media indicates a different PHY instance,
|
||||
* isolate ourselves.
|
||||
*/
|
||||
if (IFM_INST(ife->ifm_media) != sc->mii_inst) {
|
||||
reg = PHY_READ(sc, MII_BMCR);
|
||||
PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the interface is not up, don't do anything.
|
||||
*/
|
||||
@ -232,11 +198,6 @@ bmtphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
|
||||
break;
|
||||
|
||||
case MII_TICK:
|
||||
/*
|
||||
* If we're not currently selected, just return.
|
||||
*/
|
||||
if (IFM_INST(ife->ifm_media) != sc->mii_inst)
|
||||
return (0);
|
||||
if (mii_phy_tick(sc) == EJUSTRETURN)
|
||||
return (0);
|
||||
break;
|
||||
@ -247,16 +208,15 @@ bmtphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
|
||||
|
||||
/* Callback if something changed. */
|
||||
mii_phy_update(sc, cmd);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
bmtphy_status(struct mii_softc *sc)
|
||||
{
|
||||
struct mii_data *mii;
|
||||
struct ifmedia_entry *ife;
|
||||
int bmsr, bmcr, aux_csr;
|
||||
struct mii_data *mii;
|
||||
struct ifmedia_entry *ife;
|
||||
int bmsr, bmcr, aux_csr;
|
||||
|
||||
mii = sc->mii_pdata;
|
||||
ife = mii->mii_media.ifm_cur;
|
||||
@ -265,7 +225,6 @@ bmtphy_status(struct mii_softc *sc)
|
||||
mii->mii_media_active = IFM_ETHER;
|
||||
|
||||
bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
|
||||
aux_csr = PHY_READ(sc, MII_BMTPHY_AUX_CSR);
|
||||
|
||||
if (bmsr & BMSR_LINK)
|
||||
mii->mii_media_status |= IFM_ACTIVE;
|
||||
@ -291,12 +250,45 @@ bmtphy_status(struct mii_softc *sc)
|
||||
return;
|
||||
}
|
||||
|
||||
aux_csr = PHY_READ(sc, MII_BMTPHY_AUX_CSR);
|
||||
if (aux_csr & AUX_CSR_SPEED)
|
||||
mii->mii_media_active |= IFM_100_TX;
|
||||
else
|
||||
mii->mii_media_active |= IFM_10_T;
|
||||
if (aux_csr & AUX_CSR_FDX)
|
||||
mii->mii_media_active |= IFM_FDX;
|
||||
mii->mii_media_active |=
|
||||
IFM_FDX | mii_phy_flowstatus(sc);
|
||||
else
|
||||
mii->mii_media_active |= IFM_HDX;
|
||||
} else
|
||||
mii->mii_media_active = ife->ifm_media;
|
||||
}
|
||||
|
||||
static void
|
||||
bmtphy_reset(struct mii_softc *sc)
|
||||
{
|
||||
struct bmtphy_softc *bsc;
|
||||
u_int16_t data;
|
||||
|
||||
bsc = (struct bmtphy_softc *)sc;
|
||||
|
||||
mii_phy_reset(sc);
|
||||
|
||||
if (bsc->mii_model == MII_MODEL_BROADCOM_BCM5221) {
|
||||
/* Enable shadow register mode. */
|
||||
data = PHY_READ(sc, 0x1f);
|
||||
PHY_WRITE(sc, 0x1f, data | 0x0080);
|
||||
|
||||
/* Enable APD (Auto PowerDetect). */
|
||||
data = PHY_READ(sc, MII_BMTPHY_AUX2);
|
||||
PHY_WRITE(sc, MII_BMTPHY_AUX2, data | 0x0020);
|
||||
|
||||
/* Enable clocks across APD for Auto-MDIX functionality. */
|
||||
data = PHY_READ(sc, MII_BMTPHY_INTR);
|
||||
PHY_WRITE(sc, MII_BMTPHY_INTR, data | 0x0004);
|
||||
|
||||
/* Disable shadow register mode. */
|
||||
data = PHY_READ(sc, 0x1f);
|
||||
PHY_WRITE(sc, 0x1f, data & ~0x0080);
|
||||
}
|
||||
}
|
||||
|
@ -13,13 +13,6 @@
|
||||
* 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
|
||||
@ -35,7 +28,7 @@
|
||||
*
|
||||
* from NetBSD: bmtphyreg.h,v 1.1 2001/06/02 21:42:10 thorpej Exp
|
||||
*
|
||||
* $FreeBSD: src/sys/dev/mii/bmtphyreg.h,v 1.2 2005/01/06 01:42:55 imp Exp $
|
||||
* $FreeBSD: src/sys/dev/mii/bmtphyreg.h,v 1.2.22.2.2.1 2010/12/21 17:09:25 kensmith Exp $
|
||||
*/
|
||||
|
||||
#ifndef _DEV_MII_BMTPHYREG_H_
|
||||
|
@ -16,13 +16,6 @@
|
||||
* 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
|
||||
@ -48,11 +41,6 @@
|
||||
* 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 Manuel Bouyer.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
@ -67,7 +55,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/dev/mii/exphy.c,v 1.19.2.1 2006/08/08 04:37:18 yongari Exp $");
|
||||
__FBSDID("$FreeBSD: src/sys/dev/mii/exphy.c,v 1.23.10.5.2.1 2010/12/21 17:09:25 kensmith Exp $");
|
||||
|
||||
/*
|
||||
* driver for 3Com internal PHYs
|
||||
@ -114,42 +102,31 @@ DRIVER_MODULE(xlphy, miibus, exphy_driver, exphy_devclass, 0, 0);
|
||||
static int exphy_service(struct mii_softc *, struct mii_data *, int);
|
||||
static void exphy_reset(struct mii_softc *);
|
||||
|
||||
/*
|
||||
* Some 3Com internal PHYs report zero for OUI and model, others use
|
||||
* actual values.
|
||||
* Note that the 3Com internal PHYs having OUI 0x105a and model 0 are
|
||||
* handled fine by ukphy(4); they can be isolated and don't require
|
||||
* special treatment after reset.
|
||||
*/
|
||||
static const struct mii_phydesc exphys[] = {
|
||||
{ 0, 0, "3Com internal media interface" },
|
||||
MII_PHY_DESC(BROADCOM, 3C905C),
|
||||
MII_PHY_END
|
||||
};
|
||||
|
||||
static int
|
||||
exphy_probe(dev)
|
||||
device_t dev;
|
||||
exphy_probe(device_t dev)
|
||||
{
|
||||
struct mii_attach_args *ma;
|
||||
device_t parent;
|
||||
|
||||
ma = device_get_ivars(dev);
|
||||
parent = device_get_parent(device_get_parent(dev));
|
||||
|
||||
/*
|
||||
* Argh, 3Com PHY reports oui == 0 model == 0!
|
||||
*/
|
||||
if ((MII_OUI(ma->mii_id1, ma->mii_id2) != 0 ||
|
||||
MII_MODEL(ma->mii_id2) != 0) &&
|
||||
(MII_OUI(ma->mii_id1, ma->mii_id2) != MII_OUI_BROADCOM ||
|
||||
MII_MODEL(ma->mii_id2) != MII_MODEL_BROADCOM_3C905C))
|
||||
return (ENXIO);
|
||||
|
||||
/*
|
||||
* Make sure the parent is an `ex'.
|
||||
*/
|
||||
if (strcmp(device_get_name(parent), "xl") != 0)
|
||||
return (ENXIO);
|
||||
|
||||
if (MII_OUI(ma->mii_id1, ma->mii_id2) == 0)
|
||||
device_set_desc(dev, "3Com internal media interface");
|
||||
else
|
||||
device_set_desc(dev, MII_STR_BROADCOM_3C905C);
|
||||
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
if (strcmp(device_get_name(device_get_parent(device_get_parent(dev))),
|
||||
"xl") == 0)
|
||||
return (mii_phy_dev_probe(dev, exphys, BUS_PROBE_DEFAULT));
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
static int
|
||||
exphy_attach(dev)
|
||||
device_t dev;
|
||||
exphy_attach(device_t dev)
|
||||
{
|
||||
struct mii_softc *sc;
|
||||
struct mii_attach_args *ma;
|
||||
@ -158,62 +135,39 @@ exphy_attach(dev)
|
||||
sc = device_get_softc(dev);
|
||||
ma = device_get_ivars(dev);
|
||||
sc->mii_dev = device_get_parent(dev);
|
||||
mii = device_get_softc(sc->mii_dev);
|
||||
|
||||
/*
|
||||
* The 3Com PHY can never be isolated, so never allow non-zero
|
||||
* instances!
|
||||
*/
|
||||
if (mii->mii_instance != 0) {
|
||||
device_printf(dev, "ignoring this PHY, non-zero instance\n");
|
||||
return(ENXIO);
|
||||
}
|
||||
|
||||
mii = ma->mii_data;
|
||||
LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);
|
||||
|
||||
sc->mii_inst = mii->mii_instance;
|
||||
sc->mii_flags = miibus_get_flags(dev);
|
||||
sc->mii_inst = mii->mii_instance++;
|
||||
sc->mii_phy = ma->mii_phyno;
|
||||
sc->mii_service = exphy_service;
|
||||
sc->mii_pdata = mii;
|
||||
mii->mii_instance++;
|
||||
|
||||
/*
|
||||
* The 3Com PHY can never be isolated.
|
||||
*/
|
||||
sc->mii_flags |= MIIF_NOISOLATE;
|
||||
|
||||
#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
|
||||
|
||||
#if 0 /* See above. */
|
||||
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst),
|
||||
BMCR_ISO);
|
||||
#endif
|
||||
|
||||
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst),
|
||||
BMCR_LOOP|BMCR_S100);
|
||||
MII_MEDIA_100_TX);
|
||||
|
||||
exphy_reset(sc);
|
||||
|
||||
sc->mii_capabilities =
|
||||
PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
|
||||
sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
|
||||
device_printf(dev, " ");
|
||||
mii_phy_add_media(sc);
|
||||
printf("\n");
|
||||
#undef ADD
|
||||
MIIBUS_MEDIAINIT(sc->mii_dev);
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
exphy_service(sc, mii, cmd)
|
||||
struct mii_softc *sc;
|
||||
struct mii_data *mii;
|
||||
int cmd;
|
||||
exphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
|
||||
{
|
||||
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
|
||||
|
||||
/*
|
||||
* We can't isolate the 3Com PHY, so it has to be the only one!
|
||||
*/
|
||||
if (IFM_INST(ife->ifm_media) != sc->mii_inst)
|
||||
panic("exphy_service: can't isolate 3Com PHY");
|
||||
|
||||
switch (cmd) {
|
||||
case MII_POLLSTAT:
|
||||
@ -236,12 +190,6 @@ exphy_service(sc, mii, cmd)
|
||||
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Only used for autonegotiation.
|
||||
*/
|
||||
if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO)
|
||||
break;
|
||||
|
||||
/*
|
||||
* The 3Com PHY's autonegotiation doesn't need to be
|
||||
* kicked; it continues in the background.
|
||||
|
@ -16,13 +16,6 @@
|
||||
* 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
|
||||
@ -48,11 +41,6 @@
|
||||
* 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 Manuel Bouyer.
|
||||
* 4. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
@ -67,7 +55,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy.c,v 1.20 2007/01/20 00:52:29 marius Exp $");
|
||||
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy.c,v 1.20.10.6.2.1 2010/12/21 17:09:25 kensmith Exp $");
|
||||
|
||||
/*
|
||||
* driver for generic unknown PHYs
|
||||
@ -134,7 +122,7 @@ ukphy_attach(device_t dev)
|
||||
sc = device_get_softc(dev);
|
||||
ma = device_get_ivars(dev);
|
||||
sc->mii_dev = device_get_parent(dev);
|
||||
mii = device_get_softc(sc->mii_dev);
|
||||
mii = ma->mii_data;
|
||||
LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);
|
||||
|
||||
if (bootverbose)
|
||||
@ -142,17 +130,17 @@ ukphy_attach(device_t dev)
|
||||
MII_OUI(ma->mii_id1, ma->mii_id2),
|
||||
MII_MODEL(ma->mii_id2), MII_REV(ma->mii_id2));
|
||||
|
||||
sc->mii_inst = mii->mii_instance;
|
||||
sc->mii_flags = miibus_get_flags(dev);
|
||||
sc->mii_inst = mii->mii_instance++;
|
||||
sc->mii_phy = ma->mii_phyno;
|
||||
sc->mii_service = ukphy_service;
|
||||
sc->mii_pdata = mii;
|
||||
|
||||
mii->mii_instance++;
|
||||
sc->mii_flags |= MIIF_NOMANPAUSE;
|
||||
|
||||
mii_phy_reset(sc);
|
||||
|
||||
sc->mii_capabilities =
|
||||
PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
|
||||
sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
|
||||
if (sc->mii_capabilities & BMSR_EXTSTAT)
|
||||
sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
|
||||
device_printf(dev, " ");
|
||||
@ -168,29 +156,12 @@ ukphy_attach(device_t dev)
|
||||
static int
|
||||
ukphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
|
||||
{
|
||||
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
|
||||
int reg;
|
||||
|
||||
switch (cmd) {
|
||||
case MII_POLLSTAT:
|
||||
/*
|
||||
* If we're not polling our PHY instance, just return.
|
||||
*/
|
||||
if (IFM_INST(ife->ifm_media) != sc->mii_inst)
|
||||
return (0);
|
||||
break;
|
||||
|
||||
case MII_MEDIACHG:
|
||||
/*
|
||||
* If the media indicates a different PHY instance,
|
||||
* isolate ourselves.
|
||||
*/
|
||||
if (IFM_INST(ife->ifm_media) != sc->mii_inst) {
|
||||
reg = PHY_READ(sc, MII_BMCR);
|
||||
PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the interface is not up, don't do anything.
|
||||
*/
|
||||
@ -201,11 +172,6 @@ ukphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
|
||||
break;
|
||||
|
||||
case MII_TICK:
|
||||
/*
|
||||
* If we're not currently selected, just return.
|
||||
*/
|
||||
if (IFM_INST(ife->ifm_media) != sc->mii_inst)
|
||||
return (0);
|
||||
if (mii_phy_tick(sc) == EJUSTRETURN)
|
||||
return (0);
|
||||
break;
|
||||
|
@ -16,13 +16,6 @@
|
||||
* 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
|
||||
@ -38,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy_subr.c,v 1.8.8.1 2006/07/19 04:40:26 yongari Exp $");
|
||||
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy_subr.c,v 1.10.2.4.2.1 2010/12/21 17:09:25 kensmith Exp $");
|
||||
|
||||
/*
|
||||
* Subroutines shared by the ukphy driver and other PHY drivers.
|
||||
@ -111,19 +104,26 @@ ukphy_status(struct mii_softc *phy)
|
||||
mii->mii_media_active |= IFM_1000_T|IFM_FDX;
|
||||
else if ((gtcr & GTCR_ADV_1000THDX) &&
|
||||
(gtsr & GTSR_LP_1000THDX))
|
||||
mii->mii_media_active |= IFM_1000_T;
|
||||
else if (anlpar & ANLPAR_T4)
|
||||
mii->mii_media_active |= IFM_100_T4;
|
||||
mii->mii_media_active |= IFM_1000_T|IFM_HDX;
|
||||
else if (anlpar & ANLPAR_TX_FD)
|
||||
mii->mii_media_active |= IFM_100_TX|IFM_FDX;
|
||||
else if (anlpar & ANLPAR_T4)
|
||||
mii->mii_media_active |= IFM_100_T4|IFM_HDX;
|
||||
else if (anlpar & ANLPAR_TX)
|
||||
mii->mii_media_active |= IFM_100_TX;
|
||||
mii->mii_media_active |= IFM_100_TX|IFM_HDX;
|
||||
else if (anlpar & ANLPAR_10_FD)
|
||||
mii->mii_media_active |= IFM_10_T|IFM_FDX;
|
||||
else if (anlpar & ANLPAR_10)
|
||||
mii->mii_media_active |= IFM_10_T;
|
||||
mii->mii_media_active |= IFM_10_T|IFM_HDX;
|
||||
else
|
||||
mii->mii_media_active |= IFM_NONE;
|
||||
|
||||
if ((mii->mii_media_active & IFM_1000_T) != 0 &&
|
||||
(gtsr & GTSR_MS_RES) != 0)
|
||||
mii->mii_media_active |= IFM_ETH_MASTER;
|
||||
|
||||
if ((mii->mii_media_active & IFM_FDX) != 0)
|
||||
mii->mii_media_active |= mii_phy_flowstatus(phy);
|
||||
} else
|
||||
mii->mii_media_active = ife->ifm_media;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel drivers network 3com pci ;
|
||||
SubDir HAIKU_TOP src add-ons kernel drivers network 3com dev xl ;
|
||||
|
||||
UseHeaders [ FDirName $(SUBDIR) .. ] : true ;
|
||||
UseHeaders [ FDirName $(SUBDIR) .. .. ] : true ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ] : true ;
|
||||
|
||||
UsePrivateHeaders net system ;
|
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/pci/if_xl.c,v 1.210 2007/08/06 14:26:03 rwatson Exp $");
|
||||
__FBSDID("$FreeBSD: src/sys/dev/xl/if_xl.c,v 1.8.2.7.2.1 2010/12/21 17:09:25 kensmith Exp $");
|
||||
|
||||
/*
|
||||
* 3Com 3c90x Etherlink XL PCI NIC driver
|
||||
@ -96,9 +96,6 @@ __FBSDID("$FreeBSD: src/sys/pci/if_xl.c,v 1.210 2007/08/06 14:26:03 rwatson Exp
|
||||
* Since using bus master DMA is a big win, we use this driver to
|
||||
* support the PCI "boomerang" chips even though they work with the
|
||||
* "vortex" driver in order to obtain better performance.
|
||||
*
|
||||
* This driver is in the /sys/pci directory because it only supports
|
||||
* PCI-based NICs.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_KERNEL_OPTION_HEADERS
|
||||
@ -142,7 +139,7 @@ MODULE_DEPEND(xl, miibus, 1, 1, 1);
|
||||
/* "device miibus" required. See GENERIC if you get errors here. */
|
||||
#include "miibus_if.h"
|
||||
|
||||
#include <pci/if_xlreg.h>
|
||||
#include <dev/xl/if_xlreg.h>
|
||||
|
||||
/*
|
||||
* TX Checksumming is disabled by default for two reasons:
|
||||
@ -163,7 +160,7 @@ MODULE_DEPEND(xl, miibus, 1, 1, 1);
|
||||
/*
|
||||
* Various supported device vendors/types and their names.
|
||||
*/
|
||||
static struct xl_type xl_devs[] = {
|
||||
static const struct xl_type xl_devs[] = {
|
||||
{ TC_VENDORID, TC_DEVICEID_BOOMERANG_10BT,
|
||||
"3Com 3c900-TPO Etherlink XL" },
|
||||
{ TC_VENDORID, TC_DEVICEID_BOOMERANG_10BT_COMBO,
|
||||
@ -230,8 +227,8 @@ static int xl_detach(device_t);
|
||||
static int xl_newbuf(struct xl_softc *, struct xl_chain_onefrag *);
|
||||
static void xl_stats_update(void *);
|
||||
static void xl_stats_update_locked(struct xl_softc *);
|
||||
static int xl_encap(struct xl_softc *, struct xl_chain *, struct mbuf *);
|
||||
static void xl_rxeof(struct xl_softc *);
|
||||
static int xl_encap(struct xl_softc *, struct xl_chain *, struct mbuf **);
|
||||
static int xl_rxeof(struct xl_softc *);
|
||||
static void xl_rxeof_task(void *, int);
|
||||
static int xl_rx_resync(struct xl_softc *);
|
||||
static void xl_txeof(struct xl_softc *);
|
||||
@ -246,13 +243,14 @@ static void xl_init(void *);
|
||||
static void xl_init_locked(struct xl_softc *);
|
||||
static void xl_stop(struct xl_softc *);
|
||||
static int xl_watchdog(struct xl_softc *);
|
||||
static void xl_shutdown(device_t);
|
||||
static int xl_shutdown(device_t);
|
||||
static int xl_suspend(device_t);
|
||||
static int xl_resume(device_t);
|
||||
static void xl_setwol(struct xl_softc *);
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
static void xl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count);
|
||||
static void xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count);
|
||||
static int xl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count);
|
||||
static int xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count);
|
||||
#endif
|
||||
|
||||
static int xl_ifmedia_upd(struct ifnet *);
|
||||
@ -278,8 +276,6 @@ static void xl_mediacheck(struct xl_softc *);
|
||||
static void xl_choose_media(struct xl_softc *sc, int *media);
|
||||
static void xl_choose_xcvr(struct xl_softc *, int);
|
||||
static void xl_dma_map_addr(void *, bus_dma_segment_t *, int, int);
|
||||
static void xl_dma_map_rxbuf(void *, bus_dma_segment_t *, int, bus_size_t, int);
|
||||
static void xl_dma_map_txbuf(void *, bus_dma_segment_t *, int, bus_size_t, int);
|
||||
#ifdef notdef
|
||||
static void xl_testpacket(struct xl_softc *);
|
||||
#endif
|
||||
@ -319,7 +315,6 @@ static driver_t xl_driver = {
|
||||
|
||||
static devclass_t xl_devclass;
|
||||
|
||||
DRIVER_MODULE(xl, cardbus, xl_driver, xl_devclass, 0, 0);
|
||||
DRIVER_MODULE(xl, pci, xl_driver, xl_devclass, 0, 0);
|
||||
DRIVER_MODULE(miibus, xl, miibus_driver, miibus_devclass, 0, 0);
|
||||
|
||||
@ -332,46 +327,6 @@ xl_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
|
||||
*paddr = segs->ds_addr;
|
||||
}
|
||||
|
||||
static void
|
||||
xl_dma_map_rxbuf(void *arg, bus_dma_segment_t *segs, int nseg,
|
||||
bus_size_t mapsize, int error)
|
||||
{
|
||||
u_int32_t *paddr;
|
||||
|
||||
if (error)
|
||||
return;
|
||||
|
||||
KASSERT(nseg == 1, ("xl_dma_map_rxbuf: too many DMA segments"));
|
||||
paddr = arg;
|
||||
*paddr = segs->ds_addr;
|
||||
}
|
||||
|
||||
static void
|
||||
xl_dma_map_txbuf(void *arg, bus_dma_segment_t *segs, int nseg,
|
||||
bus_size_t mapsize, int error)
|
||||
{
|
||||
struct xl_list *l;
|
||||
int i, total_len;
|
||||
|
||||
if (error)
|
||||
return;
|
||||
|
||||
KASSERT(nseg <= XL_MAXFRAGS, ("too many DMA segments"));
|
||||
|
||||
total_len = 0;
|
||||
l = arg;
|
||||
for (i = 0; i < nseg; i++) {
|
||||
KASSERT(segs[i].ds_len <= MCLBYTES, ("segment size too large"));
|
||||
l->xl_frag[i].xl_addr = htole32(segs[i].ds_addr);
|
||||
l->xl_frag[i].xl_len = htole32(segs[i].ds_len);
|
||||
total_len += segs[i].ds_len;
|
||||
}
|
||||
l->xl_frag[nseg - 1].xl_len = htole32(segs[nseg - 1].ds_len |
|
||||
XL_LAST_FRAG);
|
||||
l->xl_status = htole32(total_len);
|
||||
l->xl_next = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Murphy's law says that it's possible the chip can wedge and
|
||||
* the 'command in progress' bit may never clear. Hence, we wait
|
||||
@ -568,16 +523,6 @@ xl_miibus_readreg(device_t dev, int phy, int reg)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
/*
|
||||
* Pretend that PHYs are only available at MII address 24.
|
||||
* This is to guard against problems with certain 3Com ASIC
|
||||
* revisions that incorrectly map the internal transceiver
|
||||
* control registers at all MII addresses. This can cause
|
||||
* the miibus code to attach the same PHY several times over.
|
||||
*/
|
||||
if ((sc->xl_flags & XL_FLAG_PHYOK) == 0 && phy != 24)
|
||||
return (0);
|
||||
|
||||
bzero((char *)&frame, sizeof(frame));
|
||||
frame.mii_phyaddr = phy;
|
||||
frame.mii_regaddr = reg;
|
||||
@ -595,9 +540,6 @@ xl_miibus_writereg(device_t dev, int phy, int reg, int data)
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
if ((sc->xl_flags & XL_FLAG_PHYOK) == 0 && phy != 24)
|
||||
return (0);
|
||||
|
||||
bzero((char *)&frame, sizeof(frame));
|
||||
frame.mii_phyaddr = phy;
|
||||
frame.mii_regaddr = reg;
|
||||
@ -613,6 +555,7 @@ xl_miibus_statchg(device_t dev)
|
||||
{
|
||||
struct xl_softc *sc;
|
||||
struct mii_data *mii;
|
||||
uint8_t macctl;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
mii = device_get_softc(sc->xl_miibus);
|
||||
@ -621,11 +564,22 @@ xl_miibus_statchg(device_t dev)
|
||||
|
||||
/* Set ASIC's duplex mode to match the PHY. */
|
||||
XL_SEL_WIN(3);
|
||||
if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX)
|
||||
CSR_WRITE_1(sc, XL_W3_MAC_CTRL, XL_MACCTRL_DUPLEX);
|
||||
else
|
||||
CSR_WRITE_1(sc, XL_W3_MAC_CTRL,
|
||||
(CSR_READ_1(sc, XL_W3_MAC_CTRL) & ~XL_MACCTRL_DUPLEX));
|
||||
macctl = CSR_READ_1(sc, XL_W3_MAC_CTRL);
|
||||
if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) {
|
||||
macctl |= XL_MACCTRL_DUPLEX;
|
||||
if (sc->xl_type == XL_TYPE_905B) {
|
||||
if ((IFM_OPTIONS(mii->mii_media_active) &
|
||||
IFM_ETH_RXPAUSE) != 0)
|
||||
macctl |= XL_MACCTRL_FLOW_CONTROL_ENB;
|
||||
else
|
||||
macctl &= ~XL_MACCTRL_FLOW_CONTROL_ENB;
|
||||
}
|
||||
} else {
|
||||
macctl &= ~XL_MACCTRL_DUPLEX;
|
||||
if (sc->xl_type == XL_TYPE_905B)
|
||||
macctl &= ~XL_MACCTRL_FLOW_CONTROL_ENB;
|
||||
}
|
||||
CSR_WRITE_1(sc, XL_W3_MAC_CTRL, macctl);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -770,10 +724,10 @@ xl_setmulti(struct xl_softc *sc)
|
||||
return;
|
||||
}
|
||||
|
||||
IF_ADDR_LOCK(ifp);
|
||||
if_maddr_rlock(ifp);
|
||||
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
|
||||
mcnt++;
|
||||
IF_ADDR_UNLOCK(ifp);
|
||||
if_maddr_runlock(ifp);
|
||||
|
||||
if (mcnt)
|
||||
rxfilt |= XL_RXFILTER_ALLMULTI;
|
||||
@ -812,7 +766,7 @@ xl_setmulti_hash(struct xl_softc *sc)
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_HASH|i);
|
||||
|
||||
/* now program new ones */
|
||||
IF_ADDR_LOCK(ifp);
|
||||
if_maddr_rlock(ifp);
|
||||
TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
|
||||
if (ifma->ifma_addr->sa_family != AF_LINK)
|
||||
continue;
|
||||
@ -834,7 +788,7 @@ xl_setmulti_hash(struct xl_softc *sc)
|
||||
h | XL_CMD_RX_SET_HASH | XL_HASH_SET);
|
||||
mcnt++;
|
||||
}
|
||||
IF_ADDR_UNLOCK(ifp);
|
||||
if_maddr_runlock(ifp);
|
||||
|
||||
if (mcnt)
|
||||
rxfilt |= XL_RXFILTER_MULTIHASH;
|
||||
@ -844,32 +798,6 @@ xl_setmulti_hash(struct xl_softc *sc)
|
||||
CSR_WRITE_2(sc, XL_COMMAND, rxfilt | XL_CMD_RX_SET_FILT);
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
static void
|
||||
xl_testpacket(struct xl_softc *sc)
|
||||
{
|
||||
struct mbuf *m;
|
||||
struct ifnet *ifp = sc->xl_ifp;
|
||||
|
||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||
|
||||
if (m == NULL)
|
||||
return;
|
||||
|
||||
bcopy(IF_LLADDR(sc->xl_ifp),
|
||||
mtod(m, struct ether_header *)->ether_dhost, ETHER_ADDR_LEN);
|
||||
bcopy(IF_LLADDR(sc->xl_ifp),
|
||||
mtod(m, struct ether_header *)->ether_shost, ETHER_ADDR_LEN);
|
||||
mtod(m, struct ether_header *)->ether_type = htons(3);
|
||||
mtod(m, unsigned char *)[14] = 0;
|
||||
mtod(m, unsigned char *)[15] = 0;
|
||||
mtod(m, unsigned char *)[16] = 0xE3;
|
||||
m->m_len = m->m_pkthdr.len = sizeof(struct ether_header) + 3;
|
||||
IFQ_ENQUEUE(&ifp->if_snd, m);
|
||||
xl_start(ifp);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
xl_setcfg(struct xl_softc *sc)
|
||||
{
|
||||
@ -1052,7 +980,7 @@ xl_reset(struct xl_softc *sc)
|
||||
static int
|
||||
xl_probe(device_t dev)
|
||||
{
|
||||
struct xl_type *t;
|
||||
const struct xl_type *t;
|
||||
|
||||
t = xl_devs;
|
||||
|
||||
@ -1217,16 +1145,16 @@ static int
|
||||
xl_attach(device_t dev)
|
||||
{
|
||||
u_char eaddr[ETHER_ADDR_LEN];
|
||||
u_int16_t xcvr[2];
|
||||
u_int16_t sinfo2, xcvr[2];
|
||||
struct xl_softc *sc;
|
||||
struct ifnet *ifp;
|
||||
int media;
|
||||
int unit, error = 0, rid, res;
|
||||
int media, pmcap;
|
||||
int error = 0, phy, rid, res, unit;
|
||||
uint16_t did;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
sc->xl_dev = dev;
|
||||
|
||||
|
||||
unit = device_get_unit(dev);
|
||||
|
||||
mtx_init(&sc->xl_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
|
||||
@ -1369,7 +1297,6 @@ xl_attach(device_t dev)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sc->xl_unit = unit;
|
||||
callout_init_mtx(&sc->xl_stat_callout, &sc->xl_mtx, 0);
|
||||
TASK_INIT(&sc->xl_task, 0, xl_rxeof_task, sc);
|
||||
|
||||
@ -1478,6 +1405,18 @@ xl_attach(device_t dev)
|
||||
else
|
||||
sc->xl_type = XL_TYPE_90X;
|
||||
|
||||
/* Check availability of WOL. */
|
||||
if ((sc->xl_caps & XL_CAPS_PWRMGMT) != 0 &&
|
||||
pci_find_extcap(dev, PCIY_PMG, &pmcap) == 0) {
|
||||
sc->xl_pmcap = pmcap;
|
||||
sc->xl_flags |= XL_FLAG_WOL;
|
||||
sinfo2 = 0;
|
||||
xl_read_eeprom(sc, (caddr_t)&sinfo2, XL_EE_SOFTINFO2, 1, 0);
|
||||
if ((sinfo2 & XL_SINFO2_AUX_WOL_CON) == 0 && bootverbose)
|
||||
device_printf(dev,
|
||||
"No auxiliary remote wakeup connector!\n");
|
||||
}
|
||||
|
||||
/* Set the TX start threshold for best performance. */
|
||||
sc->xl_tx_thresh = XL_MIN_FRAMELEN;
|
||||
|
||||
@ -1492,6 +1431,8 @@ xl_attach(device_t dev)
|
||||
ifp->if_capabilities |= IFCAP_HWCSUM;
|
||||
#endif
|
||||
}
|
||||
if ((sc->xl_flags & XL_FLAG_WOL) != 0)
|
||||
ifp->if_capabilities |= IFCAP_WOL_MAGIC;
|
||||
ifp->if_capenable = ifp->if_capabilities;
|
||||
#ifdef DEVICE_POLLING
|
||||
ifp->if_capabilities |= IFCAP_POLLING;
|
||||
@ -1525,10 +1466,20 @@ xl_attach(device_t dev)
|
||||
if (bootverbose)
|
||||
device_printf(dev, "found MII/AUTO\n");
|
||||
xl_setcfg(sc);
|
||||
if (mii_phy_probe(dev, &sc->xl_miibus,
|
||||
xl_ifmedia_upd, xl_ifmedia_sts)) {
|
||||
device_printf(dev, "no PHY found!\n");
|
||||
error = ENXIO;
|
||||
/*
|
||||
* Attach PHYs only at MII address 24 if !XL_FLAG_PHYOK.
|
||||
* This is to guard against problems with certain 3Com ASIC
|
||||
* revisions that incorrectly map the internal transceiver
|
||||
* control registers at all MII addresses.
|
||||
*/
|
||||
phy = MII_PHY_ANY;
|
||||
if ((sc->xl_flags & XL_FLAG_PHYOK) == 0)
|
||||
phy = 24;
|
||||
error = mii_attach(dev, &sc->xl_miibus, ifp, xl_ifmedia_upd,
|
||||
xl_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY,
|
||||
sc->xl_type == XL_TYPE_905B ? MIIF_DOPAUSE : 0);
|
||||
if (error != 0) {
|
||||
device_printf(dev, "attaching PHYs failed\n");
|
||||
goto fail;
|
||||
}
|
||||
goto done;
|
||||
@ -1708,7 +1659,6 @@ xl_detach(device_t dev)
|
||||
/* These should only be active if attach succeeded */
|
||||
if (device_is_attached(dev)) {
|
||||
XL_LOCK(sc);
|
||||
xl_reset(sc);
|
||||
xl_stop(sc);
|
||||
XL_UNLOCK(sc);
|
||||
taskqueue_drain(taskqueue_swi, &sc->xl_task);
|
||||
@ -1890,8 +1840,8 @@ xl_newbuf(struct xl_softc *sc, struct xl_chain_onefrag *c)
|
||||
{
|
||||
struct mbuf *m_new = NULL;
|
||||
bus_dmamap_t map;
|
||||
int error;
|
||||
u_int32_t baddr;
|
||||
bus_dma_segment_t segs[1];
|
||||
int error, nseg;
|
||||
|
||||
XL_LOCK_ASSERT(sc);
|
||||
|
||||
@ -1904,14 +1854,16 @@ xl_newbuf(struct xl_softc *sc, struct xl_chain_onefrag *c)
|
||||
/* Force longword alignment for packet payload. */
|
||||
m_adj(m_new, ETHER_ALIGN);
|
||||
|
||||
error = bus_dmamap_load_mbuf(sc->xl_mtag, sc->xl_tmpmap, m_new,
|
||||
xl_dma_map_rxbuf, &baddr, BUS_DMA_NOWAIT);
|
||||
error = bus_dmamap_load_mbuf_sg(sc->xl_mtag, sc->xl_tmpmap, m_new,
|
||||
segs, &nseg, BUS_DMA_NOWAIT);
|
||||
if (error) {
|
||||
m_freem(m_new);
|
||||
device_printf(sc->xl_dev, "can't map mbuf (error %d)\n",
|
||||
error);
|
||||
return (error);
|
||||
}
|
||||
KASSERT(nseg == 1,
|
||||
("%s: too many DMA segments (%d)", __func__, nseg));
|
||||
|
||||
bus_dmamap_unload(sc->xl_mtag, c->xl_map);
|
||||
map = c->xl_map;
|
||||
@ -1920,7 +1872,7 @@ xl_newbuf(struct xl_softc *sc, struct xl_chain_onefrag *c)
|
||||
c->xl_mbuf = m_new;
|
||||
c->xl_ptr->xl_frag.xl_len = htole32(m_new->m_len | XL_LAST_FRAG);
|
||||
c->xl_ptr->xl_status = 0;
|
||||
c->xl_ptr->xl_frag.xl_addr = htole32(baddr);
|
||||
c->xl_ptr->xl_frag.xl_addr = htole32(segs->ds_addr);
|
||||
bus_dmamap_sync(sc->xl_mtag, c->xl_map, BUS_DMASYNC_PREREAD);
|
||||
return (0);
|
||||
}
|
||||
@ -1953,13 +1905,14 @@ xl_rx_resync(struct xl_softc *sc)
|
||||
* A frame has been uploaded: pass the resulting mbuf chain up to
|
||||
* the higher level protocols.
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
xl_rxeof(struct xl_softc *sc)
|
||||
{
|
||||
struct mbuf *m;
|
||||
struct ifnet *ifp = sc->xl_ifp;
|
||||
struct xl_chain_onefrag *cur_rx;
|
||||
int total_len = 0;
|
||||
int rx_npkts = 0;
|
||||
u_int32_t rxstat;
|
||||
|
||||
XL_LOCK_ASSERT(sc);
|
||||
@ -2061,6 +2014,7 @@ again:
|
||||
XL_UNLOCK(sc);
|
||||
(*ifp->if_input)(ifp, m);
|
||||
XL_LOCK(sc);
|
||||
rx_npkts++;
|
||||
|
||||
/*
|
||||
* If we are running from the taskqueue, the interface
|
||||
@ -2068,7 +2022,7 @@ again:
|
||||
* packet up the network stack.
|
||||
*/
|
||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
|
||||
return;
|
||||
return (rx_npkts);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2092,6 +2046,7 @@ again:
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_UP_UNSTALL);
|
||||
goto again;
|
||||
}
|
||||
return (rx_npkts);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2142,13 +2097,13 @@ xl_txeof(struct xl_softc *sc)
|
||||
m_freem(cur_tx->xl_mbuf);
|
||||
cur_tx->xl_mbuf = NULL;
|
||||
ifp->if_opackets++;
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
|
||||
cur_tx->xl_next = sc->xl_cdata.xl_tx_free;
|
||||
sc->xl_cdata.xl_tx_free = cur_tx;
|
||||
}
|
||||
|
||||
if (sc->xl_cdata.xl_tx_head == NULL) {
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
sc->xl_wdog_timer = 0;
|
||||
sc->xl_cdata.xl_tx_tail = NULL;
|
||||
} else {
|
||||
@ -2174,7 +2129,6 @@ xl_txeof_90xB(struct xl_softc *sc)
|
||||
BUS_DMASYNC_POSTREAD);
|
||||
idx = sc->xl_cdata.xl_tx_cons;
|
||||
while (idx != sc->xl_cdata.xl_tx_prod) {
|
||||
|
||||
cur_tx = &sc->xl_cdata.xl_tx_chain[idx];
|
||||
|
||||
if (!(le32toh(cur_tx->xl_ptr->xl_status) &
|
||||
@ -2286,6 +2240,7 @@ xl_intr(void *arg)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __HAIKU__
|
||||
while ((status = CSR_READ_2(sc, XL_STATUS)) & XL_INTRS &&
|
||||
status != 0xFFFF) {
|
||||
@ -2293,6 +2248,9 @@ xl_intr(void *arg)
|
||||
status = atomic_get((int32 *)&sc->xl_intr_status);
|
||||
while (true) {
|
||||
#endif
|
||||
CSR_WRITE_2(sc, XL_COMMAND,
|
||||
XL_CMD_INTR_ACK|(status & XL_INTRS));
|
||||
|
||||
if (status & XL_STAT_UP_COMPLETE) {
|
||||
int curpkts;
|
||||
|
||||
@ -2317,7 +2275,7 @@ xl_intr(void *arg)
|
||||
}
|
||||
|
||||
if (status & XL_STAT_ADFAIL) {
|
||||
xl_reset(sc);
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
xl_init_locked(sc);
|
||||
}
|
||||
|
||||
@ -2347,26 +2305,29 @@ xl_intr(void *arg)
|
||||
}
|
||||
|
||||
#ifdef DEVICE_POLLING
|
||||
static void
|
||||
static int
|
||||
xl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
|
||||
{
|
||||
struct xl_softc *sc = ifp->if_softc;
|
||||
int rx_npkts = 0;
|
||||
|
||||
XL_LOCK(sc);
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
|
||||
xl_poll_locked(ifp, cmd, count);
|
||||
rx_npkts = xl_poll_locked(ifp, cmd, count);
|
||||
XL_UNLOCK(sc);
|
||||
return (rx_npkts);
|
||||
}
|
||||
|
||||
static void
|
||||
static int
|
||||
xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
|
||||
{
|
||||
struct xl_softc *sc = ifp->if_softc;
|
||||
int rx_npkts;
|
||||
|
||||
XL_LOCK_ASSERT(sc);
|
||||
|
||||
sc->rxcycles = count;
|
||||
xl_rxeof(sc);
|
||||
rx_npkts = xl_rxeof(sc);
|
||||
if (sc->xl_type == XL_TYPE_905B)
|
||||
xl_txeof_90xB(sc);
|
||||
else
|
||||
@ -2393,7 +2354,7 @@ xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
|
||||
}
|
||||
|
||||
if (status & XL_STAT_ADFAIL) {
|
||||
xl_reset(sc);
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
xl_init_locked(sc);
|
||||
}
|
||||
|
||||
@ -2404,6 +2365,7 @@ xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
|
||||
}
|
||||
}
|
||||
}
|
||||
return (rx_npkts);
|
||||
}
|
||||
#endif /* DEVICE_POLLING */
|
||||
|
||||
@ -2475,26 +2437,21 @@ xl_stats_update_locked(struct xl_softc *sc)
|
||||
* pointers to the fragment pointers.
|
||||
*/
|
||||
static int
|
||||
xl_encap(struct xl_softc *sc, struct xl_chain *c, struct mbuf *m_head)
|
||||
xl_encap(struct xl_softc *sc, struct xl_chain *c, struct mbuf **m_head)
|
||||
{
|
||||
int error;
|
||||
u_int32_t status;
|
||||
struct mbuf *m_new;
|
||||
struct ifnet *ifp = sc->xl_ifp;
|
||||
int error, i, nseg, total_len;
|
||||
u_int32_t status;
|
||||
|
||||
XL_LOCK_ASSERT(sc);
|
||||
|
||||
/*
|
||||
* Start packing the mbufs in this chain into
|
||||
* the fragment pointers. Stop when we run out
|
||||
* of fragments or hit the end of the mbuf chain.
|
||||
*/
|
||||
error = bus_dmamap_load_mbuf(sc->xl_mtag, c->xl_map, m_head,
|
||||
xl_dma_map_txbuf, c->xl_ptr, BUS_DMA_NOWAIT);
|
||||
error = bus_dmamap_load_mbuf_sg(sc->xl_mtag, c->xl_map, *m_head,
|
||||
sc->xl_cdata.xl_tx_segs, &nseg, BUS_DMA_NOWAIT);
|
||||
|
||||
if (error && error != EFBIG) {
|
||||
m_freem(m_head);
|
||||
if_printf(ifp, "can't map mbuf (error %d)\n", error);
|
||||
return (1);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2506,42 +2463,64 @@ xl_encap(struct xl_softc *sc, struct xl_chain *c, struct mbuf *m_head)
|
||||
* and would waste cycles.
|
||||
*/
|
||||
if (error) {
|
||||
struct mbuf *m_new;
|
||||
|
||||
m_new = m_defrag(m_head, M_DONTWAIT);
|
||||
m_new = m_collapse(*m_head, M_DONTWAIT, XL_MAXFRAGS);
|
||||
if (m_new == NULL) {
|
||||
m_freem(m_head);
|
||||
return (1);
|
||||
} else {
|
||||
m_head = m_new;
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
return (ENOBUFS);
|
||||
}
|
||||
*m_head = m_new;
|
||||
|
||||
error = bus_dmamap_load_mbuf(sc->xl_mtag, c->xl_map,
|
||||
m_head, xl_dma_map_txbuf, c->xl_ptr, BUS_DMA_NOWAIT);
|
||||
error = bus_dmamap_load_mbuf_sg(sc->xl_mtag, c->xl_map,
|
||||
*m_head, sc->xl_cdata.xl_tx_segs, &nseg, BUS_DMA_NOWAIT);
|
||||
if (error) {
|
||||
m_freem(m_head);
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
if_printf(ifp, "can't map mbuf (error %d)\n", error);
|
||||
return (1);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
|
||||
KASSERT(nseg <= XL_MAXFRAGS,
|
||||
("%s: too many DMA segments (%d)", __func__, nseg));
|
||||
if (nseg == 0) {
|
||||
m_freem(*m_head);
|
||||
*m_head = NULL;
|
||||
return (EIO);
|
||||
}
|
||||
|
||||
total_len = 0;
|
||||
for (i = 0; i < nseg; i++) {
|
||||
KASSERT(sc->xl_cdata.xl_tx_segs[i].ds_len <= MCLBYTES,
|
||||
("segment size too large"));
|
||||
c->xl_ptr->xl_frag[i].xl_addr =
|
||||
htole32(sc->xl_cdata.xl_tx_segs[i].ds_addr);
|
||||
c->xl_ptr->xl_frag[i].xl_len =
|
||||
htole32(sc->xl_cdata.xl_tx_segs[i].ds_len);
|
||||
total_len += sc->xl_cdata.xl_tx_segs[i].ds_len;
|
||||
}
|
||||
c->xl_ptr->xl_frag[nseg - 1].xl_len =
|
||||
htole32(sc->xl_cdata.xl_tx_segs[nseg - 1].ds_len | XL_LAST_FRAG);
|
||||
c->xl_ptr->xl_status = htole32(total_len);
|
||||
c->xl_ptr->xl_next = 0;
|
||||
|
||||
if (sc->xl_type == XL_TYPE_905B) {
|
||||
status = XL_TXSTAT_RND_DEFEAT;
|
||||
|
||||
#ifndef XL905B_TXCSUM_BROKEN
|
||||
if (m_head->m_pkthdr.csum_flags) {
|
||||
if (m_head->m_pkthdr.csum_flags & CSUM_IP)
|
||||
if ((*m_head)->m_pkthdr.csum_flags) {
|
||||
if ((*m_head)->m_pkthdr.csum_flags & CSUM_IP)
|
||||
status |= XL_TXSTAT_IPCKSUM;
|
||||
if (m_head->m_pkthdr.csum_flags & CSUM_TCP)
|
||||
if ((*m_head)->m_pkthdr.csum_flags & CSUM_TCP)
|
||||
status |= XL_TXSTAT_TCPCKSUM;
|
||||
if (m_head->m_pkthdr.csum_flags & CSUM_UDP)
|
||||
if ((*m_head)->m_pkthdr.csum_flags & CSUM_UDP)
|
||||
status |= XL_TXSTAT_UDPCKSUM;
|
||||
}
|
||||
#endif
|
||||
c->xl_ptr->xl_status = htole32(status);
|
||||
}
|
||||
|
||||
c->xl_mbuf = m_head;
|
||||
c->xl_mbuf = *m_head;
|
||||
bus_dmamap_sync(sc->xl_mtag, c->xl_map, BUS_DMASYNC_PREWRITE);
|
||||
return (0);
|
||||
}
|
||||
@ -2574,12 +2553,14 @@ xl_start_locked(struct ifnet *ifp)
|
||||
struct xl_softc *sc = ifp->if_softc;
|
||||
struct mbuf *m_head = NULL;
|
||||
struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx;
|
||||
struct xl_chain *prev_tx;
|
||||
u_int32_t status;
|
||||
int error;
|
||||
|
||||
XL_LOCK_ASSERT(sc);
|
||||
|
||||
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
|
||||
IFF_DRV_RUNNING)
|
||||
return;
|
||||
/*
|
||||
* Check for an available queue slot. If there are none,
|
||||
* punt.
|
||||
@ -2595,20 +2576,23 @@ xl_start_locked(struct ifnet *ifp)
|
||||
|
||||
start_tx = sc->xl_cdata.xl_tx_free;
|
||||
|
||||
while (sc->xl_cdata.xl_tx_free != NULL) {
|
||||
for (; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) &&
|
||||
sc->xl_cdata.xl_tx_free != NULL;) {
|
||||
IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
|
||||
if (m_head == NULL)
|
||||
break;
|
||||
|
||||
/* Pick a descriptor off the free list. */
|
||||
prev_tx = cur_tx;
|
||||
cur_tx = sc->xl_cdata.xl_tx_free;
|
||||
|
||||
/* Pack the data into the descriptor. */
|
||||
error = xl_encap(sc, cur_tx, m_head);
|
||||
error = xl_encap(sc, cur_tx, &m_head);
|
||||
if (error) {
|
||||
cur_tx = prev_tx;
|
||||
continue;
|
||||
if (m_head == NULL)
|
||||
break;
|
||||
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
||||
IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
|
||||
break;
|
||||
}
|
||||
|
||||
sc->xl_cdata.xl_tx_free = cur_tx->xl_next;
|
||||
@ -2638,7 +2622,7 @@ xl_start_locked(struct ifnet *ifp)
|
||||
* Place the request for the upload interrupt
|
||||
* in the last descriptor in the chain. This way, if
|
||||
* we're chaining several packets at once, we'll only
|
||||
* get an interupt once for the whole chain rather than
|
||||
* get an interrupt once for the whole chain rather than
|
||||
* once for each packet.
|
||||
*/
|
||||
cur_tx->xl_ptr->xl_status = htole32(le32toh(cur_tx->xl_ptr->xl_status) |
|
||||
@ -2701,19 +2685,19 @@ xl_start_90xB_locked(struct ifnet *ifp)
|
||||
struct xl_softc *sc = ifp->if_softc;
|
||||
struct mbuf *m_head = NULL;
|
||||
struct xl_chain *prev = NULL, *cur_tx = NULL, *start_tx;
|
||||
struct xl_chain *prev_tx;
|
||||
int error, idx;
|
||||
|
||||
XL_LOCK_ASSERT(sc);
|
||||
|
||||
if (ifp->if_drv_flags & IFF_DRV_OACTIVE)
|
||||
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
|
||||
IFF_DRV_RUNNING)
|
||||
return;
|
||||
|
||||
idx = sc->xl_cdata.xl_tx_prod;
|
||||
start_tx = &sc->xl_cdata.xl_tx_chain[idx];
|
||||
|
||||
while (sc->xl_cdata.xl_tx_chain[idx].xl_mbuf == NULL) {
|
||||
|
||||
for (; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) &&
|
||||
sc->xl_cdata.xl_tx_chain[idx].xl_mbuf == NULL;) {
|
||||
if ((XL_TX_LIST_CNT - sc->xl_cdata.xl_tx_cnt) < 3) {
|
||||
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
||||
break;
|
||||
@ -2723,14 +2707,16 @@ xl_start_90xB_locked(struct ifnet *ifp)
|
||||
if (m_head == NULL)
|
||||
break;
|
||||
|
||||
prev_tx = cur_tx;
|
||||
cur_tx = &sc->xl_cdata.xl_tx_chain[idx];
|
||||
|
||||
/* Pack the data into the descriptor. */
|
||||
error = xl_encap(sc, cur_tx, m_head);
|
||||
error = xl_encap(sc, cur_tx, &m_head);
|
||||
if (error) {
|
||||
cur_tx = prev_tx;
|
||||
continue;
|
||||
if (m_head == NULL)
|
||||
break;
|
||||
ifp->if_drv_flags |= IFF_DRV_OACTIVE;
|
||||
IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Chain it together. */
|
||||
@ -2758,7 +2744,7 @@ xl_start_90xB_locked(struct ifnet *ifp)
|
||||
* Place the request for the upload interrupt
|
||||
* in the last descriptor in the chain. This way, if
|
||||
* we're chaining several packets at once, we'll only
|
||||
* get an interupt once for the whole chain rather than
|
||||
* get an interrupt once for the whole chain rather than
|
||||
* once for each packet.
|
||||
*/
|
||||
cur_tx->xl_ptr->xl_status = htole32(le32toh(cur_tx->xl_ptr->xl_status) |
|
||||
@ -2796,11 +2782,16 @@ xl_init_locked(struct xl_softc *sc)
|
||||
|
||||
XL_LOCK_ASSERT(sc);
|
||||
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
|
||||
return;
|
||||
/*
|
||||
* Cancel pending I/O and free all RX/TX buffers.
|
||||
*/
|
||||
xl_stop(sc);
|
||||
|
||||
/* Reset the chip to a known state. */
|
||||
xl_reset(sc);
|
||||
|
||||
if (sc->xl_miibus == NULL) {
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_RESET);
|
||||
xl_wait(sc);
|
||||
@ -2812,6 +2803,15 @@ xl_init_locked(struct xl_softc *sc)
|
||||
if (sc->xl_miibus != NULL)
|
||||
mii = device_get_softc(sc->xl_miibus);
|
||||
|
||||
/*
|
||||
* Clear WOL status and disable all WOL feature as WOL
|
||||
* would interfere Rx operation under normal environments.
|
||||
*/
|
||||
if ((sc->xl_flags & XL_FLAG_WOL) != 0) {
|
||||
XL_SEL_WIN(7);
|
||||
CSR_READ_2(sc, XL_W7_BM_PME);
|
||||
CSR_WRITE_2(sc, XL_W7_BM_PME, 0);
|
||||
}
|
||||
/* Init our MAC address */
|
||||
XL_SEL_WIN(2);
|
||||
for (i = 0; i < ETHER_ADDR_LEN; i++) {
|
||||
@ -3037,15 +3037,14 @@ xl_ifmedia_upd(struct ifnet *ifp)
|
||||
case IFM_10_2:
|
||||
case IFM_10_5:
|
||||
xl_setmode(sc, ifm->ifm_media);
|
||||
XL_UNLOCK(sc);
|
||||
return (0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (sc->xl_media & XL_MEDIAOPT_MII ||
|
||||
sc->xl_media & XL_MEDIAOPT_BTX ||
|
||||
sc->xl_media & XL_MEDIAOPT_BT4) {
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
xl_init_locked(sc);
|
||||
} else {
|
||||
xl_setmode(sc, ifm->ifm_media);
|
||||
@ -3136,7 +3135,7 @@ xl_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
{
|
||||
struct xl_softc *sc = ifp->if_softc;
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int error = 0;
|
||||
int error = 0, mask;
|
||||
struct mii_data *mii = NULL;
|
||||
u_int8_t rxfilt;
|
||||
|
||||
@ -3161,10 +3160,8 @@ xl_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
CSR_WRITE_2(sc, XL_COMMAND,
|
||||
XL_CMD_RX_SET_FILT|rxfilt);
|
||||
XL_SEL_WIN(7);
|
||||
} else {
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
||||
xl_init_locked(sc);
|
||||
}
|
||||
} else
|
||||
xl_init_locked(sc);
|
||||
} else {
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
|
||||
xl_stop(sc);
|
||||
@ -3196,41 +3193,50 @@ xl_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
&mii->mii_media, command);
|
||||
break;
|
||||
case SIOCSIFCAP:
|
||||
mask = ifr->ifr_reqcap ^ ifp->if_capenable;
|
||||
#ifdef DEVICE_POLLING
|
||||
if (ifr->ifr_reqcap & IFCAP_POLLING &&
|
||||
!(ifp->if_capenable & IFCAP_POLLING)) {
|
||||
error = ether_poll_register(xl_poll, ifp);
|
||||
if (error)
|
||||
return(error);
|
||||
XL_LOCK(sc);
|
||||
/* Disable interrupts */
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0);
|
||||
ifp->if_capenable |= IFCAP_POLLING;
|
||||
XL_UNLOCK(sc);
|
||||
return (error);
|
||||
|
||||
}
|
||||
if (!(ifr->ifr_reqcap & IFCAP_POLLING) &&
|
||||
ifp->if_capenable & IFCAP_POLLING) {
|
||||
error = ether_poll_deregister(ifp);
|
||||
/* Enable interrupts. */
|
||||
XL_LOCK(sc);
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|0xFF);
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|XL_INTRS);
|
||||
if (sc->xl_flags & XL_FLAG_FUNCREG)
|
||||
bus_space_write_4(sc->xl_ftag, sc->xl_fhandle,
|
||||
4, 0x8000);
|
||||
ifp->if_capenable &= ~IFCAP_POLLING;
|
||||
XL_UNLOCK(sc);
|
||||
return (error);
|
||||
if ((mask & IFCAP_POLLING) != 0 &&
|
||||
(ifp->if_capabilities & IFCAP_POLLING) != 0) {
|
||||
ifp->if_capenable ^= IFCAP_POLLING;
|
||||
if ((ifp->if_capenable & IFCAP_POLLING) != 0) {
|
||||
error = ether_poll_register(xl_poll, ifp);
|
||||
if (error)
|
||||
break;
|
||||
XL_LOCK(sc);
|
||||
/* Disable interrupts */
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0);
|
||||
ifp->if_capenable |= IFCAP_POLLING;
|
||||
XL_UNLOCK(sc);
|
||||
} else {
|
||||
error = ether_poll_deregister(ifp);
|
||||
/* Enable interrupts. */
|
||||
XL_LOCK(sc);
|
||||
CSR_WRITE_2(sc, XL_COMMAND,
|
||||
XL_CMD_INTR_ACK | 0xFF);
|
||||
CSR_WRITE_2(sc, XL_COMMAND,
|
||||
XL_CMD_INTR_ENB | XL_INTRS);
|
||||
if (sc->xl_flags & XL_FLAG_FUNCREG)
|
||||
bus_space_write_4(sc->xl_ftag,
|
||||
sc->xl_fhandle, 4, 0x8000);
|
||||
XL_UNLOCK(sc);
|
||||
}
|
||||
}
|
||||
#endif /* DEVICE_POLLING */
|
||||
XL_LOCK(sc);
|
||||
ifp->if_capenable = ifr->ifr_reqcap;
|
||||
if (ifp->if_capenable & IFCAP_TXCSUM)
|
||||
ifp->if_hwassist = XL905B_CSUM_FEATURES;
|
||||
else
|
||||
ifp->if_hwassist = 0;
|
||||
if ((mask & IFCAP_TXCSUM) != 0 &&
|
||||
(ifp->if_capabilities & IFCAP_TXCSUM) != 0) {
|
||||
ifp->if_capenable ^= IFCAP_TXCSUM;
|
||||
if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
|
||||
ifp->if_hwassist |= XL905B_CSUM_FEATURES;
|
||||
else
|
||||
ifp->if_hwassist &= ~XL905B_CSUM_FEATURES;
|
||||
}
|
||||
if ((mask & IFCAP_RXCSUM) != 0 &&
|
||||
(ifp->if_capabilities & IFCAP_RXCSUM) != 0)
|
||||
ifp->if_capenable ^= IFCAP_RXCSUM;
|
||||
if ((mask & IFCAP_WOL_MAGIC) != 0 &&
|
||||
(ifp->if_capabilities & IFCAP_WOL_MAGIC) != 0)
|
||||
ifp->if_capenable ^= IFCAP_WOL_MAGIC;
|
||||
XL_UNLOCK(sc);
|
||||
break;
|
||||
default:
|
||||
@ -3246,12 +3252,31 @@ xl_watchdog(struct xl_softc *sc)
|
||||
{
|
||||
struct ifnet *ifp = sc->xl_ifp;
|
||||
u_int16_t status = 0;
|
||||
int misintr;
|
||||
|
||||
XL_LOCK_ASSERT(sc);
|
||||
|
||||
if (sc->xl_wdog_timer == 0 || --sc->xl_wdog_timer != 0)
|
||||
return (0);
|
||||
|
||||
xl_rxeof(sc);
|
||||
xl_txeoc(sc);
|
||||
misintr = 0;
|
||||
if (sc->xl_type == XL_TYPE_905B) {
|
||||
xl_txeof_90xB(sc);
|
||||
if (sc->xl_cdata.xl_tx_cnt == 0)
|
||||
misintr++;
|
||||
} else {
|
||||
xl_txeof(sc);
|
||||
if (sc->xl_cdata.xl_tx_head == NULL)
|
||||
misintr++;
|
||||
}
|
||||
if (misintr != 0) {
|
||||
device_printf(sc->xl_dev,
|
||||
"watchdog timeout (missed Tx interrupts) -- recovering\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
ifp->if_oerrors++;
|
||||
XL_SEL_WIN(4);
|
||||
status = CSR_READ_2(sc, XL_W4_MEDIA_STATUS);
|
||||
@ -3261,10 +3286,7 @@ xl_watchdog(struct xl_softc *sc)
|
||||
device_printf(sc->xl_dev,
|
||||
"no carrier - transceiver cable problem?\n");
|
||||
|
||||
xl_txeoc(sc);
|
||||
xl_txeof(sc);
|
||||
xl_rxeof(sc);
|
||||
xl_reset(sc);
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
xl_init_locked(sc);
|
||||
|
||||
if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
|
||||
@ -3354,17 +3376,11 @@ xl_stop(struct xl_softc *sc)
|
||||
* Stop all chip I/O so that the kernel's probe routines don't
|
||||
* get confused by errant DMAs when rebooting.
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
xl_shutdown(device_t dev)
|
||||
{
|
||||
struct xl_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
|
||||
XL_LOCK(sc);
|
||||
xl_reset(sc);
|
||||
xl_stop(sc);
|
||||
XL_UNLOCK(sc);
|
||||
return (xl_suspend(dev));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -3376,6 +3392,7 @@ xl_suspend(device_t dev)
|
||||
|
||||
XL_LOCK(sc);
|
||||
xl_stop(sc);
|
||||
xl_setwol(sc);
|
||||
XL_UNLOCK(sc);
|
||||
|
||||
return (0);
|
||||
@ -3392,11 +3409,43 @@ xl_resume(device_t dev)
|
||||
|
||||
XL_LOCK(sc);
|
||||
|
||||
xl_reset(sc);
|
||||
if (ifp->if_flags & IFF_UP)
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
xl_init_locked(sc);
|
||||
}
|
||||
|
||||
XL_UNLOCK(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
xl_setwol(struct xl_softc *sc)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
u_int16_t cfg, pmstat;
|
||||
|
||||
if ((sc->xl_flags & XL_FLAG_WOL) == 0)
|
||||
return;
|
||||
|
||||
ifp = sc->xl_ifp;
|
||||
XL_SEL_WIN(7);
|
||||
/* Clear any pending PME events. */
|
||||
CSR_READ_2(sc, XL_W7_BM_PME);
|
||||
cfg = 0;
|
||||
if ((ifp->if_capenable & IFCAP_WOL_MAGIC) != 0)
|
||||
cfg |= XL_BM_PME_MAGIC;
|
||||
CSR_WRITE_2(sc, XL_W7_BM_PME, cfg);
|
||||
/* Enable RX. */
|
||||
if ((ifp->if_capenable & IFCAP_WOL_MAGIC) != 0)
|
||||
CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_ENABLE);
|
||||
/* Request PME. */
|
||||
pmstat = pci_read_config(sc->xl_dev,
|
||||
sc->xl_pmcap + PCIR_POWER_STATUS, 2);
|
||||
if ((ifp->if_capenable & IFCAP_WOL_MAGIC) != 0)
|
||||
pmstat |= PCIM_PSTAT_PMEENABLE;
|
||||
else
|
||||
pmstat &= ~PCIM_PSTAT_PMEENABLE;
|
||||
pci_write_config(sc->xl_dev,
|
||||
sc->xl_pmcap + PCIR_POWER_STATUS, pmstat, 2);
|
||||
}
|
@ -29,7 +29,7 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: src/sys/pci/if_xlreg.h,v 1.59 2006/12/06 02:18:41 marius Exp $
|
||||
* $FreeBSD: src/sys/dev/xl/if_xlreg.h,v 1.1.2.2.2.1 2010/12/21 17:09:25 kensmith Exp $
|
||||
*/
|
||||
|
||||
#define XL_EE_READ 0x0080 /* read, 5 bit address */
|
||||
@ -81,6 +81,17 @@
|
||||
#define XL_CAPS_100MBPS 0x1000
|
||||
#define XL_CAPS_PWRMGMT 0x2000
|
||||
|
||||
/*
|
||||
* Bits in the software information 2 word
|
||||
*/
|
||||
#define XL_SINFO2_FIXED_BCAST_RX_BUG 0x0002
|
||||
#define XL_SINFO2_FIXED_ENDEC_LOOP_BUG 0x0004
|
||||
#define XL_SINFO2_AUX_WOL_CON 0x0008
|
||||
#define XL_SINFO2_PME_PULSED 0x0010
|
||||
#define XL_SINFO2_FIXED_MWI_BUG 0x0020
|
||||
#define XL_SINFO2_WOL_AFTER_PWR_LOSS 0x0040
|
||||
#define XL_SINFO2_AUTO_RST_TO_D0 0x0080
|
||||
|
||||
#define XL_PACKET_SIZE 1540
|
||||
#define XL_MAX_FRAMELEN (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN)
|
||||
|
||||
@ -408,7 +419,12 @@
|
||||
#define XL_W7_BM_LEN 0x06
|
||||
#define XL_W7_BM_STATUS 0x0B
|
||||
#define XL_W7_BM_TIMEr 0x0A
|
||||
#define XL_W7_BM_PME 0x0C
|
||||
|
||||
#define XL_BM_PME_WAKE 0x0001
|
||||
#define XL_BM_PME_MAGIC 0x0002
|
||||
#define XL_BM_PME_LINKCHG 0x0004
|
||||
#define XL_BM_PME_WAKETIMER 0x0008
|
||||
/*
|
||||
* bus master control registers
|
||||
*/
|
||||
@ -486,6 +502,7 @@ struct xl_chain_onefrag {
|
||||
struct xl_chain_data {
|
||||
struct xl_chain_onefrag xl_rx_chain[XL_RX_LIST_CNT];
|
||||
struct xl_chain xl_tx_chain[XL_TX_LIST_CNT];
|
||||
bus_dma_segment_t xl_tx_segs[XL_MAXFRAGS];
|
||||
|
||||
struct xl_chain_onefrag *xl_rx_head;
|
||||
|
||||
@ -576,6 +593,7 @@ struct xl_mii_frame {
|
||||
#define XL_FLAG_NO_XCVR_PWR 0x0080
|
||||
#define XL_FLAG_USE_MMIO 0x0100
|
||||
#define XL_FLAG_NO_MMIO 0x0200
|
||||
#define XL_FLAG_WOL 0x0400
|
||||
|
||||
#define XL_NO_XCVR_PWR_MAGICBITS 0x0900
|
||||
|
||||
@ -589,16 +607,16 @@ struct xl_softc {
|
||||
struct resource *xl_irq;
|
||||
struct resource *xl_res;
|
||||
device_t xl_miibus;
|
||||
struct xl_type *xl_info; /* 3Com adapter info */
|
||||
const struct xl_type *xl_info; /* 3Com adapter info */
|
||||
bus_dma_tag_t xl_mtag;
|
||||
bus_dmamap_t xl_tmpmap; /* spare DMA map */
|
||||
u_int8_t xl_unit; /* interface number */
|
||||
u_int8_t xl_type;
|
||||
u_int32_t xl_xcvr;
|
||||
u_int16_t xl_media;
|
||||
u_int16_t xl_caps;
|
||||
u_int8_t xl_stats_no_timeout;
|
||||
u_int16_t xl_tx_thresh;
|
||||
int xl_pmcap;
|
||||
int xl_if_flags;
|
||||
struct xl_list_data xl_ldata;
|
||||
struct xl_chain_data xl_cdata;
|
@ -3,7 +3,6 @@ SubDir HAIKU_TOP src add-ons kernel drivers network ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network etherpci ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network ipro1000 ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network pegasus ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network rtl8139 ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network rtl8169 ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network sis900 ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network usb_asix ;
|
||||
@ -14,10 +13,8 @@ SubInclude HAIKU_TOP src add-ons kernel drivers network vlance ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network wb840 ;
|
||||
|
||||
# FreeBSD 7 drivers
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network 3com ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network broadcom440x ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network broadcom570x ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network ipro100 ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network jmicron2x0 ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network marvell_yukon ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network nforce ;
|
||||
@ -33,7 +30,11 @@ SubIncludeGPL HAIKU_TOP src add-ons kernel drivers network bcm440x ;
|
||||
SubIncludeGPL HAIKU_TOP src add-ons kernel drivers network bcm570x ;
|
||||
|
||||
# FreeBSD 8 drivers
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network 3com ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network atheros813x ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network ipro100 ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network dec21xxx ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network rtl8139 ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network wlan ;
|
||||
|
||||
|
3
src/add-ons/kernel/drivers/network/dec21xxx/Jamfile
Normal file
3
src/add-ons/kernel/drivers/network/dec21xxx/Jamfile
Normal file
@ -0,0 +1,3 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel drivers network dec21xxx ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network dec21xxx dev ;
|
4
src/add-ons/kernel/drivers/network/dec21xxx/dev/Jamfile
Normal file
4
src/add-ons/kernel/drivers/network/dec21xxx/dev/Jamfile
Normal file
@ -0,0 +1,4 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel drivers network dec21xxx dev ;
|
||||
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network dec21xxx dev mii ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers network dec21xxx dev dc ;
|
15
src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/Jamfile
Normal file
15
src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/Jamfile
Normal file
@ -0,0 +1,15 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel drivers network dec21xxx dev dc ;
|
||||
|
||||
UseHeaders [ FDirName $(SUBDIR) .. .. ] : true ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ] : true ;
|
||||
|
||||
UsePrivateHeaders net ;
|
||||
UsePrivateKernelHeaders ;
|
||||
|
||||
SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] ;
|
||||
|
||||
KernelAddon dec21xxx :
|
||||
if_dc.c
|
||||
glue.c
|
||||
: libfreebsd_network.a dec21xxx_mii.a
|
||||
;
|
82
src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/glue.c
Normal file
82
src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/glue.c
Normal file
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/bus.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/systm.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include "if_dcreg.h"
|
||||
|
||||
HAIKU_FBSD_DRIVER_GLUE(dec21xxx, dc, pci)
|
||||
|
||||
HAIKU_DRIVER_REQUIREMENTS(FBSD_TASKQUEUES | FBSD_FAST_TASKQUEUE | FBSD_SWI_TASKQUEUE);
|
||||
|
||||
extern driver_t *DRIVER_MODULE_NAME(acphy, miibus);
|
||||
extern driver_t *DRIVER_MODULE_NAME(amphy, miibus);
|
||||
extern driver_t *DRIVER_MODULE_NAME(dcphy, miibus);
|
||||
extern driver_t *DRIVER_MODULE_NAME(pnphy, miibus);
|
||||
extern driver_t *DRIVER_MODULE_NAME(ukphy, miibus);
|
||||
|
||||
|
||||
driver_t *
|
||||
__haiku_select_miibus_driver(device_t dev)
|
||||
{
|
||||
driver_t *drivers[] = {
|
||||
DRIVER_MODULE_NAME(acphy, miibus),
|
||||
DRIVER_MODULE_NAME(amphy, miibus),
|
||||
DRIVER_MODULE_NAME(dcphy, miibus),
|
||||
DRIVER_MODULE_NAME(pnphy, miibus),
|
||||
DRIVER_MODULE_NAME(ukphy, miibus),
|
||||
NULL
|
||||
};
|
||||
|
||||
return __haiku_probe_miibus(dev, drivers);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
HAIKU_CHECK_DISABLE_INTERRUPTS(device_t dev)
|
||||
{
|
||||
struct dc_softc *sc = device_get_softc(dev);
|
||||
uint16_t status;
|
||||
HAIKU_INTR_REGISTER_STATE;
|
||||
|
||||
HAIKU_INTR_REGISTER_ENTER();
|
||||
|
||||
status = CSR_READ_4(sc, DC_ISR);
|
||||
if (status == 0xffff) {
|
||||
HAIKU_INTR_REGISTER_LEAVE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (status != 0 && (status & DC_INTRS) == 0) {
|
||||
CSR_WRITE_4(sc, DC_ISR, status);
|
||||
HAIKU_INTR_REGISTER_LEAVE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((status & DC_INTRS) == 0) {
|
||||
HAIKU_INTR_REGISTER_LEAVE();
|
||||
return 0;
|
||||
}
|
||||
|
||||
CSR_WRITE_4(sc, DC_IMR, 0);
|
||||
|
||||
HAIKU_INTR_REGISTER_LEAVE();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
HAIKU_REENABLE_INTERRUPTS(device_t dev)
|
||||
{
|
||||
struct dc_softc *sc = device_get_softc(dev);
|
||||
DC_LOCK(sc);
|
||||
CSR_WRITE_4(sc, DC_IMR, DC_INTRS);
|
||||
DC_UNLOCK(sc);
|
||||
}
|
3804
src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/if_dc.c
Normal file
3804
src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/if_dc.c
Normal file
File diff suppressed because it is too large
Load Diff
1172
src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/if_dcreg.h
Normal file
1172
src/add-ons/kernel/drivers/network/dec21xxx/dev/dc/if_dcreg.h
Normal file
File diff suppressed because it is too large
Load Diff
26
src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/Jamfile
Normal file
26
src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/Jamfile
Normal file
@ -0,0 +1,26 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel drivers network dec21xxx dev mii ;
|
||||
|
||||
UseHeaders [ FDirName $(SUBDIR) .. .. ] : true ;
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ]
|
||||
: true ;
|
||||
|
||||
UsePrivateHeaders net system ;
|
||||
UsePrivateKernelHeaders ;
|
||||
|
||||
SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] ;
|
||||
|
||||
KernelStaticLibrary dec21xxx_mii.a
|
||||
:
|
||||
acphy.c
|
||||
amphy.c
|
||||
dcphy.c
|
||||
pnphy.c
|
||||
ukphy.c
|
||||
ukphy_subr.c
|
||||
;
|
||||
|
||||
ObjectHdrs [ FGristFiles acphy$(SUFOBJ) amphy$(SUFOBJ) dcphy$(SUFOBJ)
|
||||
pnphy$(SUFOBJ) ukphy$(SUFOBJ) ]
|
||||
: [ FDirName $(TARGET_COMMON_DEBUG_OBJECT_DIR) libs compat freebsd_network ] ;
|
||||
Includes [ FGristFiles dcphy.c pnphy.c ]
|
||||
: <src!libs!compat!freebsd_network>miidevs.h ;
|
261
src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/acphy.c
Normal file
261
src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/acphy.c
Normal file
@ -0,0 +1,261 @@
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
|
||||
* NASA Ames Research Center.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 Manuel Bouyer. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/dev/mii/acphy.c,v 1.21.10.6.2.1 2010/12/21 17:09:25 kensmith Exp $");
|
||||
|
||||
/*
|
||||
* Driver for Altima AC101 10/100 PHY
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
|
||||
#include <dev/mii/mii.h>
|
||||
#include <dev/mii/miivar.h>
|
||||
#include "miidevs.h"
|
||||
|
||||
#include <dev/mii/acphyreg.h>
|
||||
|
||||
#include "miibus_if.h"
|
||||
|
||||
static int acphy_probe(device_t);
|
||||
static int acphy_attach(device_t);
|
||||
|
||||
static device_method_t acphy_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, acphy_probe),
|
||||
DEVMETHOD(device_attach, acphy_attach),
|
||||
DEVMETHOD(device_detach, mii_phy_detach),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static devclass_t acphy_devclass;
|
||||
|
||||
static driver_t acphy_driver = {
|
||||
"acphy",
|
||||
acphy_methods,
|
||||
sizeof(struct mii_softc)
|
||||
};
|
||||
|
||||
DRIVER_MODULE(acphy, miibus, acphy_driver, acphy_devclass, 0, 0);
|
||||
|
||||
static int acphy_service(struct mii_softc *, struct mii_data *, int);
|
||||
static void acphy_reset(struct mii_softc *);
|
||||
static void acphy_status(struct mii_softc *);
|
||||
|
||||
static const struct mii_phydesc acphys[] = {
|
||||
MII_PHY_DESC(xxALTIMA, AC101),
|
||||
MII_PHY_DESC(xxALTIMA, AC101L),
|
||||
/* XXX This is reported to work, but it's not from any data sheet. */
|
||||
MII_PHY_DESC(xxALTIMA, ACXXX),
|
||||
MII_PHY_END
|
||||
};
|
||||
|
||||
static int
|
||||
acphy_probe(device_t dev)
|
||||
{
|
||||
|
||||
return (mii_phy_dev_probe(dev, acphys, BUS_PROBE_DEFAULT));
|
||||
}
|
||||
|
||||
static int
|
||||
acphy_attach(device_t dev)
|
||||
{
|
||||
struct mii_softc *sc;
|
||||
struct mii_attach_args *ma;
|
||||
struct mii_data *mii;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
ma = device_get_ivars(dev);
|
||||
sc->mii_dev = device_get_parent(dev);
|
||||
mii = ma->mii_data;
|
||||
LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);
|
||||
|
||||
sc->mii_flags = miibus_get_flags(dev);
|
||||
sc->mii_inst = mii->mii_instance++;
|
||||
sc->mii_phy = ma->mii_phyno;
|
||||
sc->mii_service = acphy_service;
|
||||
sc->mii_pdata = mii;
|
||||
|
||||
acphy_reset(sc);
|
||||
|
||||
sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
|
||||
device_printf(dev, " ");
|
||||
|
||||
#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
|
||||
if ((PHY_READ(sc, MII_ACPHY_MCTL) & AC_MCTL_FX_SEL) != 0) {
|
||||
sc->mii_flags |= MIIF_HAVEFIBER;
|
||||
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_FX, 0, sc->mii_inst),
|
||||
MII_MEDIA_100_TX);
|
||||
printf("100baseFX, ");
|
||||
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_FX, IFM_FDX, sc->mii_inst),
|
||||
MII_MEDIA_100_TX_FDX);
|
||||
printf("100baseFX-FDX, ");
|
||||
}
|
||||
#undef ADD
|
||||
|
||||
mii_phy_add_media(sc);
|
||||
printf("\n");
|
||||
|
||||
MIIBUS_MEDIAINIT(sc->mii_dev);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
acphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
|
||||
{
|
||||
int reg;
|
||||
|
||||
switch (cmd) {
|
||||
case MII_POLLSTAT:
|
||||
break;
|
||||
|
||||
case MII_MEDIACHG:
|
||||
/*
|
||||
* If the interface is not up, don't do anything.
|
||||
*/
|
||||
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
|
||||
break;
|
||||
|
||||
/* Wake & deisolate up if necessary */
|
||||
reg = PHY_READ(sc, MII_BMCR);
|
||||
if (reg & (BMCR_ISO | BMCR_PDOWN))
|
||||
PHY_WRITE(sc, MII_BMCR, reg & ~(BMCR_ISO | BMCR_PDOWN));
|
||||
|
||||
mii_phy_setmedia(sc);
|
||||
break;
|
||||
|
||||
case MII_TICK:
|
||||
/*
|
||||
* Is the interface even up?
|
||||
*/
|
||||
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* This PHY's autonegotiation doesn't need to be kicked.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
/* Update the media status. */
|
||||
acphy_status(sc);
|
||||
|
||||
/* Callback if something changed. */
|
||||
mii_phy_update(sc, cmd);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
acphy_status(struct mii_softc *sc)
|
||||
{
|
||||
struct mii_data *mii = sc->mii_pdata;
|
||||
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
|
||||
int bmsr, bmcr, diag;
|
||||
|
||||
mii->mii_media_status = IFM_AVALID;
|
||||
mii->mii_media_active = IFM_ETHER;
|
||||
|
||||
bmsr = PHY_READ(sc, MII_BMSR) |
|
||||
PHY_READ(sc, MII_BMSR);
|
||||
if (bmsr & BMSR_LINK)
|
||||
mii->mii_media_status |= IFM_ACTIVE;
|
||||
|
||||
bmcr = PHY_READ(sc, MII_BMCR);
|
||||
if (bmcr & BMCR_ISO) {
|
||||
mii->mii_media_active |= IFM_NONE;
|
||||
mii->mii_media_status = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (bmcr & BMCR_LOOP)
|
||||
mii->mii_media_active |= IFM_LOOP;
|
||||
|
||||
if (bmcr & BMCR_AUTOEN) {
|
||||
if ((bmsr & BMSR_ACOMP) == 0) {
|
||||
/* Erg, still trying, I guess... */
|
||||
mii->mii_media_active |= IFM_NONE;
|
||||
return;
|
||||
}
|
||||
diag = PHY_READ(sc, MII_ACPHY_DIAG);
|
||||
if (diag & AC_DIAG_SPEED)
|
||||
mii->mii_media_active |= IFM_100_TX;
|
||||
else
|
||||
mii->mii_media_active |= IFM_10_T;
|
||||
|
||||
if (diag & AC_DIAG_DUPLEX)
|
||||
mii->mii_media_active |= IFM_FDX;
|
||||
else
|
||||
mii->mii_media_active |= IFM_HDX;
|
||||
} else
|
||||
mii->mii_media_active = ife->ifm_media;
|
||||
}
|
||||
|
||||
static void
|
||||
acphy_reset(struct mii_softc *sc)
|
||||
{
|
||||
|
||||
mii_phy_reset(sc);
|
||||
PHY_WRITE(sc, MII_ACPHY_INT, 0);
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/*-
|
||||
* Copyright (c) 2001 Semen Ustimenko (semenu@FreeBSD.org)
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $FreeBSD: src/sys/dev/mii/acphyreg.h,v 1.2.10.1.6.1 2010/12/21 17:09:25 kensmith Exp $
|
||||
*/
|
||||
|
||||
#ifndef _DEV_MII_ACPHYREG_H_
|
||||
#define _DEV_MII_ACPHYREG_H_
|
||||
|
||||
/*
|
||||
* Register definitions for the Altima Communications AC101
|
||||
*/
|
||||
|
||||
#define MII_ACPHY_POL 0x10 /* Polarity int level */
|
||||
|
||||
/* High byte is interrupt mask register */
|
||||
#define MII_ACPHY_INT 0x11 /* Interrupt control/status */
|
||||
#define AC_INT_ACOMP 0x0001 /* Autoneg complete */
|
||||
#define AC_INT_REM_FLT 0x0002 /* Remote fault */
|
||||
#define AC_INT_LINK_DOWN 0x0004 /* Link not OK */
|
||||
#define AC_INT_LP_ACK 0x0008 /* FLP ack recved */
|
||||
#define AC_INT_PD_FLT 0x0010 /* Parallel detect fault */
|
||||
#define AC_INT_PAGE_RECV 0x0020 /* New page recved */
|
||||
#define AC_INT_RX_ER 0x0040 /* RX_ER transitions high */
|
||||
#define AC_INT_JAB 0x0080 /* Jabber detected */
|
||||
|
||||
#define MII_ACPHY_DIAG 0x12 /* Diagnostic */
|
||||
#define AC_DIAG_RX_LOCK 0x0100
|
||||
#define AC_DIAG_RX_PASS 0x0200
|
||||
#define AC_DIAG_SPEED 0x0400 /* Aneg speed result */
|
||||
#define AC_DIAG_DUPLEX 0x0800 /* Aneg duplex result */
|
||||
|
||||
#define MII_ACPHY_PWRLOOP 0x13 /* Power/Loopback */
|
||||
#define MII_ACPHY_CBLMEAS 0x14 /* Cable meas. */
|
||||
|
||||
#define MII_ACPHY_MCTL 0x15 /* Mode control */
|
||||
#define AC_MCTL_FX_SEL 0x0001 /* FX mode */
|
||||
#define AC_MCTL_BYP_PCS 0x0002 /* Bypass PCS */
|
||||
#define AC_MCTL_SCRMBL 0x0004 /* Data scrambling */
|
||||
#define AC_MCTL_REM_LOOP 0x0008 /* Remote loopback */
|
||||
#define AC_MCTL_DIS_WDT 0x0010 /* Disable watchdog timer */
|
||||
#define AC_MCTL_DIS_REC 0x0020 /* Disable recv error counter */
|
||||
#define AC_MCTL_REC_FULL 0x0040 /* Recv error counter full */
|
||||
#define AC_MCTL_FRC_FEF 0x0080 /* Force Far End Fault Insert. */
|
||||
#define AC_MCTL_DIS_FEF 0x0100 /* Disable FEF Insertion */
|
||||
#define AC_MCTL_LED_SEL 0x0200 /* Compat LED config */
|
||||
#define AC_MCTL_ALED_SEL 0x0400 /* ActLED RX&TX - RX only */
|
||||
#define AC_MCTL_10BT_SEL 0x0800 /* Enable 7-wire interface */
|
||||
#define AC_MCTL_DIS_JAB 0x1000 /* Disable jabber */
|
||||
#define AC_MCTL_FRC_LINK 0x2000 /* Force TX link up */
|
||||
#define AC_MCTL_DIS_NLP 0x4000 /* Disable NLP check */
|
||||
|
||||
#define MII_ACPHY_REC 0x18 /* Recv error counter */
|
||||
|
||||
#endif /* _DEV_MII_ACPHYREG_H_ */
|
236
src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/amphy.c
Normal file
236
src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/amphy.c
Normal file
@ -0,0 +1,236 @@
|
||||
/*-
|
||||
* Copyright (c) 1997, 1998, 1999
|
||||
* Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
|
||||
*
|
||||
* 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 Bill Paul.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/dev/mii/amphy.c,v 1.24.2.5.2.1 2010/12/21 17:09:25 kensmith Exp $");
|
||||
|
||||
/*
|
||||
* driver for AMD AM79c873 PHYs
|
||||
* This driver also works for Davicom DM910{1,2} PHYs, which appear
|
||||
* to be AM79c873 workalikes.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
|
||||
#include <dev/mii/mii.h>
|
||||
#include <dev/mii/miivar.h>
|
||||
#include "miidevs.h"
|
||||
|
||||
#include <dev/mii/amphyreg.h>
|
||||
|
||||
#include "miibus_if.h"
|
||||
|
||||
static int amphy_probe(device_t);
|
||||
static int amphy_attach(device_t);
|
||||
|
||||
static device_method_t amphy_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, amphy_probe),
|
||||
DEVMETHOD(device_attach, amphy_attach),
|
||||
DEVMETHOD(device_detach, mii_phy_detach),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static devclass_t amphy_devclass;
|
||||
|
||||
static driver_t amphy_driver = {
|
||||
"amphy",
|
||||
amphy_methods,
|
||||
sizeof(struct mii_softc)
|
||||
};
|
||||
|
||||
DRIVER_MODULE(amphy, miibus, amphy_driver, amphy_devclass, 0, 0);
|
||||
|
||||
static int amphy_service(struct mii_softc *, struct mii_data *, int);
|
||||
static void amphy_status(struct mii_softc *);
|
||||
|
||||
static const struct mii_phydesc amphys[] = {
|
||||
MII_PHY_DESC(DAVICOM, DM9102),
|
||||
MII_PHY_DESC(xxAMD, 79C873),
|
||||
MII_PHY_DESC(xxDAVICOM, DM9101),
|
||||
MII_PHY_END
|
||||
};
|
||||
|
||||
static int
|
||||
amphy_probe(device_t dev)
|
||||
{
|
||||
|
||||
return (mii_phy_dev_probe(dev, amphys, BUS_PROBE_DEFAULT));
|
||||
}
|
||||
|
||||
static int
|
||||
amphy_attach(device_t dev)
|
||||
{
|
||||
struct mii_softc *sc;
|
||||
struct mii_attach_args *ma;
|
||||
struct mii_data *mii;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
ma = device_get_ivars(dev);
|
||||
sc->mii_dev = device_get_parent(dev);
|
||||
mii = ma->mii_data;
|
||||
LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);
|
||||
|
||||
sc->mii_flags = miibus_get_flags(dev);
|
||||
sc->mii_inst = mii->mii_instance++;
|
||||
sc->mii_phy = ma->mii_phyno;
|
||||
sc->mii_service = amphy_service;
|
||||
sc->mii_pdata = mii;
|
||||
|
||||
#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
|
||||
|
||||
#if 0
|
||||
ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst),
|
||||
MII_MEDIA_100_TX);
|
||||
#endif
|
||||
|
||||
mii_phy_reset(sc);
|
||||
|
||||
sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
|
||||
device_printf(dev, " ");
|
||||
mii_phy_add_media(sc);
|
||||
printf("\n");
|
||||
#undef ADD
|
||||
MIIBUS_MEDIAINIT(sc->mii_dev);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
amphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
|
||||
{
|
||||
|
||||
switch (cmd) {
|
||||
case MII_POLLSTAT:
|
||||
break;
|
||||
|
||||
case MII_MEDIACHG:
|
||||
/*
|
||||
* If the interface is not up, don't do anything.
|
||||
*/
|
||||
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
|
||||
break;
|
||||
|
||||
mii_phy_setmedia(sc);
|
||||
break;
|
||||
|
||||
case MII_TICK:
|
||||
if (mii_phy_tick(sc) == EJUSTRETURN)
|
||||
return (0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Update the media status. */
|
||||
amphy_status(sc);
|
||||
|
||||
/* Callback if something changed. */
|
||||
mii_phy_update(sc, cmd);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
amphy_status(struct mii_softc *sc)
|
||||
{
|
||||
struct mii_data *mii = sc->mii_pdata;
|
||||
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
|
||||
int bmsr, bmcr, par, anlpar;
|
||||
|
||||
mii->mii_media_status = IFM_AVALID;
|
||||
mii->mii_media_active = IFM_ETHER;
|
||||
|
||||
bmsr = PHY_READ(sc, MII_BMSR) |
|
||||
PHY_READ(sc, MII_BMSR);
|
||||
if (bmsr & BMSR_LINK)
|
||||
mii->mii_media_status |= IFM_ACTIVE;
|
||||
|
||||
bmcr = PHY_READ(sc, MII_BMCR);
|
||||
if (bmcr & BMCR_ISO) {
|
||||
mii->mii_media_active |= IFM_NONE;
|
||||
mii->mii_media_status = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (bmcr & BMCR_LOOP)
|
||||
mii->mii_media_active |= IFM_LOOP;
|
||||
|
||||
if (bmcr & BMCR_AUTOEN) {
|
||||
/*
|
||||
* The PAR status bits are only valid if autonegotiation
|
||||
* has completed (or it's disabled).
|
||||
*/
|
||||
if ((bmsr & BMSR_ACOMP) == 0) {
|
||||
/* Erg, still trying, I guess... */
|
||||
mii->mii_media_active |= IFM_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (PHY_READ(sc, MII_ANER) & ANER_LPAN) {
|
||||
anlpar = PHY_READ(sc, MII_ANAR) &
|
||||
PHY_READ(sc, MII_ANLPAR);
|
||||
if (anlpar & ANLPAR_TX_FD)
|
||||
mii->mii_media_active |= IFM_100_TX|IFM_FDX;
|
||||
else if (anlpar & ANLPAR_T4)
|
||||
mii->mii_media_active |= IFM_100_T4|IFM_HDX;
|
||||
else if (anlpar & ANLPAR_TX)
|
||||
mii->mii_media_active |= IFM_100_TX|IFM_HDX;
|
||||
else if (anlpar & ANLPAR_10_FD)
|
||||
mii->mii_media_active |= IFM_10_T|IFM_FDX;
|
||||
else if (anlpar & ANLPAR_10)
|
||||
mii->mii_media_active |= IFM_10_T|IFM_HDX;
|
||||
else
|
||||
mii->mii_media_active |= IFM_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Link partner is not capable of autonegotiation.
|
||||
*/
|
||||
par = PHY_READ(sc, MII_AMPHY_DSCSR);
|
||||
if (par & DSCSR_100FDX)
|
||||
mii->mii_media_active |= IFM_100_TX|IFM_FDX;
|
||||
else if (par & DSCSR_100HDX)
|
||||
mii->mii_media_active |= IFM_100_TX|IFM_HDX;
|
||||
else if (par & DSCSR_10FDX)
|
||||
mii->mii_media_active |= IFM_10_T|IFM_HDX;
|
||||
else if (par & DSCSR_10HDX)
|
||||
mii->mii_media_active |= IFM_10_T|IFM_HDX;
|
||||
} else
|
||||
mii->mii_media_active = ife->ifm_media;
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*-
|
||||
* Copyright (c) 1997, 1998, 1999
|
||||
* Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
|
||||
*
|
||||
* 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 Bill Paul.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD
|
||||
* 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.
|
||||
*
|
||||
* $FreeBSD: src/sys/dev/mii/amphyreg.h,v 1.2.22.1.6.1 2010/12/21 17:09:25 kensmith Exp $
|
||||
*/
|
||||
|
||||
#ifndef _DEV_MII_AMTPHYREG_H_
|
||||
#define _DEV_MII_AMTPHYREG_H_
|
||||
|
||||
/*
|
||||
* AMD Am79C873 registers.
|
||||
*/
|
||||
|
||||
|
||||
#define MII_AMPHY_DSCR 0x10 /* Specified configuration register */a
|
||||
#define DSCR_BP4B5B 0x8000 /* Bypass 4B5B encoding */
|
||||
#define DSCR_BPSCR 0x4000 /* Bypass scrambler */
|
||||
#define DSCR_BPALIGN 0x2000 /* Bypass symbol alignment */
|
||||
#define DSCR_REPEATER 0x0800 /* Repeater mode */
|
||||
#define DSCR_TX 0x0400 /* TX/FX mode control */
|
||||
#define DSCR_UTP 0x0200 /* UTP/STP mode control */
|
||||
#define DSCR_CLK25MDIS 0x0100 /* CLK25M disable */
|
||||
#define DSCR_FGLNKTX 0x0080 /* Force good link at 100baseTX */
|
||||
#define DSCR_LINKLEDCTL 0x0020 /* Link LED control */
|
||||
#define DSCR_FDXLEDCTL 0x0010 /* FDX LED control */
|
||||
#define DSCR_SMRTS 0x0008 /* Reset state machine */
|
||||
#define DSCR_MFPSC 0x0004 /* Preamble surpression control */
|
||||
#define DSCR_SLEEP 0x0002 /* Sleep mode */
|
||||
#define DSCR_RLOUT 0x0001 /* Remote loopout control */
|
||||
|
||||
#define MII_AMPHY_DSCSR 0x11 /* Specified configuration and status */
|
||||
#define DSCSR_100FDX 0x8000 /* 100MBps full duplex */
|
||||
#define DSCSR_100HDX 0x4000 /* 100Mbps half duplex */
|
||||
#define DSCSR_10FDX 0x2000 /* 10Mbps full duplex */
|
||||
#define DSCSR_10HDX 0x1000 /* 10Mbps half duplex */
|
||||
#define DSCSR_PADDR 0x01F0 /* PHY address */
|
||||
#define DSCSR_ASTAT 0x000F /* Autonegotiation status */
|
||||
|
||||
#define ASTAT_COMPLETE 0x8
|
||||
#define ASTAT_PDLINK_READY_FAIL 0x7
|
||||
#define ASTAT_PDLINK_READY 0x6
|
||||
#define ASTAT_CONSTMATCH_FAIL 0x5
|
||||
#define ASTAT_CONSTMATCH 0x4
|
||||
#define ASTAT_ACKMATCH_FAIL 0x3
|
||||
#define ASTAT_ACKMATCH 0x2
|
||||
#define ASTAT_ABILITYMATCH 0x1
|
||||
#define ASTAT_IDLE 0x0
|
||||
|
||||
#define MII_AMPHY_T10CSRSCR 0x12 /* 10baseT configuration/status */
|
||||
#define T10CSRSCR_LPEN 0x4000 /* Link pulse enable */
|
||||
#define T10CSRSCR_HBE 0x2000 /* Heartbeat enable */
|
||||
#define T10CSRSCR_JABEN 0x0800 /* Jabber enable */
|
||||
#define T10CSRSCR_SER 0x0400 /* Serial mode enable */
|
||||
#define T10CSRSCR_POLR 0x0001 /* Polarity reversed */
|
||||
|
||||
#endif /* _DEV_MII_AMTPHYREG_H_ */
|
421
src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/dcphy.c
Normal file
421
src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/dcphy.c
Normal file
@ -0,0 +1,421 @@
|
||||
/*-
|
||||
* Copyright (c) 1997, 1998, 1999
|
||||
* Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
|
||||
*
|
||||
* 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 Bill Paul.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/dev/dc/dcphy.c,v 1.35.2.5.2.1 2010/12/21 17:09:25 kensmith Exp $");
|
||||
|
||||
/*
|
||||
* Pseudo-driver for internal NWAY support on DEC 21143 and workalike
|
||||
* controllers. Technically we're abusing the miibus code to handle
|
||||
* media selection and NWAY support here since there is no MII
|
||||
* interface. However the logical operations are roughly the same,
|
||||
* and the alternative is to create a fake MII interface in the driver,
|
||||
* which is harder to do.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_media.h>
|
||||
|
||||
#include <dev/mii/mii.h>
|
||||
#include <dev/mii/miivar.h>
|
||||
#include "miidevs.h"
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <dev/pci/pcivar.h>
|
||||
|
||||
#include <dev/dc/if_dcreg.h>
|
||||
|
||||
#include "miibus_if.h"
|
||||
|
||||
#define DC_SETBIT(sc, reg, x) \
|
||||
CSR_WRITE_4(sc, reg, \
|
||||
CSR_READ_4(sc, reg) | x)
|
||||
|
||||
#define DC_CLRBIT(sc, reg, x) \
|
||||
CSR_WRITE_4(sc, reg, \
|
||||
CSR_READ_4(sc, reg) & ~x)
|
||||
|
||||
#define MIIF_AUTOTIMEOUT 0x0004
|
||||
|
||||
/*
|
||||
* This is the subsystem ID for the built-in 21143 ethernet
|
||||
* in several Compaq Presario systems. Apparently these are
|
||||
* 10Mbps only, so we need to treat them specially.
|
||||
*/
|
||||
#define COMPAQ_PRESARIO_ID 0xb0bb0e11
|
||||
|
||||
static int dcphy_probe(device_t);
|
||||
static int dcphy_attach(device_t);
|
||||
|
||||
static device_method_t dcphy_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, dcphy_probe),
|
||||
DEVMETHOD(device_attach, dcphy_attach),
|
||||
DEVMETHOD(device_detach, mii_phy_detach),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static devclass_t dcphy_devclass;
|
||||
|
||||
static driver_t dcphy_driver = {
|
||||
"dcphy",
|
||||
dcphy_methods,
|
||||
sizeof(struct mii_softc)
|
||||
};
|
||||
|
||||
DRIVER_MODULE(dcphy, miibus, dcphy_driver, dcphy_devclass, 0, 0);
|
||||
|
||||
static int dcphy_service(struct mii_softc *, struct mii_data *, int);
|
||||
static void dcphy_status(struct mii_softc *);
|
||||
static void dcphy_reset(struct mii_softc *);
|
||||
static int dcphy_auto(struct mii_softc *);
|
||||
|
||||
static int
|
||||
dcphy_probe(device_t dev)
|
||||
{
|
||||
struct mii_attach_args *ma;
|
||||
|
||||
ma = device_get_ivars(dev);
|
||||
|
||||
/*
|
||||
* The dc driver will report the 21143 vendor and device
|
||||
* ID to let us know that it wants us to attach.
|
||||
*/
|
||||
if (ma->mii_id1 != DC_VENDORID_DEC ||
|
||||
ma->mii_id2 != DC_DEVICEID_21143)
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "Intel 21143 NWAY media interface");
|
||||
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
dcphy_attach(device_t dev)
|
||||
{
|
||||
struct mii_softc *sc;
|
||||
struct mii_attach_args *ma;
|
||||
struct mii_data *mii;
|
||||
struct dc_softc *dc_sc;
|
||||
device_t brdev;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
ma = device_get_ivars(dev);
|
||||
sc->mii_dev = device_get_parent(dev);
|
||||
mii = ma->mii_data;
|
||||
LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);
|
||||
|
||||
sc->mii_flags = miibus_get_flags(dev);
|
||||
sc->mii_inst = mii->mii_instance++;
|
||||
sc->mii_phy = ma->mii_phyno;
|
||||
sc->mii_service = dcphy_service;
|
||||
sc->mii_pdata = mii;
|
||||
|
||||
/*
|
||||
* Apparently, we can neither isolate nor do loopback.
|
||||
*/
|
||||
sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOLOOP;
|
||||
|
||||
/*dcphy_reset(sc);*/
|
||||
dc_sc = mii->mii_ifp->if_softc;
|
||||
CSR_WRITE_4(dc_sc, DC_10BTSTAT, 0);
|
||||
CSR_WRITE_4(dc_sc, DC_10BTCTRL, 0);
|
||||
|
||||
brdev = device_get_parent(sc->mii_dev);
|
||||
switch (pci_get_subdevice(brdev) << 16 | pci_get_subvendor(brdev)) {
|
||||
case COMPAQ_PRESARIO_ID:
|
||||
/* Example of how to only allow 10Mbps modes. */
|
||||
sc->mii_capabilities = BMSR_ANEG | BMSR_10TFDX | BMSR_10THDX;
|
||||
break;
|
||||
default:
|
||||
if (dc_sc->dc_pmode == DC_PMODE_SIA)
|
||||
sc->mii_capabilities =
|
||||
BMSR_ANEG | BMSR_10TFDX | BMSR_10THDX;
|
||||
else
|
||||
sc->mii_capabilities =
|
||||
BMSR_ANEG | BMSR_100TXFDX | BMSR_100TXHDX |
|
||||
BMSR_10TFDX | BMSR_10THDX;
|
||||
break;
|
||||
}
|
||||
|
||||
sc->mii_capabilities &= ma->mii_capmask;
|
||||
device_printf(dev, " ");
|
||||
mii_phy_add_media(sc);
|
||||
printf("\n");
|
||||
|
||||
MIIBUS_MEDIAINIT(sc->mii_dev);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
dcphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
|
||||
{
|
||||
struct dc_softc *dc_sc;
|
||||
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
|
||||
int reg;
|
||||
u_int32_t mode;
|
||||
|
||||
dc_sc = mii->mii_ifp->if_softc;
|
||||
|
||||
switch (cmd) {
|
||||
case MII_POLLSTAT:
|
||||
break;
|
||||
|
||||
case MII_MEDIACHG:
|
||||
/*
|
||||
* If the interface is not up, don't do anything.
|
||||
*/
|
||||
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
|
||||
break;
|
||||
|
||||
mii->mii_media_active = IFM_NONE;
|
||||
mode = CSR_READ_4(dc_sc, DC_NETCFG);
|
||||
mode &= ~(DC_NETCFG_FULLDUPLEX | DC_NETCFG_PORTSEL |
|
||||
DC_NETCFG_PCS | DC_NETCFG_SCRAMBLER | DC_NETCFG_SPEEDSEL);
|
||||
|
||||
switch (IFM_SUBTYPE(ife->ifm_media)) {
|
||||
case IFM_AUTO:
|
||||
/*dcphy_reset(sc);*/
|
||||
(void) dcphy_auto(sc);
|
||||
break;
|
||||
case IFM_100_T4:
|
||||
/*
|
||||
* XXX Not supported as a manual setting right now.
|
||||
*/
|
||||
return (EINVAL);
|
||||
case IFM_100_TX:
|
||||
dcphy_reset(sc);
|
||||
DC_CLRBIT(dc_sc, DC_10BTCTRL, DC_TCTL_AUTONEGENBL);
|
||||
mode |= DC_NETCFG_PORTSEL | DC_NETCFG_PCS |
|
||||
DC_NETCFG_SCRAMBLER;
|
||||
if ((ife->ifm_media & IFM_GMASK) == IFM_FDX)
|
||||
mode |= DC_NETCFG_FULLDUPLEX;
|
||||
else
|
||||
mode &= ~DC_NETCFG_FULLDUPLEX;
|
||||
CSR_WRITE_4(dc_sc, DC_NETCFG, mode);
|
||||
break;
|
||||
case IFM_10_T:
|
||||
DC_CLRBIT(dc_sc, DC_SIARESET, DC_SIA_RESET);
|
||||
DC_CLRBIT(dc_sc, DC_10BTCTRL, 0xFFFF);
|
||||
if ((ife->ifm_media & IFM_GMASK) == IFM_FDX)
|
||||
DC_SETBIT(dc_sc, DC_10BTCTRL, 0x7F3D);
|
||||
else
|
||||
DC_SETBIT(dc_sc, DC_10BTCTRL, 0x7F3F);
|
||||
DC_SETBIT(dc_sc, DC_SIARESET, DC_SIA_RESET);
|
||||
DC_CLRBIT(dc_sc, DC_10BTCTRL, DC_TCTL_AUTONEGENBL);
|
||||
mode &= ~DC_NETCFG_PORTSEL;
|
||||
mode |= DC_NETCFG_SPEEDSEL;
|
||||
if ((ife->ifm_media & IFM_GMASK) == IFM_FDX)
|
||||
mode |= DC_NETCFG_FULLDUPLEX;
|
||||
else
|
||||
mode &= ~DC_NETCFG_FULLDUPLEX;
|
||||
CSR_WRITE_4(dc_sc, DC_NETCFG, mode);
|
||||
break;
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
break;
|
||||
|
||||
case MII_TICK:
|
||||
/*
|
||||
* Is the interface even up?
|
||||
*/
|
||||
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Only used for autonegotiation.
|
||||
*/
|
||||
if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO)
|
||||
break;
|
||||
|
||||
reg = CSR_READ_4(dc_sc, DC_10BTSTAT);
|
||||
if (!(reg & DC_TSTAT_LS10) || !(reg & DC_TSTAT_LS100))
|
||||
break;
|
||||
|
||||
/*
|
||||
* Only retry autonegotiation every 5 seconds.
|
||||
*
|
||||
* Otherwise, fall through to calling dcphy_status()
|
||||
* since real Intel 21143 chips don't show valid link
|
||||
* status until autonegotiation is switched off, and
|
||||
* that only happens in dcphy_status(). Without this,
|
||||
* successful autonegotiation is never recognised on
|
||||
* these chips.
|
||||
*/
|
||||
if (++sc->mii_ticks <= 50)
|
||||
break;
|
||||
|
||||
sc->mii_ticks = 0;
|
||||
dcphy_auto(sc);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Update the media status. */
|
||||
dcphy_status(sc);
|
||||
|
||||
/* Callback if something changed. */
|
||||
mii_phy_update(sc, cmd);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
dcphy_status(struct mii_softc *sc)
|
||||
{
|
||||
struct mii_data *mii = sc->mii_pdata;
|
||||
int reg, anlpar, tstat = 0;
|
||||
struct dc_softc *dc_sc;
|
||||
|
||||
dc_sc = mii->mii_ifp->if_softc;
|
||||
|
||||
mii->mii_media_status = IFM_AVALID;
|
||||
mii->mii_media_active = IFM_ETHER;
|
||||
|
||||
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
|
||||
return;
|
||||
|
||||
reg = CSR_READ_4(dc_sc, DC_10BTSTAT);
|
||||
if (!(reg & DC_TSTAT_LS10) || !(reg & DC_TSTAT_LS100))
|
||||
mii->mii_media_status |= IFM_ACTIVE;
|
||||
|
||||
if (CSR_READ_4(dc_sc, DC_10BTCTRL) & DC_TCTL_AUTONEGENBL) {
|
||||
/* Erg, still trying, I guess... */
|
||||
tstat = CSR_READ_4(dc_sc, DC_10BTSTAT);
|
||||
if ((tstat & DC_TSTAT_ANEGSTAT) != DC_ASTAT_AUTONEGCMP) {
|
||||
if ((DC_IS_MACRONIX(dc_sc) || DC_IS_PNICII(dc_sc)) &&
|
||||
(tstat & DC_TSTAT_ANEGSTAT) == DC_ASTAT_DISABLE)
|
||||
goto skip;
|
||||
mii->mii_media_active |= IFM_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (tstat & DC_TSTAT_LP_CAN_NWAY) {
|
||||
anlpar = tstat >> 16;
|
||||
if (anlpar & ANLPAR_TX_FD &&
|
||||
sc->mii_capabilities & BMSR_100TXFDX)
|
||||
mii->mii_media_active |= IFM_100_TX | IFM_FDX;
|
||||
else if (anlpar & ANLPAR_T4 &&
|
||||
sc->mii_capabilities & BMSR_100T4)
|
||||
mii->mii_media_active |= IFM_100_T4 | IFM_HDX;
|
||||
else if (anlpar & ANLPAR_TX &&
|
||||
sc->mii_capabilities & BMSR_100TXHDX)
|
||||
mii->mii_media_active |= IFM_100_TX | IFM_HDX;
|
||||
else if (anlpar & ANLPAR_10_FD)
|
||||
mii->mii_media_active |= IFM_10_T | IFM_FDX;
|
||||
else if (anlpar & ANLPAR_10)
|
||||
mii->mii_media_active |= IFM_10_T | IFM_HDX;
|
||||
else
|
||||
mii->mii_media_active |= IFM_NONE;
|
||||
if (DC_IS_INTEL(dc_sc))
|
||||
DC_CLRBIT(dc_sc, DC_10BTCTRL,
|
||||
DC_TCTL_AUTONEGENBL);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the other side doesn't support NWAY, then the
|
||||
* best we can do is determine if we have a 10Mbps or
|
||||
* 100Mbps link. There's no way to know if the link
|
||||
* is full or half duplex, so we default to half duplex
|
||||
* and hope that the user is clever enough to manually
|
||||
* change the media settings if we're wrong.
|
||||
*/
|
||||
if (!(reg & DC_TSTAT_LS100))
|
||||
mii->mii_media_active |= IFM_100_TX | IFM_HDX;
|
||||
else if (!(reg & DC_TSTAT_LS10))
|
||||
mii->mii_media_active |= IFM_10_T | IFM_HDX;
|
||||
else
|
||||
mii->mii_media_active |= IFM_NONE;
|
||||
if (DC_IS_INTEL(dc_sc))
|
||||
DC_CLRBIT(dc_sc, DC_10BTCTRL, DC_TCTL_AUTONEGENBL);
|
||||
return;
|
||||
}
|
||||
|
||||
skip:
|
||||
if (CSR_READ_4(dc_sc, DC_NETCFG) & DC_NETCFG_SPEEDSEL)
|
||||
mii->mii_media_active |= IFM_10_T;
|
||||
else
|
||||
mii->mii_media_active |= IFM_100_TX;
|
||||
if (CSR_READ_4(dc_sc, DC_NETCFG) & DC_NETCFG_FULLDUPLEX)
|
||||
mii->mii_media_active |= IFM_FDX;
|
||||
else
|
||||
mii->mii_media_active |= IFM_HDX;
|
||||
}
|
||||
|
||||
static int
|
||||
dcphy_auto(struct mii_softc *mii)
|
||||
{
|
||||
struct dc_softc *sc;
|
||||
|
||||
sc = mii->mii_pdata->mii_ifp->if_softc;
|
||||
|
||||
DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
|
||||
DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_FULLDUPLEX);
|
||||
DC_CLRBIT(sc, DC_SIARESET, DC_SIA_RESET);
|
||||
if (mii->mii_capabilities & BMSR_100TXHDX)
|
||||
CSR_WRITE_4(sc, DC_10BTCTRL, 0x3FFFF);
|
||||
else
|
||||
CSR_WRITE_4(sc, DC_10BTCTRL, 0xFFFF);
|
||||
DC_SETBIT(sc, DC_SIARESET, DC_SIA_RESET);
|
||||
DC_SETBIT(sc, DC_10BTCTRL, DC_TCTL_AUTONEGENBL);
|
||||
DC_SETBIT(sc, DC_10BTSTAT, DC_ASTAT_TXDISABLE);
|
||||
|
||||
return (EJUSTRETURN);
|
||||
}
|
||||
|
||||
static void
|
||||
dcphy_reset(struct mii_softc *mii)
|
||||
{
|
||||
struct dc_softc *sc;
|
||||
|
||||
sc = mii->mii_pdata->mii_ifp->if_softc;
|
||||
|
||||
DC_CLRBIT(sc, DC_SIARESET, DC_SIA_RESET);
|
||||
DELAY(1000);
|
||||
DC_SETBIT(sc, DC_SIARESET, DC_SIA_RESET);
|
||||
}
|
241
src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/pnphy.c
Normal file
241
src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/pnphy.c
Normal file
@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, 1999
|
||||
* Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
|
||||
*
|
||||
* 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 Bill Paul.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/dev/dc/pnphy.c,v 1.23.2.5.2.1 2010/12/21 17:09:25 kensmith Exp $");
|
||||
|
||||
/*
|
||||
* Pseudo-driver for media selection on the Lite-On PNIC 82c168
|
||||
* chip. The NWAY support on this chip is horribly broken, so we
|
||||
* only support manual mode selection. This is lame, but getting
|
||||
* NWAY to work right is amazingly difficult.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if_media.h>
|
||||
|
||||
#include <dev/mii/mii.h>
|
||||
#include <dev/mii/miivar.h>
|
||||
#include "miidevs.h"
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <machine/resource.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <dev/dc/if_dcreg.h>
|
||||
|
||||
#include "miibus_if.h"
|
||||
|
||||
#define DC_SETBIT(sc, reg, x) \
|
||||
CSR_WRITE_4(sc, reg, \
|
||||
CSR_READ_4(sc, reg) | x)
|
||||
|
||||
#define DC_CLRBIT(sc, reg, x) \
|
||||
CSR_WRITE_4(sc, reg, \
|
||||
CSR_READ_4(sc, reg) & ~x)
|
||||
|
||||
static int pnphy_probe(device_t);
|
||||
static int pnphy_attach(device_t);
|
||||
|
||||
static device_method_t pnphy_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, pnphy_probe),
|
||||
DEVMETHOD(device_attach, pnphy_attach),
|
||||
DEVMETHOD(device_detach, mii_phy_detach),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static devclass_t pnphy_devclass;
|
||||
|
||||
static driver_t pnphy_driver = {
|
||||
"pnphy",
|
||||
pnphy_methods,
|
||||
sizeof(struct mii_softc)
|
||||
};
|
||||
|
||||
DRIVER_MODULE(pnphy, miibus, pnphy_driver, pnphy_devclass, 0, 0);
|
||||
|
||||
static int pnphy_service(struct mii_softc *, struct mii_data *, int);
|
||||
static void pnphy_status(struct mii_softc *);
|
||||
|
||||
static int
|
||||
pnphy_probe(device_t dev)
|
||||
{
|
||||
struct mii_attach_args *ma;
|
||||
|
||||
ma = device_get_ivars(dev);
|
||||
|
||||
/*
|
||||
* The dc driver will report the 82c168 vendor and device
|
||||
* ID to let us know that it wants us to attach.
|
||||
*/
|
||||
if (ma->mii_id1 != DC_VENDORID_LO ||
|
||||
ma->mii_id2 != DC_DEVICEID_82C168)
|
||||
return (ENXIO);
|
||||
|
||||
device_set_desc(dev, "PNIC 82c168 media interface");
|
||||
|
||||
return (BUS_PROBE_DEFAULT);
|
||||
}
|
||||
|
||||
static int
|
||||
pnphy_attach(device_t dev)
|
||||
{
|
||||
struct mii_softc *sc;
|
||||
struct mii_attach_args *ma;
|
||||
struct mii_data *mii;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
ma = device_get_ivars(dev);
|
||||
sc->mii_dev = device_get_parent(dev);
|
||||
mii = ma->mii_data;
|
||||
LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);
|
||||
|
||||
sc->mii_flags = miibus_get_flags(dev);
|
||||
sc->mii_inst = mii->mii_instance++;
|
||||
sc->mii_phy = ma->mii_phyno;
|
||||
sc->mii_service = pnphy_service;
|
||||
sc->mii_pdata = mii;
|
||||
|
||||
/*
|
||||
* Apparently, we can neither isolate nor do loopback.
|
||||
*/
|
||||
sc->mii_flags |= MIIF_NOISOLATE | MIIF_NOLOOP;
|
||||
|
||||
sc->mii_capabilities =
|
||||
BMSR_100TXFDX | BMSR_100TXHDX | BMSR_10TFDX | BMSR_10THDX;
|
||||
sc->mii_capabilities &= ma->mii_capmask;
|
||||
device_printf(dev, " ");
|
||||
mii_phy_add_media(sc);
|
||||
printf("\n");
|
||||
|
||||
MIIBUS_MEDIAINIT(sc->mii_dev);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pnphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
|
||||
{
|
||||
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
|
||||
|
||||
switch (cmd) {
|
||||
case MII_POLLSTAT:
|
||||
break;
|
||||
|
||||
case MII_MEDIACHG:
|
||||
/*
|
||||
* If the interface is not up, don't do anything.
|
||||
*/
|
||||
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
|
||||
break;
|
||||
|
||||
switch (IFM_SUBTYPE(ife->ifm_media)) {
|
||||
case IFM_AUTO:
|
||||
/* NWAY is busted on this chip */
|
||||
case IFM_100_T4:
|
||||
/*
|
||||
* XXX Not supported as a manual setting right now.
|
||||
*/
|
||||
return (EINVAL);
|
||||
case IFM_100_TX:
|
||||
mii->mii_media_active = IFM_ETHER | IFM_100_TX;
|
||||
if ((ife->ifm_media & IFM_GMASK) == IFM_FDX)
|
||||
mii->mii_media_active |= IFM_FDX;
|
||||
MIIBUS_STATCHG(sc->mii_dev);
|
||||
return (0);
|
||||
case IFM_10_T:
|
||||
mii->mii_media_active = IFM_ETHER | IFM_10_T;
|
||||
if ((ife->ifm_media & IFM_GMASK) == IFM_FDX)
|
||||
mii->mii_media_active |= IFM_FDX;
|
||||
MIIBUS_STATCHG(sc->mii_dev);
|
||||
return (0);
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
break;
|
||||
|
||||
case MII_TICK:
|
||||
/*
|
||||
* Is the interface even up?
|
||||
*/
|
||||
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
|
||||
return (0);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Update the media status. */
|
||||
pnphy_status(sc);
|
||||
|
||||
/* Callback if something changed. */
|
||||
mii_phy_update(sc, cmd);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
pnphy_status(struct mii_softc *sc)
|
||||
{
|
||||
struct mii_data *mii = sc->mii_pdata;
|
||||
int reg;
|
||||
struct dc_softc *dc_sc;
|
||||
|
||||
dc_sc = mii->mii_ifp->if_softc;
|
||||
|
||||
mii->mii_media_status = IFM_AVALID;
|
||||
mii->mii_media_active = IFM_ETHER;
|
||||
|
||||
reg = CSR_READ_4(dc_sc, DC_ISR);
|
||||
|
||||
if (!(reg & DC_ISR_LINKFAIL))
|
||||
mii->mii_media_status |= IFM_ACTIVE;
|
||||
|
||||
if (CSR_READ_4(dc_sc, DC_NETCFG) & DC_NETCFG_SPEEDSEL)
|
||||
mii->mii_media_active |= IFM_10_T;
|
||||
else
|
||||
mii->mii_media_active |= IFM_100_TX;
|
||||
if (CSR_READ_4(dc_sc, DC_NETCFG) & DC_NETCFG_FULLDUPLEX)
|
||||
mii->mii_media_active |= IFM_FDX;
|
||||
else
|
||||
mii->mii_media_active |= IFM_HDX;
|
||||
}
|
186
src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/ukphy.c
Normal file
186
src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/ukphy.c
Normal file
@ -0,0 +1,186 @@
|
||||
/* $NetBSD: ukphy.c,v 1.2 1999/04/23 04:24:32 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
|
||||
* NASA Ames Research Center, and by Frank van der Linden.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997 Manuel Bouyer. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy.c,v 1.20.10.6.2.1 2010/12/21 17:09:25 kensmith Exp $");
|
||||
|
||||
/*
|
||||
* driver for generic unknown PHYs
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
|
||||
#include <dev/mii/mii.h>
|
||||
#include <dev/mii/miivar.h>
|
||||
|
||||
#include "miibus_if.h"
|
||||
|
||||
static int ukphy_probe(device_t);
|
||||
static int ukphy_attach(device_t);
|
||||
|
||||
static device_method_t ukphy_methods[] = {
|
||||
/* device interface */
|
||||
DEVMETHOD(device_probe, ukphy_probe),
|
||||
DEVMETHOD(device_attach, ukphy_attach),
|
||||
DEVMETHOD(device_detach, mii_phy_detach),
|
||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static devclass_t ukphy_devclass;
|
||||
|
||||
static driver_t ukphy_driver = {
|
||||
"ukphy",
|
||||
ukphy_methods,
|
||||
sizeof(struct mii_softc)
|
||||
};
|
||||
|
||||
DRIVER_MODULE(ukphy, miibus, ukphy_driver, ukphy_devclass, 0, 0);
|
||||
|
||||
static int ukphy_service(struct mii_softc *, struct mii_data *, int);
|
||||
|
||||
static int
|
||||
ukphy_probe(device_t dev)
|
||||
{
|
||||
|
||||
/*
|
||||
* We know something is here, so always match at a low priority.
|
||||
*/
|
||||
device_set_desc(dev, "Generic IEEE 802.3u media interface");
|
||||
return (BUS_PROBE_GENERIC);
|
||||
}
|
||||
|
||||
static int
|
||||
ukphy_attach(device_t dev)
|
||||
{
|
||||
struct mii_softc *sc;
|
||||
struct mii_attach_args *ma;
|
||||
struct mii_data *mii;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
ma = device_get_ivars(dev);
|
||||
sc->mii_dev = device_get_parent(dev);
|
||||
mii = ma->mii_data;
|
||||
LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);
|
||||
|
||||
if (bootverbose)
|
||||
device_printf(dev, "OUI 0x%06x, model 0x%04x, rev. %d\n",
|
||||
MII_OUI(ma->mii_id1, ma->mii_id2),
|
||||
MII_MODEL(ma->mii_id2), MII_REV(ma->mii_id2));
|
||||
|
||||
sc->mii_flags = miibus_get_flags(dev);
|
||||
sc->mii_inst = mii->mii_instance++;
|
||||
sc->mii_phy = ma->mii_phyno;
|
||||
sc->mii_service = ukphy_service;
|
||||
sc->mii_pdata = mii;
|
||||
|
||||
sc->mii_flags |= MIIF_NOMANPAUSE;
|
||||
|
||||
mii_phy_reset(sc);
|
||||
|
||||
sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
|
||||
if (sc->mii_capabilities & BMSR_EXTSTAT)
|
||||
sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR);
|
||||
device_printf(dev, " ");
|
||||
mii_phy_add_media(sc);
|
||||
printf("\n");
|
||||
|
||||
MIIBUS_MEDIAINIT(sc->mii_dev);
|
||||
mii_phy_setmedia(sc);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ukphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
|
||||
{
|
||||
|
||||
switch (cmd) {
|
||||
case MII_POLLSTAT:
|
||||
break;
|
||||
|
||||
case MII_MEDIACHG:
|
||||
/*
|
||||
* If the interface is not up, don't do anything.
|
||||
*/
|
||||
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
|
||||
break;
|
||||
|
||||
mii_phy_setmedia(sc);
|
||||
break;
|
||||
|
||||
case MII_TICK:
|
||||
if (mii_phy_tick(sc) == EJUSTRETURN)
|
||||
return (0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Update the media status. */
|
||||
ukphy_status(sc);
|
||||
|
||||
/* Callback if something changed. */
|
||||
mii_phy_update(sc, cmd);
|
||||
return (0);
|
||||
}
|
129
src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/ukphy_subr.c
Normal file
129
src/add-ons/kernel/drivers/network/dec21xxx/dev/mii/ukphy_subr.c
Normal file
@ -0,0 +1,129 @@
|
||||
/* $NetBSD: ukphy_subr.c,v 1.2 1998/11/05 04:08:02 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
|
||||
* NASA Ames Research Center, and by Frank van der Linden.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy_subr.c,v 1.10.2.4.2.1 2010/12/21 17:09:25 kensmith Exp $");
|
||||
|
||||
/*
|
||||
* Subroutines shared by the ukphy driver and other PHY drivers.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/bus.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_media.h>
|
||||
|
||||
#include <dev/mii/mii.h>
|
||||
#include <dev/mii/miivar.h>
|
||||
|
||||
#include "miibus_if.h"
|
||||
|
||||
/*
|
||||
* Media status subroutine. If a PHY driver does media detection simply
|
||||
* by decoding the NWay autonegotiation, use this routine.
|
||||
*/
|
||||
void
|
||||
ukphy_status(struct mii_softc *phy)
|
||||
{
|
||||
struct mii_data *mii = phy->mii_pdata;
|
||||
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
|
||||
int bmsr, bmcr, anlpar, gtcr, gtsr;
|
||||
|
||||
mii->mii_media_status = IFM_AVALID;
|
||||
mii->mii_media_active = IFM_ETHER;
|
||||
|
||||
bmsr = PHY_READ(phy, MII_BMSR) | PHY_READ(phy, MII_BMSR);
|
||||
if (bmsr & BMSR_LINK)
|
||||
mii->mii_media_status |= IFM_ACTIVE;
|
||||
|
||||
bmcr = PHY_READ(phy, MII_BMCR);
|
||||
if (bmcr & BMCR_ISO) {
|
||||
mii->mii_media_active |= IFM_NONE;
|
||||
mii->mii_media_status = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (bmcr & BMCR_LOOP)
|
||||
mii->mii_media_active |= IFM_LOOP;
|
||||
|
||||
if (bmcr & BMCR_AUTOEN) {
|
||||
/*
|
||||
* NWay autonegotiation takes the highest-order common
|
||||
* bit of the ANAR and ANLPAR (i.e. best media advertised
|
||||
* both by us and our link partner).
|
||||
*/
|
||||
if ((bmsr & BMSR_ACOMP) == 0) {
|
||||
/* Erg, still trying, I guess... */
|
||||
mii->mii_media_active |= IFM_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
anlpar = PHY_READ(phy, MII_ANAR) & PHY_READ(phy, MII_ANLPAR);
|
||||
if ((phy->mii_flags & MIIF_HAVE_GTCR) != 0 &&
|
||||
(phy->mii_extcapabilities &
|
||||
(EXTSR_1000THDX | EXTSR_1000TFDX)) != 0) {
|
||||
gtcr = PHY_READ(phy, MII_100T2CR);
|
||||
gtsr = PHY_READ(phy, MII_100T2SR);
|
||||
} else
|
||||
gtcr = gtsr = 0;
|
||||
|
||||
if ((gtcr & GTCR_ADV_1000TFDX) && (gtsr & GTSR_LP_1000TFDX))
|
||||
mii->mii_media_active |= IFM_1000_T|IFM_FDX;
|
||||
else if ((gtcr & GTCR_ADV_1000THDX) &&
|
||||
(gtsr & GTSR_LP_1000THDX))
|
||||
mii->mii_media_active |= IFM_1000_T|IFM_HDX;
|
||||
else if (anlpar & ANLPAR_TX_FD)
|
||||
mii->mii_media_active |= IFM_100_TX|IFM_FDX;
|
||||
else if (anlpar & ANLPAR_T4)
|
||||
mii->mii_media_active |= IFM_100_T4|IFM_HDX;
|
||||
else if (anlpar & ANLPAR_TX)
|
||||
mii->mii_media_active |= IFM_100_TX|IFM_HDX;
|
||||
else if (anlpar & ANLPAR_10_FD)
|
||||
mii->mii_media_active |= IFM_10_T|IFM_FDX;
|
||||
else if (anlpar & ANLPAR_10)
|
||||
mii->mii_media_active |= IFM_10_T|IFM_HDX;
|
||||
else
|
||||
mii->mii_media_active |= IFM_NONE;
|
||||
|
||||
if ((mii->mii_media_active & IFM_1000_T) != 0 &&
|
||||
(gtsr & GTSR_MS_RES) != 0)
|
||||
mii->mii_media_active |= IFM_ETH_MASTER;
|
||||
|
||||
if ((mii->mii_media_active & IFM_FDX) != 0)
|
||||
mii->mii_media_active |= mii_phy_flowstatus(phy);
|
||||
} else
|
||||
mii->mii_media_active = ife->ifm_media;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -25,7 +25,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: src/sys/dev/fxp/if_fxpreg.h,v 1.39 2005/04/22 13:05:53 mux Exp $
|
||||
* $FreeBSD: src/sys/dev/fxp/if_fxpreg.h,v 1.43.2.3.2.1 2010/12/21 17:09:25 kensmith Exp $
|
||||
*/
|
||||
|
||||
#define FXP_VENDORID_INTEL 0x8086
|
||||
@ -45,7 +45,9 @@
|
||||
#define FXP_CSR_FLASHCONTROL 12 /* flash control (2 bytes) */
|
||||
#define FXP_CSR_EEPROMCONTROL 14 /* eeprom control (2 bytes) */
|
||||
#define FXP_CSR_MDICONTROL 16 /* mdi control (4 bytes) */
|
||||
#define FXP_CSR_FLOWCONTROL 0x19 /* flow control (2 bytes) */
|
||||
#define FXP_CSR_FC_THRESH 0x19 /* flow control (1 byte) */
|
||||
#define FXP_CSR_FC_STATUS 0x1A /* flow control status (1 byte) */
|
||||
#define FXP_CSR_PMDR 0x1B /* power management driver (1 byte) */
|
||||
#define FXP_CSR_GENCONTROL 0x1C /* general control (1 byte) */
|
||||
|
||||
/*
|
||||
@ -223,7 +225,7 @@ struct fxp_cb_config {
|
||||
|
||||
/* Bytes 22 - 31 -- i82550 only */
|
||||
u_int __FXP_BITFIELD3(gamla_rx:1,
|
||||
vlan_drop_en:1,
|
||||
vlan_strip_en:1,
|
||||
:6);
|
||||
uint8_t pad[9];
|
||||
};
|
||||
@ -287,12 +289,12 @@ struct fxp_cb_tx {
|
||||
/*
|
||||
* The following structure isn't actually part of the TxCB,
|
||||
* unless the extended TxCB feature is being used. In this
|
||||
* case, the first two elements of the structure below are
|
||||
* case, the first two elements of the structure below are
|
||||
* fetched along with the TxCB.
|
||||
*/
|
||||
union {
|
||||
struct fxp_ipcb ipcb;
|
||||
struct fxp_tbd tbd[FXP_NTXSEG];
|
||||
struct fxp_tbd tbd[FXP_NTXSEG + 1];
|
||||
} tx_cb_u;
|
||||
};
|
||||
|
||||
@ -376,6 +378,7 @@ struct fxp_rfa {
|
||||
#define FXP_RFA_STATUS_RNR 0x0200 /* no resources */
|
||||
#define FXP_RFA_STATUS_ALIGN 0x0400 /* alignment error */
|
||||
#define FXP_RFA_STATUS_CRC 0x0800 /* CRC error */
|
||||
#define FXP_RFA_STATUS_VLAN 0x1000 /* VLAN tagged frame */
|
||||
#define FXP_RFA_STATUS_OK 0x2000 /* packet received okay */
|
||||
#define FXP_RFA_STATUS_C 0x8000 /* packet reception complete */
|
||||
#define FXP_RFA_CONTROL_SF 0x08 /* simple/flexible memory mode */
|
||||
@ -416,11 +419,19 @@ struct fxp_stats {
|
||||
uint32_t rx_overrun_errors;
|
||||
uint32_t rx_cdt_errors;
|
||||
uint32_t rx_shortframes;
|
||||
uint32_t tx_pause;
|
||||
uint32_t rx_pause;
|
||||
uint32_t rx_controls;
|
||||
uint16_t tx_tco;
|
||||
uint16_t rx_tco;
|
||||
uint32_t completion_status;
|
||||
uint32_t reserved0;
|
||||
uint32_t reserved1;
|
||||
uint32_t reserved2;
|
||||
};
|
||||
#define FXP_STATS_DUMP_COMPLETE 0xa005
|
||||
#define FXP_STATS_DR_COMPLETE 0xa007
|
||||
|
||||
|
||||
/*
|
||||
* Serial EEPROM control register bits
|
||||
*/
|
||||
|
@ -1,13 +1,13 @@
|
||||
/*-
|
||||
* Copyright (c) 1995, David Greenman
|
||||
* All rights reserved.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice unmodified, this list of conditions, and the following
|
||||
* disclaimer.
|
||||
* 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.
|
||||
@ -24,7 +24,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: src/sys/dev/fxp/if_fxpvar.h,v 1.40 2006/11/30 14:58:01 glebius Exp $
|
||||
* $FreeBSD: src/sys/dev/fxp/if_fxpvar.h,v 1.49.2.4.2.1 2010/12/21 17:09:25 kensmith Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -38,6 +38,12 @@
|
||||
* This must be a power of two.
|
||||
*/
|
||||
#define FXP_NTXCB 128
|
||||
#define FXP_NTXCB_HIWAT ((FXP_NTXCB * 7) / 10)
|
||||
|
||||
/*
|
||||
* Maximum size of a DMA segment.
|
||||
*/
|
||||
#define FXP_TSO_SEGSIZE 4096
|
||||
|
||||
/*
|
||||
* Size of the TxCB list.
|
||||
@ -86,16 +92,16 @@
|
||||
|
||||
/*
|
||||
* Default maximum time, in microseconds, that an interrupt may be delayed
|
||||
* in an attempt to coalesce interrupts. This is only effective if the Intel
|
||||
* in an attempt to coalesce interrupts. This is only effective if the Intel
|
||||
* microcode is loaded, and may be changed via either loader tunables or
|
||||
* sysctl. See also the CPUSAVER_DWORD entry in rcvbundl.h.
|
||||
*/
|
||||
#define TUNABLE_INT_DELAY 1000
|
||||
|
||||
/*
|
||||
* Default number of packets that will be bundled, before an interrupt is
|
||||
* Default number of packets that will be bundled, before an interrupt is
|
||||
* generated. This is only effective if the Intel microcode is loaded, and
|
||||
* may be changed via either loader tunables or sysctl. This may not be
|
||||
* may be changed via either loader tunables or sysctl. This may not be
|
||||
* present in all microcode revisions, see also the CPUSAVER_BUNDLE_MAX_DWORD
|
||||
* entry in rcvbundl.h.
|
||||
*/
|
||||
@ -136,6 +142,37 @@ struct fxp_desc_list {
|
||||
bus_dma_tag_t rx_tag;
|
||||
};
|
||||
|
||||
struct fxp_ident {
|
||||
uint16_t devid;
|
||||
int16_t revid; /* -1 matches anything */
|
||||
uint8_t ich;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct fxp_hwstats {
|
||||
uint32_t tx_good;
|
||||
uint32_t tx_maxcols;
|
||||
uint32_t tx_latecols;
|
||||
uint32_t tx_underruns;
|
||||
uint32_t tx_lostcrs;
|
||||
uint32_t tx_deffered;
|
||||
uint32_t tx_single_collisions;
|
||||
uint32_t tx_multiple_collisions;
|
||||
uint32_t tx_total_collisions;
|
||||
uint32_t tx_pause;
|
||||
uint32_t tx_tco;
|
||||
uint32_t rx_good;
|
||||
uint32_t rx_crc_errors;
|
||||
uint32_t rx_alignment_errors;
|
||||
uint32_t rx_rnr_errors;
|
||||
uint32_t rx_overrun_errors;
|
||||
uint32_t rx_cdt_errors;
|
||||
uint32_t rx_shortframes;
|
||||
uint32_t rx_pause;
|
||||
uint32_t rx_controls;
|
||||
uint32_t rx_tco;
|
||||
};
|
||||
|
||||
/*
|
||||
* NOTE: Elements are ordered for optimal cacheline behavior, and NOT
|
||||
* for functional grouping.
|
||||
@ -145,8 +182,10 @@ struct fxp_softc {
|
||||
struct resource *fxp_res[2]; /* I/O and IRQ resources */
|
||||
struct resource_spec *fxp_spec; /* the resource spec we used */
|
||||
void *ih; /* interrupt handler cookie */
|
||||
const struct fxp_ident *ident;
|
||||
struct mtx sc_mtx;
|
||||
bus_dma_tag_t fxp_mtag; /* bus DMA tag for mbufs */
|
||||
bus_dma_tag_t fxp_txmtag; /* bus DMA tag for Tx mbufs */
|
||||
bus_dma_tag_t fxp_rxmtag; /* bus DMA tag for Rx mbufs */
|
||||
bus_dma_tag_t fxp_stag; /* bus DMA tag for stats */
|
||||
bus_dmamap_t fxp_smap; /* bus DMA map for stats */
|
||||
bus_dma_tag_t cbl_tag; /* DMA tag for the TxCB list */
|
||||
@ -156,10 +195,11 @@ struct fxp_softc {
|
||||
bus_dmamap_t spare_map; /* spare DMA map */
|
||||
struct fxp_desc_list fxp_desc; /* descriptors management struct */
|
||||
int maxtxseg; /* maximum # of TX segments */
|
||||
int maxsegsize; /* maximum size of a TX segment */
|
||||
int tx_queued; /* # of active TxCB's */
|
||||
int need_mcsetup; /* multicast filter needs programming */
|
||||
struct fxp_stats *fxp_stats; /* Pointer to interface stats */
|
||||
uint32_t stats_addr; /* DMA address of the stats structure */
|
||||
struct fxp_hwstats fxp_hwstats;
|
||||
int rx_idle_secs; /* # of seconds RX has been idle */
|
||||
struct callout stat_ch; /* stat callout */
|
||||
int watchdog_timer; /* seconds until chip reset */
|
||||
@ -170,13 +210,13 @@ struct fxp_softc {
|
||||
device_t dev;
|
||||
int tunable_int_delay; /* interrupt delay value for ucode */
|
||||
int tunable_bundle_max; /* max # frames per interrupt (ucode) */
|
||||
int tunable_noflow; /* flow control disabled */
|
||||
int rnr; /* RNR events */
|
||||
int eeprom_size; /* size of serial EEPROM */
|
||||
int suspended; /* 0 = normal 1 = suspended or dead */
|
||||
int cu_resume_bug;
|
||||
int revision;
|
||||
int flags;
|
||||
int if_flags;
|
||||
uint8_t rfa_size;
|
||||
uint32_t tx_cmd;
|
||||
};
|
||||
@ -187,12 +227,15 @@ struct fxp_softc {
|
||||
#define FXP_FLAG_EXT_TXCB 0x0008 /* enable use of extended TXCB */
|
||||
#define FXP_FLAG_SERIAL_MEDIA 0x0010 /* 10Mbps serial interface */
|
||||
#define FXP_FLAG_LONG_PKT_EN 0x0020 /* enable long packet reception */
|
||||
#define FXP_FLAG_ALL_MCAST 0x0040 /* accept all multicast frames */
|
||||
#define FXP_FLAG_CU_RESUME_BUG 0x0080 /* requires workaround for CU_RESUME */
|
||||
#define FXP_FLAG_UCODE 0x0100 /* ucode is loaded */
|
||||
#define FXP_FLAG_DEFERRED_RNR 0x0200 /* DEVICE_POLLING deferred RNR */
|
||||
#define FXP_FLAG_EXT_RFA 0x0400 /* extended RFDs for csum offload */
|
||||
#define FXP_FLAG_SAVE_BAD 0x0800 /* save bad pkts: bad size, CRC, etc */
|
||||
#define FXP_FLAG_82559_RXCSUM 0x1000 /* 82559 compatible RX checksum */
|
||||
#define FXP_FLAG_WOLCAP 0x2000 /* WOL capability */
|
||||
#define FXP_FLAG_WOL 0x4000 /* WOL active */
|
||||
#define FXP_FLAG_RXBUG 0x8000 /* Rx lock-up bug */
|
||||
|
||||
/* Macros to ease CSR access. */
|
||||
#define CSR_READ_1(sc, reg) bus_read_1(sc->fxp_res[0], reg)
|
||||
|
@ -29,7 +29,7 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
/*
|
||||
* $FreeBSD: src/sys/dev/fxp/rcvbundl.h,v 1.3 2005/04/21 19:34:57 mux Exp $
|
||||
* $FreeBSD: src/sys/dev/fxp/rcvbundl.h,v 1.3.22.1.6.1 2010/12/21 17:09:25 kensmith Exp $
|
||||
*/
|
||||
/*
|
||||
rcvbundl.h
|
||||
|
@ -29,7 +29,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/dev/mii/inphy.c,v 1.17 2007/01/12 22:27:46 marius Exp $");
|
||||
__FBSDID("$FreeBSD: src/sys/dev/mii/inphy.c,v 1.17.10.7.2.1 2010/12/21 17:09:25 kensmith Exp $");
|
||||
|
||||
/*
|
||||
* driver for Intel 82553 and 82555 PHYs
|
||||
@ -77,6 +77,7 @@ DRIVER_MODULE(inphy, miibus, inphy_driver, inphy_devclass, 0, 0);
|
||||
|
||||
static int inphy_service(struct mii_softc *, struct mii_data *, int);
|
||||
static void inphy_status(struct mii_softc *);
|
||||
static void inphy_reset(struct mii_softc *);
|
||||
|
||||
static const struct mii_phydesc inphys[] = {
|
||||
MII_PHY_DESC(INTEL, I82553C),
|
||||
@ -104,20 +105,22 @@ inphy_attach(device_t dev)
|
||||
sc = device_get_softc(dev);
|
||||
ma = device_get_ivars(dev);
|
||||
sc->mii_dev = device_get_parent(dev);
|
||||
mii = device_get_softc(sc->mii_dev);
|
||||
mii = ma->mii_data;
|
||||
LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);
|
||||
|
||||
sc->mii_inst = mii->mii_instance;
|
||||
sc->mii_flags = miibus_get_flags(dev);
|
||||
sc->mii_inst = mii->mii_instance++;
|
||||
sc->mii_phy = ma->mii_phyno;
|
||||
sc->mii_service = inphy_service;
|
||||
sc->mii_pdata = mii;
|
||||
mii->mii_instance++;
|
||||
|
||||
sc->mii_flags |= MIIF_NOMANPAUSE;
|
||||
|
||||
ifmedia_add(&mii->mii_media,
|
||||
IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->mii_inst),
|
||||
MII_MEDIA_100_TX, NULL);
|
||||
|
||||
mii_phy_reset(sc);
|
||||
inphy_reset(sc);
|
||||
|
||||
sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
|
||||
device_printf(dev, " ");
|
||||
@ -132,22 +135,12 @@ inphy_attach(device_t dev)
|
||||
static int
|
||||
inphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
|
||||
{
|
||||
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
|
||||
int reg;
|
||||
|
||||
switch (cmd) {
|
||||
case MII_POLLSTAT:
|
||||
if (IFM_INST(ife->ifm_media) != sc->mii_inst)
|
||||
return (0);
|
||||
break;
|
||||
|
||||
case MII_MEDIACHG:
|
||||
if (IFM_INST(ife->ifm_media) != sc->mii_inst) {
|
||||
reg = PHY_READ(sc, MII_BMCR);
|
||||
PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the interface is not up, don't do anything.
|
||||
*/
|
||||
@ -158,8 +151,6 @@ inphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
|
||||
break;
|
||||
|
||||
case MII_TICK:
|
||||
if (IFM_INST(ife->ifm_media) != sc->mii_inst)
|
||||
return (0);
|
||||
if (mii_phy_tick(sc) == EJUSTRETURN)
|
||||
return (0);
|
||||
break;
|
||||
@ -209,7 +200,21 @@ inphy_status(struct mii_softc *sc)
|
||||
else
|
||||
mii->mii_media_active |= IFM_10_T;
|
||||
if (scr & SCR_FDX)
|
||||
mii->mii_media_active |= IFM_FDX;
|
||||
mii->mii_media_active |=
|
||||
IFM_FDX | mii_phy_flowstatus(sc);
|
||||
else
|
||||
mii->mii_media_active |= IFM_HDX;
|
||||
} else
|
||||
mii->mii_media_active = ife->ifm_media;
|
||||
}
|
||||
|
||||
static void
|
||||
inphy_reset(struct mii_softc *sc)
|
||||
{
|
||||
|
||||
mii_phy_reset(sc);
|
||||
|
||||
/* Ensure Bay flow control is disabled. */
|
||||
PHY_WRITE(sc, MII_INPHY_SCR,
|
||||
PHY_READ(sc, MII_INPHY_SCR) & ~SCR_FLOWCTL);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: src/sys/dev/mii/inphyreg.h,v 1.1 2001/03/12 02:41:57 jlemon Exp $
|
||||
* $FreeBSD: src/sys/dev/mii/inphyreg.h,v 1.1.38.1.6.1 2010/12/21 17:09:25 kensmith Exp $
|
||||
*/
|
||||
|
||||
#define MII_INPHY_SCR 0x10 /* status and control register */
|
||||
|
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: src/sys/dev/mii/rlphy.c,v 1.31 2007/06/06 07:07:23 yongari Exp $");
|
||||
__FBSDID("$FreeBSD: src/sys/dev/mii/rlphy.c,v 1.32.2.5.2.1 2010/12/21 17:09:25 kensmith Exp $");
|
||||
|
||||
/*
|
||||
* driver for RealTek 8139 internal PHYs
|
||||
@ -109,8 +109,13 @@ rlphy_probe(device_t dev)
|
||||
int rv;
|
||||
|
||||
rv = mii_phy_dev_probe(dev, rlphys, BUS_PROBE_DEFAULT);
|
||||
#ifdef __HAIKU__
|
||||
if (rv == BUS_PROBE_DEFAULT)
|
||||
return (rv);
|
||||
#else
|
||||
if (rv <= 0)
|
||||
return (rv);
|
||||
#endif
|
||||
|
||||
nic = device_get_name(device_get_parent(device_get_parent(dev)));
|
||||
if (strcmp(nic, "rl") == 0 || strcmp(nic, "re") == 0)
|
||||
@ -129,7 +134,7 @@ rlphy_attach(device_t dev)
|
||||
sc = device_get_softc(dev);
|
||||
ma = device_get_ivars(dev);
|
||||
sc->mii_dev = device_get_parent(dev);
|
||||
mii = device_get_softc(sc->mii_dev);
|
||||
mii = ma->mii_data;
|
||||
|
||||
/*
|
||||
* Check whether we're the RTL8201L PHY and remember so the status
|
||||
@ -139,23 +144,17 @@ rlphy_attach(device_t dev)
|
||||
if (mii_phy_dev_probe(dev, rlphys, 0) == 0)
|
||||
rsc->sc_is_RTL8201L++;
|
||||
|
||||
/*
|
||||
* The RealTek PHY can never be isolated, so never allow non-zero
|
||||
* instances!
|
||||
*/
|
||||
if (mii->mii_instance != 0) {
|
||||
device_printf(dev, "ignoring this PHY, non-zero instance\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list);
|
||||
|
||||
sc->mii_inst = mii->mii_instance;
|
||||
sc->mii_flags = miibus_get_flags(dev);
|
||||
sc->mii_inst = mii->mii_instance++;
|
||||
sc->mii_phy = ma->mii_phyno;
|
||||
sc->mii_service = rlphy_service;
|
||||
sc->mii_pdata = mii;
|
||||
mii->mii_instance++;
|
||||
|
||||
/*
|
||||
* The RealTek PHY can never be isolated.
|
||||
*/
|
||||
sc->mii_flags |= MIIF_NOISOLATE;
|
||||
|
||||
#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
|
||||
@ -165,8 +164,7 @@ rlphy_attach(device_t dev)
|
||||
|
||||
mii_phy_reset(sc);
|
||||
|
||||
sc->mii_capabilities =
|
||||
PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
|
||||
sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
|
||||
device_printf(dev, " ");
|
||||
mii_phy_add_media(sc);
|
||||
printf("\n");
|
||||
@ -178,13 +176,6 @@ rlphy_attach(device_t dev)
|
||||
static int
|
||||
rlphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
|
||||
{
|
||||
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
|
||||
|
||||
/*
|
||||
* We can't isolate the RealTek PHY, so it has to be the only one!
|
||||
*/
|
||||
if (IFM_INST(ife->ifm_media) != sc->mii_inst)
|
||||
panic("rlphy_service: can't isolate RealTek PHY");
|
||||
|
||||
switch (cmd) {
|
||||
case MII_POLLSTAT:
|
||||
@ -261,16 +252,16 @@ rlphy_status(struct mii_softc *phy)
|
||||
|
||||
if ((anlpar = PHY_READ(phy, MII_ANAR) &
|
||||
PHY_READ(phy, MII_ANLPAR))) {
|
||||
if (anlpar & ANLPAR_T4)
|
||||
mii->mii_media_active |= IFM_100_T4;
|
||||
else if (anlpar & ANLPAR_TX_FD)
|
||||
if (anlpar & ANLPAR_TX_FD)
|
||||
mii->mii_media_active |= IFM_100_TX|IFM_FDX;
|
||||
else if (anlpar & ANLPAR_T4)
|
||||
mii->mii_media_active |= IFM_100_T4|IFM_HDX;
|
||||
else if (anlpar & ANLPAR_TX)
|
||||
mii->mii_media_active |= IFM_100_TX;
|
||||
mii->mii_media_active |= IFM_100_TX|IFM_HDX;
|
||||
else if (anlpar & ANLPAR_10_FD)
|
||||
mii->mii_media_active |= IFM_10_T|IFM_FDX;
|
||||
else if (anlpar & ANLPAR_10)
|
||||
mii->mii_media_active |= IFM_10_T;
|
||||
mii->mii_media_active |= IFM_10_T|IFM_HDX;
|
||||
else
|
||||
mii->mii_media_active |= IFM_NONE;
|
||||
return;
|
||||
@ -314,6 +305,7 @@ rlphy_status(struct mii_softc *phy)
|
||||
else
|
||||
mii->mii_media_active |= IFM_100_TX;
|
||||
}
|
||||
mii->mii_media_active |= IFM_HDX;
|
||||
} else
|
||||
mii->mii_media_active = ife->ifm_media;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -600,6 +600,25 @@ pci_get_domain(device_t dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
pci_get_devid(device_t dev)
|
||||
{
|
||||
return pci_read_config(dev, PCI_device_id, 2) << 16 |
|
||||
pci_read_config(dev, PCI_vendor_id, 2);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
pci_get_cachelnsz(device_t dev)
|
||||
{
|
||||
return pci_read_config(dev, PCI_line_size, 1);
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
pci_get_ether(device_t dev)
|
||||
{
|
||||
/* used in if_dc to get the MAC from CardBus CIS for Xircom card */
|
||||
return NULL; /* NULL is handled in the caller correctly */
|
||||
}
|
||||
|
||||
uint8_t
|
||||
pci_get_bus(device_t dev)
|
||||
|
@ -133,7 +133,9 @@ model ATHEROS F2 0x0002 Atheros F2 10/100 PHY
|
||||
model BROADCOM 3C905B 0x0012 3c905B 10/100 internal PHY
|
||||
model BROADCOM 3C905C 0x0017 3c905C 10/100 internal PHY
|
||||
model BROADCOM BCM5201 0x0021 BCM5201 10/100baseTX PHY
|
||||
model BROADCOM BCM5214 0x0028 BCM5214 Quad 10/100 PHY
|
||||
model BROADCOM BCM5221 0x001e BCM5221 10/100baseTX PHY
|
||||
model BROADCOM BCM5222 0x0032 BCM5222 Dual 10/100 PHY
|
||||
model BROADCOM BCM4401 0x0036 BCM4401 10/100baseTX PHY
|
||||
model xxBROADCOM BCM5400 0x0004 Broadcom 1000baseTX PHY
|
||||
model xxBROADCOM BCM5401 0x0005 BCM5401 10/100/1000baseTX PHY
|
||||
|
@ -32,6 +32,8 @@ uint16_t pci_get_device(device_t dev);
|
||||
uint16_t pci_get_subvendor(device_t dev);
|
||||
uint16_t pci_get_subdevice(device_t dev);
|
||||
uint8_t pci_get_revid(device_t dev);
|
||||
uint8_t pci_get_cachelnsz(device_t dev);
|
||||
uint8_t *pci_get_ether(device_t dev);
|
||||
|
||||
uint32_t pci_read_config(device_t dev, int reg, int width);
|
||||
void pci_write_config(device_t dev, int reg, uint32_t val, int width);
|
||||
|
@ -258,6 +258,7 @@ uint64_t ifmedia_baudrate(int);
|
||||
*/
|
||||
#define IFM_FDX 0x00100000 /* Force full duplex */
|
||||
#define IFM_HDX 0x00200000 /* Force half duplex */
|
||||
#define IFM_FLOW 0x00400000 /* Enable hardware flow control */
|
||||
#define IFM_FLAG0 0x01000000 /* Driver defined flag */
|
||||
#define IFM_FLAG1 0x02000000 /* Driver defined flag */
|
||||
#define IFM_FLAG2 0x04000000 /* Driver defined flag */
|
||||
|
@ -45,6 +45,7 @@ struct __system_init {
|
||||
struct __system_init __uninit_##uniquifier = { (system_init_func_t) func }
|
||||
|
||||
#define TUNABLE_INT(path, var)
|
||||
#define TUNABLE_INT_FETCH(path, var)
|
||||
|
||||
extern int ticks;
|
||||
|
||||
|
@ -17,5 +17,6 @@
|
||||
|
||||
typedef int boolean_t;
|
||||
typedef __const char* c_caddr_t;
|
||||
typedef uint64_t u_quad_t;
|
||||
|
||||
#endif
|
||||
|
@ -551,3 +551,54 @@ mii_phy_dev_probe(device_t dev, const struct mii_phydesc *mpd, int mrv)
|
||||
|
||||
return (ENXIO);
|
||||
}
|
||||
/*
|
||||
* Return the flow control status flag from MII_ANAR & MII_ANLPAR.
|
||||
*/
|
||||
u_int
|
||||
mii_phy_flowstatus(struct mii_softc *sc)
|
||||
{
|
||||
int anar, anlpar;
|
||||
|
||||
if ((sc->mii_flags & MIIF_DOPAUSE) == 0)
|
||||
return (0);
|
||||
|
||||
anar = PHY_READ(sc, MII_ANAR);
|
||||
anlpar = PHY_READ(sc, MII_ANLPAR);
|
||||
|
||||
/*
|
||||
* Check for 1000BASE-X. Autonegotiation is a bit
|
||||
* different on such devices.
|
||||
*/
|
||||
if ((sc->mii_flags & MIIF_IS_1000X) != 0) {
|
||||
anar <<= 3;
|
||||
anlpar <<= 3;
|
||||
}
|
||||
|
||||
if ((anar & ANAR_PAUSE_SYM) != 0 && (anlpar & ANLPAR_PAUSE_SYM) != 0)
|
||||
return (IFM_FLOW | IFM_ETH_TXPAUSE | IFM_ETH_RXPAUSE);
|
||||
|
||||
if ((anar & ANAR_PAUSE_SYM) == 0) {
|
||||
if ((anar & ANAR_PAUSE_ASYM) != 0 &&
|
||||
(anlpar & ANLPAR_PAUSE_TOWARDS) != 0)
|
||||
return (IFM_FLOW | IFM_ETH_TXPAUSE);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
if ((anar & ANAR_PAUSE_ASYM) == 0) {
|
||||
if ((anlpar & ANLPAR_PAUSE_SYM) != 0)
|
||||
return (IFM_FLOW | IFM_ETH_TXPAUSE | IFM_ETH_RXPAUSE);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
switch ((anlpar & ANLPAR_PAUSE_TOWARDS)) {
|
||||
case ANLPAR_PAUSE_NONE:
|
||||
return (0);
|
||||
case ANLPAR_PAUSE_ASYM:
|
||||
return (IFM_FLOW | IFM_ETH_RXPAUSE);
|
||||
default:
|
||||
return (IFM_FLOW | IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user