1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-17 15:27:36 +00:00

NPE cleanups needed for ancillary drivers (e.g. crypto acceleration):

o check feature bits when probing NPE ethernet support
o move firmware loading logic from if_npe to core npe support
o allow multiple refs to core NPE driver
o while here fix hw.npe.debug tunable path
This commit is contained in:
Sam Leffler 2008-12-23 04:51:46 +00:00
parent cb52ddf021
commit bb3f721b2b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=186420
3 changed files with 109 additions and 66 deletions

View File

@ -157,7 +157,6 @@ struct npe_softc {
* assumptions probably need to be handled through hints.
*/
static const struct {
uint32_t imageid; /* default fw image */
uint32_t macbase;
uint32_t miibase;
int phy; /* phy id */
@ -167,7 +166,6 @@ static const struct {
uint8_t tx_doneqid;
} npeconfig[NPE_MAX] = {
[NPE_A] = {
.imageid = IXP425_NPE_A_IMAGEID,
.macbase = IXP435_MAC_A_HWBASE,
.miibase = IXP425_MAC_C_HWBASE,
.phy = 2,
@ -177,7 +175,6 @@ static const struct {
.tx_doneqid = 31
},
[NPE_B] = {
.imageid = IXP425_NPE_B_IMAGEID,
.macbase = IXP425_MAC_B_HWBASE,
.miibase = IXP425_MAC_C_HWBASE,
.phy = 0,
@ -187,7 +184,6 @@ static const struct {
.tx_doneqid = 31
},
[NPE_C] = {
.imageid = IXP425_NPE_C_IMAGEID,
.macbase = IXP425_MAC_C_HWBASE,
.miibase = IXP425_MAC_C_HWBASE,
.phy = 1,
@ -258,7 +254,7 @@ SYSCTL_NODE(_hw, OID_AUTO, npe, CTLFLAG_RD, 0, "IXP4XX NPE driver parameters");
static int npe_debug = 0;
SYSCTL_INT(_hw_npe, OID_AUTO, debug, CTLFLAG_RW, &npe_debug,
0, "IXP4XX NPE network interface debug msgs");
TUNABLE_INT("hw.npe.npe", &npe_debug);
TUNABLE_INT("hw.npe.debug", &npe_debug);
#define DPRINTF(sc, fmt, ...) do { \
if (sc->sc_debug) device_printf(sc->sc_dev, fmt, __VA_ARGS__); \
} while (0)
@ -301,16 +297,21 @@ npe_probe(device_t dev)
[NPE_B] = "IXP NPE-B",
[NPE_C] = "IXP NPE-C"
};
int unit = device_get_unit(dev);
int npeid;
if (unit > 2 ||
(ixp4xx_read_feature_bits() &
(unit == 0 ? EXP_FCTRL_ETH0 : EXP_FCTRL_ETH1)) == 0)
return EINVAL;
npeid = -1;
if (!override_npeid(dev, "npeid", &npeid))
npeid = unit2npeid(device_get_unit(dev));
npeid = unit2npeid(unit);
if (npeid == -1) {
device_printf(dev, "unit not supported\n");
device_printf(dev, "unit %d not supported\n", unit);
return EINVAL;
}
/* XXX check feature register to see if enabled */
device_set_desc(dev, desc[npeid]);
return 0;
}
@ -644,22 +645,6 @@ override_unit(device_t dev, const char *resname, int *val, int min, int max)
return 1;
}
static int
override_imageid(device_t dev, const char *resname, uint32_t *val)
{
int unit = device_get_unit(dev);
int resval;
if (resource_int_value("npe", unit, resname, &resval) != 0)
return 0;
/* XXX validate */
if (bootverbose)
device_printf(dev, "using npe.%d.%s=0x%x override\n",
unit, resname, resval);
*val = resval;
return 1;
}
static void
npe_mac_reset(struct npe_softc *sc)
{
@ -677,7 +662,6 @@ npe_activate(device_t dev)
{
struct npe_softc * sc = device_get_softc(dev);
int error, i, macbase, miibase;
uint32_t imageid, msg[2];
/*
* Setup NEP ID, MAC, and MII bindings. We allow override
@ -722,35 +706,12 @@ npe_activate(device_t dev)
sc->sc_miih = sc->sc_ioh;
/*
* Load NPE firmware and start it running. We assume
* that minor version bumps remain compatible so probe
* the firmware image starting with the expected version
* and then bump the minor version up to the max.
* Load NPE firmware and start it running.
*/
if (!override_imageid(dev, "imageid", &imageid))
imageid = npeconfig[sc->sc_npeid].imageid;
for (;;) {
error = ixpnpe_init(sc->sc_npe, "npe_fw", imageid);
if (error == 0)
break;
/* ESRCH is returned when the requested image is not present */
if (error != ESRCH) {
device_printf(dev, "cannot init NPE (error %d)\n",
error);
return error;
}
/* bump the minor version up to the max possible */
if (NPEIMAGE_MINOR(imageid) == 0xff) {
device_printf(dev, "cannot locate firmware "
"(imageid 0x%08x)\n", imageid);
return error;
}
imageid++;
}
/* NB: firmware should respond with a status msg */
if (ixpnpe_recvmsg_sync(sc->sc_npe, msg) != 0) {
device_printf(dev, "firmware did not respond as expected\n");
return EIO;
error = ixpnpe_init(sc->sc_npe);
if (error != 0) {
device_printf(dev, "cannot init NPE (error %d)\n", error);
return error;
}
/* probe for PHY */
@ -984,7 +945,6 @@ npe_setmac(struct npe_softc *sc, u_char *eaddr)
WR4(sc, NPE_MAC_UNI_ADDR_4, eaddr[3]);
WR4(sc, NPE_MAC_UNI_ADDR_5, eaddr[4]);
WR4(sc, NPE_MAC_UNI_ADDR_6, eaddr[5]);
}
static void

View File

@ -112,6 +112,8 @@ struct ixpnpe_softc {
struct mtx sc_mtx; /* mailbox lock */
uint32_t sc_msg[2]; /* reply msg collected in ixpnpe_intr */
int sc_msgwaiting; /* sc_msg holds valid data */
int sc_npeid;
int sc_nrefs; /* # of references */
int validImage; /* valid ucode image loaded */
int started; /* NPE is started */
@ -121,6 +123,7 @@ struct ixpnpe_softc {
uint32_t savedExecCount;
uint32_t savedEcsDbgCtxtReg2;
};
static struct ixpnpe_softc *npes[NPE_MAX];
#define IX_NPEDL_NPEIMAGE_FIELD_MASK 0xff
@ -287,6 +290,11 @@ ixpnpe_attach(device_t dev, int npeid)
device_printf(dev, "%s: bad npeid %d\n", __func__, npeid);
return NULL;
}
sc = npes[npeid];
if (sc != NULL) {
sc->sc_nrefs++;
return sc;
}
config = &npeconfigs[npeid];
/* XXX M_BUS */
@ -294,6 +302,8 @@ ixpnpe_attach(device_t dev, int npeid)
sc->sc_dev = dev;
sc->sc_iot = sa->sc_iot;
mtx_init(&sc->sc_mtx, device_get_nameunit(dev), "npe driver", MTX_DEF);
sc->sc_npeid = npeid;
sc->sc_nrefs = 1;
sc->sc_size = config->size;
sc->insMemSize = config->ins_memsize; /* size of instruction memory */
@ -320,20 +330,26 @@ ixpnpe_attach(device_t dev, int npeid)
npe_reg_write(sc, IX_NPECTL,
npe_reg_read(sc, IX_NPECTL) | (IX_NPECTL_OFE | IX_NPECTL_OFWE));
npes[npeid] = sc;
return sc;
}
void
ixpnpe_detach(struct ixpnpe_softc *sc)
{
/* disable output fifo interrupts */
npe_reg_write(sc, IX_NPECTL,
npe_reg_read(sc, IX_NPECTL) &~ (IX_NPECTL_OFE | IX_NPECTL_OFWE));
if (--sc->sc_nrefs == 0) {
npes[sc->sc_npeid] = NULL;
bus_teardown_intr(sc->sc_dev, sc->sc_irq, sc->sc_ih);
bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
mtx_destroy(&sc->sc_mtx);
free(sc, M_TEMP);
/* disable output fifo interrupts */
npe_reg_write(sc, IX_NPECTL,
npe_reg_read(sc, IX_NPECTL) &~ (IX_NPECTL_OFE | IX_NPECTL_OFWE));
bus_teardown_intr(sc->sc_dev, sc->sc_irq, sc->sc_ih);
bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
mtx_destroy(&sc->sc_mtx);
free(sc, M_TEMP);
}
}
int
@ -361,7 +377,7 @@ ixpnpe_start_locked(struct ixpnpe_softc *sc)
if (!sc->started) {
error = npe_cpu_start(sc);
if (error == 0)
sc->started = 1;
sc->started = 1;
} else
error = 0;
@ -442,8 +458,9 @@ npe_findimage(struct ixpnpe_softc *sc,
return ESRCH;
}
int
ixpnpe_init(struct ixpnpe_softc *sc, const char *imageName, uint32_t imageId)
static int
ixpnpe_load_firmware(struct ixpnpe_softc *sc, const char *imageName,
uint32_t imageId)
{
static const char *devname[4] =
{ "IXP425", "IXP435/IXP465", "DeviceID#2", "DeviceID#3" };
@ -504,6 +521,73 @@ ixpnpe_init(struct ixpnpe_softc *sc, const char *imageName, uint32_t imageId)
return error;
}
static int
override_imageid(device_t dev, const char *resname, uint32_t *val)
{
int unit = device_get_unit(dev);
int resval;
if (resource_int_value("npe", unit, resname, &resval) != 0)
return 0;
/* XXX validate */
if (bootverbose)
device_printf(dev, "using npe.%d.%s=0x%x override\n",
unit, resname, resval);
*val = resval;
return 1;
}
int
ixpnpe_init(struct ixpnpe_softc *sc)
{
static const uint32_t npeconfig[NPE_MAX] = {
[NPE_A] = IXP425_NPE_A_IMAGEID,
[NPE_B] = IXP425_NPE_B_IMAGEID,
[NPE_C] = IXP425_NPE_C_IMAGEID,
};
uint32_t imageid, msg[2];
int error;
if (sc->started)
return 0;
/*
* Load NPE firmware and start it running. We assume
* that minor version bumps remain compatible so probe
* the firmware image starting with the expected version
* and then bump the minor version up to the max.
*/
if (!override_imageid(sc->sc_dev, "imageid", &imageid))
imageid = npeconfig[sc->sc_npeid];
for (;;) {
error = ixpnpe_load_firmware(sc, "npe_fw", imageid);
if (error == 0)
break;
/*
* ESRCH is returned when the requested image
* is not present
*/
if (error != ESRCH) {
device_printf(sc->sc_dev,
"cannot init NPE (error %d)\n", error);
return error;
}
/* bump the minor version up to the max possible */
if (NPEIMAGE_MINOR(imageid) == 0xff) {
device_printf(sc->sc_dev, "cannot locate firmware "
"(imageid 0x%08x)\n", imageid);
return error;
}
imageid++;
}
/* NB: firmware should respond with a status msg */
if (ixpnpe_recvmsg_sync(sc, msg) != 0) {
device_printf(sc->sc_dev,
"firmware did not respond as expected\n");
return EIO;
}
return 0;
}
int
ixpnpe_getfunctionality(struct ixpnpe_softc *sc)
{

View File

@ -111,8 +111,7 @@ void ixpnpe_detach(struct ixpnpe_softc *);
int ixpnpe_stopandreset(struct ixpnpe_softc *);
int ixpnpe_start(struct ixpnpe_softc *);
int ixpnpe_stop(struct ixpnpe_softc *);
int ixpnpe_init(struct ixpnpe_softc *,
const char *imageName, uint32_t imageId);
int ixpnpe_init(struct ixpnpe_softc *);
int ixpnpe_getfunctionality(struct ixpnpe_softc *sc);
int ixpnpe_sendmsg_async(struct ixpnpe_softc *, const uint32_t msg[2]);