summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/dev/fxp/if_fxp.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/dev/fxp/if_fxp.c')
-rw-r--r--freebsd/sys/dev/fxp/if_fxp.c180
1 files changed, 114 insertions, 66 deletions
diff --git a/freebsd/sys/dev/fxp/if_fxp.c b/freebsd/sys/dev/fxp/if_fxp.c
index 7bc247dc..2b1f51d6 100644
--- a/freebsd/sys/dev/fxp/if_fxp.c
+++ b/freebsd/sys/dev/fxp/if_fxp.c
@@ -89,7 +89,7 @@ MODULE_DEPEND(fxp, miibus, 1, 1, 1);
#include <rtems/bsd/local/miibus_if.h>
/*
- * NOTE! On the Alpha, we have an alignment constraint. The
+ * NOTE! On !x86 we typically have an alignment constraint. The
* card DMAs the packet immediately following the RFA. However,
* the first thing in the packet is a 14-byte Ethernet header.
* This means that the packet is misaligned. To compensate,
@@ -113,7 +113,7 @@ static int tx_threshold = 64;
*
* See struct fxp_cb_config for the bit definitions.
*/
-static const u_char const fxp_cb_config_template[] = {
+static const u_char fxp_cb_config_template[] = {
0x0, 0x0, /* cb_status */
0x0, 0x0, /* cb_command */
0x0, 0x0, 0x0, 0x0, /* link_addr */
@@ -157,7 +157,7 @@ static const u_char const fxp_cb_config_template[] = {
* particular variants, but we don't currently differentiate between
* them.
*/
-static const struct fxp_ident const fxp_ident_table[] = {
+static const struct fxp_ident fxp_ident_table[] = {
{ 0x1029, -1, 0, "Intel 82559 PCI/CardBus Pro/100" },
{ 0x1030, -1, 0, "Intel 82559 Pro/100 Ethernet" },
{ 0x1031, -1, 3, "Intel 82801CAM (ICH3) Pro/100 VE Ethernet" },
@@ -196,7 +196,7 @@ static const struct fxp_ident const fxp_ident_table[] = {
{ 0x1229, 0x08, 0, "Intel 82559 Pro/100 Ethernet" },
{ 0x1229, 0x09, 0, "Intel 82559ER Pro/100 Ethernet" },
{ 0x1229, 0x0c, 0, "Intel 82550 Pro/100 Ethernet" },
- { 0x1229, 0x0d, 0, "Intel 82550 Pro/100 Ethernet" },
+ { 0x1229, 0x0d, 0, "Intel 82550C Pro/100 Ethernet" },
{ 0x1229, 0x0e, 0, "Intel 82550 Pro/100 Ethernet" },
{ 0x1229, 0x0f, 0, "Intel 82551 Pro/100 Ethernet" },
{ 0x1229, 0x10, 0, "Intel 82551 Pro/100 Ethernet" },
@@ -238,11 +238,11 @@ static int fxp_ioctl(struct ifnet *ifp, u_long command,
caddr_t data);
static void fxp_watchdog(struct fxp_softc *sc);
static void fxp_add_rfabuf(struct fxp_softc *sc,
- struct fxp_rx *rxp);
+ struct fxp_rx *rxp);
static void fxp_discard_rfabuf(struct fxp_softc *sc,
- struct fxp_rx *rxp);
+ struct fxp_rx *rxp);
static int fxp_new_rfabuf(struct fxp_softc *sc,
- struct fxp_rx *rxp);
+ struct fxp_rx *rxp);
static int fxp_mc_addrs(struct fxp_softc *sc);
static void fxp_mc_setup(struct fxp_softc *sc);
static uint16_t fxp_eeprom_getword(struct fxp_softc *sc, int offset,
@@ -250,6 +250,7 @@ static uint16_t fxp_eeprom_getword(struct fxp_softc *sc, int offset,
static void fxp_eeprom_putword(struct fxp_softc *sc, int offset,
uint16_t data);
static void fxp_autosize_eeprom(struct fxp_softc *sc);
+static void fxp_load_eeprom(struct fxp_softc *sc);
static void fxp_read_eeprom(struct fxp_softc *sc, u_short *data,
int offset, int words);
static void fxp_write_eeprom(struct fxp_softc *sc, u_short *data,
@@ -274,7 +275,7 @@ static int sysctl_hw_fxp_int_delay(SYSCTL_HANDLER_ARGS);
static void fxp_scb_wait(struct fxp_softc *sc);
static void fxp_scb_cmd(struct fxp_softc *sc, int cmd);
static void fxp_dma_wait(struct fxp_softc *sc,
- volatile uint16_t *status, bus_dma_tag_t dmat,
+ volatile uint16_t *status, bus_dma_tag_t dmat,
bus_dmamap_t map);
static device_method_t fxp_methods[] = {
@@ -428,7 +429,7 @@ fxp_attach(device_t dev)
struct fxp_rx *rxp;
struct ifnet *ifp;
uint32_t val;
- uint16_t data, myea[ETHER_ADDR_LEN / 2];
+ uint16_t data;
u_char eaddr[ETHER_ADDR_LEN];
int error, flags, i, pmc, prefer_iomap;
@@ -500,6 +501,7 @@ fxp_attach(device_t dev)
* Find out how large of an SEEPROM we have.
*/
fxp_autosize_eeprom(sc);
+ fxp_load_eeprom(sc);
/*
* Find out the chip revision; lump all 82557 revs together.
@@ -509,7 +511,7 @@ fxp_attach(device_t dev)
/* Assume ICH controllers are 82559. */
sc->revision = FXP_REV_82559_A0;
} else {
- fxp_read_eeprom(sc, &data, 5, 1);
+ data = sc->eeprom[FXP_EEPROM_MAP_CNTR];
if ((data >> 8) == 1)
sc->revision = FXP_REV_82557;
else
@@ -521,15 +523,27 @@ fxp_attach(device_t dev)
*/
if (sc->revision >= FXP_REV_82558_A4 &&
sc->revision != FXP_REV_82559S_A) {
- fxp_read_eeprom(sc, &data, 10, 1);
+ data = sc->eeprom[FXP_EEPROM_MAP_ID];
if ((data & 0x20) != 0 &&
pci_find_extcap(sc->dev, PCIY_PMG, &pmc) == 0)
sc->flags |= FXP_FLAG_WOLCAP;
}
+ if (sc->revision == FXP_REV_82550_C) {
+ /*
+ * 82550C with server extension requires microcode to
+ * receive fragmented UDP datagrams. However if the
+ * microcode is used for client-only featured 82550C
+ * it locks up controller.
+ */
+ data = sc->eeprom[FXP_EEPROM_MAP_COMPAT];
+ if ((data & 0x0400) == 0)
+ sc->flags |= FXP_FLAG_NO_UCODE;
+ }
+
/* Receiver lock-up workaround detection. */
if (sc->revision < FXP_REV_82558_A4) {
- fxp_read_eeprom(sc, &data, 3, 1);
+ data = sc->eeprom[FXP_EEPROM_MAP_COMPAT];
if ((data & 0x03) != 0x03) {
sc->flags |= FXP_FLAG_RXBUG;
device_printf(dev, "Enabling Rx lock-up workaround\n");
@@ -539,7 +553,7 @@ fxp_attach(device_t dev)
/*
* Determine whether we must use the 503 serial interface.
*/
- fxp_read_eeprom(sc, &data, 6, 1);
+ data = sc->eeprom[FXP_EEPROM_MAP_PRI_PHY];
if (sc->revision == FXP_REV_82557 && (data & FXP_PHY_DEVICE_MASK) != 0
&& (data & FXP_PHY_SERIAL_ONLY))
sc->flags |= FXP_FLAG_SERIAL_MEDIA;
@@ -559,7 +573,7 @@ fxp_attach(device_t dev)
*/
if ((sc->ident->ich >= 2 && sc->ident->ich <= 3) ||
(sc->ident->ich == 0 && sc->revision >= FXP_REV_82559_A0)) {
- fxp_read_eeprom(sc, &data, 10, 1);
+ data = sc->eeprom[FXP_EEPROM_MAP_ID];
if (data & 0x02) { /* STB enable */
uint16_t cksum;
int i;
@@ -567,27 +581,24 @@ fxp_attach(device_t dev)
device_printf(dev,
"Disabling dynamic standby mode in EEPROM\n");
data &= ~0x02;
- fxp_write_eeprom(sc, &data, 10, 1);
+ sc->eeprom[FXP_EEPROM_MAP_ID] = data;
+ fxp_write_eeprom(sc, &data, FXP_EEPROM_MAP_ID, 1);
device_printf(dev, "New EEPROM ID: 0x%x\n", data);
cksum = 0;
- for (i = 0; i < (1 << sc->eeprom_size) - 1; i++) {
- fxp_read_eeprom(sc, &data, i, 1);
- cksum += data;
- }
+ for (i = 0; i < (1 << sc->eeprom_size) - 1; i++)
+ cksum += sc->eeprom[i];
i = (1 << sc->eeprom_size) - 1;
cksum = 0xBABA - cksum;
- fxp_read_eeprom(sc, &data, i, 1);
fxp_write_eeprom(sc, &cksum, i, 1);
device_printf(dev,
"EEPROM checksum @ 0x%x: 0x%x -> 0x%x\n",
- i, data, cksum);
-#if 1
+ i, sc->eeprom[i], cksum);
+ sc->eeprom[i] = cksum;
/*
* If the user elects to continue, try the software
* workaround, as it is better than nothing.
*/
sc->flags |= FXP_FLAG_CU_RESUME_BUG;
-#endif
}
}
@@ -677,13 +688,14 @@ fxp_attach(device_t dev)
}
error = bus_dmamem_alloc(sc->fxp_stag, (void **)&sc->fxp_stats,
- BUS_DMA_NOWAIT | BUS_DMA_ZERO, &sc->fxp_smap);
+ BUS_DMA_NOWAIT | BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->fxp_smap);
if (error) {
device_printf(dev, "could not allocate stats DMA memory\n");
goto fail;
}
error = bus_dmamap_load(sc->fxp_stag, sc->fxp_smap, sc->fxp_stats,
- sizeof(struct fxp_stats), fxp_dma_map_addr, &sc->stats_addr, 0);
+ sizeof(struct fxp_stats), fxp_dma_map_addr, &sc->stats_addr,
+ BUS_DMA_NOWAIT);
if (error) {
device_printf(dev, "could not load the stats DMA buffer\n");
goto fail;
@@ -699,7 +711,7 @@ fxp_attach(device_t dev)
}
error = bus_dmamem_alloc(sc->cbl_tag, (void **)&sc->fxp_desc.cbl_list,
- BUS_DMA_NOWAIT | BUS_DMA_ZERO, &sc->cbl_map);
+ BUS_DMA_NOWAIT | BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->cbl_map);
if (error) {
device_printf(dev, "could not allocate TxCB DMA memory\n");
goto fail;
@@ -707,7 +719,7 @@ fxp_attach(device_t dev)
error = bus_dmamap_load(sc->cbl_tag, sc->cbl_map,
sc->fxp_desc.cbl_list, FXP_TXCB_SZ, fxp_dma_map_addr,
- &sc->fxp_desc.cbl_addr, 0);
+ &sc->fxp_desc.cbl_addr, BUS_DMA_NOWAIT);
if (error) {
device_printf(dev, "could not load TxCB DMA buffer\n");
goto fail;
@@ -724,14 +736,15 @@ fxp_attach(device_t dev)
}
error = bus_dmamem_alloc(sc->mcs_tag, (void **)&sc->mcsp,
- BUS_DMA_NOWAIT | BUS_DMA_ZERO, &sc->mcs_map);
+ BUS_DMA_NOWAIT | BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->mcs_map);
if (error) {
device_printf(dev,
"could not allocate multicast setup DMA memory\n");
goto fail;
}
error = bus_dmamap_load(sc->mcs_tag, sc->mcs_map, sc->mcsp,
- sizeof(struct fxp_cb_mcs), fxp_dma_map_addr, &sc->mcs_addr, 0);
+ sizeof(struct fxp_cb_mcs), fxp_dma_map_addr, &sc->mcs_addr,
+ BUS_DMA_NOWAIT);
if (error) {
device_printf(dev,
"can't load the multicast setup DMA buffer\n");
@@ -779,21 +792,20 @@ fxp_attach(device_t dev)
/*
* Read MAC address.
*/
- fxp_read_eeprom(sc, myea, 0, 3);
- eaddr[0] = myea[0] & 0xff;
- eaddr[1] = myea[0] >> 8;
- eaddr[2] = myea[1] & 0xff;
- eaddr[3] = myea[1] >> 8;
- eaddr[4] = myea[2] & 0xff;
- eaddr[5] = myea[2] >> 8;
+ eaddr[0] = sc->eeprom[FXP_EEPROM_MAP_IA0] & 0xff;
+ eaddr[1] = sc->eeprom[FXP_EEPROM_MAP_IA0] >> 8;
+ eaddr[2] = sc->eeprom[FXP_EEPROM_MAP_IA1] & 0xff;
+ eaddr[3] = sc->eeprom[FXP_EEPROM_MAP_IA1] >> 8;
+ eaddr[4] = sc->eeprom[FXP_EEPROM_MAP_IA2] & 0xff;
+ eaddr[5] = sc->eeprom[FXP_EEPROM_MAP_IA2] >> 8;
if (bootverbose) {
device_printf(dev, "PCI IDs: %04x %04x %04x %04x %04x\n",
pci_get_vendor(dev), pci_get_device(dev),
pci_get_subvendor(dev), pci_get_subdevice(dev),
pci_get_revid(dev));
- fxp_read_eeprom(sc, &data, 10, 1);
device_printf(dev, "Dynamic Standby mode is %s\n",
- data & 0x02 ? "enabled" : "disabled");
+ sc->eeprom[FXP_EEPROM_MAP_ID] & 0x02 ? "enabled" :
+ "disabled");
}
/*
@@ -902,7 +914,7 @@ fxp_attach(device_t dev)
FXP_LOCK(sc);
/* Clear wakeup events. */
CSR_WRITE_1(sc, FXP_CSR_PMDR, CSR_READ_1(sc, FXP_CSR_PMDR));
- fxp_init_body(sc, 1);
+ fxp_init_body(sc, 0);
fxp_stop(sc);
FXP_UNLOCK(sc);
}
@@ -1064,7 +1076,8 @@ fxp_suspend(device_t dev)
pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE;
sc->flags |= FXP_FLAG_WOL;
/* Reconfigure hardware to accept magic frames. */
- fxp_init_body(sc, 1);
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ fxp_init_body(sc, 0);
}
pci_write_config(sc->dev, pmc + PCIR_POWER_STATUS, pmstat, 2);
}
@@ -1289,6 +1302,23 @@ fxp_write_eeprom(struct fxp_softc *sc, u_short *data, int offset, int words)
fxp_eeprom_putword(sc, offset + i, data[i]);
}
+static void
+fxp_load_eeprom(struct fxp_softc *sc)
+{
+ int i;
+ uint16_t cksum;
+
+ fxp_read_eeprom(sc, sc->eeprom, 0, 1 << sc->eeprom_size);
+ cksum = 0;
+ for (i = 0; i < (1 << sc->eeprom_size) - 1; i++)
+ cksum += sc->eeprom[i];
+ cksum = 0xBABA - cksum;
+ if (cksum != sc->eeprom[(1 << sc->eeprom_size) - 1])
+ device_printf(sc->dev,
+ "EEPROM checksum mismatch! (0x%04x -> 0x%04x)\n",
+ cksum, sc->eeprom[(1 << sc->eeprom_size) - 1]);
+}
+
/*
* Grab the softc lock and call the real fxp_start_body() routine
*/
@@ -1456,7 +1486,7 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
return (ENOBUFS);
}
tcp = (struct tcphdr *)(mtod(m, char *) + poff);
- m = m_pullup(m, poff + sizeof(struct tcphdr) + tcp->th_off);
+ m = m_pullup(m, poff + (tcp->th_off << 2));
if (m == NULL) {
*m_head = NULL;
return (ENOBUFS);
@@ -1543,7 +1573,7 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
}
*m_head = m;
error = bus_dmamap_load_mbuf_sg(sc->fxp_txmtag, txp->tx_map,
- *m_head, segs, &nseg, 0);
+ *m_head, segs, &nseg, 0);
if (error != 0) {
m_freem(*m_head);
*m_head = NULL;
@@ -1943,11 +1973,11 @@ fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, uint8_t statack,
/* Adjust for appended checksum bytes. */
total_len -= 2;
}
- if (total_len < sizeof(struct ether_header) ||
+ if (total_len < (int)sizeof(struct ether_header) ||
total_len > (MCLBYTES - RFA_ALIGNMENT_FUDGE -
sc->rfa_size) ||
status & (FXP_RFA_STATUS_CRC |
- FXP_RFA_STATUS_ALIGN)) {
+ FXP_RFA_STATUS_ALIGN | FXP_RFA_STATUS_OVERRUN)) {
m_freem(m);
fxp_add_rfabuf(sc, rxp);
continue;
@@ -2050,7 +2080,7 @@ fxp_update_stats(struct fxp_softc *sc)
*/
sc->rx_idle_secs++;
}
- ifp->if_ierrors +=
+ ifp->if_ierrors +=
le32toh(sp->rx_crc_errors) +
le32toh(sp->rx_alignment_errors) +
le32toh(sp->rx_rnr_errors) +
@@ -2113,8 +2143,10 @@ fxp_tick(void *xsc)
*/
if (sc->rx_idle_secs > FXP_MAX_RX_IDLE) {
sc->rx_idle_secs = 0;
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
fxp_init_body(sc, 1);
+ }
return;
}
/*
@@ -2177,7 +2209,7 @@ fxp_stop(struct fxp_softc *sc)
txp = sc->fxp_desc.tx_list;
if (txp != NULL) {
for (i = 0; i < FXP_NTXCB; i++) {
- if (txp[i].tx_mbuf != NULL) {
+ if (txp[i].tx_mbuf != NULL) {
bus_dmamap_sync(sc->fxp_txmtag, txp[i].tx_map,
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->fxp_txmtag,
@@ -2212,6 +2244,7 @@ fxp_watchdog(struct fxp_softc *sc)
device_printf(sc->dev, "device timeout\n");
sc->ifp->if_oerrors++;
+ sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
fxp_init_body(sc, 1);
}
@@ -2246,6 +2279,10 @@ fxp_init_body(struct fxp_softc *sc, int setmedia)
int i, prm;
FXP_LOCK_ASSERT(sc, MA_OWNED);
+
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
+ return;
+
/*
* Cancel any pending I/O
*/
@@ -2557,14 +2594,12 @@ fxp_ifmedia_upd(struct ifnet *ifp)
{
struct fxp_softc *sc = ifp->if_softc;
struct mii_data *mii;
+ struct mii_softc *miisc;
mii = device_get_softc(sc->miibus);
FXP_LOCK(sc);
- if (mii->mii_instance) {
- struct mii_softc *miisc;
- LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
- mii_phy_reset(miisc);
- }
+ LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
+ mii_phy_reset(miisc);
mii_mediachg(mii);
FXP_UNLOCK(sc);
return (0);
@@ -2584,12 +2619,6 @@ fxp_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
mii_pollstat(mii);
ifmr->ifm_active = mii->mii_media_active;
ifmr->ifm_status = mii->mii_media_status;
-
- if (IFM_SUBTYPE(ifmr->ifm_active) == IFM_10_T &&
- sc->flags & FXP_FLAG_CU_RESUME_BUG)
- sc->cu_resume_bug = 1;
- else
- sc->cu_resume_bug = 0;
FXP_UNLOCK(sc);
}
@@ -2782,12 +2811,18 @@ fxp_miibus_statchg(device_t dev)
(IFM_AVALID | IFM_ACTIVE))
return;
+ if (IFM_SUBTYPE(mii->mii_media_active) == IFM_10_T &&
+ sc->flags & FXP_FLAG_CU_RESUME_BUG)
+ sc->cu_resume_bug = 1;
+ else
+ sc->cu_resume_bug = 0;
/*
* Call fxp_init_body in order to adjust the flow control settings.
* Note that the 82557 doesn't support hardware flow control.
*/
if (sc->revision == FXP_REV_82557)
return;
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
fxp_init_body(sc, 0);
}
@@ -2811,9 +2846,10 @@ fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
if (ifp->if_flags & IFF_UP) {
if (((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) &&
((ifp->if_flags ^ sc->if_flags) &
- (IFF_PROMISC | IFF_ALLMULTI | IFF_LINK0)) != 0)
- fxp_init_body(sc, 1);
- else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
+ (IFF_PROMISC | IFF_ALLMULTI | IFF_LINK0)) != 0) {
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ fxp_init_body(sc, 0);
+ } else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
fxp_init_body(sc, 1);
} else {
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
@@ -2825,8 +2861,12 @@ fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
case SIOCADDMULTI:
case SIOCDELMULTI:
- if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
- fxp_init(sc);
+ FXP_LOCK(sc);
+ if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ fxp_init_body(sc, 0);
+ }
+ FXP_UNLOCK(sc);
break;
case SIOCSIFMEDIA:
@@ -2915,8 +2955,10 @@ fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
~(IFCAP_VLAN_HWTSO | IFCAP_VLAN_HWCSUM);
reinit++;
}
- if (reinit > 0 && ifp->if_flags & IFF_UP)
- fxp_init_body(sc, 1);
+ if (reinit > 0 && (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
+ ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
+ fxp_init_body(sc, 0);
+ }
FXP_UNLOCK(sc);
VLAN_CAPABILITIES(ifp);
break;
@@ -3026,7 +3068,7 @@ static const struct ucode {
int length;
u_short int_delay_offset;
u_short bundle_max_offset;
-} const ucode_table[] = {
+} ucode_table[] = {
{ FXP_REV_82558_A4, UCODE(fxp_ucode_d101a), D101_CPUSAVER_DWORD, 0 },
{ FXP_REV_82558_B0, UCODE(fxp_ucode_d101b0), D101_CPUSAVER_DWORD, 0 },
{ FXP_REV_82559_A0, UCODE(fxp_ucode_d101ma),
@@ -3039,6 +3081,8 @@ static const struct ucode {
D102_C_CPUSAVER_DWORD, D102_C_CPUSAVER_BUNDLE_MAX_DWORD },
{ FXP_REV_82551_F, UCODE(fxp_ucode_d102e),
D102_E_CPUSAVER_DWORD, D102_E_CPUSAVER_BUNDLE_MAX_DWORD },
+ { FXP_REV_82551_10, UCODE(fxp_ucode_d102e),
+ D102_E_CPUSAVER_DWORD, D102_E_CPUSAVER_BUNDLE_MAX_DWORD },
{ 0, NULL, 0, 0, 0 }
};
@@ -3049,6 +3093,9 @@ fxp_load_ucode(struct fxp_softc *sc)
struct fxp_cb_ucode *cbp;
int i;
+ if (sc->flags & FXP_FLAG_NO_UCODE)
+ return;
+
for (uc = ucode_table; uc->ucode != NULL; uc++)
if (sc->revision == uc->revision)
break;
@@ -3081,6 +3128,7 @@ fxp_load_ucode(struct fxp_softc *sc)
sc->tunable_int_delay,
uc->bundle_max_offset == 0 ? 0 : sc->tunable_bundle_max);
sc->flags |= FXP_FLAG_UCODE;
+ bzero(cbp, FXP_TXCB_SZ);
}
#define FXP_SYSCTL_STAT_ADD(c, h, n, p, d) \