Module Name: src Committed By: yamaguchi Date: Wed Dec 11 10:03:08 UTC 2019
Modified Files: src/sys/dev/pci: if_ixl.c Log Message: Fix to detect link state down Link status event that is used to update link status sometimes is not notified when link down. So, use Get Link Status response that has the same information with the event. The handling of the event is needed to detect link state up because the response sometimes does not notify link up. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/sys/dev/pci/if_ixl.c 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/if_ixl.c diff -u src/sys/dev/pci/if_ixl.c:1.3 src/sys/dev/pci/if_ixl.c:1.4 --- src/sys/dev/pci/if_ixl.c:1.3 Wed Dec 11 05:50:03 2019 +++ src/sys/dev/pci/if_ixl.c Wed Dec 11 10:03:08 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_ixl.c,v 1.3 2019/12/11 05:50:03 yamaguchi Exp $ */ +/* $NetBSD: if_ixl.c,v 1.4 2019/12/11 10:03:08 yamaguchi Exp $ */ /* * Copyright (c) 2013-2015, Intel Corporation @@ -475,7 +475,8 @@ struct ixl_queue_pair { struct ixl_atq { struct ixl_aq_desc iatq_desc; - void (*iatq_fn)(struct ixl_softc *); + void (*iatq_fn)(struct ixl_softc *, + const struct ixl_aq_desc *); }; SIMPLEQ_HEAD(ixl_atq_list, ixl_atq); @@ -616,7 +617,8 @@ static void ixl_arq_unfill(struct ixl_so static int ixl_atq_poll(struct ixl_softc *, struct ixl_aq_desc *, unsigned int); -static void ixl_atq_set(struct ixl_atq *, void (*)(struct ixl_softc *)); +static void ixl_atq_set(struct ixl_atq *, + void (*)(struct ixl_softc *, const struct ixl_aq_desc *)); static int ixl_atq_post(struct ixl_softc *, struct ixl_atq *); static int ixl_atq_post_locked(struct ixl_softc *, struct ixl_atq *); static void ixl_atq_done(struct ixl_softc *); @@ -635,7 +637,8 @@ static void ixl_hmc_free(struct ixl_soft static int ixl_get_vsi(struct ixl_softc *); static int ixl_set_vsi(struct ixl_softc *); static void ixl_set_filter_control(struct ixl_softc *); -static int ixl_get_link_status(struct ixl_softc *); +static void ixl_get_link_status(void *); +static int ixl_get_link_status_poll(struct ixl_softc *); static int ixl_set_link_status(struct ixl_softc *, const struct ixl_aq_desc *); static void ixl_config_rss(struct ixl_softc *); @@ -644,7 +647,6 @@ static int ixl_add_macvlan(struct ixl_so static int ixl_remove_macvlan(struct ixl_softc *, uint8_t *, uint16_t, uint16_t); static void ixl_arq(void *); -static void ixl_link_state_update(void *); static void ixl_hmc_pack(void *, const void *, const struct ixl_hmc_pack *, unsigned int); static uint32_t ixl_rd_rx_csr(struct ixl_softc *, uint32_t); @@ -719,7 +721,8 @@ static void ixl_work_wait(struct workque static void ixl_workq_work(struct work *, void *); static const struct ixl_product * ixl_lookup(const struct pci_attach_args *pa); -static void ixl_link_status(struct ixl_softc *); +static void ixl_link_state_update(struct ixl_softc *, + const struct ixl_aq_desc *); static int ixl_set_macvlan(struct ixl_softc *); static int ixl_setup_interrupts(struct ixl_softc *);; static void ixl_teardown_interrupts(struct ixl_softc *); @@ -1109,7 +1112,7 @@ ixl_attach(device_t parent, device_t sel goto free_hmc; } - rv = ixl_get_link_status(sc); + rv = ixl_get_link_status_poll(sc); if (rv != 0) { aprint_error_dev(self, "GET LINK STATUS %s\n", rv == ETIMEDOUT ? "timeout" : "error"); @@ -1204,7 +1207,7 @@ ixl_attach(device_t parent, device_t sel ether_set_ifflags_cb(&sc->sc_ec, ixl_ifflags_cb); (void)ixl_get_link_status(sc); - ixl_work_set(&sc->sc_link_state_task, ixl_link_state_update, sc); + ixl_work_set(&sc->sc_link_state_task, ixl_get_link_status, sc); ixl_config_other_intr(sc); @@ -1787,7 +1790,8 @@ ixl_init_locked(struct ixl_softc *sc) SET(ifp->if_flags, IFF_RUNNING); CLR(ifp->if_flags, IFF_OACTIVE); - ixl_link_status(sc); + + (void)ixl_get_link_status_poll(sc); ixl_config_rss(sc); ixl_config_queue_intr(sc); @@ -3128,14 +3132,15 @@ ixl_other_intr(void *xsc) } static void -ixl_link_state_update_done(struct ixl_softc *sc) +ixl_get_link_status_done(struct ixl_softc *sc, + const struct ixl_aq_desc *iaq) { - /* IXL_AQ_OP_PHY_LINK_STATUS already posted to admin reply queue */ + ixl_link_state_update(sc, iaq); } static void -ixl_link_state_update(void *xsc) +ixl_get_link_status(void *xsc) { struct ixl_softc *sc = xsc; struct ixl_aq_desc *iaq; @@ -3147,12 +3152,12 @@ ixl_link_state_update(void *xsc) 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); + ixl_atq_set(&sc->sc_link_state_atq, ixl_get_link_status_done); (void)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) +ixl_link_state_update(struct ixl_softc *sc, const struct ixl_aq_desc *iaq) { struct ifnet *ifp = &sc->sc_ec.ec_if; int link_state; @@ -3168,7 +3173,8 @@ ixl_arq_link_status(struct ixl_softc *sc } static void -ixl_aq_dump(const struct ixl_softc *sc, const struct ixl_aq_desc *iaq) +ixl_aq_dump(const struct ixl_softc *sc, const struct ixl_aq_desc *iaq, + const char *msg) { char buf[512]; size_t len; @@ -3176,6 +3182,7 @@ ixl_aq_dump(const struct ixl_softc *sc, len = sizeof(buf); buf[--len] = '\0'; + device_printf(sc->sc_dev, "%s\n", msg); snprintb(buf, len, IXL_AQ_FLAGS_FMT, le16toh(iaq->iaq_flags)); device_printf(sc->sc_dev, "flags %s opcode %04x\n", buf, le16toh(iaq->iaq_opcode)); @@ -3219,11 +3226,11 @@ ixl_arq(void *xsc) BUS_DMASYNC_POSTREAD); if (ISSET(sc->sc_ec.ec_if.if_flags, IFF_DEBUG)) - ixl_aq_dump(sc, iaq); + ixl_aq_dump(sc, iaq, "arq event"); switch (iaq->iaq_opcode) { case htole16(IXL_AQ_OP_PHY_LINK_STATUS): - ixl_arq_link_status(sc, iaq); + ixl_link_state_update(sc, iaq); break; } @@ -3250,8 +3257,10 @@ done: } static void -ixl_atq_set(struct ixl_atq *iatq, void (*fn)(struct ixl_softc *)) +ixl_atq_set(struct ixl_atq *iatq, + void (*fn)(struct ixl_softc *, const struct ixl_aq_desc *)) { + iatq->iatq_fn = fn; } @@ -3281,7 +3290,7 @@ ixl_atq_post_locked(struct ixl_softc *sc slot->iaq_cookie = (uint64_t)((intptr_t)iatq); if (ISSET(sc->sc_ec.ec_if.if_flags, IFF_DEBUG)) - ixl_aq_dump(sc, slot); + ixl_aq_dump(sc, slot, "atq command"); bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq), 0, IXL_DMA_LEN(&sc->sc_atq), BUS_DMASYNC_PREWRITE); @@ -3336,7 +3345,10 @@ ixl_atq_done_locked(struct ixl_softc *sc memset(slot, 0, sizeof(*slot)); - (*iatq->iatq_fn)(sc); + if (ISSET(sc->sc_ec.ec_if.if_flags, IFF_DEBUG)) + ixl_aq_dump(sc, &iatq->iatq_desc, "atq response"); + + (*iatq->iatq_fn)(sc, &iatq->iatq_desc); cons++; cons &= IXL_AQ_MASK; @@ -3359,7 +3371,7 @@ ixl_atq_done(struct ixl_softc *sc) } static void -ixl_wakeup(struct ixl_softc *sc) +ixl_wakeup(struct ixl_softc *sc, const struct ixl_aq_desc *iaq) { KASSERT(mutex_owned(&sc->sc_atq_lock)); @@ -3845,7 +3857,7 @@ done: } static int -ixl_get_link_status(struct ixl_softc *sc) +ixl_get_link_status_poll(struct ixl_softc *sc) { struct ixl_aq_desc iaq; struct ixl_aq_link_param *param; @@ -4770,13 +4782,6 @@ ixl_set_macvlan(struct ixl_softc *sc) return rv; } -static void -ixl_link_status(struct ixl_softc *sc) -{ - - (void)ixl_get_link_status(sc); -} - static int ixl_ifflags_cb(struct ethercom *ec) {