From 9e511d5342999ecc11e83799ebc6ffd2240facbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Thu, 20 May 2021 01:14:18 +0300 Subject: [PATCH] atheros813x: import patch from stable FreeBSD13 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 MFC after: 1 week Change-Id: I83cdeb24caccad15a9647a72159d979ecbd647f0 Reviewed-on: https://review.haiku-os.org/c/haiku/+/4361 Tested-by: Commit checker robot Reviewed-by: Jérôme Duval --- .../drivers/network/atheros813x/dev/alc/if_alc.c | 16 ++++++++++++++-- .../network/atheros813x/dev/alc/if_alcreg.h | 8 ++++++++ .../network/atheros813x/dev/alc/if_alcvar.h | 3 ++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/add-ons/kernel/drivers/network/atheros813x/dev/alc/if_alc.c b/src/add-ons/kernel/drivers/network/atheros813x/dev/alc/if_alc.c index 59e719d6b3..886bd6147c 100644 --- a/src/add-ons/kernel/drivers/network/atheros813x/dev/alc/if_alc.c +++ b/src/add-ons/kernel/drivers/network/atheros813x/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/src/add-ons/kernel/drivers/network/atheros813x/dev/alc/if_alcreg.h b/src/add-ons/kernel/drivers/network/atheros813x/dev/alc/if_alcreg.h index cade3f5526..aa93188d8c 100644 --- a/src/add-ons/kernel/drivers/network/atheros813x/dev/alc/if_alcreg.h +++ b/src/add-ons/kernel/drivers/network/atheros813x/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/src/add-ons/kernel/drivers/network/atheros813x/dev/alc/if_alcvar.h b/src/add-ons/kernel/drivers/network/atheros813x/dev/alc/if_alcvar.h index c1cd08949d..b6c643e1e6 100644 --- a/src/add-ons/kernel/drivers/network/atheros813x/dev/alc/if_alcvar.h +++ b/src/add-ons/kernel/drivers/network/atheros813x/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 */