rtl8139/rtl81xx: Update with the 11.1 release of re and rl drivers.

* switch compat layer.
* tested on Qemu and RTL8168 rev 10.
This commit is contained in:
Jérôme Duval 2017-11-18 15:40:06 +01:00
parent 76ad0d68c3
commit 7472cf5784
16 changed files with 371 additions and 232 deletions

View File

@ -1,4 +1,3 @@
SubDir HAIKU_TOP src add-ons kernel drivers network rtl8139 ;
HaikuSubInclude dev ;
HaikuSubInclude pci ;

View File

@ -1,3 +1,4 @@
SubDir HAIKU_TOP src add-ons kernel drivers network rtl8139 dev ;
HaikuSubInclude mii ;
HaikuSubInclude rl ;

View File

@ -1,7 +1,7 @@
SubDir HAIKU_TOP src add-ons kernel drivers network rtl8139 dev mii ;
UseHeaders [ FDirName $(SUBDIR) .. .. ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ]
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd11_network compat ]
: true ;
UsePrivateHeaders net system ;
@ -15,5 +15,5 @@ KernelStaticLibrary rtl8139_mii.a :
ObjectHdrs [ FGristFiles rlphy$(SUFOBJ) ]
: [ FDirName $(TARGET_COMMON_DEBUG_OBJECT_DIR_$(TARGET_PACKAGING_ARCH)) libs
compat freebsd_network ] ;
Includes [ FGristFiles rlphy.c ] : <src!libs!compat!freebsd_network>miidevs.h ;
compat freebsd11_network ] ;
Includes [ FGristFiles rlphy.c ] : <src!libs!compat!freebsd11_network>miidevs.h ;

View File

@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/socket.h>
#include <sys/bus.h>
#include <sys/taskqueue.h> /* XXXGL: if_rlreg.h contamination */
#include <net/if.h>
#include <net/if_arp.h>
@ -53,7 +54,7 @@ __FBSDID("$FreeBSD$");
#include "miidevs.h"
#include <machine/bus.h>
#include <pci/if_rlreg.h>
#include <dev/rl/if_rlreg.h>
#include "miibus_if.h"
@ -107,7 +108,6 @@ static const struct mii_phy_funcs rlphy_funcs = {
static int
rlphy_probe(device_t dev)
{
const char *nic;
int rv;
rv = mii_phy_dev_probe(dev, rlphys, BUS_PROBE_DEFAULT);
@ -117,10 +117,9 @@ rlphy_probe(device_t dev)
#else
if (rv <= 0)
return (rv);
#endif
#endif
nic = device_get_name(device_get_parent(device_get_parent(dev)));
if (strcmp(nic, "rl") == 0 || strcmp(nic, "re") == 0)
if (mii_dev_mac_match(dev, "rl") || mii_dev_mac_match(dev, "re"))
return (mii_phy_dev_probe(dev, rlintphys, BUS_PROBE_DEFAULT));
return (ENXIO);
}
@ -146,22 +145,10 @@ rlphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
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:
/*
* Is the interface even up?
*/
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
return (0);
/*
* The RealTek PHY's autonegotiation doesn't need to be
* kicked; it continues in the background.

View File

@ -0,0 +1,16 @@
SubDir HAIKU_TOP src add-ons kernel drivers network rtl8139 dev rl ;
UseHeaders [ FDirName $(SUBDIR) .. .. ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd11_network compat ] : true ;
UsePrivateHeaders net system ;
UsePrivateKernelHeaders ;
SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] ;
KernelAddon rtl8139 :
if_rl.c
glue.c
: rtl8139_mii.a libfreebsd11_network.a
;

View File

@ -5,7 +5,7 @@
#include <machine/bus.h>
#include <pci/if_rlreg.h>
#include <dev/rl/if_rlreg.h>
HAIKU_FBSD_DRIVER_GLUE(rtl8139, rl, pci);
HAIKU_FBSD_MII_DRIVER(rlphy);

View File

@ -99,6 +99,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_arp.h>
#include <net/ethernet.h>
#include <net/if_dl.h>
@ -126,12 +127,12 @@ MODULE_DEPEND(rl, miibus, 1, 1, 1);
/* "device miibus" required. See GENERIC if you get errors here. */
#include "miibus_if.h"
#include <pci/if_rlreg.h>
#include <dev/rl/if_rlreg.h>
/*
* Various supported device vendors/types and their names.
*/
static const struct rl_type const rl_devs[] = {
static const struct rl_type rl_devs[] = {
{ RT_VENDORID, RT_DEVICEID_8129, RL_8129,
"RealTek 8129 10/100BaseTX" },
{ RT_VENDORID, RT_DEVICEID_8139, RL_8139,
@ -148,6 +149,8 @@ static const struct rl_type const rl_devs[] = {
"Delta Electronics 8139 10/100BaseTX" },
{ ADDTRON_VENDORID, ADDTRON_DEVICEID_8139, RL_8139,
"Addtron Technology 8139 10/100BaseTX" },
{ DLINK_VENDORID, DLINK_DEVICEID_520TX_REVC1, RL_8139,
"D-Link DFE-520TX (rev. C1) 10/100BaseTX" },
{ DLINK_VENDORID, DLINK_DEVICEID_530TXPLUS, RL_8139,
"D-Link DFE-530TX+ 10/100BaseTX" },
{ DLINK_VENDORID, DLINK_DEVICEID_690TXD, RL_8139,
@ -595,7 +598,7 @@ rl_probe(device_t dev)
}
}
t = rl_devs;
for (i = 0; i < sizeof(rl_devs) / sizeof(rl_devs[0]); i++, t++) {
for (i = 0; i < nitems(rl_devs); i++, t++) {
if (vendor == t->rl_vid && devid == t->rl_did) {
device_set_desc(dev, t->rl_name);
return (BUS_PROBE_DEFAULT);
@ -1015,17 +1018,16 @@ rl_dma_free(struct rl_softc *sc)
/* Rx memory block. */
if (sc->rl_cdata.rl_rx_tag != NULL) {
if (sc->rl_cdata.rl_rx_dmamap != NULL)
if (sc->rl_cdata.rl_rx_buf_paddr != 0)
bus_dmamap_unload(sc->rl_cdata.rl_rx_tag,
sc->rl_cdata.rl_rx_dmamap);
if (sc->rl_cdata.rl_rx_dmamap != NULL &&
sc->rl_cdata.rl_rx_buf_ptr != NULL)
if (sc->rl_cdata.rl_rx_buf_ptr != NULL)
bus_dmamem_free(sc->rl_cdata.rl_rx_tag,
sc->rl_cdata.rl_rx_buf_ptr,
sc->rl_cdata.rl_rx_dmamap);
sc->rl_cdata.rl_rx_buf_ptr = NULL;
sc->rl_cdata.rl_rx_buf = NULL;
sc->rl_cdata.rl_rx_dmamap = NULL;
sc->rl_cdata.rl_rx_buf_paddr = 0;
bus_dma_tag_destroy(sc->rl_cdata.rl_rx_tag);
sc->rl_cdata.rl_tx_tag = NULL;
}
@ -1164,7 +1166,7 @@ rl_rxeof(struct rl_softc *sc)
if (!(rxstat & RL_RXSTAT_RXOK) ||
total_len < ETHER_MIN_LEN ||
total_len > ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN) {
ifp->if_ierrors++;
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
rl_init_locked(sc);
return (rx_npkts);
@ -1213,11 +1215,11 @@ rl_rxeof(struct rl_softc *sc)
CSR_WRITE_2(sc, RL_CURRXADDR, cur_rx - 16);
if (m == NULL) {
ifp->if_iqdrops++;
if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
continue;
}
ifp->if_ipackets++;
if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
RL_UNLOCK(sc);
(*ifp->if_input)(ifp, m);
RL_LOCK(sc);
@ -1252,7 +1254,7 @@ rl_txeof(struct rl_softc *sc)
RL_TXSTAT_TX_UNDERRUN|RL_TXSTAT_TXABRT)))
break;
ifp->if_collisions += (txstat & RL_TXSTAT_COLLCNT) >> 24;
if_inc_counter(ifp, IFCOUNTER_COLLISIONS, (txstat & RL_TXSTAT_COLLCNT) >> 24);
bus_dmamap_sync(sc->rl_cdata.rl_tx_tag, RL_LAST_DMAMAP(sc),
BUS_DMASYNC_POSTWRITE);
@ -1268,10 +1270,10 @@ rl_txeof(struct rl_softc *sc)
(sc->rl_txthresh < 2016))
sc->rl_txthresh += 32;
if (txstat & RL_TXSTAT_TX_OK)
ifp->if_opackets++;
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
else {
int oldthresh;
ifp->if_oerrors++;
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
if ((txstat & RL_TXSTAT_TXABRT) ||
(txstat & RL_TXSTAT_OUTOFWIN))
CSR_WRITE_4(sc, RL_TXCFG, RL_TXCFG_CONFIG);
@ -1565,7 +1567,7 @@ rl_encap(struct rl_softc *sc, struct mbuf **m_head)
*/
if (m->m_next != NULL || (mtod(m, uintptr_t) & 3) != 0 ||
(padlen > 0 && M_TRAILINGSPACE(m) < padlen)) {
m = m_defrag(*m_head, M_DONTWAIT);
m = m_defrag(*m_head, M_NOWAIT);
if (m == NULL) {
m_freem(*m_head);
*m_head = NULL;
@ -1895,7 +1897,7 @@ rl_watchdog(struct rl_softc *sc)
return;
device_printf(sc->rl_dev, "watchdog timeout\n");
sc->rl_ifp->if_oerrors++;
if_inc_counter(sc->rl_ifp, IFCOUNTER_OERRORS, 1);
rl_txeof(sc);
rl_rxeof(sc);
@ -1936,15 +1938,13 @@ rl_stop(struct rl_softc *sc)
*/
for (i = 0; i < RL_TX_LIST_CNT; i++) {
if (sc->rl_cdata.rl_tx_chain[i] != NULL) {
if (sc->rl_cdata.rl_tx_chain[i] != NULL) {
bus_dmamap_sync(sc->rl_cdata.rl_tx_tag,
sc->rl_cdata.rl_tx_dmamap[i],
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->rl_cdata.rl_tx_tag,
sc->rl_cdata.rl_tx_dmamap[i]);
m_freem(sc->rl_cdata.rl_tx_chain[i]);
sc->rl_cdata.rl_tx_chain[i] = NULL;
}
bus_dmamap_sync(sc->rl_cdata.rl_tx_tag,
sc->rl_cdata.rl_tx_dmamap[i],
BUS_DMASYNC_POSTWRITE);
bus_dmamap_unload(sc->rl_cdata.rl_tx_tag,
sc->rl_cdata.rl_tx_dmamap[i]);
m_freem(sc->rl_cdata.rl_tx_chain[i]);
sc->rl_cdata.rl_tx_chain[i] = NULL;
CSR_WRITE_4(sc, RL_TXADDR0 + (i * sizeof(uint32_t)),
0x0000000);
}

View File

@ -145,6 +145,7 @@
#define RL_PMCH 0x006F /* 8 bits */
#define RL_MAXRXPKTLEN 0x00DA /* 16 bits, chip multiplies by 8 */
#define RL_INTRMOD 0x00E2 /* 16 bits */
#define RL_MISC 0x00F0
/*
* TX config register bits
@ -163,7 +164,6 @@
#define RL_LOOPTEST_ON_CPLUS 0x00060000
/* Known revision codes. */
#define RL_HWREV_8169 0x00000000
#define RL_HWREV_8169S 0x00800000
#define RL_HWREV_8110S 0x04000000
@ -195,6 +195,7 @@
#define RL_HWREV_8168G 0x4C000000
#define RL_HWREV_8168EP 0x50000000
#define RL_HWREV_8168GU 0x50800000
#define RL_HWREV_8168H 0x54000000
#define RL_HWREV_8411B 0x5C800000
#define RL_HWREV_8139 0x60000000
#define RL_HWREV_8139A 0x70000000
@ -287,8 +288,10 @@
#define RL_RXCFG_RX_RUNT 0x00000010
#define RL_RXCFG_RX_ERRPKT 0x00000020
#define RL_RXCFG_WRAP 0x00000080
#define RL_RXCFG_EARLYOFFV2 0x00000800
#define RL_RXCFG_MAXDMA 0x00000700
#define RL_RXCFG_BUFSZ 0x00001800
#define RL_RXCFG_EARLYOFF 0x00003800
#define RL_RXCFG_FIFOTHRESH 0x0000E000
#define RL_RXCFG_EARLYTHRESH 0x07000000
@ -329,8 +332,8 @@
#define RL_RXSTAT_INDIV 0x00004000
#define RL_RXSTAT_MULTI 0x00008000
#define RL_RXSTAT_LENMASK 0xFFFF0000
#define RL_RXSTAT_UNFINISHED 0x0000FFF0 /* DMA still in progress */
#define RL_RXSTAT_UNFINISHED 0xFFF0 /* DMA still in progress */
/*
* Command register.
*/
@ -361,6 +364,7 @@
#define RL_PARA7C 0x7C
#define RL_PARA7C_DEF 0xcb38de43
#define RL_PARA7C_RETUNE 0xfb38de03
/*
* EEPROM control register
*/
@ -473,11 +477,9 @@
*/
/* RL_DUMPSTATS_LO register */
#define RL_DUMPSTATS_START 0x00000008
/* Transmit start register */
#define RL_TXSTART_SWI 0x01 /* generate TX interrupt */
#define RL_TXSTART_START 0x40 /* start normal queue transmit */
#define RL_TXSTART_HPRIO_START 0x80 /* start hi prio queue transmit */
@ -496,7 +498,6 @@
#define RL_BUSWIDTH_64BITS 0x08
/* C+ mode command register */
#define RL_CPLUSCMD_TXENB 0x0001 /* enable C+ transmit mode */
#define RL_CPLUSCMD_RXENB 0x0002 /* enable C+ receive mode */
#define RL_CPLUSCMD_PCI_MRW 0x0008 /* enable PCI multi-read/write */
@ -514,7 +515,6 @@
#define RL_CPLUSCMD_BIST_ENB 0x8000 /* 8168C/CP */
/* C+ early transmit threshold */
#define RL_EARLYTXTHRESH_CNT 0x003F /* byte count times 8 */
/* Timer interrupt register */
@ -528,7 +528,6 @@
/*
* Gigabit PHY access register (8169 only)
*/
#define RL_PHYAR_PHYDATA 0x0000FFFF
#define RL_PHYAR_PHYREG 0x001F0000
#define RL_PHYAR_BUSY 0x80000000
@ -559,7 +558,6 @@
* For reception, there's just one large buffer where the chip stores
* all received packets.
*/
#define RL_RX_BUF_SZ RL_RXBUF_64
#define RL_RXBUFLEN (1 << ((RL_RX_BUF_SZ >> 11) + 13))
#define RL_TX_LIST_CNT 4
@ -642,11 +640,10 @@ struct rl_hwrev {
/*
* RX/TX descriptor definition. When large send mode is enabled, the
* lower 11 bits of the TX rl_cmd word are used to hold the MSS, and
* lower 11 bits of the TX rl_cmdstat word are used to hold the MSS, and
* the checksum offload bits are disabled. The structure layout is
* the same for RX and TX descriptors
*/
struct rl_desc {
uint32_t rl_cmdstat;
uint32_t rl_vlanctl;
@ -679,19 +676,17 @@ struct rl_desc {
* Error bits are valid only on the last descriptor of a frame
* (i.e. RL_TDESC_CMD_EOF == 1)
*/
#define RL_TDESC_STAT_COLCNT 0x000F0000 /* collision count */
#define RL_TDESC_STAT_EXCESSCOL 0x00100000 /* excessive collisions */
#define RL_TDESC_STAT_LINKFAIL 0x00200000 /* link faulure */
#define RL_TDESC_STAT_OWINCOL 0x00400000 /* out-of-window collision */
#define RL_TDESC_STAT_TXERRSUM 0x00800000 /* transmit error summary */
#define RL_TDESC_STAT_UNDERRUN 0x02000000 /* TX underrun occured */
#define RL_TDESC_STAT_UNDERRUN 0x02000000 /* TX underrun occurred */
#define RL_TDESC_STAT_OWN 0x80000000
/*
* RX descriptor cmd/vlan definitions
*/
#define RL_RDESC_CMD_EOR 0x40000000
#define RL_RDESC_CMD_OWN 0x80000000
#define RL_RDESC_CMD_BUFLEN 0x00001FFF
@ -782,7 +777,7 @@ struct rl_stats {
#define RL_TX_DESC_CNT RL_8169_TX_DESC_CNT
#define RL_RX_DESC_CNT RL_8169_RX_DESC_CNT
#define RL_RX_JUMBO_DESC_CNT RL_RX_DESC_CNT
#define RL_NTXSEGS 32
#define RL_NTXSEGS 35
#define RL_RING_ALIGN 256
#define RL_DUMP_ALIGN 64
@ -935,6 +930,8 @@ struct rl_softc {
#define RL_FLAG_WAIT_TXPOLL 0x00004000
#define RL_FLAG_CMDSTOP_WAIT_TXQ 0x00008000
#define RL_FLAG_WOL_MANLINK 0x00010000
#define RL_FLAG_EARLYOFF 0x00020000
#define RL_FLAG_8168G_PLUS 0x00040000
#define RL_FLAG_PCIE 0x40000000
#define RL_FLAG_LINK 0x80000000
};
@ -1161,3 +1158,8 @@ struct rl_softc {
/* US Robotics 997902 device ID */
#define USR_DEVICEID_997902 0x0116
/*
* NCube vendor ID
*/
#define NCUBE_VENDORID 0x10FF

View File

@ -1,16 +0,0 @@
SubDir HAIKU_TOP src add-ons kernel drivers network rtl8139 pci ;
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 ] ;
KernelAddon rtl8139 :
if_rl.c
glue.c
: libfreebsd_network.a rtl8139_mii.a
;

View File

@ -1,7 +1,7 @@
SubDir HAIKU_TOP src add-ons kernel drivers network rtl81xx dev mii ;
UseHeaders [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ]
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd11_network compat ]
: true ;
UsePrivateHeaders net system ;
@ -19,6 +19,6 @@ SEARCH on [ FGristFiles rlphy.c ] = [ FDirName $(HAIKU_TOP) src add-ons kernel
ObjectHdrs [ FGristFiles rgephy$(SUFOBJ) rlphy$(SUFOBJ) ]
: [ FDirName $(TARGET_COMMON_DEBUG_OBJECT_DIR_$(TARGET_PACKAGING_ARCH)) libs
compat freebsd_network ] ;
compat freebsd11_network ] ;
Includes [ FGristFiles rgephy.c rlphy.c ]
: <src!libs!compat!freebsd_network>miidevs.h ;
: <src!libs!compat!freebsd11_network>miidevs.h ;

View File

@ -42,9 +42,11 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/socket.h>
#include <sys/taskqueue.h>
#include <sys/bus.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_arp.h>
#include <net/if_media.h>
@ -57,7 +59,7 @@ __FBSDID("$FreeBSD$");
#include "miibus_if.h"
#include <machine/bus.h>
#include <pci/if_rlreg.h>
#include <dev/rl/if_rlreg.h>
static int rgephy_probe(device_t);
static int rgephy_attach(device_t);
@ -85,8 +87,10 @@ static int rgephy_service(struct mii_softc *, struct mii_data *, int);
static void rgephy_status(struct mii_softc *);
static int rgephy_mii_phy_auto(struct mii_softc *, int);
static void rgephy_reset(struct mii_softc *);
static int rgephy_linkup(struct mii_softc *);
static void rgephy_loop(struct mii_softc *);
static void rgephy_load_dspcode(struct mii_softc *);
static void rgephy_disable_eee(struct mii_softc *);
static const struct mii_phydesc rgephys[] = {
MII_PHY_DESC(REALTEK, RTL8169S),
@ -111,13 +115,11 @@ static int
rgephy_attach(device_t dev)
{
struct mii_softc *sc;
struct mii_attach_args *ma;
u_int flags;
sc = device_get_softc(dev);
ma = device_get_ivars(dev);
flags = 0;
if (strcmp(ma->mii_data->mii_ifp->if_dname, "re") == 0)
if (mii_dev_mac_match(dev, "re"))
flags |= MIIF_PHYPRIV0;
mii_phy_dev_attach(dev, flags, &rgephy_funcs, 0);
@ -147,19 +149,13 @@ static int
rgephy_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
{
struct ifmedia_entry *ife = mii->mii_media.ifm_cur;
int reg, speed, gig, anar;
int speed, gig, anar;
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;
PHY_RESET(sc); /* XXX hardware bug work-around */
anar = PHY_READ(sc, RGEPHY_MII_ANAR);
@ -231,12 +227,6 @@ setit:
break;
case MII_TICK:
/*
* Is the interface even up?
*/
if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
return (0);
/*
* Only used for autonegotiation.
*/
@ -249,20 +239,9 @@ setit:
* Check to see if we have link. If we do, we don't
* need to restart the autonegotiation process.
*/
if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 &&
sc->mii_mpd_rev >= 2) {
/* RTL8211B(L) */
reg = PHY_READ(sc, RGEPHY_MII_SSR);
if (reg & RGEPHY_SSR_LINK) {
sc->mii_ticks = 0;
break;
}
} else {
reg = PHY_READ(sc, RL_GMEDIASTAT);
if (reg & RL_GMEDIASTAT_LINK) {
sc->mii_ticks = 0;
break;
}
if (rgephy_linkup(sc) != 0) {
sc->mii_ticks = 0;
break;
}
/* Announce link loss right after it happens. */
@ -295,6 +274,33 @@ setit:
return (0);
}
static int
rgephy_linkup(struct mii_softc *sc)
{
int linkup;
uint16_t reg;
linkup = 0;
if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 &&
sc->mii_mpd_rev >= RGEPHY_8211B) {
if (sc->mii_mpd_rev == RGEPHY_8211F) {
reg = PHY_READ(sc, RGEPHY_F_MII_SSR);
if (reg & RGEPHY_F_SSR_LINK)
linkup++;
} else {
reg = PHY_READ(sc, RGEPHY_MII_SSR);
if (reg & RGEPHY_SSR_LINK)
linkup++;
}
} else {
reg = PHY_READ(sc, RL_GMEDIASTAT);
if (reg & RL_GMEDIASTAT_LINK)
linkup++;
}
return (linkup);
}
static void
rgephy_status(struct mii_softc *sc)
{
@ -305,18 +311,10 @@ rgephy_status(struct mii_softc *sc)
mii->mii_media_status = IFM_AVALID;
mii->mii_media_active = IFM_ETHER;
if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev >= 2) {
ssr = PHY_READ(sc, RGEPHY_MII_SSR);
if (ssr & RGEPHY_SSR_LINK)
mii->mii_media_status |= IFM_ACTIVE;
} else {
bmsr = PHY_READ(sc, RL_GMEDIASTAT);
if (bmsr & RL_GMEDIASTAT_LINK)
mii->mii_media_status |= IFM_ACTIVE;
}
if (rgephy_linkup(sc) != 0)
mii->mii_media_status |= IFM_ACTIVE;
bmsr = PHY_READ(sc, RGEPHY_MII_BMSR);
bmcr = PHY_READ(sc, RGEPHY_MII_BMCR);
if (bmcr & RGEPHY_BMCR_ISO) {
mii->mii_media_active |= IFM_NONE;
@ -335,26 +333,50 @@ rgephy_status(struct mii_softc *sc)
}
}
if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev >= 2) {
ssr = PHY_READ(sc, RGEPHY_MII_SSR);
switch (ssr & RGEPHY_SSR_SPD_MASK) {
case RGEPHY_SSR_S1000:
mii->mii_media_active |= IFM_1000_T;
break;
case RGEPHY_SSR_S100:
mii->mii_media_active |= IFM_100_TX;
break;
case RGEPHY_SSR_S10:
mii->mii_media_active |= IFM_10_T;
break;
default:
mii->mii_media_active |= IFM_NONE;
break;
if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 &&
sc->mii_mpd_rev >= RGEPHY_8211B) {
if (sc->mii_mpd_rev == RGEPHY_8211F) {
ssr = PHY_READ(sc, RGEPHY_F_MII_SSR);
switch (ssr & RGEPHY_F_SSR_SPD_MASK) {
case RGEPHY_F_SSR_S1000:
mii->mii_media_active |= IFM_1000_T;
break;
case RGEPHY_F_SSR_S100:
mii->mii_media_active |= IFM_100_TX;
break;
case RGEPHY_F_SSR_S10:
mii->mii_media_active |= IFM_10_T;
break;
default:
mii->mii_media_active |= IFM_NONE;
break;
}
if (ssr & RGEPHY_F_SSR_FDX)
mii->mii_media_active |= IFM_FDX;
else
mii->mii_media_active |= IFM_HDX;
} else {
ssr = PHY_READ(sc, RGEPHY_MII_SSR);
switch (ssr & RGEPHY_SSR_SPD_MASK) {
case RGEPHY_SSR_S1000:
mii->mii_media_active |= IFM_1000_T;
break;
case RGEPHY_SSR_S100:
mii->mii_media_active |= IFM_100_TX;
break;
case RGEPHY_SSR_S10:
mii->mii_media_active |= IFM_10_T;
break;
default:
mii->mii_media_active |= IFM_NONE;
break;
}
if (ssr & RGEPHY_SSR_FDX)
mii->mii_media_active |= IFM_FDX;
else
mii->mii_media_active |= IFM_HDX;
}
if (ssr & RGEPHY_SSR_FDX)
mii->mii_media_active |= IFM_FDX;
else
mii->mii_media_active |= IFM_HDX;
} else {
bmsr = PHY_READ(sc, RL_GMEDIASTAT);
if (bmsr & RL_GMEDIASTAT_1000MBPS)
@ -408,7 +430,7 @@ rgephy_loop(struct mii_softc *sc)
int i;
if (sc->mii_mpd_model != MII_MODEL_REALTEK_RTL8251 &&
sc->mii_mpd_rev < 2) {
sc->mii_mpd_rev < RGEPHY_8211B) {
PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_PDOWN);
DELAY(1000);
}
@ -442,7 +464,7 @@ rgephy_load_dspcode(struct mii_softc *sc)
int val;
if (sc->mii_mpd_model == MII_MODEL_REALTEK_RTL8251 ||
sc->mii_mpd_rev >= 2)
sc->mii_mpd_rev >= RGEPHY_8211B)
return;
PHY_WRITE(sc, 31, 0x0001);
@ -493,25 +515,62 @@ rgephy_reset(struct mii_softc *sc)
{
uint16_t pcr, ssr;
if ((sc->mii_flags & MIIF_PHYPRIV0) == 0 && sc->mii_mpd_rev == 3) {
/* RTL8211C(L) */
ssr = PHY_READ(sc, RGEPHY_MII_SSR);
if ((ssr & RGEPHY_SSR_ALDPS) != 0) {
ssr &= ~RGEPHY_SSR_ALDPS;
PHY_WRITE(sc, RGEPHY_MII_SSR, ssr);
switch (sc->mii_mpd_rev) {
case RGEPHY_8211F:
pcr = PHY_READ(sc, RGEPHY_F_MII_PCR1);
pcr &= ~(RGEPHY_F_PCR1_MDI_MM | RGEPHY_F_PCR1_ALDPS_EN);
PHY_WRITE(sc, RGEPHY_F_MII_PCR1, pcr);
rgephy_disable_eee(sc);
break;
case RGEPHY_8211C:
if ((sc->mii_flags & MIIF_PHYPRIV0) == 0) {
/* RTL8211C(L) */
ssr = PHY_READ(sc, RGEPHY_MII_SSR);
if ((ssr & RGEPHY_SSR_ALDPS) != 0) {
ssr &= ~RGEPHY_SSR_ALDPS;
PHY_WRITE(sc, RGEPHY_MII_SSR, ssr);
}
}
}
if (sc->mii_mpd_rev >= 2) {
pcr = PHY_READ(sc, RGEPHY_MII_PCR);
if ((pcr & RGEPHY_PCR_MDIX_AUTO) == 0) {
pcr &= ~RGEPHY_PCR_MDI_MASK;
pcr |= RGEPHY_PCR_MDIX_AUTO;
PHY_WRITE(sc, RGEPHY_MII_PCR, pcr);
/* FALLTHROUGH */
default:
if (sc->mii_mpd_rev >= RGEPHY_8211B) {
pcr = PHY_READ(sc, RGEPHY_MII_PCR);
if ((pcr & RGEPHY_PCR_MDIX_AUTO) == 0) {
pcr &= ~RGEPHY_PCR_MDI_MASK;
pcr |= RGEPHY_PCR_MDIX_AUTO;
PHY_WRITE(sc, RGEPHY_MII_PCR, pcr);
}
}
break;
}
mii_phy_reset(sc);
DELAY(1000);
rgephy_load_dspcode(sc);
}
static void
rgephy_disable_eee(struct mii_softc *sc)
{
uint16_t anar;
PHY_WRITE(sc, RGEPHY_F_EPAGSR, 0x0000);
PHY_WRITE(sc, MII_MMDACR, MMDACR_FN_ADDRESS |
(MMDACR_DADDRMASK & RGEPHY_F_MMD_DEV_7));
PHY_WRITE(sc, MII_MMDAADR, RGEPHY_F_MMD_EEEAR);
PHY_WRITE(sc, MII_MMDACR, MMDACR_FN_DATANPI |
(MMDACR_DADDRMASK & RGEPHY_F_MMD_DEV_7));
PHY_WRITE(sc, MII_MMDAADR, 0x0000);
PHY_WRITE(sc, MII_MMDACR, 0x0000);
/*
* XXX
* Restart auto-negotiation to take changes effect.
* This may result in link establishment.
*/
anar = BMSR_MEDIA_TO_ANAR(sc->mii_capabilities) | ANAR_CSMA;
PHY_WRITE(sc, RGEPHY_MII_ANAR, anar);
PHY_WRITE(sc, RGEPHY_MII_1000CTL, RGEPHY_1000CTL_AHD |
RGEPHY_1000CTL_AFD);
PHY_WRITE(sc, RGEPHY_MII_BMCR, RGEPHY_BMCR_RESET |
RGEPHY_BMCR_AUTOEN | RGEPHY_BMCR_STARTNEG);
}

View File

@ -35,6 +35,10 @@
#ifndef _DEV_MII_RGEPHYREG_H_
#define _DEV_MII_RGEPHYREG_H_
#define RGEPHY_8211B 2
#define RGEPHY_8211C 3
#define RGEPHY_8211F 6
/*
* RealTek 8169S/8110S gigE PHY registers
*/
@ -162,4 +166,37 @@
#define RGEPHY_SSR_ALDPS 0x0008 /* RTL8211C(L) only */
#define RGEPHY_SSR_JABBER 0x0001 /* Jabber */
/* RTL8211F */
#define RGEPHY_F_MII_PCR1 0x18 /* PHY Specific control register 1 */
#define RGEPHY_F_PCR1_MDI_MM 0x0200 /* MDI / MDIX Manual Mode */
#define RGEPHY_F_PCR1_MDI_MODE 0x0100 /* MDI Mode (0=MDIX,1=MDI) */
#define RGEPHY_F_PCR1_ALDPS_EN 0x0004 /* Link Down Power Saving Enable */
/* RTL8211F */
#define RGEPHY_F_MII_SSR 0x1A /* PHY Specific status register */
#define RGEPHY_F_SSR_S1000 0x0020 /* 1000Mbps */
#define RGEPHY_F_SSR_S100 0x0010 /* 100Mbps */
#define RGEPHY_F_SSR_S10 0x0000 /* 10Mbps */
#define RGEPHY_F_SSR_SPD_MASK 0x0030
#define RGEPHY_F_SSR_FDX 0x0008 /* full duplex */
#define RGEPHY_F_SSR_LINK 0x0004 /* link up */
#define RGEPHY_F_SSR_MDI 0x0002 /* MDI/MDIX */
#define RGEPHY_F_SSR_JABBER 0x0001 /* Jabber */
/* RTL8211F */
#define RGEPHY_F_EPAGSR 0x1F /* Extension page select register */
/* RTL8211F */
#define RGEPHY_F_MMD_DEV_7 0x07
/* RTL8211F MMD device 7 */
#define RGEPHY_F_MMD_EEEAR 0x3C /* EEE advertisement */
#define EEEAR_1000T 0x0004 /* adv. 1000baseT EEE */
#define EEEAR_100TX 0x0002 /* adv. 100baseTX EEE */
/* RTL8211F MMD device 7 */
#define RGEPHY_F_MMD_EEELPAR 0x3D /* EEE link partner abilities */
#define EEELPAR_1000T 0x0004 /* link partner 1000baseT EEE capable */
#define EEELPAR_100TX 0x0002 /* link partner 100baseTX EEE capable */
#endif /* _DEV_RGEPHY_MIIREG_H_ */

View File

@ -1,7 +1,7 @@
SubDir HAIKU_TOP src add-ons kernel drivers network rtl81xx dev re ;
UseHeaders [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ] : true ;
UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd11_network compat ] : true ;
UsePrivateHeaders net system ;
UsePrivateKernelHeaders ;
@ -11,5 +11,5 @@ SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] ;
KernelAddon rtl81xx :
if_re.c
glue.c
: libfreebsd_network.a rtl81xx_mii.a
: rtl81xx_mii.a libfreebsd11_network.a
;

View File

@ -11,7 +11,7 @@
#include <machine/bus.h>
#include <pci/if_rlreg.h>
#include <dev/rl/if_rlreg.h>
extern driver_t *DRIVER_MODULE_NAME(rgephy, miibus);

View File

@ -127,6 +127,7 @@ __FBSDID("$FreeBSD$");
#include <sys/taskqueue.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_arp.h>
#include <net/ethernet.h>
#include <net/if_dl.h>
@ -147,7 +148,7 @@ __FBSDID("$FreeBSD$");
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <pci/if_rlreg.h>
#include <dev/rl/if_rlreg.h>
MODULE_DEPEND(re, pci, 1, 1, 1);
MODULE_DEPEND(re, ether, 1, 1, 1);
@ -182,6 +183,8 @@ static const struct rl_type re_devs[] = {
"RealTek 810xE PCIe 10/100baseTX" },
{ RT_VENDORID, RT_DEVICEID_8168, 0,
"RealTek 8168/8111 B/C/CP/D/DP/E/F/G PCIe Gigabit Ethernet" },
{ NCUBE_VENDORID, RT_DEVICEID_8168, 0,
"TP-Link TG-3468 v2 (RTL8168) Gigabit Ethernet" },
{ RT_VENDORID, RT_DEVICEID_8169, 0,
"RealTek 8169/8169S/8169SB(L)/8110S/8110SB(L) Gigabit Ethernet" },
{ RT_VENDORID, RT_DEVICEID_8169SC, 0,
@ -237,6 +240,7 @@ static const struct rl_hwrev re_hwrevs[] = {
{ RL_HWREV_8168F, RL_8169, "8168F/8111F", RL_JUMBO_MTU_9K},
{ RL_HWREV_8168G, RL_8169, "8168G/8111G", RL_JUMBO_MTU_9K},
{ RL_HWREV_8168GU, RL_8169, "8168GU/8111GU", RL_JUMBO_MTU_9K},
{ RL_HWREV_8168H, RL_8169, "8168H/8111H", RL_JUMBO_MTU_9K},
{ RL_HWREV_8411, RL_8169, "8411", RL_JUMBO_MTU_9K},
{ RL_HWREV_8411B, RL_8169, "8411B", RL_JUMBO_MTU_9K},
{ 0, 0, NULL, 0 }
@ -303,6 +307,7 @@ static void re_set_linkspeed (struct rl_softc *);
#ifdef DEV_NETMAP /* see ixgbe.c for details */
#include <dev/netmap/if_re_netmap.h>
MODULE_DEPEND(re, netmap, 1, 1, 1);
#endif /* !DEV_NETMAP */
#ifdef RE_DIAG
@ -633,9 +638,8 @@ re_miibus_statchg(device_t dev)
}
}
/*
* RealTek controllers does not provide any interface to
* Tx/Rx MACs for resolved speed, duplex and flow-control
* parameters.
* RealTek controllers do not provide any interface to the RX/TX
* MACs for resolved speed, duplex and flow-control parameters.
*/
}
@ -655,6 +659,10 @@ re_set_rxmode(struct rl_softc *sc)
ifp = sc->rl_ifp;
rxfilt = RL_RXCFG_CONFIG | RL_RXCFG_RX_INDIV | RL_RXCFG_RX_BROAD;
if ((sc->rl_flags & RL_FLAG_EARLYOFF) != 0)
rxfilt |= RL_RXCFG_EARLYOFF;
else if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0)
rxfilt |= RL_RXCFG_EARLYOFFV2;
if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) {
if (ifp->if_flags & IFF_PROMISC)
@ -698,6 +706,12 @@ re_set_rxmode(struct rl_softc *sc)
rxfilt |= RL_RXCFG_RX_MULTI;
}
if (sc->rl_hwrev->rl_rev == RL_HWREV_8168F) {
/* Disable multicast filtering due to silicon bug. */
hashes[0] = 0xffffffff;
hashes[1] = 0xffffffff;
}
done:
CSR_WRITE_4(sc, RL_MAR0, hashes[0]);
CSR_WRITE_4(sc, RL_MAR4, hashes[1]);
@ -941,7 +955,7 @@ re_probe(device_t dev)
}
t = re_devs;
for (i = 0; i < sizeof(re_devs) / sizeof(re_devs[0]); i++, t++) {
for (i = 0; i < nitems(re_devs); i++, t++) {
if (vendor == t->rl_vid && devid == t->rl_did) {
device_set_desc(dev, t->rl_name);
return (BUS_PROBE_DEFAULT);
@ -1194,11 +1208,10 @@ re_attach(device_t dev)
struct rl_softc *sc;
struct ifnet *ifp;
const struct rl_hwrev *hw_rev;
int capmask, error = 0, hwrev, i, msic, msixc,
phy, reg, rid;
u_int32_t cap, ctl;
int hwrev;
u_int16_t devid, re_did = 0;
int error = 0, i, phy, rid;
int msic, msixc, reg;
uint8_t cfg;
sc = device_get_softc(dev);
@ -1264,7 +1277,7 @@ re_attach(device_t dev)
msic = 0;
/* Prefer MSI-X to MSI. */
if (msixc > 0) {
msixc = 1;
msixc = RL_MSI_MESSAGES;
rid = PCIR_BAR(4);
sc->rl_res_pba = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
&rid, RF_ACTIVE);
@ -1274,7 +1287,7 @@ re_attach(device_t dev)
}
if (sc->rl_res_pba != NULL &&
pci_alloc_msix(dev, &msixc) == 0) {
if (msixc == 1) {
if (msixc == RL_MSI_MESSAGES) {
device_printf(dev, "Using %d MSI-X message\n",
msixc);
sc->rl_flags |= RL_FLAG_MSIX;
@ -1291,7 +1304,7 @@ re_attach(device_t dev)
}
/* Prefer MSI to INTx. */
if (msixc == 0 && msic > 0) {
msic = 1;
msic = RL_MSI_MESSAGES;
if (pci_alloc_msi(dev, &msic) == 0) {
if (msic == RL_MSI_MESSAGES) {
device_printf(dev, "Using %d MSI message\n",
@ -1462,26 +1475,36 @@ re_attach(device_t dev)
RL_FLAG_WOL_MANLINK;
break;
case RL_HWREV_8168E_VL:
case RL_HWREV_8168EP:
case RL_HWREV_8168F:
case RL_HWREV_8168G:
sc->rl_flags |= RL_FLAG_EARLYOFF;
/* FALLTHROUGH */
case RL_HWREV_8411:
case RL_HWREV_8411B:
sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR |
RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP |
RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2 |
RL_FLAG_CMDSTOP_WAIT_TXQ | RL_FLAG_WOL_MANLINK;
break;
case RL_HWREV_8168EP:
case RL_HWREV_8168G:
case RL_HWREV_8411B:
sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR |
RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP |
RL_FLAG_AUTOPAD | RL_FLAG_JUMBOV2 |
RL_FLAG_CMDSTOP_WAIT_TXQ | RL_FLAG_WOL_MANLINK |
RL_FLAG_8168G_PLUS;
break;
case RL_HWREV_8168GU:
case RL_HWREV_8168H:
if (pci_get_device(dev) == RT_DEVICEID_8101E) {
/* RTL8106EUS */
/* RTL8106E(US), RTL8107E */
sc->rl_flags |= RL_FLAG_FASTETHER;
} else
sc->rl_flags |= RL_FLAG_JUMBOV2 | RL_FLAG_WOL_MANLINK;
sc->rl_flags |= RL_FLAG_PHYWAKE | RL_FLAG_PAR |
RL_FLAG_DESCV2 | RL_FLAG_MACSTAT | RL_FLAG_CMDSTOP |
RL_FLAG_AUTOPAD | RL_FLAG_CMDSTOP_WAIT_TXQ;
RL_FLAG_AUTOPAD | RL_FLAG_CMDSTOP_WAIT_TXQ |
RL_FLAG_8168G_PLUS;
break;
case RL_HWREV_8169_8110SB:
case RL_HWREV_8169_8110SBL:
@ -1605,16 +1628,18 @@ re_attach(device_t dev)
ifp->if_start = re_start;
/*
* RTL8168/8111C generates wrong IP checksummed frame if the
* packet has IP options so disable TX IP checksum offloading.
* packet has IP options so disable TX checksum offloading.
*/
if (sc->rl_hwrev->rl_rev == RL_HWREV_8168C ||
sc->rl_hwrev->rl_rev == RL_HWREV_8168C_SPIN2 ||
sc->rl_hwrev->rl_rev == RL_HWREV_8168CP)
ifp->if_hwassist = CSUM_TCP | CSUM_UDP;
else
sc->rl_hwrev->rl_rev == RL_HWREV_8168CP) {
ifp->if_hwassist = 0;
ifp->if_capabilities = IFCAP_RXCSUM | IFCAP_TSO4;
} else {
ifp->if_hwassist = CSUM_IP | CSUM_TCP | CSUM_UDP;
ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_TSO4;
}
ifp->if_hwassist |= CSUM_TSO;
ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_TSO4;
ifp->if_capenable = ifp->if_capabilities;
ifp->if_init = re_init;
IFQ_SET_MAXLEN(&ifp->if_snd, RL_IFQ_MAXLEN);
@ -1629,8 +1654,11 @@ re_attach(device_t dev)
phy = RE_PHYAD_INTERNAL;
if (sc->rl_type == RL_8169)
phy = 1;
capmask = BMSR_DEFCAPMASK;
if ((sc->rl_flags & RL_FLAG_FASTETHER) != 0)
capmask &= ~BMSR_EXTSTAT;
error = mii_attach(dev, &sc->rl_miibus, ifp, re_ifmedia_upd,
re_ifmedia_sts, BMSR_DEFCAPMASK, phy, MII_OFFSET_ANY, MIIF_DOPAUSE);
re_ifmedia_sts, capmask, phy, MII_OFFSET_ANY, MIIF_DOPAUSE);
if (error != 0) {
device_printf(dev, "attaching PHYs failed\n");
goto fail;
@ -1665,18 +1693,18 @@ re_attach(device_t dev)
* Must appear after the call to ether_ifattach() because
* ether_ifattach() sets ifi_hdrlen to the default value.
*/
ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
ifp->if_hdrlen = sizeof(struct ether_vlan_header);
#ifdef DEV_NETMAP
re_netmap_attach(sc);
#endif /* DEV_NETMAP */
#ifdef RE_DIAG
/*
* Perform hardware diagnostic on the original RTL8169.
* Some 32-bit cards were incorrectly wired and would
* malfunction if plugged into a 64-bit slot.
*/
if (hwrev == RL_HWREV_8169) {
error = re_diag(sc);
if (error) {
@ -1708,7 +1736,6 @@ re_attach(device_t dev)
}
fail:
if (error)
re_detach(dev);
@ -1802,10 +1829,10 @@ re_detach(device_t dev)
/* Unload and free the RX DMA ring memory and map */
if (sc->rl_ldata.rl_rx_list_tag) {
if (sc->rl_ldata.rl_rx_list_map)
if (sc->rl_ldata.rl_rx_list_addr)
bus_dmamap_unload(sc->rl_ldata.rl_rx_list_tag,
sc->rl_ldata.rl_rx_list_map);
if (sc->rl_ldata.rl_rx_list_map && sc->rl_ldata.rl_rx_list)
if (sc->rl_ldata.rl_rx_list)
bus_dmamem_free(sc->rl_ldata.rl_rx_list_tag,
sc->rl_ldata.rl_rx_list,
sc->rl_ldata.rl_rx_list_map);
@ -1815,10 +1842,10 @@ re_detach(device_t dev)
/* Unload and free the TX DMA ring memory and map */
if (sc->rl_ldata.rl_tx_list_tag) {
if (sc->rl_ldata.rl_tx_list_map)
if (sc->rl_ldata.rl_tx_list_addr)
bus_dmamap_unload(sc->rl_ldata.rl_tx_list_tag,
sc->rl_ldata.rl_tx_list_map);
if (sc->rl_ldata.rl_tx_list_map && sc->rl_ldata.rl_tx_list)
if (sc->rl_ldata.rl_tx_list)
bus_dmamem_free(sc->rl_ldata.rl_tx_list_tag,
sc->rl_ldata.rl_tx_list,
sc->rl_ldata.rl_tx_list_map);
@ -1860,10 +1887,10 @@ re_detach(device_t dev)
/* Unload and free the stats buffer and map */
if (sc->rl_ldata.rl_stag) {
if (sc->rl_ldata.rl_smap)
if (sc->rl_ldata.rl_stats_addr)
bus_dmamap_unload(sc->rl_ldata.rl_stag,
sc->rl_ldata.rl_smap);
if (sc->rl_ldata.rl_smap && sc->rl_ldata.rl_stats)
if (sc->rl_ldata.rl_stats)
bus_dmamem_free(sc->rl_ldata.rl_stag,
sc->rl_ldata.rl_stats, sc->rl_ldata.rl_smap);
bus_dma_tag_destroy(sc->rl_ldata.rl_stag);
@ -2133,8 +2160,7 @@ re_rxeof(struct rl_softc *sc, int *rx_npktsp)
ifp = sc->rl_ifp;
#ifdef DEV_NETMAP
if (netmap_rx_irq(ifp, 0 | (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT),
&rx_npkts))
if (netmap_rx_irq(ifp, 0, &rx_npkts))
return 0;
#endif /* DEV_NETMAP */
if (ifp->if_mtu > RL_MTU && (sc->rl_flags & RL_FLAG_JUMBOV2) != 0)
@ -2226,7 +2252,7 @@ re_rxeof(struct rl_softc *sc, int *rx_npktsp)
(rxstat & RL_RDESC_STAT_ERRS) == RL_RDESC_STAT_GIANT)
rxerr = 0;
if (rxerr != 0) {
ifp->if_ierrors++;
if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
/*
* If this is part of a multi-fragment packet,
* discard all the pieces.
@ -2249,7 +2275,7 @@ re_rxeof(struct rl_softc *sc, int *rx_npktsp)
else
rxerr = re_newbuf(sc, i);
if (rxerr != 0) {
ifp->if_iqdrops++;
if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
if (sc->rl_head != NULL) {
m_freem(sc->rl_head);
sc->rl_head = sc->rl_tail = NULL;
@ -2291,7 +2317,7 @@ re_rxeof(struct rl_softc *sc, int *rx_npktsp)
#ifdef RE_FIXUP_RX
re_fixup_rx(m);
#endif
ifp->if_ipackets++;
if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
m->m_pkthdr.rcvif = ifp;
/* Do RX checksumming if enabled */
@ -2379,7 +2405,7 @@ re_txeof(struct rl_softc *sc)
ifp = sc->rl_ifp;
#ifdef DEV_NETMAP
if (netmap_tx_irq(ifp, 0 | (NETMAP_LOCKED_ENTER|NETMAP_LOCKED_EXIT)))
if (netmap_tx_irq(ifp, 0))
return;
#endif /* DEV_NETMAP */
/* Invalidate the TX descriptor list */
@ -2410,11 +2436,11 @@ re_txeof(struct rl_softc *sc)
txd->tx_m = NULL;
if (txstat & (RL_TDESC_STAT_EXCESSCOL|
RL_TDESC_STAT_COLCNT))
ifp->if_collisions++;
if_inc_counter(ifp, IFCOUNTER_COLLISIONS, 1);
if (txstat & RL_TDESC_STAT_TXERRSUM)
ifp->if_oerrors++;
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
else
ifp->if_opackets++;
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
}
sc->rl_ldata.rl_tx_free++;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
@ -2529,7 +2555,7 @@ re_intr(void *arg)
return (FILTER_STRAY);
CSR_WRITE_2(sc, RL_IMR, 0);
taskqueue_enqueue_fast(taskqueue_fast, &sc->rl_inttask);
taskqueue_enqueue(taskqueue_fast, &sc->rl_inttask);
return (FILTER_HANDLED);
}
@ -2597,7 +2623,7 @@ re_int_task(void *arg, int npending)
RL_UNLOCK(sc);
if ((CSR_READ_2(sc, RL_ISR) & RL_INTRS_CPLUS) || rval) {
taskqueue_enqueue_fast(taskqueue_fast, &sc->rl_inttask);
taskqueue_enqueue(taskqueue_fast, &sc->rl_inttask);
return;
}
@ -2915,6 +2941,7 @@ re_start_locked(struct ifnet *ifp)
return;
}
#endif /* DEV_NETMAP */
if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
IFF_DRV_RUNNING || (sc->rl_flags & RL_FLAG_LINK) == 0)
return;
@ -3170,10 +3197,18 @@ re_init_locked(struct rl_softc *sc)
CSR_WRITE_4(sc, RL_TXLIST_ADDR_LO,
RL_ADDR_LO(sc->rl_ldata.rl_tx_list_addr));
if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0) {
/* Disable RXDV gate. */
CSR_WRITE_4(sc, RL_MISC, CSR_READ_4(sc, RL_MISC) &
~0x00080000);
}
/*
* Enable transmit and receive.
* Enable transmit and receive for pre-RTL8168G controllers.
* RX/TX MACs should be enabled before RX/TX configuration.
*/
CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB);
if ((sc->rl_flags & RL_FLAG_8168G_PLUS) == 0)
CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB | RL_CMD_RX_ENB);
/*
* Set the initial TX configuration.
@ -3201,6 +3236,13 @@ re_init_locked(struct rl_softc *sc)
CSR_WRITE_2(sc, RL_INTRMOD, 0x5100);
}
/*
* Enable transmit and receive for RTL8168G and later controllers.
* RX/TX MACs should be enabled after RX/TX configuration.
*/
if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0)
CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB | RL_CMD_RX_ENB);
#ifdef DEVICE_POLLING
/*
* Disable interrupts if we are polling.
@ -3224,10 +3266,6 @@ re_init_locked(struct rl_softc *sc)
/* Start RX/TX process. */
CSR_WRITE_4(sc, RL_MISSEDPKT, 0);
#ifdef notdef
/* Enable receiver and transmitter. */
CSR_WRITE_1(sc, RL_COMMAND, RL_CMD_TX_ENB|RL_CMD_RX_ENB);
#endif
/*
* Initialize the timer interrupt register so that
@ -3347,7 +3385,6 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
struct rl_softc *sc = ifp->if_softc;
struct ifreq *ifr = (struct ifreq *) data;
struct mii_data *mii;
uint32_t rev;
int error = 0;
switch (command) {
@ -3436,15 +3473,9 @@ re_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
if ((mask & IFCAP_TXCSUM) != 0 &&
(ifp->if_capabilities & IFCAP_TXCSUM) != 0) {
ifp->if_capenable ^= IFCAP_TXCSUM;
if ((ifp->if_capenable & IFCAP_TXCSUM) != 0) {
rev = sc->rl_hwrev->rl_rev;
if (rev == RL_HWREV_8168C ||
rev == RL_HWREV_8168C_SPIN2 ||
rev == RL_HWREV_8168CP)
ifp->if_hwassist |= CSUM_TCP | CSUM_UDP;
else
ifp->if_hwassist |= RE_CSUM_FEATURES;
} else
if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
ifp->if_hwassist |= RE_CSUM_FEATURES;
else
ifp->if_hwassist &= ~RE_CSUM_FEATURES;
reinit = 1;
}
@ -3527,7 +3558,7 @@ re_watchdog(struct rl_softc *sc)
}
if_printf(ifp, "watchdog timeout\n");
ifp->if_oerrors++;
if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
re_rxeof(sc, NULL);
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
@ -3566,6 +3597,12 @@ re_stop(struct rl_softc *sc)
~(RL_RXCFG_RX_ALLPHYS | RL_RXCFG_RX_INDIV | RL_RXCFG_RX_MULTI |
RL_RXCFG_RX_BROAD));
if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0) {
/* Enable RXDV gate. */
CSR_WRITE_4(sc, RL_MISC, CSR_READ_4(sc, RL_MISC) |
0x00080000);
}
if ((sc->rl_flags & RL_FLAG_WAIT_TXPOLL) != 0) {
for (i = RL_TIMEOUT; i > 0; i--) {
if ((CSR_READ_1(sc, sc->rl_txstart) &
@ -3817,6 +3854,11 @@ re_setwol(struct rl_softc *sc)
CSR_READ_1(sc, RL_GPIO) & ~0x01);
}
if ((ifp->if_capenable & IFCAP_WOL) != 0) {
if ((sc->rl_flags & RL_FLAG_8168G_PLUS) != 0) {
/* Disable RXDV gate. */
CSR_WRITE_4(sc, RL_MISC, CSR_READ_4(sc, RL_MISC) &
~0x00080000);
}
re_set_rxmode(sc);
if ((sc->rl_flags & RL_FLAG_WOL_MANLINK) != 0)
re_set_linkspeed(sc);
@ -3929,7 +3971,6 @@ re_add_sysctls(struct rl_softc *sc)
sc->rl_int_rx_mod = RL_TIMER_DEFAULT;
}
}
}
static int

View File

@ -145,6 +145,7 @@
#define RL_PMCH 0x006F /* 8 bits */
#define RL_MAXRXPKTLEN 0x00DA /* 16 bits, chip multiplies by 8 */
#define RL_INTRMOD 0x00E2 /* 16 bits */
#define RL_MISC 0x00F0
/*
* TX config register bits
@ -163,7 +164,6 @@
#define RL_LOOPTEST_ON_CPLUS 0x00060000
/* Known revision codes. */
#define RL_HWREV_8169 0x00000000
#define RL_HWREV_8169S 0x00800000
#define RL_HWREV_8110S 0x04000000
@ -189,8 +189,14 @@
#define RL_HWREV_8105E 0x40800000
#define RL_HWREV_8105E_SPIN1 0x40C00000
#define RL_HWREV_8402 0x44000000
#define RL_HWREV_8106E 0x44800000
#define RL_HWREV_8168F 0x48000000
#define RL_HWREV_8411 0x48800000
#define RL_HWREV_8168G 0x4C000000
#define RL_HWREV_8168EP 0x50000000
#define RL_HWREV_8168GU 0x50800000
#define RL_HWREV_8168H 0x54000000
#define RL_HWREV_8411B 0x5C800000
#define RL_HWREV_8139 0x60000000
#define RL_HWREV_8139A 0x70000000
#define RL_HWREV_8139AG 0x70800000
@ -282,8 +288,10 @@
#define RL_RXCFG_RX_RUNT 0x00000010
#define RL_RXCFG_RX_ERRPKT 0x00000020
#define RL_RXCFG_WRAP 0x00000080
#define RL_RXCFG_EARLYOFFV2 0x00000800
#define RL_RXCFG_MAXDMA 0x00000700
#define RL_RXCFG_BUFSZ 0x00001800
#define RL_RXCFG_EARLYOFF 0x00003800
#define RL_RXCFG_FIFOTHRESH 0x0000E000
#define RL_RXCFG_EARLYTHRESH 0x07000000
@ -324,8 +332,8 @@
#define RL_RXSTAT_INDIV 0x00004000
#define RL_RXSTAT_MULTI 0x00008000
#define RL_RXSTAT_LENMASK 0xFFFF0000
#define RL_RXSTAT_UNFINISHED 0x0000FFF0 /* DMA still in progress */
#define RL_RXSTAT_UNFINISHED 0xFFF0 /* DMA still in progress */
/*
* Command register.
*/
@ -356,6 +364,7 @@
#define RL_PARA7C 0x7C
#define RL_PARA7C_DEF 0xcb38de43
#define RL_PARA7C_RETUNE 0xfb38de03
/*
* EEPROM control register
*/
@ -468,11 +477,9 @@
*/
/* RL_DUMPSTATS_LO register */
#define RL_DUMPSTATS_START 0x00000008
/* Transmit start register */
#define RL_TXSTART_SWI 0x01 /* generate TX interrupt */
#define RL_TXSTART_START 0x40 /* start normal queue transmit */
#define RL_TXSTART_HPRIO_START 0x80 /* start hi prio queue transmit */
@ -491,7 +498,6 @@
#define RL_BUSWIDTH_64BITS 0x08
/* C+ mode command register */
#define RL_CPLUSCMD_TXENB 0x0001 /* enable C+ transmit mode */
#define RL_CPLUSCMD_RXENB 0x0002 /* enable C+ receive mode */
#define RL_CPLUSCMD_PCI_MRW 0x0008 /* enable PCI multi-read/write */
@ -509,7 +515,6 @@
#define RL_CPLUSCMD_BIST_ENB 0x8000 /* 8168C/CP */
/* C+ early transmit threshold */
#define RL_EARLYTXTHRESH_CNT 0x003F /* byte count times 8 */
/* Timer interrupt register */
@ -523,7 +528,6 @@
/*
* Gigabit PHY access register (8169 only)
*/
#define RL_PHYAR_PHYDATA 0x0000FFFF
#define RL_PHYAR_PHYREG 0x001F0000
#define RL_PHYAR_BUSY 0x80000000
@ -554,7 +558,6 @@
* For reception, there's just one large buffer where the chip stores
* all received packets.
*/
#define RL_RX_BUF_SZ RL_RXBUF_64
#define RL_RXBUFLEN (1 << ((RL_RX_BUF_SZ >> 11) + 13))
#define RL_TX_LIST_CNT 4
@ -637,11 +640,10 @@ struct rl_hwrev {
/*
* RX/TX descriptor definition. When large send mode is enabled, the
* lower 11 bits of the TX rl_cmd word are used to hold the MSS, and
* lower 11 bits of the TX rl_cmdstat word are used to hold the MSS, and
* the checksum offload bits are disabled. The structure layout is
* the same for RX and TX descriptors
*/
struct rl_desc {
uint32_t rl_cmdstat;
uint32_t rl_vlanctl;
@ -674,19 +676,17 @@ struct rl_desc {
* Error bits are valid only on the last descriptor of a frame
* (i.e. RL_TDESC_CMD_EOF == 1)
*/
#define RL_TDESC_STAT_COLCNT 0x000F0000 /* collision count */
#define RL_TDESC_STAT_EXCESSCOL 0x00100000 /* excessive collisions */
#define RL_TDESC_STAT_LINKFAIL 0x00200000 /* link faulure */
#define RL_TDESC_STAT_OWINCOL 0x00400000 /* out-of-window collision */
#define RL_TDESC_STAT_TXERRSUM 0x00800000 /* transmit error summary */
#define RL_TDESC_STAT_UNDERRUN 0x02000000 /* TX underrun occured */
#define RL_TDESC_STAT_UNDERRUN 0x02000000 /* TX underrun occurred */
#define RL_TDESC_STAT_OWN 0x80000000
/*
* RX descriptor cmd/vlan definitions
*/
#define RL_RDESC_CMD_EOR 0x40000000
#define RL_RDESC_CMD_OWN 0x80000000
#define RL_RDESC_CMD_BUFLEN 0x00001FFF
@ -777,7 +777,7 @@ struct rl_stats {
#define RL_TX_DESC_CNT RL_8169_TX_DESC_CNT
#define RL_RX_DESC_CNT RL_8169_RX_DESC_CNT
#define RL_RX_JUMBO_DESC_CNT RL_RX_DESC_CNT
#define RL_NTXSEGS 32
#define RL_NTXSEGS 35
#define RL_RING_ALIGN 256
#define RL_DUMP_ALIGN 64
@ -877,6 +877,7 @@ struct rl_softc {
bus_dma_tag_t rl_parent_tag;
uint8_t rl_type;
const struct rl_hwrev *rl_hwrev;
uint32_t rl_macrev;
int rl_eecmd_read;
int rl_eewidth;
int rl_expcap;
@ -929,6 +930,8 @@ struct rl_softc {
#define RL_FLAG_WAIT_TXPOLL 0x00004000
#define RL_FLAG_CMDSTOP_WAIT_TXQ 0x00008000
#define RL_FLAG_WOL_MANLINK 0x00010000
#define RL_FLAG_EARLYOFF 0x00020000
#define RL_FLAG_8168G_PLUS 0x00040000
#define RL_FLAG_PCIE 0x40000000
#define RL_FLAG_LINK 0x80000000
};
@ -1047,6 +1050,11 @@ struct rl_softc {
*/
#define DLINK_DEVICEID_530TXPLUS 0x1300
/*
* D-Link DFE-520TX rev. C1 device ID
*/
#define DLINK_DEVICEID_520TX_REVC1 0x4200
/*
* D-Link DFE-5280T device ID
*/
@ -1150,3 +1158,8 @@ struct rl_softc {
/* US Robotics 997902 device ID */
#define USR_DEVICEID_997902 0x0116
/*
* NCube vendor ID
*/
#define NCUBE_VENDORID 0x10FF