mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-29 12:03:03 +00:00
Fix and implement missing parts of flow control support. This also removes
the dev.fxp.%d.noflow tunable as the same effect can now be achieved with ifconfig(8) by setting the flowcontrol media option as desired (besides the tunable never having a chance to actually enable flow control support so far). In joint forces with: yongari
This commit is contained in:
parent
60c1e4c405
commit
1845b5c37b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=215906
@ -224,7 +224,7 @@ static void fxp_rxcsum(struct fxp_softc *sc, struct ifnet *ifp,
|
||||
static int fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp,
|
||||
uint8_t statack, int count);
|
||||
static void fxp_init(void *xsc);
|
||||
static void fxp_init_body(struct fxp_softc *sc);
|
||||
static void fxp_init_body(struct fxp_softc *sc, int);
|
||||
static void fxp_tick(void *xsc);
|
||||
static void fxp_start(struct ifnet *ifp);
|
||||
static void fxp_start_body(struct ifnet *ifp);
|
||||
@ -261,6 +261,7 @@ static void fxp_serial_ifmedia_sts(struct ifnet *ifp,
|
||||
static int fxp_miibus_readreg(device_t dev, int phy, int reg);
|
||||
static int fxp_miibus_writereg(device_t dev, int phy, int reg,
|
||||
int value);
|
||||
static void fxp_miibus_statchg(device_t dev);
|
||||
static void fxp_load_ucode(struct fxp_softc *sc);
|
||||
static void fxp_update_stats(struct fxp_softc *sc);
|
||||
static void fxp_sysctl_node(struct fxp_softc *sc);
|
||||
@ -286,6 +287,7 @@ static device_method_t fxp_methods[] = {
|
||||
/* MII interface */
|
||||
DEVMETHOD(miibus_readreg, fxp_miibus_readreg),
|
||||
DEVMETHOD(miibus_writereg, fxp_miibus_writereg),
|
||||
DEVMETHOD(miibus_statchg, fxp_miibus_statchg),
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
@ -329,8 +331,8 @@ fxp_scb_wait(struct fxp_softc *sc)
|
||||
while (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) && --i)
|
||||
DELAY(2);
|
||||
if (i == 0) {
|
||||
flowctl.b[0] = CSR_READ_1(sc, FXP_CSR_FLOWCONTROL);
|
||||
flowctl.b[1] = CSR_READ_1(sc, FXP_CSR_FLOWCONTROL + 1);
|
||||
flowctl.b[0] = CSR_READ_1(sc, FXP_CSR_FC_THRESH);
|
||||
flowctl.b[1] = CSR_READ_1(sc, FXP_CSR_FC_STATUS);
|
||||
device_printf(sc->dev, "SCB timeout: 0x%x 0x%x 0x%x 0x%x\n",
|
||||
CSR_READ_1(sc, FXP_CSR_SCB_COMMAND),
|
||||
CSR_READ_1(sc, FXP_CSR_SCB_STATACK),
|
||||
@ -426,8 +428,7 @@ fxp_attach(device_t dev)
|
||||
uint32_t val;
|
||||
uint16_t data, myea[ETHER_ADDR_LEN / 2];
|
||||
u_char eaddr[ETHER_ADDR_LEN];
|
||||
int i, pmc, prefer_iomap;
|
||||
int error;
|
||||
int error, flags, i, pmc, prefer_iomap;
|
||||
|
||||
error = 0;
|
||||
sc = device_get_softc(dev);
|
||||
@ -807,11 +808,14 @@ fxp_attach(device_t dev)
|
||||
/*
|
||||
* i82557 wedge when isolating all of their PHYs.
|
||||
*/
|
||||
flags = MIIF_NOISOLATE;
|
||||
if (sc->revision >= FXP_REV_82558_A4)
|
||||
flags |= MIIF_DOPAUSE;
|
||||
error = mii_attach(dev, &sc->miibus, ifp, fxp_ifmedia_upd,
|
||||
fxp_ifmedia_sts, BMSR_DEFCAPMASK, MII_PHY_ANY,
|
||||
MII_OFFSET_ANY, MIIF_NOISOLATE);
|
||||
MII_OFFSET_ANY, flags);
|
||||
if (error != 0) {
|
||||
device_printf(dev, "attaching PHYs failed\n");
|
||||
device_printf(dev, "attaching PHYs failed\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
@ -894,7 +898,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);
|
||||
fxp_init_body(sc, 1);
|
||||
fxp_stop(sc);
|
||||
FXP_UNLOCK(sc);
|
||||
}
|
||||
@ -1056,7 +1060,7 @@ 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);
|
||||
fxp_init_body(sc, 1);
|
||||
}
|
||||
pci_write_config(sc->dev, pmc + PCIR_POWER_STATUS, pmstat, 2);
|
||||
}
|
||||
@ -1098,7 +1102,7 @@ fxp_resume(device_t dev)
|
||||
|
||||
/* reinitialize interface if necessary */
|
||||
if (ifp->if_flags & IFF_UP)
|
||||
fxp_init_body(sc);
|
||||
fxp_init_body(sc, 1);
|
||||
|
||||
sc->suspended = 0;
|
||||
|
||||
@ -2106,7 +2110,7 @@ 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)
|
||||
fxp_init_body(sc);
|
||||
fxp_init_body(sc, 1);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
@ -2204,7 +2208,7 @@ fxp_watchdog(struct fxp_softc *sc)
|
||||
device_printf(sc->dev, "device timeout\n");
|
||||
sc->ifp->if_oerrors++;
|
||||
|
||||
fxp_init_body(sc);
|
||||
fxp_init_body(sc, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2218,7 +2222,7 @@ fxp_init(void *xsc)
|
||||
struct fxp_softc *sc = xsc;
|
||||
|
||||
FXP_LOCK(sc);
|
||||
fxp_init_body(sc);
|
||||
fxp_init_body(sc, 1);
|
||||
FXP_UNLOCK(sc);
|
||||
}
|
||||
|
||||
@ -2227,9 +2231,10 @@ fxp_init(void *xsc)
|
||||
* softc lock held.
|
||||
*/
|
||||
static void
|
||||
fxp_init_body(struct fxp_softc *sc)
|
||||
fxp_init_body(struct fxp_softc *sc, int setmedia)
|
||||
{
|
||||
struct ifnet *ifp = sc->ifp;
|
||||
struct mii_data *mii;
|
||||
struct fxp_cb_config *cbp;
|
||||
struct fxp_cb_ias *cb_ias;
|
||||
struct fxp_cb_tx *tcbp;
|
||||
@ -2364,7 +2369,7 @@ fxp_init_body(struct fxp_softc *sc)
|
||||
cbp->vlan_strip_en = ((sc->flags & FXP_FLAG_EXT_RFA) != 0 &&
|
||||
(ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) ? 1 : 0;
|
||||
|
||||
if (sc->tunable_noflow || sc->revision == FXP_REV_82557) {
|
||||
if (sc->revision == FXP_REV_82557) {
|
||||
/*
|
||||
* The 82557 has no hardware flow control, the values
|
||||
* below are the defaults for the chip.
|
||||
@ -2378,12 +2383,30 @@ fxp_init_body(struct fxp_softc *sc)
|
||||
cbp->fc_filter = 0;
|
||||
cbp->pri_fc_loc = 1;
|
||||
} else {
|
||||
cbp->fc_delay_lsb = 0x1f;
|
||||
cbp->fc_delay_msb = 0x01;
|
||||
/* Set pause RX FIFO threshold to 1KB. */
|
||||
CSR_WRITE_1(sc, FXP_CSR_FC_THRESH, 1);
|
||||
/* Set pause time. */
|
||||
cbp->fc_delay_lsb = 0xff;
|
||||
cbp->fc_delay_msb = 0xff;
|
||||
cbp->pri_fc_thresh = 3;
|
||||
cbp->tx_fc_dis = 0; /* enable transmit FC */
|
||||
cbp->rx_fc_restop = 1; /* enable FC restop frames */
|
||||
cbp->rx_fc_restart = 1; /* enable FC restart frames */
|
||||
mii = device_get_softc(sc->miibus);
|
||||
if ((IFM_OPTIONS(mii->mii_media_active) &
|
||||
IFM_ETH_TXPAUSE) != 0)
|
||||
/* enable transmit FC */
|
||||
cbp->tx_fc_dis = 0;
|
||||
else
|
||||
/* disable transmit FC */
|
||||
cbp->tx_fc_dis = 1;
|
||||
if ((IFM_OPTIONS(mii->mii_media_active) &
|
||||
IFM_ETH_RXPAUSE) != 0) {
|
||||
/* enable FC restart/restop frames */
|
||||
cbp->rx_fc_restart = 1;
|
||||
cbp->rx_fc_restop = 1;
|
||||
} else {
|
||||
/* disable FC restart/restop frames */
|
||||
cbp->rx_fc_restart = 0;
|
||||
cbp->rx_fc_restop = 0;
|
||||
}
|
||||
cbp->fc_filter = !prm; /* drop FC frames to host */
|
||||
cbp->pri_fc_loc = 1; /* FC pri location (byte31) */
|
||||
}
|
||||
@ -2482,10 +2505,7 @@ fxp_init_body(struct fxp_softc *sc)
|
||||
CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, sc->fxp_desc.rx_head->rx_addr);
|
||||
fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START);
|
||||
|
||||
/*
|
||||
* Set current media.
|
||||
*/
|
||||
if (sc->miibus != NULL)
|
||||
if (sc->miibus != NULL && setmedia != 0)
|
||||
mii_mediachg(device_get_softc(sc->miibus));
|
||||
|
||||
ifp->if_drv_flags |= IFF_DRV_RUNNING;
|
||||
@ -2742,6 +2762,31 @@ fxp_miibus_writereg(device_t dev, int phy, int reg, int value)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
fxp_miibus_statchg(device_t dev)
|
||||
{
|
||||
struct fxp_softc *sc;
|
||||
struct mii_data *mii;
|
||||
struct ifnet *ifp;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
mii = device_get_softc(sc->miibus);
|
||||
ifp = sc->ifp;
|
||||
if (mii == NULL || ifp == NULL ||
|
||||
(ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
|
||||
(mii->mii_media_status & (IFM_AVALID | IFM_ACTIVE)) !=
|
||||
(IFM_AVALID | IFM_ACTIVE))
|
||||
return;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
fxp_init_body(sc, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
{
|
||||
@ -2763,9 +2808,9 @@ fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
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);
|
||||
fxp_init_body(sc, 1);
|
||||
else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
||||
fxp_init_body(sc);
|
||||
fxp_init_body(sc, 1);
|
||||
} else {
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
|
||||
fxp_stop(sc);
|
||||
@ -2867,7 +2912,7 @@ fxp_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
|
||||
reinit++;
|
||||
}
|
||||
if (reinit > 0 && ifp->if_flags & IFF_UP)
|
||||
fxp_init_body(sc);
|
||||
fxp_init_body(sc, 1);
|
||||
FXP_UNLOCK(sc);
|
||||
VLAN_CAPABILITIES(ifp);
|
||||
break;
|
||||
@ -3058,22 +3103,16 @@ fxp_sysctl_node(struct fxp_softc *sc)
|
||||
"FXP driver receive interrupt microcode bundle size limit");
|
||||
SYSCTL_ADD_INT(ctx, child,OID_AUTO, "rnr", CTLFLAG_RD, &sc->rnr, 0,
|
||||
"FXP RNR events");
|
||||
SYSCTL_ADD_INT(ctx, child,
|
||||
OID_AUTO, "noflow", CTLFLAG_RW, &sc->tunable_noflow, 0,
|
||||
"FXP flow control disabled");
|
||||
|
||||
/*
|
||||
* Pull in device tunables.
|
||||
*/
|
||||
sc->tunable_int_delay = TUNABLE_INT_DELAY;
|
||||
sc->tunable_bundle_max = TUNABLE_BUNDLE_MAX;
|
||||
sc->tunable_noflow = 1;
|
||||
(void) resource_int_value(device_get_name(sc->dev),
|
||||
device_get_unit(sc->dev), "int_delay", &sc->tunable_int_delay);
|
||||
(void) resource_int_value(device_get_name(sc->dev),
|
||||
device_get_unit(sc->dev), "bundle_max", &sc->tunable_bundle_max);
|
||||
(void) resource_int_value(device_get_name(sc->dev),
|
||||
device_get_unit(sc->dev), "noflow", &sc->tunable_noflow);
|
||||
sc->rnr = 0;
|
||||
|
||||
hsp = &sc->fxp_hwstats;
|
||||
|
@ -45,7 +45,8 @@
|
||||
#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) */
|
||||
|
||||
|
@ -210,7 +210,6 @@ 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 */
|
||||
|
Loading…
Reference in New Issue
Block a user