Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 Dec 2015 18:41:17 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r292704 - head/sys/dev/rt
Message-ID:  <201512241841.tBOIfHFe064302@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Thu Dec 24 18:41:16 2015
New Revision: 292704
URL: https://svnweb.freebsd.org/changeset/base/292704

Log:
  [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>

Modified:
  head/sys/dev/rt/if_rt.c
  head/sys/dev/rt/if_rtreg.h
  head/sys/dev/rt/if_rtvar.h

Modified: head/sys/dev/rt/if_rt.c
==============================================================================
--- head/sys/dev/rt/if_rt.c	Thu Dec 24 18:40:10 2015	(r292703)
+++ head/sys/dev/rt/if_rt.c	Thu Dec 24 18:41:16 2015	(r292704)
@@ -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
 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_sof
 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, CTLF
 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 
 	 * "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 
 	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);
-
-	/* reset adapter */
-	RT_WRITE(sc, GE_PORT_BASE + FE_RST_GLO, PSE_RESET);
+	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);
 
-	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 m
 
 	/* 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 m
 	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 pendi
 	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 pendi
 		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 pendi
 
 	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 pend
  * 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
 	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, uint
 
 	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, uin
 
 	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, st
 
 	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);
 

Modified: head/sys/dev/rt/if_rtreg.h
==============================================================================
--- head/sys/dev/rt/if_rtreg.h	Thu Dec 24 18:40:10 2015	(r292703)
+++ head/sys/dev/rt/if_rtreg.h	Thu Dec 24 18:41:16 2015	(r292704)
@@ -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

Modified: head/sys/dev/rt/if_rtvar.h
==============================================================================
--- head/sys/dev/rt/if_rtvar.h	Thu Dec 24 18:40:10 2015	(r292703)
+++ head/sys/dev/rt/if_rtvar.h	Thu Dec 24 18:41:16 2015	(r292704)
@@ -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];
 };

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201512241841.tBOIfHFe064302>