summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/if_ixl.c51
1 files changed, 42 insertions, 9 deletions
diff --git a/sys/dev/pci/if_ixl.c b/sys/dev/pci/if_ixl.c
index 80a40956126..abb84b88f3c 100644
--- a/sys/dev/pci/if_ixl.c
+++ b/sys/dev/pci/if_ixl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ixl.c,v 1.10 2019/01/19 00:08:10 jmatthew Exp $ */
+/* $OpenBSD: if_ixl.c,v 1.11 2019/01/20 01:32:08 jmatthew Exp $ */
/*
* Copyright (c) 2013-2015, Intel Corporation
@@ -1020,6 +1020,14 @@ struct ixl_rx_ring {
unsigned int rxr_qid;
};
+struct ixl_atq {
+ SIMPLEQ_ENTRY(ixl_atq) iatq_entry;
+ struct ixl_aq_desc iatq_desc;
+ void *iatq_arg;
+ void (*iatq_fn)(struct ixl_softc *, void *);
+};
+SIMPLEQ_HEAD(ixl_atq_list, ixl_atq);
+
struct ixl_softc {
struct device sc_dev;
struct arpcom sc_ac;
@@ -1063,6 +1071,9 @@ struct ixl_softc {
unsigned int sc_arq_prod;
unsigned int sc_arq_cons;
+ struct task sc_link_state_task;
+ struct ixl_atq sc_link_state_atq;
+
struct ixl_dmamem sc_hmc_sd;
struct ixl_dmamem sc_hmc_pd;
struct ixl_hmc_entry sc_hmc_entries[IXL_HMC_COUNT];
@@ -1075,14 +1086,6 @@ struct ixl_softc {
};
#define DEVNAME(_sc) ((_sc)->sc_dev.dv_xname)
-struct ixl_atq {
- SIMPLEQ_ENTRY(ixl_atq) iatq_entry;
- struct ixl_aq_desc iatq_desc;
- void *iatq_arg;
- void (*iatq_fn)(struct ixl_softc *, void *);
-};
-SIMPLEQ_HEAD(ixl_atq_list, ixl_atq);
-
#define delaymsec(_ms) delay(1000 * (_ms))
static void ixl_clear_hw(struct ixl_softc *);
@@ -1118,6 +1121,7 @@ static int ixl_set_vsi(struct ixl_softc *);
static int ixl_get_link_status(struct ixl_softc *);
static int ixl_set_link_status(struct ixl_softc *,
const struct ixl_aq_desc *);
+static void ixl_link_state_update(void *);
static void ixl_arq(void *);
static void ixl_hmc_pack(void *, const void *,
const struct ixl_hmc_pack *, unsigned int);
@@ -1560,6 +1564,7 @@ ixl_attach(struct device *parent, struct device *self, void *aux)
if_attach_queues(ifp, ixl_nqueues(sc));
if_attach_iqueues(ifp, ixl_nqueues(sc));
+ task_set(&sc->sc_link_state_task, ixl_link_state_update, sc);
ixl_wr(sc, I40E_PFINT_ICR0_ENA,
I40E_PFINT_ICR0_ENA_LINK_STAT_CHANGE_MASK |
I40E_PFINT_ICR0_ENA_ADMINQ_MASK);
@@ -2703,6 +2708,11 @@ ixl_intr(void *xsc)
rv = 1;
}
+ if (ISSET(icr, I40E_PFINT_ICR0_LINK_STAT_CHANGE_MASK)) {
+ task_add(systq, &sc->sc_link_state_task);
+ rv = 1;
+ }
+
if (ISSET(icr, I40E_INTR_NOTX_RX_MASK))
rv |= ixl_rxeof(sc, ifp->if_iqs[0]);
if (ISSET(icr, I40E_INTR_NOTX_TX_MASK))
@@ -2712,6 +2722,29 @@ ixl_intr(void *xsc)
}
static void
+ixl_link_state_update_done(struct ixl_softc *sc, void *arg)
+{
+ /* IXL_AQ_OP_PHY_LINK_STATUS already posted to admin reply queue */
+}
+
+static void
+ixl_link_state_update(void *xsc)
+{
+ struct ixl_softc *sc = xsc;
+ struct ixl_aq_desc *iaq;
+ struct ixl_aq_link_param *param;
+
+ memset(&sc->sc_link_state_atq, 0, sizeof(sc->sc_link_state_atq));
+ iaq = &sc->sc_link_state_atq.iatq_desc;
+ iaq->iaq_opcode = htole16(IXL_AQ_OP_PHY_LINK_STATUS);
+ param = (struct ixl_aq_link_param *)iaq->iaq_param;
+ param->notify = IXL_AQ_LINK_NOTIFY;
+
+ ixl_atq_set(&sc->sc_link_state_atq, ixl_link_state_update_done, NULL);
+ ixl_atq_post(sc, &sc->sc_link_state_atq);
+}
+
+static void
ixl_arq_link_status(struct ixl_softc *sc, const struct ixl_aq_desc *iaq)
{
struct ifnet *ifp = &sc->sc_ac.ac_if;