Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137158688
D7031.id18386.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D7031.id18386.diff
View Options
Index: head/sys/arm/allwinner/if_awg.c
===================================================================
--- head/sys/arm/allwinner/if_awg.c
+++ head/sys/arm/allwinner/if_awg.c
@@ -30,6 +30,8 @@
* Allwinner Gigabit Ethernet MAC (EMAC) controller
*/
+#include "opt_device_polling.h"
+
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -77,7 +79,7 @@
#define AWG_ASSERT_UNLOCKED(sc) mtx_assert(&(sc)->mtx, MA_NOTOWNED)
#define DESC_ALIGN 4
-#define TX_DESC_COUNT 256
+#define TX_DESC_COUNT 1024
#define TX_DESC_SIZE (sizeof(struct emac_desc) * TX_DESC_COUNT)
#define RX_DESC_COUNT 256
#define RX_DESC_SIZE (sizeof(struct emac_desc) * RX_DESC_COUNT)
@@ -97,6 +99,7 @@
#define RX_TX_PRI_DEFAULT 0
#define PAUSE_TIME_DEFAULT 0x400
#define TX_INTERVAL_DEFAULT 64
+#define RX_BATCH_DEFAULT 64
/* Burst length of RX and TX DMA transfers */
static int awg_burst_len = BURST_LEN_DEFAULT;
@@ -114,6 +117,10 @@
static int awg_tx_interval = TX_INTERVAL_DEFAULT;
TUNABLE_INT("hw.awg.tx_interval", &awg_tx_interval);
+/* Maximum number of mbufs to send to if_input */
+static int awg_rx_batch = RX_BATCH_DEFAULT;
+TUNABLE_INT("hw.awg.rx_batch", &awg_rx_batch);
+
static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun8i-a83t-emac", 1 },
{ NULL, 0 }
@@ -353,7 +360,7 @@
status = TX_DESC_CTL;
size = flags | len;
if ((index & (awg_tx_interval - 1)) == 0)
- size |= htole32(TX_INT_CTL);
+ size |= TX_INT_CTL;
++sc->tx.queued;
}
@@ -617,6 +624,20 @@
}
static void
+awg_enable_intr(struct awg_softc *sc)
+{
+ /* Enable interrupts */
+ WR4(sc, EMAC_INT_EN, RX_INT_EN | TX_INT_EN | TX_BUF_UA_INT_EN);
+}
+
+static void
+awg_disable_intr(struct awg_softc *sc)
+{
+ /* Disable interrupts */
+ WR4(sc, EMAC_INT_EN, 0);
+}
+
+static void
awg_init_locked(struct awg_softc *sc)
{
struct mii_data *mii;
@@ -640,11 +661,18 @@
WR4(sc, EMAC_BASIC_CTL_1, val);
/* Enable interrupts */
- WR4(sc, EMAC_INT_EN, RX_INT_EN | TX_INT_EN | TX_BUF_UA_INT_EN);
+#ifdef DEVICE_POLLING
+ if ((if_getcapenable(ifp) & IFCAP_POLLING) == 0)
+ awg_enable_intr(sc);
+ else
+ awg_disable_intr(sc);
+#else
+ awg_enable_intr(sc);
+#endif
/* Enable transmit DMA */
val = RD4(sc, EMAC_TX_CTL_1);
- WR4(sc, EMAC_TX_CTL_1, val | TX_DMA_EN | TX_MD);
+ WR4(sc, EMAC_TX_CTL_1, val | TX_DMA_EN | TX_MD | TX_NEXT_FRAME);
/* Enable receive DMA */
val = RD4(sc, EMAC_RX_CTL_1);
@@ -703,7 +731,7 @@
WR4(sc, EMAC_RX_CTL_0, val & ~RX_EN);
/* Disable interrupts */
- WR4(sc, EMAC_INT_EN, 0);
+ awg_disable_intr(sc);
/* Disable transmit DMA */
val = RD4(sc, EMAC_TX_CTL_1);
@@ -718,15 +746,18 @@
if_setdrvflagbits(ifp, 0, IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
}
-static void
+static int
awg_rxintr(struct awg_softc *sc)
{
if_t ifp;
- struct mbuf *m, *m0;
- int error, index, len;
+ struct mbuf *m, *m0, *mh, *mt;
+ int error, index, len, cnt, npkt;
uint32_t status;
ifp = sc->ifp;
+ mh = mt = NULL;
+ cnt = 0;
+ npkt = 0;
bus_dmamap_sync(sc->rx.desc_tag, sc->rx.desc_map,
BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
@@ -760,9 +791,23 @@
}
}
- AWG_UNLOCK(sc);
- if_input(ifp, m);
- AWG_LOCK(sc);
+ m->m_nextpkt = NULL;
+ if (mh == NULL)
+ mh = m;
+ else
+ mt->m_nextpkt = m;
+ mt = m;
+ ++cnt;
+ ++npkt;
+
+ if (cnt == awg_rx_batch) {
+ AWG_UNLOCK(sc);
+ if_input(ifp, mh);
+ AWG_LOCK(sc);
+ mh = mt = NULL;
+ cnt = 0;
+ }
+
}
if ((m0 = awg_alloc_mbufcl(sc)) != NULL) {
@@ -779,7 +824,15 @@
BUS_DMASYNC_PREWRITE);
}
+ if (mh != NULL) {
+ AWG_UNLOCK(sc);
+ if_input(ifp, mh);
+ AWG_LOCK(sc);
+ }
+
sc->rx.cur = index;
+
+ return (npkt);
}
static void
@@ -845,6 +898,41 @@
AWG_UNLOCK(sc);
}
+#ifdef DEVICE_POLLING
+static int
+awg_poll(if_t ifp, enum poll_cmd cmd, int count)
+{
+ struct awg_softc *sc;
+ uint32_t val;
+ int rx_npkts;
+
+ sc = if_getsoftc(ifp);
+ rx_npkts = 0;
+
+ AWG_LOCK(sc);
+
+ if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0) {
+ AWG_UNLOCK(sc);
+ return (0);
+ }
+
+ rx_npkts = awg_rxintr(sc);
+ awg_txintr(sc);
+ if (!if_sendq_empty(ifp))
+ awg_start_locked(sc);
+
+ if (cmd == POLL_AND_CHECK_STATUS) {
+ val = RD4(sc, EMAC_INT_STA);
+ if (val != 0)
+ WR4(sc, EMAC_INT_STA, val);
+ }
+
+ AWG_UNLOCK(sc);
+
+ return (rx_npkts);
+}
+#endif
+
static int
awg_ioctl(if_t ifp, u_long cmd, caddr_t data)
{
@@ -889,6 +977,25 @@
break;
case SIOCSIFCAP:
mask = ifr->ifr_reqcap ^ if_getcapenable(ifp);
+#ifdef DEVICE_POLLING
+ if (mask & IFCAP_POLLING) {
+ if ((ifr->ifr_reqcap & IFCAP_POLLING) != 0) {
+ error = ether_poll_register(awg_poll, ifp);
+ if (error != 0)
+ break;
+ AWG_LOCK(sc);
+ awg_disable_intr(sc);
+ if_setcapenablebit(ifp, IFCAP_POLLING, 0);
+ AWG_UNLOCK(sc);
+ } else {
+ error = ether_poll_deregister(ifp);
+ AWG_LOCK(sc);
+ awg_enable_intr(sc);
+ if_setcapenablebit(ifp, 0, IFCAP_POLLING);
+ AWG_UNLOCK(sc);
+ }
+ }
+#endif
if (mask & IFCAP_VLAN_MTU)
if_togglecapenable(ifp, IFCAP_VLAN_MTU);
if (mask & IFCAP_RXCSUM)
@@ -1374,6 +1481,9 @@
if_sethwassist(sc->ifp, CSUM_IP | CSUM_UDP | CSUM_TCP);
if_setcapabilities(sc->ifp, IFCAP_VLAN_MTU | IFCAP_HWCSUM);
if_setcapenable(sc->ifp, if_getcapabilities(sc->ifp));
+#ifdef DEVICE_POLLING
+ if_setcapabilitiesbit(sc->ifp, IFCAP_POLLING, 0);
+#endif
/* Attach MII driver */
error = mii_attach(dev, &sc->miibus, sc->ifp, awg_media_change,
Index: head/sys/arm/allwinner/if_awgreg.h
===================================================================
--- head/sys/arm/allwinner/if_awgreg.h
+++ head/sys/arm/allwinner/if_awgreg.h
@@ -65,6 +65,7 @@
#define EMAC_TX_CTL_1 0x14
#define TX_DMA_START (1 << 31)
#define TX_DMA_EN (1 << 30)
+#define TX_NEXT_FRAME (1 << 2)
#define TX_MD (1 << 1)
#define FLUSH_TX_FIFO (1 << 0)
#define EMAC_TX_FLOW_CTL 0x1c
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 22, 7:47 AM (18 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25935004
Default Alt Text
D7031.id18386.diff (5 KB)
Attached To
Mode
D7031: if_awg: performance improvements
Attached
Detach File
Event Timeline
Log In to Comment