[Midnightbsd-cvs] src: dev/msk: enable msi, sync changes with freebsd, maintain support
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Tue Dec 2 19:03:00 EST 2008
Log Message:
-----------
enable msi, sync changes with freebsd, maintain support for intel macs
Modified Files:
--------------
src/sys/dev/msk:
if_msk.c (r1.3 -> r1.4)
if_mskreg.h (r1.3 -> r1.4)
-------------- next part --------------
Index: if_mskreg.h
===================================================================
RCS file: /home/cvs/src/sys/dev/msk/if_mskreg.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -L sys/dev/msk/if_mskreg.h -L sys/dev/msk/if_mskreg.h -u -r1.3 -r1.4
--- sys/dev/msk/if_mskreg.h
+++ sys/dev/msk/if_mskreg.h
@@ -93,8 +93,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $MidnightBSD$ */
-/*$FreeBSD: src/sys/dev/msk/if_mskreg.h,v 1.3.2.4.2.1 2007/12/08 12:19:13 remko Exp $*/
+/*$FreeBSD: src/sys/dev/msk/if_mskreg.h,v 1.6.2.1 2007/12/08 12:16:15 remko Exp $*/
/*
* SysKonnect PCI vendor ID
@@ -2319,9 +2318,9 @@
/* Softc for the Marvell Yukon II controller. */
struct msk_softc {
struct resource *msk_res[1]; /* I/O resource */
- int msk_res_type;
- int msk_res_id;
+ struct resource_spec *msk_res_spec;
struct resource *msk_irq[2]; /* IRQ resources */
+ struct resource_spec *msk_irq_spec;
void *msk_intrhand[2]; /* irq handler handle */
device_t msk_dev;
uint8_t msk_hw_id;
Index: if_msk.c
===================================================================
RCS file: /home/cvs/src/sys/dev/msk/if_msk.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -L sys/dev/msk/if_msk.c -L sys/dev/msk/if_msk.c -u -r1.3 -r1.4
--- sys/dev/msk/if_msk.c
+++ sys/dev/msk/if_msk.c
@@ -2,7 +2,7 @@
*
* Name : sky2.c
* Project: Gigabit Ethernet Driver for FreeBSD 5.x/6.x
- * Version: $Revision: 1.11 $
+ * Version: $Revision: 1.23 $
* Date : $Date: 2005/12/22 09:04:11 $
* Purpose: Main driver source file
*
@@ -99,8 +99,7 @@
*/
#include <sys/cdefs.h>
-/* $FreeBSD: src/sys/dev/msk/if_msk.c,v 1.11.2.8.2.1 2007/12/08 12:19:13 remko Exp $ */
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: src/sys/dev/msk/if_msk.c,v 1.18.2.1 2007/12/08 12:16:14 remko Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -153,26 +152,13 @@
#include "miibus_if.h"
/* Tunables. */
-
-static int msi_disable = 1;
+static int msi_disable = 0;
TUNABLE_INT("hw.msk.msi_disable", &msi_disable);
+static int legacy_intr = 0;
+TUNABLE_INT("hw.msk.legacy_intr", &legacy_intr);
#define MSK_CSUM_FEATURES (CSUM_TCP | CSUM_UDP)
-/* RELENG_6 support code */
-#ifndef IFCAP_TSO4
-#define IFCAP_TSO4 0
-#define CSUM_TSO 0
-#endif
-#ifndef VLAN_CAPABILITIES
-#define VLAN_CAPABILITIES(x)
-#endif
-#ifndef IFCAP_VLAN_HWCSUM
-#define IFCAP_VLAN_HWCSUM 0
-#endif
-#undef MSI_SUPPORT
-#undef TSO_SUPPORT
-
/*
* Devices supported by this driver.
*/
@@ -249,7 +235,8 @@
static int msk_detach(device_t);
static void msk_tick(void *);
-static void msk_intr(void *);
+static void msk_legacy_intr(void *);
+static int msk_intr(void *);
static void msk_int_task(void *, int);
static void msk_intr_phy(struct msk_if_softc *);
static void msk_intr_gmac(struct msk_if_softc *);
@@ -358,6 +345,27 @@
DRIVER_MODULE(msk, mskc, msk_driver, msk_devclass, 0, 0);
DRIVER_MODULE(miibus, msk, miibus_driver, miibus_devclass, 0, 0);
+static struct resource_spec msk_res_spec_io[] = {
+ { SYS_RES_IOPORT, PCIR_BAR(1), RF_ACTIVE },
+ { -1, 0, 0 }
+};
+
+static struct resource_spec msk_res_spec_mem[] = {
+ { SYS_RES_MEMORY, PCIR_BAR(0), RF_ACTIVE },
+ { -1, 0, 0 }
+};
+
+static struct resource_spec msk_irq_spec_legacy[] = {
+ { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE },
+ { -1, 0, 0 }
+};
+
+static struct resource_spec msk_irq_spec_msi[] = {
+ { SYS_RES_IRQ, 1, RF_ACTIVE },
+ { SYS_RES_IRQ, 2, RF_ACTIVE },
+ { -1, 0, 0 }
+};
+
static int
msk_miibus_readreg(device_t dev, int phy, int reg)
{
@@ -1296,7 +1304,6 @@
* On dual port PCI-X card, there is an problem where status
* can be received out of order due to split transactions.
*/
-#if 0
if (sc->msk_bustype == MSK_PCIX_BUS && sc->msk_num_port > 1) {
int pcix;
uint16_t pcix_cmd;
@@ -1310,7 +1317,6 @@
CSR_WRITE_1(sc, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
}
}
-#endif
if (sc->msk_bustype == MSK_PEX_BUS) {
uint16_t v, width;
@@ -1538,10 +1544,7 @@
mskc_attach(device_t dev)
{
struct msk_softc *sc;
- int error, *port, rid; /* int reg */
-#ifdef MSI_SUPPORT
- int i, msic;
-#endif
+ int error, msic, *port, reg;
sc = device_get_softc(dev);
sc->msk_dev = dev;
@@ -1555,27 +1558,21 @@
/* Allocate I/O resource */
#ifdef MSK_USEIOSPACE
- sc->msk_res_type = SYS_RES_IOPORT;
- sc->msk_res_id = PCIR_BAR(1);
+ sc->msk_res_spec = msk_res_spec_io;
#else
- sc->msk_res_type = SYS_RES_MEMORY;
- sc->msk_res_id = PCIR_BAR(0);
+ sc->msk_res_spec = msk_res_spec_mem;
#endif
- sc->msk_res[0] = bus_alloc_resource_any(dev, sc->msk_res_type,
- &sc->msk_res_id, RF_ACTIVE);
- if (sc->msk_res[0] == NULL) {
- if (sc->msk_res_type == SYS_RES_MEMORY) {
- sc->msk_res_type = SYS_RES_IOPORT;
- sc->msk_res_id = PCIR_BAR(1);
- } else {
- sc->msk_res_type = SYS_RES_MEMORY;
- sc->msk_res_id = PCIR_BAR(0);
- }
- sc->msk_res[0] = bus_alloc_resource_any(dev, sc->msk_res_type,
- &sc->msk_res_id, RF_ACTIVE);
- if (sc->msk_res[0] == NULL) {
+ sc->msk_irq_spec = msk_irq_spec_legacy;
+ error = bus_alloc_resources(dev, sc->msk_res_spec, sc->msk_res);
+ if (error) {
+ if (sc->msk_res_spec == msk_res_spec_mem)
+ sc->msk_res_spec = msk_res_spec_io;
+ else
+ sc->msk_res_spec = msk_res_spec_mem;
+ error = bus_alloc_resources(dev, sc->msk_res_spec, sc->msk_res);
+ if (error) {
device_printf(dev, "couldn't allocate %s resources\n",
- sc->msk_res_type == SYS_RES_MEMORY ? "memory" :
+ sc->msk_res_spec == msk_res_spec_mem ? "memory" :
"I/O");
mtx_destroy(&sc->msk_mtx);
return (ENXIO);
@@ -1629,13 +1626,11 @@
}
/* Check bus type. */
-#if 0
if (pci_find_extcap(sc->msk_dev, PCIY_EXPRESS, ®) == 0)
sc->msk_bustype = MSK_PEX_BUS;
else if (pci_find_extcap(sc->msk_dev, PCIY_PCIX, ®) == 0)
sc->msk_bustype = MSK_PCIX_BUS;
else
-#endif
sc->msk_bustype = MSK_PCI_BUS;
/* Get H/W features(bugs). */
@@ -1708,7 +1703,6 @@
sc->msk_hw_feature = 0;
}
-#ifdef MSI_SUPPORT
/* Allocate IRQ resources. */
msic = pci_msi_count(dev);
if (bootverbose)
@@ -1722,45 +1716,22 @@
* port cards with separate MSI messages, so for now I disable MSI
* on dual port cards.
*/
+ if (legacy_intr != 0)
+ msi_disable = 1;
if (msic == 2 && msi_disable == 0 && sc->msk_num_port == 1 &&
pci_alloc_msi(dev, &msic) == 0) {
if (msic == 2) {
sc->msk_msi = 1;
+ sc->msk_irq_spec = msk_irq_spec_msi;
} else
pci_release_msi(dev);
}
- if (sc->msk_msi == 0) {
- rid = 0;
- sc->msk_irq[0] = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (sc->msk_irq[0] == NULL) {
- device_printf(dev, "couldn't allocate IRQ resources\n");
- error = ENXIO;
- goto fail;
- }
- } else {
- for (i = 0, rid = 1; i < 2; i++, rid++) {
- sc->msk_irq[i] = bus_alloc_resource_any(dev, SYS_RES_IRQ,
- &rid, RF_ACTIVE);
- if (sc->msk_irq[i] == NULL) {
- device_printf(dev,
- "couldn't allocate IRQ resources\n");
- error = ENXIO;
- goto fail;
- }
- }
- }
-#else
- rid = 0;
- sc->msk_irq[0] = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (sc->msk_irq[0] == NULL) {
+ error = bus_alloc_resources(dev, sc->msk_irq_spec, sc->msk_irq);
+ if (error) {
device_printf(dev, "couldn't allocate IRQ resources\n");
- error = ENXIO;
goto fail;
}
-#endif
if ((error = msk_status_dma_alloc(sc)) != 0)
goto fail;
@@ -1816,18 +1787,25 @@
goto fail;
}
- TASK_INIT(&sc->msk_int_task, 0, msk_int_task, sc);
- sc->msk_tq = taskqueue_create_fast("msk_taskq", M_WAITOK,
- taskqueue_thread_enqueue, &sc->msk_tq);
- taskqueue_start_threads(&sc->msk_tq, 1, PI_NET, "%s taskq",
- device_get_nameunit(sc->msk_dev));
/* Hook interrupt last to avoid having to lock softc. */
- error = bus_setup_intr(dev, sc->msk_irq[0], INTR_TYPE_NET |
- INTR_MPSAFE | INTR_FAST, msk_intr, sc, &sc->msk_intrhand[0]);
+ if (legacy_intr)
+ error = bus_setup_intr(dev, sc->msk_irq[0], INTR_TYPE_NET |
+ INTR_MPSAFE, NULL, msk_legacy_intr, sc,
+ &sc->msk_intrhand[0]);
+ else {
+ TASK_INIT(&sc->msk_int_task, 0, msk_int_task, sc);
+ sc->msk_tq = taskqueue_create_fast("msk_taskq", M_WAITOK,
+ taskqueue_thread_enqueue, &sc->msk_tq);
+ taskqueue_start_threads(&sc->msk_tq, 1, PI_NET, "%s taskq",
+ device_get_nameunit(sc->msk_dev));
+ error = bus_setup_intr(dev, sc->msk_irq[0], INTR_TYPE_NET |
+ INTR_MPSAFE, msk_intr, NULL, sc, &sc->msk_intrhand[0]);
+ }
if (error != 0) {
device_printf(dev, "couldn't set up interrupt handler\n");
- taskqueue_free(sc->msk_tq);
+ if (legacy_intr == 0)
+ taskqueue_free(sc->msk_tq);
sc->msk_tq = NULL;
goto fail;
}
@@ -1930,7 +1908,7 @@
msk_status_dma_free(sc);
- if (sc->msk_tq != NULL) {
+ if (legacy_intr == 0 && sc->msk_tq != NULL) {
taskqueue_drain(sc->msk_tq, &sc->msk_int_task);
taskqueue_free(sc->msk_tq);
sc->msk_tq = NULL;
@@ -1943,33 +1921,10 @@
bus_teardown_intr(dev, sc->msk_irq[0], sc->msk_intrhand[0]);
sc->msk_intrhand[1] = NULL;
}
-#ifdef MSI_SUPPORT
- if (sc->msk_msi) {
- int i, rid;
- for (i = 0, rid = 1; i < 2; i++, rid++) {
- if (sc->msk_irq[i] != NULL) {
- bus_release_resource(dev, SYS_RES_IRQ, rid,
- sc->msk_irq[i]);
- sc->msk_irq[i] = NULL;
- }
- }
+ bus_release_resources(dev, sc->msk_irq_spec, sc->msk_irq);
+ if (sc->msk_msi)
pci_release_msi(dev);
- } else {
- if (sc->msk_irq[0] != NULL) {
- bus_release_resource(dev, SYS_RES_IRQ, 0,
- sc->msk_irq[0]);
- sc->msk_irq[0] = NULL;
- }
- }
-#else
- if (sc->msk_irq[0] != NULL) {
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->msk_irq[0]);
- sc->msk_irq[0] = NULL;
- }
-#endif
- if (sc->msk_res[0] != NULL)
- bus_release_resource(dev, sc->msk_res_type, sc->msk_res_id,
- sc->msk_res[0]);
+ bus_release_resources(dev, sc->msk_res_spec, sc->msk_res);
mtx_destroy(&sc->msk_mtx);
return (0);
@@ -1998,7 +1953,7 @@
int error;
error = bus_dma_tag_create(
- NULL, /* parent */
+ bus_get_dma_tag(sc->msk_dev), /* parent */
MSK_STAT_ALIGN, 0, /* alignment, boundary */
BUS_SPACE_MAXADDR, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
@@ -2093,7 +2048,7 @@
* never seen these exotic scheme on ethernet interface hardware.
*/
error = bus_dma_tag_create(
- NULL, /* parent */
+ bus_get_dma_tag(sc_if->msk_if_dev), /* parent */
1, 0, /* alignment, boundary */
BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
@@ -2689,14 +2644,10 @@
struct msk_txdesc *txd, *txd_last;
struct msk_tx_desc *tx_le;
struct mbuf *m;
- struct m_tag *mtag;
bus_dmamap_t map;
bus_dma_segment_t txsegs[MSK_MAXTXSEGS];
uint32_t control, prod, si;
- uint16_t offset, tcp_offset;
-#ifdef TSO_SUPPORT
- uint16_t tso_mtu;
-#endif
+ uint16_t offset, tcp_offset, tso_mtu;
int error, i, nseg, tso;
MSK_IF_LOCK_ASSERT(sc_if);
@@ -2818,7 +2769,6 @@
tx_le = NULL;
/* Check TSO support. */
-#ifdef TSO_SUPPORT
if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) {
tso_mtu = offset + m->m_pkthdr.tso_segsz;
if (tso_mtu != sc_if->msk_cdata.msk_tso_mtu) {
@@ -2831,20 +2781,18 @@
}
tso++;
}
-#endif
/* Check if we have a VLAN tag to insert. */
- mtag = VLAN_OUTPUT_TAG(sc_if->msk_ifp, m);
- if (mtag != NULL) {
+ if ((m->m_flags & M_VLANTAG) != 0) {
if (tso == 0) {
tx_le = &sc_if->msk_rdata.msk_tx_ring[prod];
tx_le->msk_addr = htole32(0);
tx_le->msk_control = htole32(OP_VLAN | HW_OWNER |
- htons(VLAN_TAG_VALUE(mtag)));
+ htons(m->m_pkthdr.ether_vtag));
sc_if->msk_cdata.msk_tx_cnt++;
MSK_INC(prod, MSK_TX_RING_CNT);
} else {
tx_le->msk_control |= htole32(OP_VLAN |
- htons(VLAN_TAG_VALUE(mtag)));
+ htons(m->m_pkthdr.ether_vtag));
}
control |= INS_VLAN;
}
@@ -2958,7 +2906,7 @@
* If there's a BPF listener, bounce a copy of this frame
* to him.
*/
- BPF_MTAP(ifp, m_head);
+ ETHER_BPF_MTAP(ifp, m_head);
}
if (enq > 0) {
@@ -3143,7 +3091,8 @@
/* Check for VLAN tagged packets. */
if ((status & GMR_FS_VLAN) != 0 &&
(ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
- VLAN_INPUT_TAG_NEW(ifp, m, sc_if->msk_vtag);
+ m->m_pkthdr.ether_vtag = sc_if->msk_vtag;
+ m->m_flags |= M_VLANTAG;
}
MSK_IF_UNLOCK(sc_if);
(*ifp->if_input)(ifp, m);
@@ -3195,7 +3144,8 @@
/* Check for VLAN tagged packets. */
if ((status & GMR_FS_VLAN) != 0 &&
(ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) {
- VLAN_INPUT_TAG_NEW(ifp, m, sc_if->msk_vtag);
+ m->m_pkthdr.ether_vtag = sc_if->msk_vtag;
+ m->m_flags |= M_VLANTAG;
}
MSK_IF_UNLOCK(sc_if);
(*ifp->if_input)(ifp, m);
@@ -3569,7 +3519,76 @@
return (sc->msk_stat_cons != CSR_READ_2(sc, STAT_PUT_IDX));
}
+/* Legacy interrupt handler for shared interrupt. */
static void
+msk_legacy_intr(void *xsc)
+{
+ struct msk_softc *sc;
+ struct msk_if_softc *sc_if0, *sc_if1;
+ struct ifnet *ifp0, *ifp1;
+ uint32_t status;
+
+ sc = xsc;
+ MSK_LOCK(sc);
+
+ /* Reading B0_Y2_SP_ISRC2 masks further interrupts. */
+ status = CSR_READ_4(sc, B0_Y2_SP_ISRC2);
+ if (status == 0 || status == 0xffffffff || sc->msk_suspended != 0 ||
+ (status & sc->msk_intrmask) == 0) {
+ CSR_WRITE_4(sc, B0_Y2_SP_ICR, 2);
+ return;
+ }
+
+ sc_if0 = sc->msk_if[MSK_PORT_A];
+ sc_if1 = sc->msk_if[MSK_PORT_B];
+ ifp0 = ifp1 = NULL;
+ if (sc_if0 != NULL)
+ ifp0 = sc_if0->msk_ifp;
+ if (sc_if1 != NULL)
+ ifp1 = sc_if1->msk_ifp;
+
+ if ((status & Y2_IS_IRQ_PHY1) != 0 && sc_if0 != NULL)
+ msk_intr_phy(sc_if0);
+ if ((status & Y2_IS_IRQ_PHY2) != 0 && sc_if1 != NULL)
+ msk_intr_phy(sc_if1);
+ if ((status & Y2_IS_IRQ_MAC1) != 0 && sc_if0 != NULL)
+ msk_intr_gmac(sc_if0);
+ if ((status & Y2_IS_IRQ_MAC2) != 0 && sc_if1 != NULL)
+ msk_intr_gmac(sc_if1);
+ if ((status & (Y2_IS_CHK_RX1 | Y2_IS_CHK_RX2)) != 0) {
+ device_printf(sc->msk_dev, "Rx descriptor error\n");
+ sc->msk_intrmask &= ~(Y2_IS_CHK_RX1 | Y2_IS_CHK_RX2);
+ CSR_WRITE_4(sc, B0_IMSK, sc->msk_intrmask);
+ CSR_READ_4(sc, B0_IMSK);
+ }
+ if ((status & (Y2_IS_CHK_TXA1 | Y2_IS_CHK_TXA2)) != 0) {
+ device_printf(sc->msk_dev, "Tx descriptor error\n");
+ sc->msk_intrmask &= ~(Y2_IS_CHK_TXA1 | Y2_IS_CHK_TXA2);
+ CSR_WRITE_4(sc, B0_IMSK, sc->msk_intrmask);
+ CSR_READ_4(sc, B0_IMSK);
+ }
+ if ((status & Y2_IS_HW_ERR) != 0)
+ msk_intr_hwerr(sc);
+
+ while (msk_handle_events(sc) != 0)
+ ;
+ if ((status & Y2_IS_STAT_BMU) != 0)
+ CSR_WRITE_4(sc, STAT_CTRL, SC_STAT_CLR_IRQ);
+
+ /* Reenable interrupts. */
+ CSR_WRITE_4(sc, B0_Y2_SP_ICR, 2);
+
+ if (ifp0 != NULL && (ifp0->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
+ !IFQ_DRV_IS_EMPTY(&ifp0->if_snd))
+ taskqueue_enqueue(taskqueue_fast, &sc_if0->msk_tx_task);
+ if (ifp1 != NULL && (ifp1->if_drv_flags & IFF_DRV_RUNNING) != 0 &&
+ !IFQ_DRV_IS_EMPTY(&ifp1->if_snd))
+ taskqueue_enqueue(taskqueue_fast, &sc_if1->msk_tx_task);
+
+ MSK_UNLOCK(sc);
+}
+
+static int
msk_intr(void *xsc)
{
struct msk_softc *sc;
@@ -3580,10 +3599,11 @@
/* Reading B0_Y2_SP_ISRC2 masks further interrupts. */
if (status == 0 || status == 0xffffffff) {
CSR_WRITE_4(sc, B0_Y2_SP_ICR, 2);
- return;
+ return (FILTER_STRAY);
}
taskqueue_enqueue(sc->msk_tq, &sc->msk_int_task);
+ return (FILTER_HANDLED);
}
static void
More information about the Midnightbsd-cvs
mailing list