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:
parent
cb52ddf021
commit
bb3f721b2b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=186420
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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]);
|
||||
|
Loading…
Reference in New Issue
Block a user