This revision adds support to if_rt for more SoCs.
The SoCs I've tried the driver with include the following: RT3050, RT5350, RT3662, RT3883, MT7620, MT7621, MT7688. On boards, based on the above SoCs traffic is passing through correctly and the boards survive a flood ping with very little or no drops (drops may be caused elsewhere in my test setup, however). One issue still remains and needs to be fixed in the future: if_rt does not survive an ifconfig rt0 down/ifconfig rt0 up cycle. This issue existed before this commit as well, however. Reviewed by: ray Approved by: adrian (mentor) Sponsored by: Smartcom - Bulgaria AD Differential Revision: https://reviews.freebsd.org/D5864
This commit is contained in:
parent
e43d20993a
commit
5ce34567e6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=297646
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2015, Stanislav Galabov
|
||||
* Copyright (c) 2015-2016, Stanislav Galabov
|
||||
* Copyright (c) 2014, Aleksandr A. Mityaev
|
||||
* Copyright (c) 2011, Aleksandr Rybalko
|
||||
* based on hard work
|
||||
@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <vm/vm_param.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
@ -69,8 +70,10 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/mii/mii.h>
|
||||
#include <dev/mii/miivar.h>
|
||||
|
||||
#if 0
|
||||
#include <mips/rt305x/rt305x_sysctlvar.h>
|
||||
#include <mips/rt305x/rt305xreg.h>
|
||||
#endif
|
||||
|
||||
#ifdef IF_RT_PHY_SUPPORT
|
||||
#include "miibus_if.h"
|
||||
@ -89,19 +92,20 @@ __FBSDID("$FreeBSD$");
|
||||
#define RT_TX_WATCHDOG_TIMEOUT 5
|
||||
|
||||
#define RT_CHIPID_RT3050 0x3050
|
||||
#define RT_CHIPID_RT3052 0x3052
|
||||
#define RT_CHIPID_RT5350 0x5350
|
||||
#define RT_CHIPID_RT6855 0x6855
|
||||
#define RT_CHIPID_MT7620 0x7620
|
||||
#define RT_CHIPID_MT7621 0x7621
|
||||
|
||||
#ifdef FDT
|
||||
/* more specific and new models should go first */
|
||||
static const struct ofw_compat_data rt_compat_data[] = {
|
||||
{ "ralink,rt6855-eth", (uintptr_t)RT_CHIPID_RT6855 },
|
||||
{ "ralink,rt5350-eth", (uintptr_t)RT_CHIPID_RT5350 },
|
||||
{ "ralink,rt3052-eth", (uintptr_t)RT_CHIPID_RT3052 },
|
||||
{ "ralink,rt305x-eth", (uintptr_t)RT_CHIPID_RT3050 },
|
||||
{ NULL, (uintptr_t)NULL }
|
||||
{ "ralink,rt3050-eth", RT_CHIPID_RT3050 },
|
||||
{ "ralink,rt3352-eth", RT_CHIPID_RT3050 },
|
||||
{ "ralink,rt3883-eth", RT_CHIPID_RT3050 },
|
||||
{ "ralink,rt5350-eth", RT_CHIPID_RT5350 },
|
||||
{ "ralink,mt7620a-eth", RT_CHIPID_MT7620 },
|
||||
{ "ralink,mt7621-eth", RT_CHIPID_MT7621 },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -182,21 +186,23 @@ rt_probe(device_t dev)
|
||||
const struct ofw_compat_data * cd;
|
||||
|
||||
cd = ofw_bus_search_compatible(dev, rt_compat_data);
|
||||
if (cd->ocd_data == (uintptr_t)NULL)
|
||||
if (cd->ocd_data == 0)
|
||||
return (ENXIO);
|
||||
|
||||
sc->rt_chipid = (unsigned int)(cd->ocd_data);
|
||||
#else
|
||||
#if defined(MT7620)
|
||||
sc->rt_chipid = RT_CHIPID_MT7620;
|
||||
#elif defined(MT7621)
|
||||
sc->rt_chipid = RT_CHIPID_MT7621;
|
||||
#elif defined(RT5350)
|
||||
sc->rt_chipid = RT_CHIPID_RT5350;
|
||||
#else
|
||||
sc->rt_chipid = RT_CHIPID_RT3050;
|
||||
#endif
|
||||
#endif
|
||||
snprintf(buf, sizeof(buf), "Ralink RT%x onChip Ethernet driver",
|
||||
sc->rt_chipid);
|
||||
snprintf(buf, sizeof(buf), "Ralink %cT%x onChip Ethernet driver",
|
||||
sc->rt_chipid >= 0x7600 ? 'M' : 'R', sc->rt_chipid);
|
||||
device_set_desc_copy(dev, buf);
|
||||
return (BUS_PROBE_GENERIC);
|
||||
}
|
||||
@ -373,12 +379,26 @@ rt_attach(device_t dev)
|
||||
|
||||
/* Reset hardware */
|
||||
reset_freng(sc);
|
||||
|
||||
|
||||
if (sc->rt_chipid == RT_CHIPID_MT7620) {
|
||||
sc->csum_fail_ip = MT7620_RXD_SRC_IP_CSUM_FAIL;
|
||||
sc->csum_fail_l4 = MT7620_RXD_SRC_L4_CSUM_FAIL;
|
||||
} else if (sc->rt_chipid == RT_CHIPID_MT7621) {
|
||||
sc->csum_fail_ip = MT7621_RXD_SRC_IP_CSUM_FAIL;
|
||||
sc->csum_fail_l4 = MT7621_RXD_SRC_L4_CSUM_FAIL;
|
||||
} else {
|
||||
sc->csum_fail_ip = RT305X_RXD_SRC_IP_CSUM_FAIL;
|
||||
sc->csum_fail_l4 = RT305X_RXD_SRC_L4_CSUM_FAIL;
|
||||
}
|
||||
|
||||
/* Fill in soc-specific registers map */
|
||||
switch(sc->rt_chipid) {
|
||||
case RT_CHIPID_MT7620:
|
||||
case RT_CHIPID_MT7621:
|
||||
case RT_CHIPID_RT5350:
|
||||
device_printf(dev, "RT%x Ethernet MAC (rev 0x%08x)\n",
|
||||
device_printf(dev, "%cT%x Ethernet MAC (rev 0x%08x)\n",
|
||||
sc->rt_chipid >= 0x7600 ? 'M' : 'R',
|
||||
sc->rt_chipid, sc->mac_rev);
|
||||
/* RT5350: No GDMA, PSE, CDMA, PPE */
|
||||
RT_WRITE(sc, GE_PORT_BASE + 0x0C00, // UDPCS, TCPCS, IPCS=1
|
||||
@ -406,10 +426,6 @@ rt_attach(device_t dev)
|
||||
sc->int_rx_done_mask=RT5350_INT_RXQ0_DONE;
|
||||
sc->int_tx_done_mask=RT5350_INT_TXQ0_DONE;
|
||||
break;
|
||||
case RT_CHIPID_RT6855:
|
||||
device_printf(dev, "RT6855 Ethernet MAC (rev 0x%08x)\n",
|
||||
sc->mac_rev);
|
||||
break;
|
||||
default:
|
||||
device_printf(dev, "RT305XF Ethernet MAC (rev 0x%08x)\n",
|
||||
sc->mac_rev);
|
||||
@ -533,7 +549,8 @@ rt_attach(device_t dev)
|
||||
/* set up interrupt */
|
||||
error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE,
|
||||
NULL, (sc->rt_chipid == RT_CHIPID_RT5350 ||
|
||||
sc->rt_chipid == RT_CHIPID_MT7620) ? rt_rt5350_intr : rt_intr,
|
||||
sc->rt_chipid == RT_CHIPID_MT7620 ||
|
||||
sc->rt_chipid == RT_CHIPID_MT7621) ? rt_rt5350_intr : rt_intr,
|
||||
sc, &sc->irqh);
|
||||
if (error != 0) {
|
||||
printf("%s: could not set up interrupt\n",
|
||||
@ -763,7 +780,7 @@ rt_init_locked(void *priv)
|
||||
//rt305x_sysctl_set(SYSCTL_RSTCTRL, SYSCTL_RSTCTRL_FRENG);
|
||||
|
||||
/* Fwd to CPU (uni|broad|multi)cast and Unknown */
|
||||
if(sc->rt_chipid == RT_CHIPID_RT3050 || sc->rt_chipid == RT_CHIPID_RT3052)
|
||||
if(sc->rt_chipid == RT_CHIPID_RT3050)
|
||||
RT_WRITE(sc, GDMA1_BASE + GDMA_FWD_CFG,
|
||||
(
|
||||
GDM_ICS_EN | /* Enable IP Csum */
|
||||
@ -831,7 +848,8 @@ rt_init_locked(void *priv)
|
||||
|
||||
/* write back DDONE, 16byte burst enable RX/TX DMA */
|
||||
tmp = FE_TX_WB_DDONE | FE_DMA_BT_SIZE16 | FE_RX_DMA_EN | FE_TX_DMA_EN;
|
||||
if (sc->rt_chipid == RT_CHIPID_MT7620)
|
||||
if (sc->rt_chipid == RT_CHIPID_MT7620 ||
|
||||
sc->rt_chipid == RT_CHIPID_MT7621)
|
||||
tmp |= (1<<31);
|
||||
RT_WRITE(sc, sc->pdma_glo_cfg, tmp);
|
||||
|
||||
@ -843,7 +861,8 @@ rt_init_locked(void *priv)
|
||||
|
||||
/* enable interrupts */
|
||||
if (sc->rt_chipid == RT_CHIPID_RT5350 ||
|
||||
sc->rt_chipid == RT_CHIPID_MT7620)
|
||||
sc->rt_chipid == RT_CHIPID_MT7620 ||
|
||||
sc->rt_chipid == RT_CHIPID_MT7621)
|
||||
tmp = RT5350_INT_TX_COHERENT |
|
||||
RT5350_INT_RX_COHERENT |
|
||||
RT5350_INT_TXQ3_DONE |
|
||||
@ -945,7 +964,8 @@ rt_stop_locked(void *priv)
|
||||
RT_WRITE(sc, sc->fe_int_enable, 0);
|
||||
|
||||
if(sc->rt_chipid == RT_CHIPID_RT5350 ||
|
||||
sc->rt_chipid == RT_CHIPID_MT7620) {
|
||||
sc->rt_chipid == RT_CHIPID_MT7620 ||
|
||||
sc->rt_chipid == RT_CHIPID_MT7621) {
|
||||
} else {
|
||||
/* reset adapter */
|
||||
RT_WRITE(sc, GE_PORT_BASE + FE_RST_GLO, PSE_RESET);
|
||||
@ -1055,22 +1075,29 @@ rt_tx_data(struct rt_softc *sc, struct mbuf *m, int qid)
|
||||
|
||||
/* TODO: this needs to be refined as MT7620 for example has
|
||||
* a different word3 layout than RT305x and RT5350 (the last
|
||||
* one doesn't use word3 at all).
|
||||
* one doesn't use word3 at all). And so does MT7621...
|
||||
*/
|
||||
|
||||
/* Set destination */
|
||||
if (sc->rt_chipid != RT_CHIPID_MT7620)
|
||||
desc->dst = (TXDSCR_DST_PORT_GDMA1);
|
||||
if (sc->rt_chipid != RT_CHIPID_MT7621) {
|
||||
/* Set destination */
|
||||
if (sc->rt_chipid != RT_CHIPID_MT7620)
|
||||
desc->dst = (TXDSCR_DST_PORT_GDMA1);
|
||||
|
||||
if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
|
||||
desc->dst |= (TXDSCR_IP_CSUM_GEN|TXDSCR_UDP_CSUM_GEN|
|
||||
TXDSCR_TCP_CSUM_GEN);
|
||||
/* Set queue id */
|
||||
desc->qn = qid;
|
||||
/* No PPPoE */
|
||||
desc->pppoe = 0;
|
||||
/* No VLAN */
|
||||
desc->vid = 0;
|
||||
if ((ifp->if_capenable & IFCAP_TXCSUM) != 0)
|
||||
desc->dst |= (TXDSCR_IP_CSUM_GEN |
|
||||
TXDSCR_UDP_CSUM_GEN | TXDSCR_TCP_CSUM_GEN);
|
||||
/* Set queue id */
|
||||
desc->qn = qid;
|
||||
/* No PPPoE */
|
||||
desc->pppoe = 0;
|
||||
/* No VLAN */
|
||||
desc->vid = 0;
|
||||
} else {
|
||||
desc->vid = 0;
|
||||
desc->pppoe = 0;
|
||||
desc->qn = 0;
|
||||
desc->dst = 2;
|
||||
}
|
||||
|
||||
desc->sdp0 = htole32(dma_seg[i].ds_addr);
|
||||
desc->sdl0 = htole16(dma_seg[i].ds_len |
|
||||
@ -1714,7 +1741,8 @@ rt_tx_done_task(void *context, int pending)
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
|
||||
if(sc->rt_chipid == RT_CHIPID_RT5350 ||
|
||||
sc->rt_chipid == RT_CHIPID_MT7620)
|
||||
sc->rt_chipid == RT_CHIPID_MT7620 ||
|
||||
sc->rt_chipid == RT_CHIPID_MT7621)
|
||||
intr_mask = (
|
||||
RT5350_INT_TXQ3_DONE |
|
||||
RT5350_INT_TXQ2_DONE |
|
||||
@ -1870,15 +1898,13 @@ rt_rx_eof(struct rt_softc *sc, struct rt_softc_rx_ring *ring, int limit)
|
||||
BUS_DMASYNC_PREREAD);
|
||||
|
||||
m = data->m;
|
||||
desc_flags = desc->src;
|
||||
desc_flags = desc->word3;
|
||||
|
||||
data->m = mnew;
|
||||
/* Add 2 for proper align of RX IP header */
|
||||
desc->sdp0 = htole32(segs[0].ds_addr+2);
|
||||
desc->sdl0 = htole32(segs[0].ds_len-2);
|
||||
desc->src = 0;
|
||||
desc->ai = 0;
|
||||
desc->foe = 0;
|
||||
desc->word3 = 0;
|
||||
|
||||
RT_DPRINTF(sc, RT_DEBUG_RX,
|
||||
"Rx frame: rxdesc flags=0x%08x\n", desc_flags);
|
||||
@ -1891,8 +1917,7 @@ rt_rx_eof(struct rt_softc *sc, struct rt_softc_rx_ring *ring, int limit)
|
||||
/* check for crc errors */
|
||||
if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) {
|
||||
/*check for valid checksum*/
|
||||
if (desc_flags & (RXDSXR_SRC_IP_CSUM_FAIL|
|
||||
RXDSXR_SRC_L4_CSUM_FAIL)) {
|
||||
if (desc_flags & (sc->csum_fail_ip|sc->csum_fail_l4)) {
|
||||
RT_DPRINTF(sc, RT_DEBUG_RX,
|
||||
"rxdesc: crc error\n");
|
||||
|
||||
@ -1903,7 +1928,7 @@ rt_rx_eof(struct rt_softc *sc, struct rt_softc_rx_ring *ring, int limit)
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
if ((desc_flags & RXDSXR_SRC_IP_CSUM_FAIL) != 0) {
|
||||
if ((desc_flags & sc->csum_fail_ip) == 0) {
|
||||
m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
|
||||
m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
|
||||
m->m_pkthdr.csum_data = 0xffff;
|
||||
@ -2031,7 +2056,8 @@ rt_watchdog(struct rt_softc *sc)
|
||||
int ntries;
|
||||
#endif
|
||||
if(sc->rt_chipid != RT_CHIPID_RT5350 &&
|
||||
sc->rt_chipid != RT_CHIPID_MT7620) {
|
||||
sc->rt_chipid != RT_CHIPID_MT7620 &&
|
||||
sc->rt_chipid != RT_CHIPID_MT7621) {
|
||||
tmp = RT_READ(sc, PSE_BASE + CDMA_OQ_STA);
|
||||
|
||||
RT_DPRINTF(sc, RT_DEBUG_WATCHDOG,
|
||||
|
@ -115,12 +115,21 @@ struct rt_txdesc
|
||||
} __packed;
|
||||
|
||||
#define RT_RXDESC_SDL0_DDONE (1 << 15)
|
||||
|
||||
#define RT305X_RXD_SRC_L4_CSUM_FAIL (1 << 28)
|
||||
#define RT305X_RXD_SRC_IP_CSUM_FAIL (1 << 29)
|
||||
#define MT7620_RXD_SRC_L4_CSUM_FAIL (1 << 22)
|
||||
#define MT7620_RXD_SRC_IP_CSUM_FAIL (1 << 25)
|
||||
#define MT7621_RXD_SRC_L4_CSUM_FAIL (1 << 23)
|
||||
#define MT7621_RXD_SRC_IP_CSUM_FAIL (1 << 26)
|
||||
|
||||
struct rt_rxdesc
|
||||
{
|
||||
uint32_t sdp0;
|
||||
uint16_t sdl1;
|
||||
uint16_t sdl0;
|
||||
uint32_t sdp1;
|
||||
#if 0
|
||||
uint16_t foe;
|
||||
#define RXDSXR_FOE_ENTRY_VALID 0x40
|
||||
#define RXDSXR_FOE_ENTRY_MASK 0x3f
|
||||
@ -134,6 +143,8 @@ struct rt_rxdesc
|
||||
#define RXDSXR_SRC_L4_CSUM_FAIL 0x10
|
||||
#define RXDSXR_SRC_AIS 0x08
|
||||
#define RXDSXR_SRC_PORT_MASK 0x07
|
||||
#endif
|
||||
uint32_t word3;
|
||||
} __packed;
|
||||
|
||||
struct rt_softc_rx_data
|
||||
@ -263,6 +274,8 @@ struct rt_softc
|
||||
uint32_t rt_chipid;
|
||||
/* chip specific registers config */
|
||||
int rx_ring_count;
|
||||
uint32_t csum_fail_l4;
|
||||
uint32_t csum_fail_ip;
|
||||
uint32_t int_rx_done_mask;
|
||||
uint32_t int_tx_done_mask;
|
||||
uint32_t delay_int_cfg;
|
||||
|
Loading…
Reference in New Issue
Block a user