[rt] add support for the RT5350 and MT7620 SoCs.
This is a work in progress; bringing the interface down stops further use. It only happens on RT5350/MT7620. This is based on work by Alexander A. Mityaev <sansan@adm.ua>. Submitted by: Stanislav Galabov <galabov@gmail.com>
This commit is contained in:
parent
ba1ae59a17
commit
dec1abaec3
@ -1,4 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2015, Stanislav Galabov
|
||||
* Copyright (c) 2014, Aleksandr A. Mityaev
|
||||
* Copyright (c) 2011, Aleksandr Rybalko
|
||||
* based on hard work
|
||||
* by Alexander Egorenkov <egorenar@gmail.com>
|
||||
@ -56,6 +58,15 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/bus.h>
|
||||
#include <sys/rman.h>
|
||||
|
||||
#include "opt_platform.h"
|
||||
#include "opt_rt305x.h"
|
||||
|
||||
#ifdef FDT
|
||||
#include <dev/ofw/openfirm.h>
|
||||
#include <dev/ofw/ofw_bus.h>
|
||||
#include <dev/ofw/ofw_bus_subr.h>
|
||||
#endif
|
||||
|
||||
#include <dev/mii/mii.h>
|
||||
#include <dev/mii/miivar.h>
|
||||
|
||||
@ -78,6 +89,23 @@ __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
|
||||
|
||||
#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 }
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Static function prototypes
|
||||
*/
|
||||
@ -96,16 +124,18 @@ static int rt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
|
||||
static void rt_periodic(void *arg);
|
||||
static void rt_tx_watchdog(void *arg);
|
||||
static void rt_intr(void *arg);
|
||||
static void rt_rt5350_intr(void *arg);
|
||||
static void rt_tx_coherent_intr(struct rt_softc *sc);
|
||||
static void rt_rx_coherent_intr(struct rt_softc *sc);
|
||||
static void rt_rx_delay_intr(struct rt_softc *sc);
|
||||
static void rt_tx_delay_intr(struct rt_softc *sc);
|
||||
static void rt_rx_intr(struct rt_softc *sc);
|
||||
static void rt_rx_intr(struct rt_softc *sc, int qid);
|
||||
static void rt_tx_intr(struct rt_softc *sc, int qid);
|
||||
static void rt_rx_done_task(void *context, int pending);
|
||||
static void rt_tx_done_task(void *context, int pending);
|
||||
static void rt_periodic_task(void *context, int pending);
|
||||
static int rt_rx_eof(struct rt_softc *sc, int limit);
|
||||
static int rt_rx_eof(struct rt_softc *sc,
|
||||
struct rt_softc_rx_ring *ring, int limit);
|
||||
static void rt_tx_eof(struct rt_softc *sc,
|
||||
struct rt_softc_tx_ring *ring);
|
||||
static void rt_update_stats(struct rt_softc *sc);
|
||||
@ -115,7 +145,7 @@ static void rt_intr_enable(struct rt_softc *sc, uint32_t intr_mask);
|
||||
static void rt_intr_disable(struct rt_softc *sc, uint32_t intr_mask);
|
||||
static int rt_txrx_enable(struct rt_softc *sc);
|
||||
static int rt_alloc_rx_ring(struct rt_softc *sc,
|
||||
struct rt_softc_rx_ring *ring);
|
||||
struct rt_softc_rx_ring *ring, int qid);
|
||||
static void rt_reset_rx_ring(struct rt_softc *sc,
|
||||
struct rt_softc_rx_ring *ring);
|
||||
static void rt_free_rx_ring(struct rt_softc *sc,
|
||||
@ -147,8 +177,29 @@ SYSCTL_INT(_hw_rt, OID_AUTO, debug, CTLFLAG_RWTUN, &rt_debug, 0,
|
||||
static int
|
||||
rt_probe(device_t dev)
|
||||
{
|
||||
device_set_desc(dev, "Ralink RT305XF onChip Ethernet MAC");
|
||||
return (BUS_PROBE_NOWILDCARD);
|
||||
struct rt_softc *sc = device_get_softc(dev);
|
||||
char buf[80];
|
||||
#ifdef FDT
|
||||
const struct ofw_compat_data * cd;
|
||||
|
||||
cd = ofw_bus_search_compatible(dev, rt_compat_data);
|
||||
if (cd->ocd_data == (uintptr_t)NULL)
|
||||
return (ENXIO);
|
||||
|
||||
sc->rt_chipid = (unsigned int)(cd->ocd_data);
|
||||
#else
|
||||
#if defined(MT7620)
|
||||
sc->rt_chipid = RT_CHIPID_MT7620;
|
||||
#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);
|
||||
device_set_desc_copy(dev, buf);
|
||||
return (BUS_PROBE_GENERIC);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -240,7 +291,7 @@ ether_request_mac(device_t dev, uint8_t *mac)
|
||||
* "ethaddr" is passed via envp on RedBoot platforms
|
||||
* "kmac" is passed via argv on RouterBOOT platforms
|
||||
*/
|
||||
#if defined(__U_BOOT__) || defined(__REDBOOT__) || defined(__ROUTERBOOT__)
|
||||
#if defined(RT305X_UBOOT) || defined(__REDBOOT__) || defined(__ROUTERBOOT__)
|
||||
if ((var = kern_getenv("ethaddr")) != NULL ||
|
||||
(var = kern_getenv("kmac")) != NULL ) {
|
||||
|
||||
@ -288,6 +339,16 @@ ether_request_mac(device_t dev, uint8_t *mac)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset hardware
|
||||
*/
|
||||
static void
|
||||
reset_freng(struct rt_softc *sc)
|
||||
{
|
||||
/* XXX hard reset kills everything so skip it ... */
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
rt_attach(device_t dev)
|
||||
{
|
||||
@ -331,23 +392,80 @@ rt_attach(device_t dev)
|
||||
"debug", CTLFLAG_RW, &sc->debug, 0, "rt debug level");
|
||||
#endif
|
||||
|
||||
device_printf(dev, "RT305XF Ethernet MAC (rev 0x%08x)\n",
|
||||
sc->mac_rev);
|
||||
|
||||
/* Reset hardware */
|
||||
RT_WRITE(sc, GE_PORT_BASE + FE_RST_GLO, PSE_RESET);
|
||||
|
||||
RT_WRITE(sc, GDMA1_BASE + GDMA_FWD_CFG,
|
||||
(
|
||||
GDM_ICS_EN | /* Enable IP Csum */
|
||||
GDM_TCS_EN | /* Enable TCP Csum */
|
||||
GDM_UCS_EN | /* Enable UDP Csum */
|
||||
GDM_STRPCRC | /* Strip CRC from packet */
|
||||
GDM_DST_PORT_CPU << GDM_UFRC_P_SHIFT | /* Forward UCast to CPU */
|
||||
GDM_DST_PORT_CPU << GDM_BFRC_P_SHIFT | /* Forward BCast to CPU */
|
||||
GDM_DST_PORT_CPU << GDM_MFRC_P_SHIFT | /* Forward MCast to CPU */
|
||||
GDM_DST_PORT_CPU << GDM_OFRC_P_SHIFT /* Forward Other to CPU */
|
||||
));
|
||||
reset_freng(sc);
|
||||
|
||||
/* Fill in soc-specific registers map */
|
||||
switch(sc->rt_chipid) {
|
||||
case RT_CHIPID_MT7620:
|
||||
case RT_CHIPID_RT5350:
|
||||
device_printf(dev, "RT%x Ethernet MAC (rev 0x%08x)\n",
|
||||
sc->rt_chipid, sc->mac_rev);
|
||||
/* RT5350: No GDMA, PSE, CDMA, PPE */
|
||||
RT_WRITE(sc, GE_PORT_BASE + 0x0C00, // UDPCS, TCPCS, IPCS=1
|
||||
RT_READ(sc, GE_PORT_BASE + 0x0C00) | (0x7<<16));
|
||||
sc->delay_int_cfg=RT5350_PDMA_BASE+RT5350_DELAY_INT_CFG;
|
||||
sc->fe_int_status=RT5350_FE_INT_STATUS;
|
||||
sc->fe_int_enable=RT5350_FE_INT_ENABLE;
|
||||
sc->pdma_glo_cfg=RT5350_PDMA_BASE+RT5350_PDMA_GLO_CFG;
|
||||
sc->pdma_rst_idx=RT5350_PDMA_BASE+RT5350_PDMA_RST_IDX;
|
||||
for (i = 0; i < RT_SOFTC_TX_RING_COUNT; i++) {
|
||||
sc->tx_base_ptr[i]=RT5350_PDMA_BASE+RT5350_TX_BASE_PTR(i);
|
||||
sc->tx_max_cnt[i]=RT5350_PDMA_BASE+RT5350_TX_MAX_CNT(i);
|
||||
sc->tx_ctx_idx[i]=RT5350_PDMA_BASE+RT5350_TX_CTX_IDX(i);
|
||||
sc->tx_dtx_idx[i]=RT5350_PDMA_BASE+RT5350_TX_DTX_IDX(i);
|
||||
}
|
||||
sc->rx_ring_count=2;
|
||||
sc->rx_base_ptr[0]=RT5350_PDMA_BASE+RT5350_RX_BASE_PTR0;
|
||||
sc->rx_max_cnt[0]=RT5350_PDMA_BASE+RT5350_RX_MAX_CNT0;
|
||||
sc->rx_calc_idx[0]=RT5350_PDMA_BASE+RT5350_RX_CALC_IDX0;
|
||||
sc->rx_drx_idx[0]=RT5350_PDMA_BASE+RT5350_RX_DRX_IDX0;
|
||||
sc->rx_base_ptr[1]=RT5350_PDMA_BASE+RT5350_RX_BASE_PTR1;
|
||||
sc->rx_max_cnt[1]=RT5350_PDMA_BASE+RT5350_RX_MAX_CNT1;
|
||||
sc->rx_calc_idx[1]=RT5350_PDMA_BASE+RT5350_RX_CALC_IDX1;
|
||||
sc->rx_drx_idx[1]=RT5350_PDMA_BASE+RT5350_RX_DRX_IDX1;
|
||||
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);
|
||||
RT_WRITE(sc, GDMA1_BASE + GDMA_FWD_CFG,
|
||||
(
|
||||
GDM_ICS_EN | /* Enable IP Csum */
|
||||
GDM_TCS_EN | /* Enable TCP Csum */
|
||||
GDM_UCS_EN | /* Enable UDP Csum */
|
||||
GDM_STRPCRC | /* Strip CRC from packet */
|
||||
GDM_DST_PORT_CPU << GDM_UFRC_P_SHIFT | /* fwd UCast to CPU */
|
||||
GDM_DST_PORT_CPU << GDM_BFRC_P_SHIFT | /* fwd BCast to CPU */
|
||||
GDM_DST_PORT_CPU << GDM_MFRC_P_SHIFT | /* fwd MCast to CPU */
|
||||
GDM_DST_PORT_CPU << GDM_OFRC_P_SHIFT /* fwd Other to CPU */
|
||||
));
|
||||
|
||||
sc->delay_int_cfg=PDMA_BASE+DELAY_INT_CFG;
|
||||
sc->fe_int_status=GE_PORT_BASE+FE_INT_STATUS;
|
||||
sc->fe_int_enable=GE_PORT_BASE+FE_INT_ENABLE;
|
||||
sc->pdma_glo_cfg=PDMA_BASE+PDMA_GLO_CFG;
|
||||
sc->pdma_glo_cfg=PDMA_BASE+PDMA_GLO_CFG;
|
||||
sc->pdma_rst_idx=PDMA_BASE+PDMA_RST_IDX;
|
||||
for (i = 0; i < RT_SOFTC_TX_RING_COUNT; i++) {
|
||||
sc->tx_base_ptr[i]=PDMA_BASE+TX_BASE_PTR(i);
|
||||
sc->tx_max_cnt[i]=PDMA_BASE+TX_MAX_CNT(i);
|
||||
sc->tx_ctx_idx[i]=PDMA_BASE+TX_CTX_IDX(i);
|
||||
sc->tx_dtx_idx[i]=PDMA_BASE+TX_DTX_IDX(i);
|
||||
}
|
||||
sc->rx_ring_count=1;
|
||||
sc->rx_base_ptr[0]=PDMA_BASE+RX_BASE_PTR0;
|
||||
sc->rx_max_cnt[0]=PDMA_BASE+RX_MAX_CNT0;
|
||||
sc->rx_calc_idx[0]=PDMA_BASE+RX_CALC_IDX0;
|
||||
sc->rx_drx_idx[0]=PDMA_BASE+RX_DRX_IDX0;
|
||||
sc->int_rx_done_mask=INT_RX_DONE;
|
||||
sc->int_tx_done_mask=INT_TXQ0_DONE;
|
||||
};
|
||||
|
||||
/* allocate Tx and Rx rings */
|
||||
for (i = 0; i < RT_SOFTC_TX_RING_COUNT; i++) {
|
||||
@ -360,11 +478,12 @@ rt_attach(device_t dev)
|
||||
}
|
||||
|
||||
sc->tx_ring_mgtqid = 5;
|
||||
|
||||
error = rt_alloc_rx_ring(sc, &sc->rx_ring);
|
||||
if (error != 0) {
|
||||
device_printf(dev, "could not allocate Rx ring\n");
|
||||
goto fail;
|
||||
for (i = 0; i < sc->rx_ring_count; i++) {
|
||||
error = rt_alloc_rx_ring(sc, &sc->rx_ring[i], i);
|
||||
if (error != 0) {
|
||||
device_printf(dev, "could not allocate Rx ring\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
callout_init(&sc->periodic_ch, 0);
|
||||
@ -434,7 +553,9 @@ rt_attach(device_t dev)
|
||||
|
||||
/* set up interrupt */
|
||||
error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE,
|
||||
NULL, rt_intr, sc, &sc->irqh);
|
||||
NULL, (sc->rt_chipid == RT_CHIPID_RT5350 ||
|
||||
sc->rt_chipid == RT_CHIPID_MT7620) ? rt_rt5350_intr : rt_intr,
|
||||
sc, &sc->irqh);
|
||||
if (error != 0) {
|
||||
printf("%s: could not set up interrupt\n",
|
||||
device_get_nameunit(dev));
|
||||
@ -451,7 +572,8 @@ fail:
|
||||
for (i = 0; i < RT_SOFTC_TX_RING_COUNT; i++)
|
||||
rt_free_tx_ring(sc, &sc->tx_ring[i]);
|
||||
|
||||
rt_free_rx_ring(sc, &sc->rx_ring);
|
||||
for (i = 0; i < sc->rx_ring_count; i++)
|
||||
rt_free_rx_ring(sc, &sc->rx_ring[i]);
|
||||
|
||||
mtx_destroy(&sc->lock);
|
||||
|
||||
@ -567,8 +689,8 @@ rt_detach(device_t dev)
|
||||
/* free Tx and Rx rings */
|
||||
for (i = 0; i < RT_SOFTC_TX_RING_COUNT; i++)
|
||||
rt_free_tx_ring(sc, &sc->tx_ring[i]);
|
||||
|
||||
rt_free_rx_ring(sc, &sc->rx_ring);
|
||||
for (i = 0; i < sc->rx_ring_count; i++)
|
||||
rt_free_rx_ring(sc, &sc->rx_ring[i]);
|
||||
|
||||
RT_SOFTC_UNLOCK(sc);
|
||||
|
||||
@ -658,11 +780,12 @@ rt_init_locked(void *priv)
|
||||
RT_SOFTC_ASSERT_LOCKED(sc);
|
||||
|
||||
/* hardware reset */
|
||||
RT_WRITE(sc, GE_PORT_BASE + FE_RST_GLO, PSE_RESET);
|
||||
rt305x_sysctl_set(SYSCTL_RSTCTRL, SYSCTL_RSTCTRL_FRENG);
|
||||
//RT_WRITE(sc, GE_PORT_BASE + FE_RST_GLO, PSE_RESET);
|
||||
//rt305x_sysctl_set(SYSCTL_RSTCTRL, SYSCTL_RSTCTRL_FRENG);
|
||||
|
||||
/* Fwd to CPU (uni|broad|multi)cast and Unknown */
|
||||
RT_WRITE(sc, GDMA1_BASE + GDMA_FWD_CFG,
|
||||
if(sc->rt_chipid == RT_CHIPID_RT3050 || sc->rt_chipid == RT_CHIPID_RT3052)
|
||||
RT_WRITE(sc, GDMA1_BASE + GDMA_FWD_CFG,
|
||||
(
|
||||
GDM_ICS_EN | /* Enable IP Csum */
|
||||
GDM_TCS_EN | /* Enable TCP Csum */
|
||||
@ -675,12 +798,12 @@ rt_init_locked(void *priv)
|
||||
));
|
||||
|
||||
/* disable DMA engine */
|
||||
RT_WRITE(sc, PDMA_BASE + PDMA_GLO_CFG, 0);
|
||||
RT_WRITE(sc, PDMA_BASE + PDMA_RST_IDX, 0xffffffff);
|
||||
RT_WRITE(sc, sc->pdma_glo_cfg, 0);
|
||||
RT_WRITE(sc, sc->pdma_rst_idx, 0xffffffff);
|
||||
|
||||
/* wait while DMA engine is busy */
|
||||
for (ntries = 0; ntries < 100; ntries++) {
|
||||
tmp = RT_READ(sc, PDMA_BASE + PDMA_GLO_CFG);
|
||||
tmp = RT_READ(sc, sc->pdma_glo_cfg);
|
||||
if (!(tmp & (FE_TX_DMA_BUSY | FE_RX_DMA_BUSY)))
|
||||
break;
|
||||
DELAY(1000);
|
||||
@ -698,7 +821,7 @@ rt_init_locked(void *priv)
|
||||
FE_RST_DTX_IDX1 |
|
||||
FE_RST_DTX_IDX0;
|
||||
|
||||
RT_WRITE(sc, PDMA_BASE + PDMA_RST_IDX, tmp);
|
||||
RT_WRITE(sc, sc->pdma_rst_idx, tmp);
|
||||
|
||||
/* XXX switch set mac address */
|
||||
for (i = 0; i < RT_SOFTC_TX_RING_COUNT; i++)
|
||||
@ -706,36 +829,52 @@ rt_init_locked(void *priv)
|
||||
|
||||
for (i = 0; i < RT_SOFTC_TX_RING_COUNT; i++) {
|
||||
/* update TX_BASE_PTRx */
|
||||
RT_WRITE(sc, PDMA_BASE + TX_BASE_PTR(i),
|
||||
RT_WRITE(sc, sc->tx_base_ptr[i],
|
||||
sc->tx_ring[i].desc_phys_addr);
|
||||
RT_WRITE(sc, PDMA_BASE + TX_MAX_CNT(i),
|
||||
RT_WRITE(sc, sc->tx_max_cnt[i],
|
||||
RT_SOFTC_TX_RING_DESC_COUNT);
|
||||
RT_WRITE(sc, PDMA_BASE + TX_CTX_IDX(i), 0);
|
||||
RT_WRITE(sc, sc->tx_ctx_idx[i], 0);
|
||||
}
|
||||
|
||||
/* init Rx ring */
|
||||
rt_reset_rx_ring(sc, &sc->rx_ring);
|
||||
for (i = 0; i < sc->rx_ring_count; i++)
|
||||
rt_reset_rx_ring(sc, &sc->rx_ring[i]);
|
||||
|
||||
/* update RX_BASE_PTR0 */
|
||||
RT_WRITE(sc, PDMA_BASE + RX_BASE_PTR0,
|
||||
sc->rx_ring.desc_phys_addr);
|
||||
RT_WRITE(sc, PDMA_BASE + RX_MAX_CNT0,
|
||||
RT_SOFTC_RX_RING_DATA_COUNT);
|
||||
RT_WRITE(sc, PDMA_BASE + RX_CALC_IDX0,
|
||||
RT_SOFTC_RX_RING_DATA_COUNT - 1);
|
||||
/* update RX_BASE_PTRx */
|
||||
for (i = 0; i < sc->rx_ring_count; i++) {
|
||||
RT_WRITE(sc, sc->rx_base_ptr[i],
|
||||
sc->rx_ring[i].desc_phys_addr);
|
||||
RT_WRITE(sc, sc->rx_max_cnt[i],
|
||||
RT_SOFTC_RX_RING_DATA_COUNT);
|
||||
RT_WRITE(sc, sc->rx_calc_idx[i],
|
||||
RT_SOFTC_RX_RING_DATA_COUNT - 1);
|
||||
}
|
||||
|
||||
/* write back DDONE, 16byte burst enable RX/TX DMA */
|
||||
RT_WRITE(sc, PDMA_BASE + PDMA_GLO_CFG,
|
||||
FE_TX_WB_DDONE | FE_DMA_BT_SIZE16 | FE_RX_DMA_EN | FE_TX_DMA_EN);
|
||||
tmp = FE_TX_WB_DDONE | FE_DMA_BT_SIZE16 | FE_RX_DMA_EN | FE_TX_DMA_EN;
|
||||
if (sc->rt_chipid == RT_CHIPID_MT7620)
|
||||
tmp |= (1<<31);
|
||||
RT_WRITE(sc, sc->pdma_glo_cfg, tmp);
|
||||
|
||||
/* disable interrupts mitigation */
|
||||
RT_WRITE(sc, PDMA_BASE + DELAY_INT_CFG, 0);
|
||||
RT_WRITE(sc, sc->delay_int_cfg, 0);
|
||||
|
||||
/* clear pending interrupts */
|
||||
RT_WRITE(sc, GE_PORT_BASE + FE_INT_STATUS, 0xffffffff);
|
||||
RT_WRITE(sc, sc->fe_int_status, 0xffffffff);
|
||||
|
||||
/* enable interrupts */
|
||||
tmp = CNT_PPE_AF |
|
||||
if (sc->rt_chipid == RT_CHIPID_RT5350 ||
|
||||
sc->rt_chipid == RT_CHIPID_MT7620)
|
||||
tmp = RT5350_INT_TX_COHERENT |
|
||||
RT5350_INT_RX_COHERENT |
|
||||
RT5350_INT_TXQ3_DONE |
|
||||
RT5350_INT_TXQ2_DONE |
|
||||
RT5350_INT_TXQ1_DONE |
|
||||
RT5350_INT_TXQ0_DONE |
|
||||
RT5350_INT_RXQ1_DONE |
|
||||
RT5350_INT_RXQ0_DONE;
|
||||
else
|
||||
tmp = CNT_PPE_AF |
|
||||
CNT_GDM_AF |
|
||||
PSE_P2_FC |
|
||||
GDM_CRC_DROP |
|
||||
@ -754,7 +893,7 @@ rt_init_locked(void *priv)
|
||||
|
||||
sc->intr_enable_mask = tmp;
|
||||
|
||||
RT_WRITE(sc, GE_PORT_BASE + FE_INT_ENABLE, tmp);
|
||||
RT_WRITE(sc, sc->fe_int_enable, tmp);
|
||||
|
||||
if (rt_txrx_enable(sc) != 0)
|
||||
goto fail;
|
||||
@ -824,12 +963,15 @@ rt_stop_locked(void *priv)
|
||||
RT_SOFTC_LOCK(sc);
|
||||
|
||||
/* disable interrupts */
|
||||
RT_WRITE(sc, GE_PORT_BASE + FE_INT_ENABLE, 0);
|
||||
RT_WRITE(sc, sc->fe_int_enable, 0);
|
||||
|
||||
if(sc->rt_chipid == RT_CHIPID_RT5350 ||
|
||||
sc->rt_chipid == RT_CHIPID_MT7620) {
|
||||
} else {
|
||||
/* reset adapter */
|
||||
RT_WRITE(sc, GE_PORT_BASE + FE_RST_GLO, PSE_RESET);
|
||||
|
||||
/* reset adapter */
|
||||
RT_WRITE(sc, GE_PORT_BASE + FE_RST_GLO, PSE_RESET);
|
||||
|
||||
RT_WRITE(sc, GDMA1_BASE + GDMA_FWD_CFG,
|
||||
RT_WRITE(sc, GDMA1_BASE + GDMA_FWD_CFG,
|
||||
(
|
||||
GDM_ICS_EN | /* Enable IP Csum */
|
||||
GDM_TCS_EN | /* Enable TCP Csum */
|
||||
@ -840,6 +982,7 @@ rt_stop_locked(void *priv)
|
||||
GDM_DST_PORT_CPU << GDM_MFRC_P_SHIFT | /* Forward MCast to CPU */
|
||||
GDM_DST_PORT_CPU << GDM_OFRC_P_SHIFT /* Forward Other to CPU */
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -930,8 +1073,16 @@ rt_tx_data(struct rt_softc *sc, struct mbuf *m, int qid)
|
||||
|
||||
/* set up Tx descs */
|
||||
for (i = 0; i < ndmasegs; i += 2) {
|
||||
/* Set destenation */
|
||||
desc->dst = (TXDSCR_DST_PORT_GDMA1);
|
||||
|
||||
/* 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).
|
||||
*/
|
||||
|
||||
/* 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);
|
||||
@ -986,7 +1137,7 @@ rt_tx_data(struct rt_softc *sc, struct mbuf *m, int qid)
|
||||
ring->data_cur = (ring->data_cur + 1) % RT_SOFTC_TX_RING_DATA_COUNT;
|
||||
|
||||
/* kick Tx */
|
||||
RT_WRITE(sc, PDMA_BASE + TX_CTX_IDX(qid), ring->desc_cur);
|
||||
RT_WRITE(sc, sc->tx_ctx_idx[qid], ring->desc_cur);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -1272,8 +1423,8 @@ rt_intr(void *arg)
|
||||
ifp = sc->ifp;
|
||||
|
||||
/* acknowledge interrupts */
|
||||
status = RT_READ(sc, GE_PORT_BASE + FE_INT_STATUS);
|
||||
RT_WRITE(sc, GE_PORT_BASE + FE_INT_STATUS, status);
|
||||
status = RT_READ(sc, sc->fe_int_status);
|
||||
RT_WRITE(sc, sc->fe_int_status, status);
|
||||
|
||||
RT_DPRINTF(sc, RT_DEBUG_INTR, "interrupt: status=0x%08x\n", status);
|
||||
|
||||
@ -1326,7 +1477,7 @@ rt_intr(void *arg)
|
||||
rt_tx_delay_intr(sc);
|
||||
|
||||
if (status & INT_RX_DONE)
|
||||
rt_rx_intr(sc);
|
||||
rt_rx_intr(sc, 0);
|
||||
|
||||
if (status & INT_TXQ3_DONE)
|
||||
rt_tx_intr(sc, 3);
|
||||
@ -1341,6 +1492,56 @@ rt_intr(void *arg)
|
||||
rt_tx_intr(sc, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* rt_rt5350_intr - main ISR for Ralink 5350 SoC
|
||||
*/
|
||||
static void
|
||||
rt_rt5350_intr(void *arg)
|
||||
{
|
||||
struct rt_softc *sc;
|
||||
struct ifnet *ifp;
|
||||
uint32_t status;
|
||||
|
||||
sc = arg;
|
||||
ifp = sc->ifp;
|
||||
|
||||
/* acknowledge interrupts */
|
||||
status = RT_READ(sc, sc->fe_int_status);
|
||||
RT_WRITE(sc, sc->fe_int_status, status);
|
||||
|
||||
RT_DPRINTF(sc, RT_DEBUG_INTR, "interrupt: status=0x%08x\n", status);
|
||||
|
||||
if (status == 0xffffffff || /* device likely went away */
|
||||
status == 0) /* not for us */
|
||||
return;
|
||||
|
||||
sc->interrupts++;
|
||||
|
||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
|
||||
return;
|
||||
|
||||
if (status & RT5350_INT_TX_COHERENT)
|
||||
rt_tx_coherent_intr(sc);
|
||||
if (status & RT5350_INT_RX_COHERENT)
|
||||
rt_rx_coherent_intr(sc);
|
||||
if (status & RT5350_RX_DLY_INT)
|
||||
rt_rx_delay_intr(sc);
|
||||
if (status & RT5350_TX_DLY_INT)
|
||||
rt_tx_delay_intr(sc);
|
||||
if (status & RT5350_INT_RXQ1_DONE)
|
||||
rt_rx_intr(sc, 1);
|
||||
if (status & RT5350_INT_RXQ0_DONE)
|
||||
rt_rx_intr(sc, 0);
|
||||
if (status & RT5350_INT_TXQ3_DONE)
|
||||
rt_tx_intr(sc, 3);
|
||||
if (status & RT5350_INT_TXQ2_DONE)
|
||||
rt_tx_intr(sc, 2);
|
||||
if (status & RT5350_INT_TXQ1_DONE)
|
||||
rt_tx_intr(sc, 1);
|
||||
if (status & RT5350_INT_TXQ0_DONE)
|
||||
rt_tx_intr(sc, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
rt_tx_coherent_intr(struct rt_softc *sc)
|
||||
{
|
||||
@ -1352,19 +1553,19 @@ rt_tx_coherent_intr(struct rt_softc *sc)
|
||||
sc->tx_coherent_interrupts++;
|
||||
|
||||
/* restart DMA engine */
|
||||
tmp = RT_READ(sc, PDMA_BASE + PDMA_GLO_CFG);
|
||||
tmp = RT_READ(sc, sc->pdma_glo_cfg);
|
||||
tmp &= ~(FE_TX_WB_DDONE | FE_TX_DMA_EN);
|
||||
RT_WRITE(sc, PDMA_BASE + PDMA_GLO_CFG, tmp);
|
||||
RT_WRITE(sc, sc->pdma_glo_cfg, tmp);
|
||||
|
||||
for (i = 0; i < RT_SOFTC_TX_RING_COUNT; i++)
|
||||
rt_reset_tx_ring(sc, &sc->tx_ring[i]);
|
||||
|
||||
for (i = 0; i < RT_SOFTC_TX_RING_COUNT; i++) {
|
||||
RT_WRITE(sc, PDMA_BASE + TX_BASE_PTR(i),
|
||||
RT_WRITE(sc, sc->tx_base_ptr[i],
|
||||
sc->tx_ring[i].desc_phys_addr);
|
||||
RT_WRITE(sc, PDMA_BASE + TX_MAX_CNT(i),
|
||||
RT_WRITE(sc, sc->tx_max_cnt[i],
|
||||
RT_SOFTC_TX_RING_DESC_COUNT);
|
||||
RT_WRITE(sc, PDMA_BASE + TX_CTX_IDX(i), 0);
|
||||
RT_WRITE(sc, sc->tx_ctx_idx[i], 0);
|
||||
}
|
||||
|
||||
rt_txrx_enable(sc);
|
||||
@ -1377,24 +1578,29 @@ static void
|
||||
rt_rx_coherent_intr(struct rt_softc *sc)
|
||||
{
|
||||
uint32_t tmp;
|
||||
int i;
|
||||
|
||||
RT_DPRINTF(sc, RT_DEBUG_INTR, "Rx coherent interrupt\n");
|
||||
|
||||
sc->rx_coherent_interrupts++;
|
||||
|
||||
/* restart DMA engine */
|
||||
tmp = RT_READ(sc, PDMA_BASE + PDMA_GLO_CFG);
|
||||
tmp = RT_READ(sc, sc->pdma_glo_cfg);
|
||||
tmp &= ~(FE_RX_DMA_EN);
|
||||
RT_WRITE(sc, PDMA_BASE + PDMA_GLO_CFG, tmp);
|
||||
RT_WRITE(sc, sc->pdma_glo_cfg, tmp);
|
||||
|
||||
/* init Rx ring */
|
||||
rt_reset_rx_ring(sc, &sc->rx_ring);
|
||||
RT_WRITE(sc, PDMA_BASE + RX_BASE_PTR0,
|
||||
sc->rx_ring.desc_phys_addr);
|
||||
RT_WRITE(sc, PDMA_BASE + RX_MAX_CNT0,
|
||||
RT_SOFTC_RX_RING_DATA_COUNT);
|
||||
RT_WRITE(sc, PDMA_BASE + RX_CALC_IDX0,
|
||||
RT_SOFTC_RX_RING_DATA_COUNT - 1);
|
||||
for (i = 0; i < sc->rx_ring_count; i++)
|
||||
rt_reset_rx_ring(sc, &sc->rx_ring[i]);
|
||||
|
||||
for (i = 0; i < sc->rx_ring_count; i++) {
|
||||
RT_WRITE(sc, sc->rx_base_ptr[i],
|
||||
sc->rx_ring[i].desc_phys_addr);
|
||||
RT_WRITE(sc, sc->rx_max_cnt[i],
|
||||
RT_SOFTC_RX_RING_DATA_COUNT);
|
||||
RT_WRITE(sc, sc->rx_calc_idx[i],
|
||||
RT_SOFTC_RX_RING_DATA_COUNT - 1);
|
||||
}
|
||||
|
||||
rt_txrx_enable(sc);
|
||||
}
|
||||
@ -1403,19 +1609,22 @@ rt_rx_coherent_intr(struct rt_softc *sc)
|
||||
* rt_rx_intr - a packet received
|
||||
*/
|
||||
static void
|
||||
rt_rx_intr(struct rt_softc *sc)
|
||||
rt_rx_intr(struct rt_softc *sc, int qid)
|
||||
{
|
||||
KASSERT(qid >= 0 && qid < sc->rx_ring_count,
|
||||
("%s: Rx interrupt: invalid qid=%d\n",
|
||||
device_get_nameunit(sc->dev), qid));
|
||||
|
||||
RT_DPRINTF(sc, RT_DEBUG_INTR, "Rx interrupt\n");
|
||||
sc->rx_interrupts++;
|
||||
sc->rx_interrupts[qid]++;
|
||||
RT_SOFTC_LOCK(sc);
|
||||
|
||||
if (!(sc->intr_disable_mask & INT_RX_DONE)) {
|
||||
rt_intr_disable(sc, INT_RX_DONE);
|
||||
if (!(sc->intr_disable_mask & (sc->int_rx_done_mask << qid))) {
|
||||
rt_intr_disable(sc, (sc->int_rx_done_mask << qid));
|
||||
taskqueue_enqueue(sc->taskqueue, &sc->rx_done_task);
|
||||
}
|
||||
|
||||
sc->intr_pending_mask |= INT_RX_DONE;
|
||||
sc->intr_pending_mask |= (sc->int_rx_done_mask << qid);
|
||||
RT_SOFTC_UNLOCK(sc);
|
||||
}
|
||||
|
||||
@ -1451,12 +1660,12 @@ rt_tx_intr(struct rt_softc *sc, int qid)
|
||||
sc->tx_interrupts[qid]++;
|
||||
RT_SOFTC_LOCK(sc);
|
||||
|
||||
if (!(sc->intr_disable_mask & (INT_TXQ0_DONE << qid))) {
|
||||
rt_intr_disable(sc, (INT_TXQ0_DONE << qid));
|
||||
if (!(sc->intr_disable_mask & (sc->int_tx_done_mask << qid))) {
|
||||
rt_intr_disable(sc, (sc->int_tx_done_mask << qid));
|
||||
taskqueue_enqueue(sc->taskqueue, &sc->tx_done_task);
|
||||
}
|
||||
|
||||
sc->intr_pending_mask |= (INT_TXQ0_DONE << qid);
|
||||
sc->intr_pending_mask |= (sc->int_tx_done_mask << qid);
|
||||
RT_SOFTC_UNLOCK(sc);
|
||||
}
|
||||
|
||||
@ -1478,18 +1687,18 @@ rt_rx_done_task(void *context, int pending)
|
||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
|
||||
return;
|
||||
|
||||
sc->intr_pending_mask &= ~INT_RX_DONE;
|
||||
sc->intr_pending_mask &= ~sc->int_rx_done_mask;
|
||||
|
||||
again = rt_rx_eof(sc, sc->rx_process_limit);
|
||||
again = rt_rx_eof(sc, &sc->rx_ring[0], sc->rx_process_limit);
|
||||
|
||||
RT_SOFTC_LOCK(sc);
|
||||
|
||||
if ((sc->intr_pending_mask & INT_RX_DONE) || again) {
|
||||
if ((sc->intr_pending_mask & sc->int_rx_done_mask) || again) {
|
||||
RT_DPRINTF(sc, RT_DEBUG_RX,
|
||||
"Rx done task: scheduling again\n");
|
||||
taskqueue_enqueue(sc->taskqueue, &sc->rx_done_task);
|
||||
} else {
|
||||
rt_intr_enable(sc, INT_RX_DONE);
|
||||
rt_intr_enable(sc, sc->int_rx_done_mask);
|
||||
}
|
||||
|
||||
RT_SOFTC_UNLOCK(sc);
|
||||
@ -1515,8 +1724,8 @@ rt_tx_done_task(void *context, int pending)
|
||||
return;
|
||||
|
||||
for (i = RT_SOFTC_TX_RING_COUNT - 1; i >= 0; i--) {
|
||||
if (sc->intr_pending_mask & (INT_TXQ0_DONE << i)) {
|
||||
sc->intr_pending_mask &= ~(INT_TXQ0_DONE << i);
|
||||
if (sc->intr_pending_mask & (sc->int_tx_done_mask << i)) {
|
||||
sc->intr_pending_mask &= ~(sc->int_tx_done_mask << i);
|
||||
rt_tx_eof(sc, &sc->tx_ring[i]);
|
||||
}
|
||||
}
|
||||
@ -1525,7 +1734,15 @@ rt_tx_done_task(void *context, int pending)
|
||||
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
|
||||
intr_mask = (
|
||||
if(sc->rt_chipid == RT_CHIPID_RT5350 ||
|
||||
sc->rt_chipid == RT_CHIPID_MT7620)
|
||||
intr_mask = (
|
||||
RT5350_INT_TXQ3_DONE |
|
||||
RT5350_INT_TXQ2_DONE |
|
||||
RT5350_INT_TXQ1_DONE |
|
||||
RT5350_INT_TXQ0_DONE);
|
||||
else
|
||||
intr_mask = (
|
||||
INT_TXQ3_DONE |
|
||||
INT_TXQ2_DONE |
|
||||
INT_TXQ1_DONE |
|
||||
@ -1584,10 +1801,10 @@ rt_periodic_task(void *context, int pending)
|
||||
* network subsystem.
|
||||
*/
|
||||
static int
|
||||
rt_rx_eof(struct rt_softc *sc, int limit)
|
||||
rt_rx_eof(struct rt_softc *sc, struct rt_softc_rx_ring *ring, int limit)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
struct rt_softc_rx_ring *ring;
|
||||
/* struct rt_softc_rx_ring *ring; */
|
||||
struct rt_rxdesc *desc;
|
||||
struct rt_softc_rx_data *data;
|
||||
struct mbuf *m, *mnew;
|
||||
@ -1597,12 +1814,12 @@ rt_rx_eof(struct rt_softc *sc, int limit)
|
||||
int error, nsegs, len, nframes;
|
||||
|
||||
ifp = sc->ifp;
|
||||
ring = &sc->rx_ring;
|
||||
/* ring = &sc->rx_ring[0]; */
|
||||
|
||||
nframes = 0;
|
||||
|
||||
while (limit != 0) {
|
||||
index = RT_READ(sc, PDMA_BASE + RX_DRX_IDX0);
|
||||
index = RT_READ(sc, sc->rx_drx_idx[0]);
|
||||
if (ring->cur == index)
|
||||
break;
|
||||
|
||||
@ -1728,10 +1945,10 @@ skip:
|
||||
}
|
||||
|
||||
if (ring->cur == 0)
|
||||
RT_WRITE(sc, PDMA_BASE + RX_CALC_IDX0,
|
||||
RT_WRITE(sc, sc->rx_calc_idx[0],
|
||||
RT_SOFTC_RX_RING_DATA_COUNT - 1);
|
||||
else
|
||||
RT_WRITE(sc, PDMA_BASE + RX_CALC_IDX0,
|
||||
RT_WRITE(sc, sc->rx_calc_idx[0],
|
||||
ring->cur - 1);
|
||||
|
||||
RT_DPRINTF(sc, RT_DEBUG_RX, "Rx eof: nframes=%d\n", nframes);
|
||||
@ -1760,7 +1977,7 @@ rt_tx_eof(struct rt_softc *sc, struct rt_softc_tx_ring *ring)
|
||||
nframes = 0;
|
||||
|
||||
for (;;) {
|
||||
index = RT_READ(sc, PDMA_BASE + TX_DTX_IDX(ring->qid));
|
||||
index = RT_READ(sc, sc->tx_dtx_idx[ring->qid]);
|
||||
if (ring->desc_next == index)
|
||||
break;
|
||||
|
||||
@ -1834,12 +2051,13 @@ rt_watchdog(struct rt_softc *sc)
|
||||
#ifdef notyet
|
||||
int ntries;
|
||||
#endif
|
||||
if(sc->rt_chipid != RT_CHIPID_RT5350 &&
|
||||
sc->rt_chipid != RT_CHIPID_MT7620) {
|
||||
tmp = RT_READ(sc, PSE_BASE + CDMA_OQ_STA);
|
||||
|
||||
tmp = RT_READ(sc, PSE_BASE + CDMA_OQ_STA);
|
||||
|
||||
RT_DPRINTF(sc, RT_DEBUG_WATCHDOG, "watchdog: PSE_IQ_STA=0x%08x\n",
|
||||
tmp);
|
||||
|
||||
RT_DPRINTF(sc, RT_DEBUG_WATCHDOG,
|
||||
"watchdog: PSE_IQ_STA=0x%08x\n", tmp);
|
||||
}
|
||||
/* XXX: do not reset */
|
||||
#ifdef notyet
|
||||
if (((tmp >> P0_IQ_PCNT_SHIFT) & 0xff) != 0) {
|
||||
@ -1896,7 +2114,7 @@ rt_intr_enable(struct rt_softc *sc, uint32_t intr_mask)
|
||||
|
||||
sc->intr_disable_mask &= ~intr_mask;
|
||||
tmp = sc->intr_enable_mask & ~sc->intr_disable_mask;
|
||||
RT_WRITE(sc, GE_PORT_BASE + FE_INT_ENABLE, tmp);
|
||||
RT_WRITE(sc, sc->fe_int_enable, tmp);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1906,7 +2124,7 @@ rt_intr_disable(struct rt_softc *sc, uint32_t intr_mask)
|
||||
|
||||
sc->intr_disable_mask |= intr_mask;
|
||||
tmp = sc->intr_enable_mask & ~sc->intr_disable_mask;
|
||||
RT_WRITE(sc, GE_PORT_BASE + FE_INT_ENABLE, tmp);
|
||||
RT_WRITE(sc, sc->fe_int_enable, tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1923,7 +2141,7 @@ rt_txrx_enable(struct rt_softc *sc)
|
||||
|
||||
/* enable Tx/Rx DMA engine */
|
||||
for (ntries = 0; ntries < 200; ntries++) {
|
||||
tmp = RT_READ(sc, PDMA_BASE + PDMA_GLO_CFG);
|
||||
tmp = RT_READ(sc, sc->pdma_glo_cfg);
|
||||
if (!(tmp & (FE_TX_DMA_BUSY | FE_RX_DMA_BUSY)))
|
||||
break;
|
||||
|
||||
@ -1938,7 +2156,7 @@ rt_txrx_enable(struct rt_softc *sc)
|
||||
DELAY(50);
|
||||
|
||||
tmp |= FE_TX_WB_DDONE | FE_RX_DMA_EN | FE_TX_DMA_EN;
|
||||
RT_WRITE(sc, PDMA_BASE + PDMA_GLO_CFG, tmp);
|
||||
RT_WRITE(sc, sc->pdma_glo_cfg, tmp);
|
||||
|
||||
/* XXX set Rx filter */
|
||||
return (0);
|
||||
@ -1948,7 +2166,7 @@ rt_txrx_enable(struct rt_softc *sc)
|
||||
* rt_alloc_rx_ring - allocate RX DMA ring buffer
|
||||
*/
|
||||
static int
|
||||
rt_alloc_rx_ring(struct rt_softc *sc, struct rt_softc_rx_ring *ring)
|
||||
rt_alloc_rx_ring(struct rt_softc *sc, struct rt_softc_rx_ring *ring, int qid)
|
||||
{
|
||||
struct rt_rxdesc *desc;
|
||||
struct rt_softc_rx_data *data;
|
||||
@ -2041,6 +2259,7 @@ rt_alloc_rx_ring(struct rt_softc *sc, struct rt_softc_rx_ring *ring)
|
||||
|
||||
bus_dmamap_sync(ring->desc_dma_tag, ring->desc_dma_map,
|
||||
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
|
||||
ring->qid = qid;
|
||||
return (0);
|
||||
|
||||
fail:
|
||||
@ -2352,7 +2571,7 @@ rt_sysctl_attach(struct rt_softc *sc)
|
||||
"Rx coherent interrupts");
|
||||
|
||||
SYSCTL_ADD_ULONG(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
|
||||
"rx_interrupts", CTLFLAG_RD, &sc->rx_interrupts,
|
||||
"rx_interrupts", CTLFLAG_RD, &sc->rx_interrupts[0],
|
||||
"Rx interrupts");
|
||||
|
||||
SYSCTL_ADD_ULONG(ctx, SYSCTL_CHILDREN(stats), OID_AUTO,
|
||||
@ -2606,6 +2825,10 @@ static driver_t rt_driver =
|
||||
static devclass_t rt_dev_class;
|
||||
|
||||
DRIVER_MODULE(rt, nexus, rt_driver, rt_dev_class, 0, 0);
|
||||
#ifdef FDT
|
||||
DRIVER_MODULE(rt, simplebus, rt_driver, rt_dev_class, 0, 0);
|
||||
#endif
|
||||
|
||||
MODULE_DEPEND(rt, ether, 1, 1, 1);
|
||||
MODULE_DEPEND(rt, miibus, 1, 1, 1);
|
||||
|
||||
|
@ -62,6 +62,7 @@
|
||||
#define FC_DROP_CNT_SHIFT 16
|
||||
#define PSE_RESET (1<<0)
|
||||
|
||||
/* RT305x interrupt registers */
|
||||
#define FE_INT_STATUS 0x10
|
||||
#define CNT_PPE_AF (1<<31)
|
||||
#define CNT_GDM_AF (1<<29)
|
||||
@ -82,6 +83,21 @@
|
||||
#define TX_DLY_INT (1<<1) /* TXQ[0|1]_DONE with delay */
|
||||
#define RX_DLY_INT (1<<0) /* RX_DONE with delay */
|
||||
#define FE_INT_ENABLE 0x14
|
||||
|
||||
/* RT5350 interrupt registers */
|
||||
#define RT5350_FE_INT_STATUS (RT5350_PDMA_BASE + 0x220)
|
||||
#define RT5350_INT_RX_COHERENT (1<<31)
|
||||
#define RT5350_RX_DLY_INT (1<<30)
|
||||
#define RT5350_INT_TX_COHERENT (1<<29)
|
||||
#define RT5350_TX_DLY_INT (1<<28)
|
||||
#define RT5350_INT_RXQ1_DONE (1<<17)
|
||||
#define RT5350_INT_RXQ0_DONE (1<<16)
|
||||
#define RT5350_INT_TXQ3_DONE (1<<3)
|
||||
#define RT5350_INT_TXQ2_DONE (1<<2)
|
||||
#define RT5350_INT_TXQ1_DONE (1<<1)
|
||||
#define RT5350_INT_TXQ0_DONE (1<<0)
|
||||
#define RT5350_FE_INT_ENABLE (RT5350_PDMA_BASE + 0x228)
|
||||
|
||||
#define MDIO_CFG2 0x18
|
||||
#define FOE_TS_T 0x1c
|
||||
#define PSE_FQ_PCNT_MASK 0xff000000
|
||||
@ -208,7 +224,9 @@
|
||||
#define P0_IQ_PCNT_SHIFT 0
|
||||
|
||||
#define PDMA_BASE 0x0100
|
||||
#define RT5350_PDMA_BASE 0x0800
|
||||
#define PDMA_GLO_CFG 0x00
|
||||
#define RT5350_PDMA_GLO_CFG 0x204
|
||||
#define FE_TX_WB_DDONE (1<<6)
|
||||
#define FE_DMA_BT_SIZE4 (0<<4)
|
||||
#define FE_DMA_BT_SIZE8 (1<<4)
|
||||
@ -218,6 +236,7 @@
|
||||
#define FE_TX_DMA_BUSY (1<<1)
|
||||
#define FE_TX_DMA_EN (1<<0)
|
||||
#define PDMA_RST_IDX 0x04
|
||||
#define RT5350_PDMA_RST_IDX 0x208
|
||||
#define FE_RST_DRX_IDX0 (1<<16)
|
||||
#define FE_RST_DTX_IDX3 (1<<3)
|
||||
#define FE_RST_DTX_IDX2 (1<<2)
|
||||
@ -225,7 +244,9 @@
|
||||
#define FE_RST_DTX_IDX0 (1<<0)
|
||||
|
||||
#define PDMA_SCH_CFG 0x08
|
||||
#define RT5350_PDMA_SCH_CFG 0x280
|
||||
#define DELAY_INT_CFG 0x0C
|
||||
#define RT5350_DELAY_INT_CFG 0x20C
|
||||
#define TXDLY_INT_EN (1<<31)
|
||||
#define TXMAX_PINT_SHIFT 24
|
||||
#define TXMAX_PTIME_SHIFT 16
|
||||
@ -263,6 +284,41 @@
|
||||
#define TX_CTX_IDX(qid) (((qid>1)?(0x28):(0x18)) + (qid) * 16)
|
||||
#define TX_DTX_IDX(qid) (((qid>1)?(0x2c):(0x1c)) + (qid) * 16)
|
||||
|
||||
#define RT5350_TX_BASE_PTR0 0x000
|
||||
#define RT5350_TX_MAX_CNT0 0x004
|
||||
#define RT5350_TX_CTX_IDX0 0x008
|
||||
#define RT5350_TX_DTX_IDX0 0x00C
|
||||
|
||||
#define RT5350_TX_BASE_PTR1 0x010
|
||||
#define RT5350_TX_MAX_CNT1 0x014
|
||||
#define RT5350_TX_CTX_IDX1 0x018
|
||||
#define RT5350_TX_DTX_IDX1 0x01C
|
||||
|
||||
#define RT5350_TX_BASE_PTR2 0x020
|
||||
#define RT5350_TX_MAX_CNT2 0x024
|
||||
#define RT5350_TX_CTX_IDX2 0x028
|
||||
#define RT5350_TX_DTX_IDX2 0x02C
|
||||
|
||||
#define RT5350_TX_BASE_PTR3 0x030
|
||||
#define RT5350_TX_MAX_CNT3 0x034
|
||||
#define RT5350_TX_CTX_IDX3 0x038
|
||||
#define RT5350_TX_DTX_IDX3 0x03C
|
||||
|
||||
#define RT5350_RX_BASE_PTR0 0x100
|
||||
#define RT5350_RX_MAX_CNT0 0x104
|
||||
#define RT5350_RX_CALC_IDX0 0x108
|
||||
#define RT5350_RX_DRX_IDX0 0x10C
|
||||
|
||||
#define RT5350_RX_BASE_PTR1 0x110
|
||||
#define RT5350_RX_MAX_CNT1 0x114
|
||||
#define RT5350_RX_CALC_IDX1 0x118
|
||||
#define RT5350_RX_DRX_IDX1 0x11C
|
||||
|
||||
#define RT5350_TX_BASE_PTR(qid) ((qid) * 0x10 + 0x000)
|
||||
#define RT5350_TX_MAX_CNT(qid) ((qid) * 0x10 + 0x004)
|
||||
#define RT5350_TX_CTX_IDX(qid) ((qid) * 0x10 + 0x008)
|
||||
#define RT5350_TX_DTX_IDX(qid) ((qid) * 0x10 + 0x00C)
|
||||
|
||||
#define PPE_BASE 0x0200
|
||||
|
||||
#define CNTR_BASE 0x0400
|
||||
|
@ -68,6 +68,7 @@
|
||||
mtx_assert(&(ring)->lock, MA_OWNED)
|
||||
|
||||
#define RT_SOFTC_TX_RING_COUNT 4
|
||||
#define RT_SOFTC_RX_RING_COUNT 4
|
||||
|
||||
#ifndef IF_RT_RING_DATA_COUNT
|
||||
#define IF_RT_RING_DATA_COUNT 128
|
||||
@ -151,6 +152,7 @@ struct rt_softc_rx_ring
|
||||
bus_dmamap_t spare_dma_map;
|
||||
struct rt_softc_rx_data data[RT_SOFTC_RX_RING_DATA_COUNT];
|
||||
int cur;
|
||||
int qid;
|
||||
};
|
||||
|
||||
struct rt_softc_tx_data
|
||||
@ -216,7 +218,7 @@ struct rt_softc
|
||||
unsigned long periodic_round;
|
||||
struct taskqueue *taskqueue;
|
||||
|
||||
struct rt_softc_rx_ring rx_ring;
|
||||
struct rt_softc_rx_ring rx_ring[RT_SOFTC_RX_RING_COUNT];
|
||||
struct rt_softc_tx_ring tx_ring[RT_SOFTC_TX_RING_COUNT];
|
||||
int tx_ring_mgtqid;
|
||||
|
||||
@ -227,7 +229,7 @@ struct rt_softc
|
||||
unsigned long interrupts;
|
||||
unsigned long tx_coherent_interrupts;
|
||||
unsigned long rx_coherent_interrupts;
|
||||
unsigned long rx_interrupts;
|
||||
unsigned long rx_interrupts[RT_SOFTC_RX_RING_COUNT];
|
||||
unsigned long rx_delay_interrupts;
|
||||
unsigned long tx_interrupts[RT_SOFTC_TX_RING_COUNT];
|
||||
unsigned long tx_delay_interrupts;
|
||||
@ -257,6 +259,25 @@ struct rt_softc
|
||||
#ifdef IF_RT_DEBUG
|
||||
int debug;
|
||||
#endif
|
||||
|
||||
uint32_t rt_chipid;
|
||||
/* chip specific registers config */
|
||||
int rx_ring_count;
|
||||
uint32_t int_rx_done_mask;
|
||||
uint32_t int_tx_done_mask;
|
||||
uint32_t delay_int_cfg;
|
||||
uint32_t fe_int_status;
|
||||
uint32_t fe_int_enable;
|
||||
uint32_t pdma_glo_cfg;
|
||||
uint32_t pdma_rst_idx;
|
||||
uint32_t tx_base_ptr[RT_SOFTC_TX_RING_COUNT];
|
||||
uint32_t tx_max_cnt[RT_SOFTC_TX_RING_COUNT];
|
||||
uint32_t tx_ctx_idx[RT_SOFTC_TX_RING_COUNT];
|
||||
uint32_t tx_dtx_idx[RT_SOFTC_TX_RING_COUNT];
|
||||
uint32_t rx_base_ptr[RT_SOFTC_RX_RING_COUNT];
|
||||
uint32_t rx_max_cnt[RT_SOFTC_RX_RING_COUNT];
|
||||
uint32_t rx_calc_idx[RT_SOFTC_RX_RING_COUNT];
|
||||
uint32_t rx_drx_idx[RT_SOFTC_RX_RING_COUNT];
|
||||
};
|
||||
|
||||
#ifdef IF_RT_DEBUG
|
||||
@ -274,7 +295,7 @@ enum
|
||||
|
||||
#define RT_DPRINTF(sc, m, fmt, ...) \
|
||||
do { if ((sc)->debug & (m)) \
|
||||
device_printf(sc->dev, fmt, __VA_ARGS__); } while (0)
|
||||
device_printf(sc->dev, fmt, ## __VA_ARGS__); } while (0)
|
||||
#else
|
||||
#define RT_DPRINTF(sc, m, fmt, ...)
|
||||
#endif /* #ifdef IF_RT_DEBUG */
|
||||
|
Loading…
x
Reference in New Issue
Block a user