Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 May 2021 22:30:50 GMT
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 77b637338a36 - main - alc(4): add support for Mikrotik 10/25G NIC
Message-ID:  <202105192230.14JMUokt090580@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=77b637338a3656d4ccedb9798a3f98ac283962f4

commit 77b637338a3656d4ccedb9798a3f98ac283962f4
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2021-05-19 22:14:18 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2021-05-19 22:30:25 +0000

    alc(4): add support for Mikrotik 10/25G NIC
    
    The new Mikrotik 10/25G NIC is mostly compatible with AR8151 hardware,
    with few exceptions:
    
    * card supports only 32bit DMA operations
    * card does not support write-one-to-clear semantics for interrupt status
      register
    * MDIO operations can take longer to complete
    
    This patch adds support for Mikrotik 10/25G NIC to the alc driver
    while maintaining support for all earlier HW.
    
    The patch was tested with FreeBSD main branch as of commit
    f4b38c360e63a6e66245efedbd6c070f9c0aee55
    
    This was tested on Intel i7-4790K system with Mikrotik 10/25G NIC.
    This was tested on Intel i7-4790K system with RB44Ge (AR8151 based 4-port NIC)
    to verify backwards compatibility.
    
    PR:     256000
    Submitted by:    Gatis Peisenieks  <gatis@mikrotik.com>
    MFC after:      1 week
---
 sys/dev/alc/if_alc.c    | 16 ++++++++++++++--
 sys/dev/alc/if_alcreg.h |  8 ++++++++
 sys/dev/alc/if_alcvar.h |  3 ++-
 3 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c
index 255fea53acfa..eb906d60bcbe 100644
--- a/sys/dev/alc/if_alc.c
+++ b/sys/dev/alc/if_alc.c
@@ -1438,6 +1438,8 @@ alc_attach(device_t dev)
 	case DEVICEID_ATHEROS_AR8151:
 	case DEVICEID_ATHEROS_AR8151_V2:
 		sc->alc_flags |= ALC_FLAG_APS;
+		if (CSR_READ_4(sc, ALC_MT_MAGIC) == MT_MAGIC)
+			sc->alc_flags |= ALC_FLAG_MT;
 		/* FALLTHROUGH */
 	default:
 		break;
@@ -1977,6 +1979,8 @@ alc_dma_alloc(struct alc_softc *sc)
 	int error, i;
 
 	lowaddr = BUS_SPACE_MAXADDR;
+	if (sc->alc_flags & ALC_FLAG_MT)
+		lowaddr = BUS_SPACE_MAXSIZE_32BIT;
 again:
 	/* Create parent DMA tag. */
 	error = bus_dma_tag_create(
@@ -2219,7 +2223,7 @@ again:
 	error = bus_dma_tag_create(
 	    bus_get_dma_tag(sc->alc_dev), /* parent */
 	    1, 0,			/* alignment, boundary */
-	    BUS_SPACE_MAXADDR,		/* lowaddr */
+	    lowaddr,			/* lowaddr */
 	    BUS_SPACE_MAXADDR,		/* highaddr */
 	    NULL, NULL,			/* filter, filterarg */
 	    BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
@@ -3339,6 +3343,11 @@ alc_intr(void *arg)
 
 	sc = (struct alc_softc *)arg;
 
+	if (sc->alc_flags & ALC_FLAG_MT) {
+		taskqueue_enqueue(sc->alc_tq, &sc->alc_int_task);
+		return (FILTER_HANDLED);
+	}
+
 	status = CSR_READ_4(sc, ALC_INTR_STATUS);
 	if ((status & ALC_INTRS) == 0)
 		return (FILTER_STRAY);
@@ -3416,7 +3425,10 @@ alc_int_task(void *arg, int pending)
 done:
 	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) {
 		/* Re-enable interrupts if we're running. */
-		CSR_WRITE_4(sc, ALC_INTR_STATUS, 0x7FFFFFFF);
+		if (sc->alc_flags & ALC_FLAG_MT)
+			CSR_WRITE_4(sc, ALC_INTR_STATUS, 0);
+		else
+			CSR_WRITE_4(sc, ALC_INTR_STATUS, 0x7FFFFFFF);
 	}
 	ALC_UNLOCK(sc);
 }
diff --git a/sys/dev/alc/if_alcreg.h b/sys/dev/alc/if_alcreg.h
index 3b4ee133b01a..7668f0960d9f 100644
--- a/sys/dev/alc/if_alcreg.h
+++ b/sys/dev/alc/if_alcreg.h
@@ -1121,6 +1121,14 @@
 #define	MII_EXT_ANEG_NLP78		0x8027
 #define	ANEG_NLP78_120M_DEFAULT		0x8A05
 
+#define ALC_MT_MAGIC			0x1F00
+#define ALC_MT_MODE			0x1F04
+#define ALC_MT_SPEED			0x1F08
+#define ALC_MT_VERSION			0x1F0C
+
+#define MT_MAGIC			0xaabb1234
+#define MT_MODE_4Q			BIT(0)
+
 /* Statistics counters collected by the MAC. */
 struct smb {
 	/* Rx stats. */
diff --git a/sys/dev/alc/if_alcvar.h b/sys/dev/alc/if_alcvar.h
index 8dea20196dae..926c80021858 100644
--- a/sys/dev/alc/if_alcvar.h
+++ b/sys/dev/alc/if_alcvar.h
@@ -239,6 +239,7 @@ struct alc_softc {
 #define	ALC_FLAG_LINK_WAR	0x4000
 #define	ALC_FLAG_E2X00		0x8000
 #define	ALC_FLAG_LINK		0x10000
+#define	ALC_FLAG_MT		0x20000
 
 	struct callout		alc_tick_ch;
 	struct alc_hw_stats	alc_stats;
@@ -284,6 +285,6 @@ do {									\
 #define	ALC_TX_TIMEOUT		5
 #define	ALC_RESET_TIMEOUT	100
 #define	ALC_TIMEOUT		1000
-#define	ALC_PHY_TIMEOUT		1000
+#define	ALC_PHY_TIMEOUT		10000
 
 #endif	/* _IF_ALCVAR_H */



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