Module Name: src
Committed By: msaitoh
Date: Thu Aug 13 04:56:43 UTC 2015
Modified Files:
src/sys/dev/pci/ixgbe: ixgbe.c ixgbe_82599.c ixgbe_osdep.h ixgbe_type.h
ixv.c
Log Message:
- Add MSI/MSI-X support. The multiqueue function is not supported yet.
- Make ixv.c compilable. _NOT_TESTED_YET_
To generate a diff of this commit:
cvs rdiff -u -r1.33 -r1.34 src/sys/dev/pci/ixgbe/ixgbe.c
cvs rdiff -u -r1.10 -r1.11 src/sys/dev/pci/ixgbe/ixgbe_82599.c \
src/sys/dev/pci/ixgbe/ixv.c
cvs rdiff -u -r1.9 -r1.10 src/sys/dev/pci/ixgbe/ixgbe_osdep.h
cvs rdiff -u -r1.11 -r1.12 src/sys/dev/pci/ixgbe/ixgbe_type.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/pci/ixgbe/ixgbe.c
diff -u src/sys/dev/pci/ixgbe/ixgbe.c:1.33 src/sys/dev/pci/ixgbe/ixgbe.c:1.34
--- src/sys/dev/pci/ixgbe/ixgbe.c:1.33 Wed Aug 5 04:08:44 2015
+++ src/sys/dev/pci/ixgbe/ixgbe.c Thu Aug 13 04:56:43 2015
@@ -59,7 +59,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
/*$FreeBSD: head/sys/dev/ixgbe/ixgbe.c 279805 2015-03-09 10:29:15Z araujo $*/
-/*$NetBSD: ixgbe.c,v 1.33 2015/08/05 04:08:44 msaitoh Exp $*/
+/*$NetBSD: ixgbe.c,v 1.34 2015/08/13 04:56:43 msaitoh Exp $*/
#include "opt_inet.h"
#include "opt_inet6.h"
@@ -232,8 +232,8 @@ static int ixgbe_legacy_irq(void *);
#if defined(NETBSD_MSI_OR_MSIX)
/* The MSI/X Interrupt handlers */
-static void ixgbe_msix_que(void *);
-static void ixgbe_msix_link(void *);
+static int ixgbe_msix_que(void *);
+static int ixgbe_msix_link(void *);
#endif
/* Software interrupts for deferred work */
@@ -317,7 +317,7 @@ SYSCTL_INT("hw.ixgbe.enable_msix", &ixgb
* number of cpus with a max of 8. This
* can be overriden manually here.
*/
-static int ixgbe_num_queues = 0;
+static int ixgbe_num_queues = 1;
SYSCTL_INT("hw.ixgbe.num_queues", &ixgbe_num_queues);
#endif
@@ -508,7 +508,7 @@ ixgbe_attach(device_t parent, device_t d
{
struct adapter *adapter;
struct ixgbe_hw *hw;
- int error = 0;
+ int error = -1;
u16 csum;
u32 ctrl_ext;
ixgbe_vendor_info_t *ent;
@@ -608,7 +608,8 @@ ixgbe_attach(device_t parent, device_t d
*/
adapter->sfp_probe = TRUE;
error = 0;
- } else if (error == IXGBE_ERR_SFP_NOT_SUPPORTED) {
+ } else if ((error == IXGBE_ERR_SFP_NOT_SUPPORTED)
+ && (hw->allow_unsupported_sfp == false)) {
aprint_error_dev(dev,"Unsupported SFP+ module detected!\n");
error = EIO;
goto err_late;
@@ -649,10 +650,11 @@ ixgbe_attach(device_t parent, device_t d
/* Detect and set physical type */
ixgbe_setup_optics(adapter);
+ error = -1;
if ((adapter->msix > 1) && (ixgbe_enable_msix))
- error = ixgbe_allocate_msix(adapter, pa);
- else
- error = ixgbe_allocate_legacy(adapter, pa);
+ error = ixgbe_allocate_msix(adapter, pa);
+ if (error != 0)
+ error = ixgbe_allocate_legacy(adapter, pa);
if (error)
goto err_late;
@@ -1692,7 +1694,7 @@ ixgbe_legacy_irq(void *arg)
* MSIX Queue Interrupt Service routine
*
**********************************************************************/
-void
+static int
ixgbe_msix_que(void *arg)
{
struct ix_queue *que = arg;
@@ -1705,7 +1707,7 @@ ixgbe_msix_que(void *arg)
/* Protect against spurious interrupts */
if ((ifp->if_flags & IFF_RUNNING) == 0)
- return;
+ return 0;
ixgbe_disable_queue(adapter, que->msix);
++que->irqs;
@@ -1716,6 +1718,7 @@ ixgbe_msix_que(void *arg)
ixgbe_txeof(txr);
#ifdef IXGBE_LEGACY_TX
if (!IFQ_IS_EMPTY(&adapter->ifp->if_snd))
+ ixgbe_start_locked(txr, ifp);
#else
if (!drbr_empty(ifp, txr->br))
ixgbe_mq_start_locked(ifp, txr);
@@ -1777,11 +1780,11 @@ no_calc:
softint_schedule(que->que_si);
else
ixgbe_enable_queue(adapter, que->msix);
- return;
+ return 1;
}
-static void
+static int
ixgbe_msix_link(void *arg)
{
struct adapter *adapter = arg;
@@ -1806,7 +1809,7 @@ ixgbe_msix_link(void *arg)
if (reg_eicr & IXGBE_EICR_FLOW_DIR) {
/* This is probably overkill :) */
if (!atomic_cmpset_int(&adapter->fdir_reinit, 0, 1))
- return;
+ return 1;
/* Disable the interrupt */
IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EICR_FLOW_DIR);
softint_schedule(adapter->fdir_si);
@@ -1847,7 +1850,7 @@ ixgbe_msix_link(void *arg)
}
IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
- return;
+ return 1;
}
#endif
@@ -2477,32 +2480,79 @@ ixgbe_setup_optics(struct adapter *adapt
*
**********************************************************************/
static int
-ixgbe_allocate_legacy(struct adapter *adapter, const struct pci_attach_args *pa)
+ixgbe_allocate_legacy(struct adapter *adapter,
+ const struct pci_attach_args *pa)
{
device_t dev = adapter->dev;
struct ix_queue *que = adapter->queues;
#ifndef IXGBE_LEGACY_TX
struct tx_ring *txr = adapter->tx_rings;
#endif
- char intrbuf[PCI_INTRSTR_LEN];
-#if 0
- int rid = 0;
-
- /* MSI RID at 1 */
- if (adapter->msix == 1)
- rid = 1;
+#ifndef NETBSD_MSI_OR_MSIX
+ pci_intr_handle_t ih;
+#else
+ int counts[PCI_INTR_TYPE_SIZE];
+ pci_intr_type_t intr_type, max_type;
#endif
+ char intrbuf[PCI_INTRSTR_LEN];
+ const char *intrstr = NULL;
+#ifndef NETBSD_MSI_OR_MSIX
/* We allocate a single interrupt resource */
- if (pci_intr_map(pa, &adapter->osdep.ih) != 0) {
+ if (pci_intr_map(pa, &ih) != 0) {
aprint_error_dev(dev, "unable to map interrupt\n");
return ENXIO;
} else {
- aprint_normal_dev(dev, "interrupting at %s\n",
- pci_intr_string(adapter->osdep.pc, adapter->osdep.ih,
- intrbuf, sizeof(intrbuf)));
+ intrstr = pci_intr_string(adapter->osdep.pc, ih, intrbuf,
+ sizeof(intrbuf));
}
-
+ adapter->osdep.ihs[0] = pci_intr_establish(adapter->osdep.pc, ih,
+ IPL_NET, ixgbe_legacy_irq, que);
+#else
+ /* Allocation settings */
+ max_type = PCI_INTR_TYPE_MSI;
+ counts[PCI_INTR_TYPE_MSIX] = 0;
+ counts[PCI_INTR_TYPE_MSI] = 1;
+ counts[PCI_INTR_TYPE_INTX] = 1;
+
+alloc_retry:
+ if (pci_intr_alloc(pa, &adapter->osdep.intrs, counts, max_type) != 0) {
+ aprint_error_dev(dev, "couldn't alloc interrupt\n");
+ return ENXIO;
+ }
+ adapter->osdep.nintrs = 1;
+ intrstr = pci_intr_string(adapter->osdep.pc, adapter->osdep.intrs[0],
+ intrbuf, sizeof(intrbuf));
+ adapter->osdep.ihs[0] = pci_intr_establish(adapter->osdep.pc,
+ adapter->osdep.intrs[0], IPL_NET, ixgbe_legacy_irq, que);
+ if (adapter->osdep.ihs[0] == NULL) {
+ intr_type = pci_intr_type(adapter->osdep.intrs[0]);
+ aprint_error_dev(dev,"unable to establish %s\n",
+ (intr_type == PCI_INTR_TYPE_MSI) ? "MSI" : "INTx");
+ pci_intr_release(adapter->osdep.pc, adapter->osdep.intrs, 1);
+ switch (intr_type) {
+ case PCI_INTR_TYPE_MSI:
+ /* The next try is for INTx: Disable MSI */
+ max_type = PCI_INTR_TYPE_INTX;
+ counts[PCI_INTR_TYPE_INTX] = 1;
+ goto alloc_retry;
+ case PCI_INTR_TYPE_INTX:
+ default:
+ /* See below */
+ break;
+ }
+ }
+#endif
+ if (adapter->osdep.ihs[0] == NULL) {
+ aprint_error_dev(dev,
+ "couldn't establish interrupt%s%s\n",
+ intrstr ? " at " : "", intrstr ? intrstr : "");
+#ifdef NETBSD_MSI_OR_MSIX
+ pci_intr_release(adapter->osdep.pc, adapter->osdep.intrs, 1);
+#endif
+ return ENXIO;
+ }
+ aprint_normal_dev(dev, "interrupting at %s\n", intrstr);
/*
* Try allocating a fast interrupt and the associated deferred
* processing contexts.
@@ -2537,19 +2587,6 @@ ixgbe_allocate_legacy(struct adapter *ad
return ENXIO;
}
- adapter->osdep.intr = pci_intr_establish(adapter->osdep.pc,
- adapter->osdep.ih, IPL_NET, ixgbe_legacy_irq, que);
- if (adapter->osdep.intr == NULL) {
- aprint_error_dev(dev, "failed to register interrupt handler\n");
- softint_disestablish(que->que_si);
- softint_disestablish(adapter->link_si);
- softint_disestablish(adapter->mod_si);
- softint_disestablish(adapter->msf_si);
-#ifdef IXGBE_FDIR
- softint_disestablish(adapter->fdir_si);
-#endif
- return ENXIO;
- }
/* For simplicity in the handlers */
adapter->que_mask = IXGBE_EIMS_ENABLE_MASK;
@@ -2571,13 +2608,16 @@ ixgbe_allocate_msix(struct adapter *adap
device_t dev = adapter->dev;
struct ix_queue *que = adapter->queues;
struct tx_ring *txr = adapter->tx_rings;
- int error, rid, vector = 0;
+ pci_chipset_tag_t pc;
+ char intrbuf[PCI_INTRSTR_LEN];
+ const char *intrstr = NULL;
+ int error, vector = 0;
int cpu_id = 0;
-#ifdef RSS
- cpuset_t cpu_mask;
-#endif
+ kcpuset_t *affinity;
+ pc = adapter->osdep.pc;
#ifdef RSS
+ cpuset_t cpu_mask;
/*
* If we're doing RSS, the number of queues needs to
* match the number of RSS buckets that are configured.
@@ -2599,28 +2639,33 @@ ixgbe_allocate_msix(struct adapter *adap
}
#endif
+ adapter->osdep.nintrs = adapter->num_queues + 1;
+ if (pci_msix_alloc_exact(pa, &adapter->osdep.intrs,
+ adapter->osdep.nintrs) != 0) {
+ aprint_error_dev(dev,
+ "failed to allocate MSI-X interrupt\n");
+ return (ENXIO);
+ }
+
+ kcpuset_create(&affinity, false);
for (int i = 0; i < adapter->num_queues; i++, vector++, que++, txr++) {
- rid = vector + 1;
- que->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (que->res == NULL) {
- aprint_error_dev(dev,"Unable to allocate"
- " bus resource: que interrupt [%d]\n", vector);
- return (ENXIO);
- }
+ intrstr = pci_intr_string(pc, adapter->osdep.intrs[i], intrbuf,
+ sizeof(intrbuf));
+#ifdef IXG_MPSAFE
+ pci_intr_setattr(pc, adapter->osdep.intrs[i], PCI_INTR_MPSAFE,
+ true);
+#endif
/* Set the handler function */
- error = bus_setup_intr(dev, que->res,
- INTR_TYPE_NET | INTR_MPSAFE, NULL,
- ixgbe_msix_que, que, &que->tag);
- if (error) {
- que->res = NULL;
+ que->res = adapter->osdep.ihs[i] = pci_intr_establish(pc,
+ adapter->osdep.intrs[i], IPL_NET, ixgbe_msix_que, que);
+ if (que->res == NULL) {
+ pci_intr_release(pc, adapter->osdep.intrs,
+ adapter->osdep.nintrs);
aprint_error_dev(dev,
"Failed to register QUE handler\n");
- return error;
+ kcpuset_destroy(affinity);
+ return ENXIO;
}
-#if __FreeBSD_version >= 800504
- bus_describe_intr(dev, que->res, que->tag, "que %d", i);
-#endif
que->msix = vector;
adapter->que_mask |= (u64)(1 << que->msix);
#ifdef RSS
@@ -2640,18 +2685,23 @@ ixgbe_allocate_msix(struct adapter *adap
if (adapter->num_queues > 1)
cpu_id = i;
#endif
- if (adapter->num_queues > 1)
- bus_bind_intr(dev, que->res, cpu_id);
-
+ /* Round-robin affinity */
+ kcpuset_zero(affinity);
+ kcpuset_set(affinity, cpu_id % ncpu);
+ error = pci_intr_distribute(adapter->osdep.ihs[i], affinity,
+ NULL);
+ aprint_normal_dev(dev, "for TX/RX, interrupting at %s",
+ intrstr);
+ if (error == 0) {
#ifdef RSS
- device_printf(dev,
- "Bound RSS bucket %d to CPU %d\n",
- i, cpu_id);
+ aprintf_normal(", bound RSS bucket %d to CPU %d\n",
+ i, cpu_id);
#else
- device_printf(dev,
- "Bound queue %d to cpu %d\n",
- i, cpu_id);
+ aprint_normal(", bound queue %d to cpu %d\n",
+ i, cpu_id);
#endif
+ } else
+ aprint_normal("\n");
#ifndef IXGBE_LEGACY_TX
txr->txq_si = softint_establish(SOFTINT_NET,
@@ -2666,26 +2716,34 @@ ixgbe_allocate_msix(struct adapter *adap
}
/* and Link */
- rid = vector + 1;
- adapter->res = bus_alloc_resource_any(dev,
- SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE);
- if (!adapter->res) {
- aprint_error_dev(dev,"Unable to allocate bus resource: "
- "Link interrupt [%d]\n", rid);
- return (ENXIO);
- }
+ cpu_id++;
+ intrstr = pci_intr_string(pc, adapter->osdep.intrs[vector], intrbuf,
+ sizeof(intrbuf));
+#ifdef IXG_MPSAFE
+ pci_intr_setattr(pc, &adapter->osdep.intrs[vector], PCI_INTR_MPSAFE,
+ true);
+#endif
/* Set the link handler function */
- error = bus_setup_intr(dev, adapter->res,
- INTR_TYPE_NET | INTR_MPSAFE, NULL,
- ixgbe_msix_link, adapter, &adapter->tag);
- if (error) {
+ adapter->osdep.ihs[vector] = pci_intr_establish(pc,
+ adapter->osdep.intrs[vector], IPL_NET, ixgbe_msix_link, adapter);
+ if (adapter->osdep.ihs[vector] == NULL) {
adapter->res = NULL;
aprint_error_dev(dev, "Failed to register LINK handler\n");
- return (error);
+ kcpuset_destroy(affinity);
+ return (ENXIO);
}
-#if __FreeBSD_version >= 800504
- bus_describe_intr(dev, adapter->res, adapter->tag, "link");
-#endif
+ /* Round-robin affinity */
+ kcpuset_zero(affinity);
+ kcpuset_set(affinity, cpu_id % ncpu);
+ error = pci_intr_distribute(adapter->osdep.ihs[vector], affinity,NULL);
+
+ aprint_normal_dev(dev,
+ "for link, interrupting at %s", intrstr);
+ if (error == 0)
+ aprint_normal(", affinity to cpu %d\n", cpu_id);
+ else
+ aprint_normal("\n");
+
adapter->linkvec = vector;
/* Tasklets for Link, SFP and Multispeed Fiber */
adapter->link_si =
@@ -2699,6 +2757,7 @@ ixgbe_allocate_msix(struct adapter *adap
softint_establish(SOFTINT_NET, ixgbe_reinit_fdir, adapter);
#endif
+ kcpuset_destroy(affinity);
return (0);
#endif
}
@@ -2713,33 +2772,21 @@ ixgbe_setup_msix(struct adapter *adapter
return 0;
#else
device_t dev = adapter->dev;
- int rid, want, queues, msgs;
+ int want, queues, msgs;
/* Override by tuneable */
if (ixgbe_enable_msix == 0)
goto msi;
/* First try MSI/X */
- msgs = pci_msix_count(dev);
- if (msgs == 0)
- goto msi;
- rid = PCI_BAR(MSIX_82598_BAR);
- adapter->msix_mem = bus_alloc_resource_any(dev,
- SYS_RES_MEMORY, &rid, RF_ACTIVE);
- if (adapter->msix_mem == NULL) {
- rid += 4; /* 82599 maps in higher BAR */
- adapter->msix_mem = bus_alloc_resource_any(dev,
- SYS_RES_MEMORY, &rid, RF_ACTIVE);
- }
- if (adapter->msix_mem == NULL) {
- /* May not be enabled */
- device_printf(adapter->dev,
- "Unable to map MSIX table \n");
+ msgs = pci_msix_count(adapter->osdep.pc, adapter->osdep.tag);
+ if (msgs < IXG_MSIX_NINTR)
goto msi;
- }
+
+ adapter->msix_mem = (void *)1; /* XXX */
/* Figure out a reasonable auto config value */
- queues = (mp_ncpus > (msgs-1)) ? (msgs-1) : mp_ncpus;
+ queues = (ncpu > (msgs-1)) ? (msgs-1) : ncpu;
/* Override based on tuneable */
if (ixgbe_num_queues != 0)
@@ -2762,44 +2809,34 @@ ixgbe_setup_msix(struct adapter *adapter
if (msgs >= want)
msgs = want;
else {
- device_printf(adapter->dev,
+ aprint_error_dev(dev,
"MSIX Configuration Problem, "
"%d vectors but %d queues wanted!\n",
msgs, want);
goto msi;
}
- if ((pci_alloc_msix(dev, &msgs) == 0) && (msgs == want)) {
- device_printf(adapter->dev,
- "Using MSIX interrupts with %d vectors\n", msgs);
- adapter->num_queues = queues;
- return (msgs);
- }
+ device_printf(dev,
+ "Using MSIX interrupts with %d vectors\n", msgs);
+ adapter->num_queues = queues;
+ return (msgs);
+
/*
** If MSIX alloc failed or provided us with
** less than needed, free and fall through to MSI
*/
- pci_release_msi(dev);
-
msi:
- msgs = pci_msi_count(dev);
- if (adapter->msix_mem != NULL) {
- bus_release_resource(dev, SYS_RES_MEMORY,
- rid, adapter->msix_mem);
- adapter->msix_mem = NULL;
- }
+ msgs = pci_msi_count(adapter->osdep.pc, adapter->osdep.tag);
+ adapter->msix_mem = NULL; /* XXX */
msgs = 1;
- if (pci_alloc_msi(dev, &msgs) == 0) {
- device_printf(adapter->dev,"Using an MSI interrupt\n");
- return (msgs);
- }
- device_printf(adapter->dev,"Using a Legacy interrupt\n");
- return (0);
+ aprint_normal_dev(dev,"Using an MSI interrupt\n");
+ return (msgs);
#endif
}
static int
-ixgbe_allocate_pci_resources(struct adapter *adapter, const struct pci_attach_args *pa)
+ixgbe_allocate_pci_resources(struct adapter *adapter,
+ const struct pci_attach_args *pa)
{
pcireg_t memtype;
device_t dev = adapter->dev;
@@ -2850,60 +2887,35 @@ ixgbe_free_pci_resources(struct adapter
{
#if defined(NETBSD_MSI_OR_MSIX)
struct ix_queue *que = adapter->queues;
- device_t dev = adapter->dev;
#endif
int rid;
#if defined(NETBSD_MSI_OR_MSIX)
- int memrid;
- if (adapter->hw.mac.type == ixgbe_mac_82598EB)
- memrid = PCI_BAR(MSIX_82598_BAR);
- else
- memrid = PCI_BAR(MSIX_82599_BAR);
-
- /*
- ** There is a slight possibility of a failure mode
- ** in attach that will result in entering this function
- ** before interrupt resources have been initialized, and
- ** in that case we do not want to execute the loops below
- ** We can detect this reliably by the state of the adapter
- ** res pointer.
- */
- if (adapter->res == NULL)
- goto mem;
-
/*
** Release all msix queue resources:
*/
for (int i = 0; i < adapter->num_queues; i++, que++) {
- rid = que->msix + 1;
- if (que->tag != NULL) {
- bus_teardown_intr(dev, que->res, que->tag);
- que->tag = NULL;
- }
if (que->res != NULL)
- bus_release_resource(dev, SYS_RES_IRQ, rid, que->res);
+ pci_intr_disestablish(adapter->osdep.pc,
+ adapter->osdep.ihs[i]);
}
#endif
/* Clean the Legacy or Link interrupt last */
if (adapter->linkvec) /* we are doing MSIX */
- rid = adapter->linkvec + 1;
+ rid = adapter->linkvec;
else
- (adapter->msix != 0) ? (rid = 1):(rid = 0);
+ rid = 0;
- if (adapter->osdep.intr != NULL)
- pci_intr_disestablish(adapter->osdep.pc, adapter->osdep.intr);
- adapter->osdep.intr = NULL;
+ if (adapter->osdep.ihs[rid] != NULL) {
+ pci_intr_disestablish(adapter->osdep.pc,
+ adapter->osdep.ihs[rid]);
+ adapter->osdep.ihs[rid] = NULL;
+ }
#if defined(NETBSD_MSI_OR_MSIX)
-mem:
- if (adapter->msix)
- pci_release_msi(dev);
-
- if (adapter->msix_mem != NULL)
- bus_release_resource(dev, SYS_RES_MEMORY,
- memrid, adapter->msix_mem);
+ pci_intr_release(adapter->osdep.pc, adapter->osdep.intrs,
+ adapter->osdep.nintrs);
#endif
if (adapter->osdep.mem_size != 0) {
Index: src/sys/dev/pci/ixgbe/ixgbe_82599.c
diff -u src/sys/dev/pci/ixgbe/ixgbe_82599.c:1.10 src/sys/dev/pci/ixgbe/ixgbe_82599.c:1.11
--- src/sys/dev/pci/ixgbe/ixgbe_82599.c:1.10 Wed Aug 5 04:08:44 2015
+++ src/sys/dev/pci/ixgbe/ixgbe_82599.c Thu Aug 13 04:56:43 2015
@@ -31,7 +31,7 @@
******************************************************************************/
/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_82599.c 251964 2013-06-18 21:28:19Z jfv $*/
-/*$NetBSD: ixgbe_82599.c,v 1.10 2015/08/05 04:08:44 msaitoh Exp $*/
+/*$NetBSD: ixgbe_82599.c,v 1.11 2015/08/13 04:56:43 msaitoh Exp $*/
#include "ixgbe_type.h"
#include "ixgbe_82599.h"
@@ -793,8 +793,8 @@ s32 ixgbe_setup_mac_link_multispeed_fibe
msec_delay(100);
/* If we have link, just jump out */
- status = ixgbe_check_link(hw, &link_speed,
- &link_up, FALSE);
+ status = ixgbe_check_link(hw, &link_speed, &link_up,
+ FALSE);
if (status != IXGBE_SUCCESS)
return status;
Index: src/sys/dev/pci/ixgbe/ixv.c
diff -u src/sys/dev/pci/ixgbe/ixv.c:1.10 src/sys/dev/pci/ixgbe/ixv.c:1.11
--- src/sys/dev/pci/ixgbe/ixv.c:1.10 Wed Aug 5 04:08:44 2015
+++ src/sys/dev/pci/ixgbe/ixv.c Thu Aug 13 04:56:43 2015
@@ -31,7 +31,7 @@
******************************************************************************/
/*$FreeBSD: head/sys/dev/ixgbe/ixv.c 275358 2014-12-01 11:45:24Z hselasky $*/
-/*$NetBSD: ixv.c,v 1.10 2015/08/05 04:08:44 msaitoh Exp $*/
+/*$NetBSD: ixv.c,v 1.11 2015/08/13 04:56:43 msaitoh Exp $*/
#include "opt_inet.h"
#include "opt_inet6.h"
@@ -96,7 +96,8 @@ static int ixv_media_change(struct
static void ixv_identify_hardware(struct adapter *);
static int ixv_allocate_pci_resources(struct adapter *,
const struct pci_attach_args *);
-static int ixv_allocate_msix(struct adapter *);
+static int ixv_allocate_msix(struct adapter *,
+ const struct pci_attach_args *);
static int ixv_allocate_queues(struct adapter *);
static int ixv_setup_msix(struct adapter *);
static void ixv_free_pci_resources(struct adapter *);
@@ -157,8 +158,8 @@ static __inline void ixv_rx_input(struct
struct mbuf *, u32);
/* The MSI/X Interrupt handlers */
-static void ixv_msix_que(void *);
-static void ixv_msix_mbx(void *);
+static int ixv_msix_que(void *);
+static int ixv_msix_mbx(void *);
/* Deferred interrupt tasklets */
static void ixv_handle_que(void *);
@@ -443,7 +444,7 @@ ixv_attach(device_t parent, device_t dev
goto err_late;
}
- error = ixv_allocate_msix(adapter);
+ error = ixv_allocate_msix(adapter, pa);
if (error)
goto err_late;
@@ -589,7 +590,7 @@ ixv_start_locked(struct tx_ring *txr, st
if (m_head == NULL)
break;
- if (ixv_xmit(txr, m_head) == EAGAIN) {
+ if ((rc = ixv_xmit(txr, m_head)) == EAGAIN) {
ifp->if_flags |= IFF_OACTIVE;
break;
}
@@ -1063,7 +1064,7 @@ ixv_handle_que(void *context)
* MSI Queue Interrupt Service routine
*
**********************************************************************/
-void
+int
ixv_msix_que(void *arg)
{
struct ix_queue *que = arg;
@@ -1148,10 +1149,10 @@ no_calc:
softint_schedule(que->que_si);
else /* Reenable this interrupt */
ixv_enable_queue(adapter, que->msix);
- return;
+ return 1;
}
-static void
+static int
ixv_msix_mbx(void *arg)
{
struct adapter *adapter = arg;
@@ -1170,7 +1171,7 @@ ixv_msix_mbx(void *arg)
softint_schedule(adapter->mbx_si);
IXGBE_WRITE_REG(hw, IXGBE_VTEIMS, IXGBE_EIMS_OTHER);
- return;
+ return 1;
}
/*********************************************************************
@@ -1260,7 +1261,7 @@ ixv_xmit(struct tx_ring *txr, struct mbu
struct ethercom *ec = &adapter->osdep.ec;
u32 olinfo_status = 0, cmd_type_len;
u32 paylen = 0;
- int i, j, error, nsegs;
+ int i, j, error;
int first, last = 0;
bus_dmamap_t map;
struct ixv_tx_buf *txbuf;
@@ -1309,7 +1310,7 @@ ixv_xmit(struct tx_ring *txr, struct mbu
}
/* Make certain there are enough descriptors */
- if (nsegs > txr->tx_avail - 2) {
+ if (map->dm_nsegs > txr->tx_avail - 2) {
txr->no_desc_avail.ev_count++;
/* XXX s/ixgbe/ixv/ */
ixgbe_dmamap_unload(txr->txtag, txbuf->map);
@@ -1655,76 +1656,97 @@ ixv_identify_hardware(struct adapter *ad
*
**********************************************************************/
static int
-ixv_allocate_msix(struct adapter *adapter)
+ixv_allocate_msix(struct adapter *adapter, const struct pci_attach_args *pa)
{
#if !defined(NETBSD_MSI_OR_MSIX)
return 0;
#else
device_t dev = adapter->dev;
- struct ix_queue *que = adapter->queues;
+ struct ix_queue *que = adapter->queues;
int error, rid, vector = 0;
- pcitag_t tag;
pci_chipset_tag_t pc;
+ pcitag_t tag;
+ char intrbuf[PCI_INTRSTR_LEN];
+ const char *intrstr = NULL;
+ kcpuset_t *affinity;
+ int cpu_id = 0;
pc = adapter->osdep.pc;
tag = adapter->osdep.tag;
+ if (pci_msix_alloc_exact(pa,
+ &adapter->osdep.intrs, IXG_MSIX_NINTR) != 0)
+ return (ENXIO);
+
+ kcpuset_create(&affinity, false);
for (int i = 0; i < adapter->num_queues; i++, vector++, que++) {
- rid = vector + 1;
- que->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
- RF_SHAREABLE | RF_ACTIVE);
- if (que->res == NULL) {
- aprint_error_dev(dev,"Unable to allocate"
- " bus resource: que interrupt [%d]\n", vector);
- return (ENXIO);
- }
+ intrstr = pci_intr_string(pc, adapter->osdep.intrs[i], intrbuf,
+ sizeof(intrbuf));
+#ifdef IXV_MPSAFE
+ pci_intr_setattr(pc, adapter->osdep.intrs[i], PCI_INTR_MPSAFE,
+ true);
+#endif
/* Set the handler function */
- error = bus_setup_intr(dev, que->res,
- INTR_TYPE_NET | INTR_MPSAFE, NULL,
- ixv_msix_que, que, &que->tag);
- if (error) {
+ adapter->osdep.ihs[i] = pci_intr_establish(pc,
+ adapter->osdep.intrs[i], IPL_NET, ixv_msix_que, que);
+ if (adapter->osdep.ihs[i] == NULL) {
que->res = NULL;
aprint_error_dev(dev,
"Failed to register QUE handler");
- return (error);
+ kcpuset_destroy(affinity);
+ return (ENXIO);
}
-#if __FreeBSD_version >= 800504
- bus_describe_intr(dev, que->res, que->tag, "que %d", i);
-#endif
que->msix = vector;
adapter->que_mask |= (u64)(1 << que->msix);
- /*
- ** Bind the msix vector, and thus the
- ** ring to the corresponding cpu.
- */
- if (adapter->num_queues > 1)
- bus_bind_intr(dev, que->res, i);
+ cpu_id = i;
+ /* Round-robin affinity */
+ kcpuset_zero(affinity);
+ kcpuset_set(affinity, cpu_id % ncpu);
+ error = pci_intr_distribute(adapter->osdep.ihs[i], affinity,
+ NULL);
+ aprint_normal_dev(dev, "for TX/RX, interrupting at %s",
+ intrstr);
+ if (error == 0)
+ aprint_normal(", bound queue %d to cpu %d\n",
+ i, cpu_id);
+ else
+ aprint_normal("\n");
+
que->que_si = softint_establish(SOFTINT_NET, ixv_handle_que,
que);
+ if (que->que_si == NULL) {
+ aprint_error_dev(dev,
+ "could not establish software interrupt\n");
+ }
}
/* and Mailbox */
- rid = vector + 1;
- adapter->res = bus_alloc_resource_any(dev,
- SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE);
- if (!adapter->res) {
- aprint_error_dev(dev,"Unable to allocate"
- " bus resource: MBX interrupt [%d]\n", rid);
- return (ENXIO);
- }
+ cpu_id++;
+ intrstr = pci_intr_string(pc, adapter->osdep.intrs[vector], intrbuf,
+ sizeof(intrbuf));
+#ifdef IXG_MPSAFE
+ pci_intr_setattr(pc, &adapter->osdep.intrs[vector], PCI_INTR_MPSAFE, true);
+#endif
/* Set the mbx handler function */
- error = bus_setup_intr(dev, adapter->res,
- INTR_TYPE_NET | INTR_MPSAFE, NULL,
- ixv_msix_mbx, adapter, &adapter->tag);
- if (error) {
+ adapter->osdep.ihs[vector] = pci_intr_establish(pc,
+ adapter->osdep.intrs[vector], IPL_NET, ixv_msix_mbx, adapter);
+ if (adapter->osdep.ihs[vector] == NULL) {
adapter->res = NULL;
- aprint_error_dev(dev, "Failed to register LINK handler");
- return (error);
+ aprint_error_dev(dev, "Failed to register LINK handler\n");
+ kcpuset_destroy(affinity);
+ return (ENXIO);
+ }
+ /* Round-robin affinity */
+ kcpuset_zero(affinity);
+ kcpuset_set(affinity, cpu_id % ncpu);
+ error = pci_intr_distribute(adapter->osdep.ihs[vector], affinity,NULL);
+
+ aprint_normal_dev(dev,
+ "for link, interrupting at %s, ", intrstr);
+ if (error == 0) {
+ aprint_normal("affinity to cpu %d\n", cpu_id);
}
-#if __FreeBSD_version >= 800504
- bus_describe_intr(dev, adapter->res, adapter->tag, "mbx");
-#endif
adapter->mbxvec = vector;
/* Tasklets for Mailbox */
adapter->mbx_si = softint_establish(SOFTINT_NET, ixv_handle_mbx,
@@ -1740,9 +1762,9 @@ ixv_allocate_msix(struct adapter *adapte
int msix_ctrl;
pci_get_capability(pc, tag, PCI_CAP_MSIX, &rid, NULL);
rid += PCI_MSIX_CTL;
- msix_ctrl = pci_read_config(pc, tag, rid);
+ msix_ctrl = pci_conf_read(pc, tag, rid);
msix_ctrl |= PCI_MSIX_CTL_ENABLE;
- pci_conf_write(pc, tag, msix_ctrl);
+ pci_conf_write(pc, tag, rid, msix_ctrl);
}
return (0);
@@ -1760,39 +1782,23 @@ ixv_setup_msix(struct adapter *adapter)
return 0;
#else
device_t dev = adapter->dev;
- int rid, want;
+ int want, msgs;
- /* First try MSI/X */
- rid = PCIR_BAR(3);
- adapter->msix_mem = bus_alloc_resource_any(dev,
- SYS_RES_MEMORY, &rid, RF_ACTIVE);
- if (adapter->msix_mem == NULL) {
- device_printf(adapter->dev,
- "Unable to map MSIX table \n");
- goto out;
- }
-
/*
** Want two vectors: one for a queue,
** plus an additional for mailbox.
*/
- want = 2;
- if ((pci_alloc_msix(dev, &want) == 0) && (want == 2)) {
- device_printf(adapter->dev,
- "Using MSIX interrupts with %d vectors\n", want);
- return (want);
- }
- /* Release in case alloc was insufficient */
- pci_release_msi(dev);
-out:
- if (adapter->msix_mem != NULL) {
- bus_release_resource(dev, SYS_RES_MEMORY,
- rid, adapter->msix_mem);
- adapter->msix_mem = NULL;
+ msgs = pci_msix_count(adapter->osdep.pc, adapter->osdep.tag);
+ if (msgs < IXG_MSIX_NINTR) {
+ aprint_error_dev(dev,"MSIX config error\n");
+ return (ENXIO);
}
- device_printf(adapter->dev,"MSIX config error\n");
- return (ENXIO);
+
+ adapter->msix_mem = (void *)1; /* XXX */
+ aprint_normal_dev(dev,
+ "Using MSIX interrupts with %d vectors\n", msgs);
+ return (want);
#endif
}
@@ -1851,62 +1857,42 @@ map_err:
static void
ixv_free_pci_resources(struct adapter * adapter)
{
-#if defined(NETBSD_MSI_OR_MSIX)
+#if !defined(NETBSD_MSI_OR_MSIX)
+#else
struct ix_queue *que = adapter->queues;
- device_t dev = adapter->dev;
- int rid, memrid;
-
- memrid = PCI_BAR(MSIX_BAR);
-
- /*
- ** There is a slight possibility of a failure mode
- ** in attach that will result in entering this function
- ** before interrupt resources have been initialized, and
- ** in that case we do not want to execute the loops below
- ** We can detect this reliably by the state of the adapter
- ** res pointer.
- */
- if (adapter->res == NULL)
- goto mem;
+ int rid;
/*
** Release all msix queue resources:
*/
for (int i = 0; i < adapter->num_queues; i++, que++) {
rid = que->msix + 1;
- if (que->tag != NULL) {
- bus_teardown_intr(dev, que->res, que->tag);
- que->tag = NULL;
- }
if (que->res != NULL)
- bus_release_resource(dev, SYS_RES_IRQ, rid, que->res);
+ pci_intr_disestablish(adapter->osdep.pc,
+ adapter->osdep.ihs[i]);
}
-
/* Clean the Legacy or Link interrupt last */
if (adapter->mbxvec) /* we are doing MSIX */
rid = adapter->mbxvec + 1;
else
(adapter->msix != 0) ? (rid = 1):(rid = 0);
- if (adapter->tag != NULL) {
- bus_teardown_intr(dev, adapter->res, adapter->tag);
- adapter->tag = NULL;
- }
- if (adapter->res != NULL)
- bus_release_resource(dev, SYS_RES_IRQ, rid, adapter->res);
-
-mem:
- if (adapter->msix)
- pci_release_msi(dev);
-
- if (adapter->msix_mem != NULL)
- bus_release_resource(dev, SYS_RES_MEMORY,
- memrid, adapter->msix_mem);
-
- if (adapter->pci_mem != NULL)
- bus_release_resource(dev, SYS_RES_MEMORY,
- PCIR_BAR(0), adapter->pci_mem);
+ if (adapter->osdep.ihs[rid] != NULL)
+ pci_intr_disestablish(adapter->osdep.pc,
+ adapter->osdep.ihs[rid]);
+ adapter->osdep.ihs[rid] = NULL;
+
+#if defined(NETBSD_MSI_OR_MSIX)
+ pci_intr_release(adapter->osdep.pc, adapter->osdep.intrs,
+ adapter->osdep.nintrs);
+#endif
+
+ if (adapter->osdep.mem_size != 0) {
+ bus_space_unmap(adapter->osdep.mem_bus_space_tag,
+ adapter->osdep.mem_bus_space_handle,
+ adapter->osdep.mem_size);
+ }
#endif
return;
@@ -4004,18 +3990,18 @@ ixv_print_hw_stats(struct adapter * adap
{
device_t dev = adapter->dev;
- device_printf(dev,"Std Mbuf Failed = %lu\n",
+ device_printf(dev,"Std Mbuf Failed = %"PRIu64"\n",
adapter->mbuf_defrag_failed.ev_count);
- device_printf(dev,"Driver dropped packets = %lu\n",
+ device_printf(dev,"Driver dropped packets = %"PRIu64"\n",
adapter->dropped_pkts.ev_count);
- device_printf(dev, "watchdog timeouts = %ld\n",
+ device_printf(dev, "watchdog timeouts = %"PRIu64"\n",
adapter->watchdog_events.ev_count);
- device_printf(dev,"Good Packets Rcvd = %llu\n",
+ device_printf(dev,"Good Packets Rcvd = %lld\n",
(long long)adapter->stats.vfgprc);
- device_printf(dev,"Good Packets Xmtd = %llu\n",
+ device_printf(dev,"Good Packets Xmtd = %lld\n",
(long long)adapter->stats.vfgptc);
- device_printf(dev,"TSO Transmissions = %lu\n",
+ device_printf(dev,"TSO Transmissions = %"PRIu64"\n",
adapter->tso_tx.ev_count);
}
Index: src/sys/dev/pci/ixgbe/ixgbe_osdep.h
diff -u src/sys/dev/pci/ixgbe/ixgbe_osdep.h:1.9 src/sys/dev/pci/ixgbe/ixgbe_osdep.h:1.10
--- src/sys/dev/pci/ixgbe/ixgbe_osdep.h:1.9 Wed Aug 5 04:08:44 2015
+++ src/sys/dev/pci/ixgbe/ixgbe_osdep.h Thu Aug 13 04:56:43 2015
@@ -31,7 +31,7 @@
******************************************************************************/
/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_osdep.h 251964 2013-06-18 21:28:19Z jfv $*/
-/*$NetBSD: ixgbe_osdep.h,v 1.9 2015/08/05 04:08:44 msaitoh Exp $*/
+/*$NetBSD: ixgbe_osdep.h,v 1.10 2015/08/13 04:56:43 msaitoh Exp $*/
#ifndef _IXGBE_OS_H_
#define _IXGBE_OS_H_
@@ -59,7 +59,7 @@
#define usec_delay(x) DELAY(x)
#define msec_delay(x) DELAY(1000*(x))
-#define DBG 0
+#define DBG 0
#define MSGOUT(S, A, B) printf(S "\n", A, B)
#define DEBUGFUNC(F) DEBUGOUT(F);
#if DBG
@@ -71,9 +71,9 @@
#define DEBUGOUT5(S,A,B,C,D,E) printf(S "\n",A,B,C,D,E)
#define DEBUGOUT6(S,A,B,C,D,E,F) printf(S "\n",A,B,C,D,E,F)
#define DEBUGOUT7(S,A,B,C,D,E,F,G) printf(S "\n",A,B,C,D,E,F,G)
- #define ERROR_REPORT1(S,A) printf(S "\n",A)
- #define ERROR_REPORT2(S,A,B) printf(S "\n",A,B)
- #define ERROR_REPORT3(S,A,B,C) printf(S "\n",A,B,C)
+ #define ERROR_REPORT1(S,A) printf(S A "\n")
+ #define ERROR_REPORT2(S,A,B) printf(S A "\n",B)
+ #define ERROR_REPORT3(S,A,B,C) printf(S A "\n",B,C)
#else
#define DEBUGOUT(S) do { } while (/*CONSTCOND*/false)
#define DEBUGOUT1(S,A) do { } while (/*CONSTCOND*/false)
@@ -125,6 +125,20 @@ typedef uint64_t u64;
#define le16_to_cpu
+#ifdef __HAVE_PCI_MSI_MSIX
+#define NETBSD_MSI_OR_MSIX
+/*
+ * This device driver divides interrupt to TX, RX and link state.
+ * Each MSI-X vector indexes are below.
+ */
+#define IXG_MSIX_NINTR 2
+#define IXG_MSIX_TXRXINTR_IDX 0
+#define IXG_MSIX_LINKINTR_IDX 1
+#define IXG_MAX_NINTR IXG_MSIX_NINTR
+#else
+#define IXG_MAX_NINTR 1
+#endif
+
#if __FreeBSD_version < 800000
#if defined(__i386__) || defined(__amd64__)
#define mb() __asm volatile("mfence" ::: "memory")
@@ -176,8 +190,9 @@ struct ixgbe_osdep
bus_size_t mem_size;
bus_dma_tag_t dmat;
device_t dev;
- pci_intr_handle_t ih;
- void *intr;
+ pci_intr_handle_t *intrs;
+ int nintrs;
+ void *ihs[IXG_MAX_NINTR];
bool attached;
};
Index: src/sys/dev/pci/ixgbe/ixgbe_type.h
diff -u src/sys/dev/pci/ixgbe/ixgbe_type.h:1.11 src/sys/dev/pci/ixgbe/ixgbe_type.h:1.12
--- src/sys/dev/pci/ixgbe/ixgbe_type.h:1.11 Wed Aug 5 04:08:44 2015
+++ src/sys/dev/pci/ixgbe/ixgbe_type.h Thu Aug 13 04:56:43 2015
@@ -31,7 +31,7 @@
******************************************************************************/
/*$FreeBSD: head/sys/dev/ixgbe/ixgbe_type.h 251964 2013-06-18 21:28:19Z jfv $*/
-/*$NetBSD: ixgbe_type.h,v 1.11 2015/08/05 04:08:44 msaitoh Exp $*/
+/*$NetBSD: ixgbe_type.h,v 1.12 2015/08/13 04:56:43 msaitoh Exp $*/
#ifndef _IXGBE_TYPE_H_
#define _IXGBE_TYPE_H_
@@ -80,6 +80,13 @@
* (Ex: Flow control autonegotiation or an unsupported SFP+ module.)
*/
+#define IXGBE_ERROR_INVALID_STATE "invalid state: "
+#define IXGBE_ERROR_POLLING "polling: "
+#define IXGBE_ERROR_CAUTION "caution: "
+#define IXGBE_ERROR_SOFTWARE "software: "
+#define IXGBE_ERROR_ARGUMENT "arg: "
+#define IXGBE_ERROR_UNSUPPORTED "unsupported: "
+
#include "ixgbe_osdep.h"