Module Name: src Committed By: martin Date: Mon Jan 23 13:59:04 UTC 2023
Modified Files: src/sys/dev/pci [netbsd-9]: if_wm.c if_wmreg.h Log Message: Pull up the following revisions, requested by msaitoh in ticket #1578: sys/dev/pci/if_wm.c 1.764-1.767 via patch sys/dev/pci/if_wmreg.h 1.128 - Workaround for some hypervisor environments. The environments cannot stop e1000 interrupt immediately. - Rename nq_txdesc' member "nqrx_ctx" to "nqtx_ctx". No functional change. - Add comment. Modify comment. - KNF. To generate a diff of this commit: cvs rdiff -u -r1.645.2.14 -r1.645.2.15 src/sys/dev/pci/if_wm.c cvs rdiff -u -r1.115.2.6 -r1.115.2.7 src/sys/dev/pci/if_wmreg.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/if_wm.c diff -u src/sys/dev/pci/if_wm.c:1.645.2.14 src/sys/dev/pci/if_wm.c:1.645.2.15 --- src/sys/dev/pci/if_wm.c:1.645.2.14 Wed Sep 7 10:05:42 2022 +++ src/sys/dev/pci/if_wm.c Mon Jan 23 13:59:04 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wm.c,v 1.645.2.14 2022/09/07 10:05:42 martin Exp $ */ +/* $NetBSD: if_wm.c,v 1.645.2.15 2023/01/23 13:59:04 martin Exp $ */ /* * Copyright (c) 2001, 2002, 2003, 2004 Wasabi Systems, Inc. @@ -82,7 +82,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.645.2.14 2022/09/07 10:05:42 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.645.2.15 2023/01/23 13:59:04 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_net_mpsafe.h" @@ -490,6 +490,7 @@ struct wm_queue { char sysctlname[32]; /* Name for sysctl */ bool wmq_txrx_use_workqueue; + bool wmq_wq_enqueued; struct work wmq_cookie; void *wmq_si; krndsource_t rnd_source; /* random source */ @@ -2289,7 +2290,7 @@ alloc_retry: aprint_error_dev(sc->sc_dev, "unable to find PCIX capability\n"); else if (sc->sc_type != WM_T_82545_3 && - sc->sc_type != WM_T_82546_3) { + sc->sc_type != WM_T_82546_3) { /* * Work around a problem caused by the BIOS * setting the max memory read byte count @@ -3673,7 +3674,7 @@ wm_watchdog_txq_locked(struct ifnet *ifp ifp->if_oerrors++; #ifdef WM_DEBUG for (i = txq->txq_sdirty; i != txq->txq_snext; - i = WM_NEXTTXS(txq, i)) { + i = WM_NEXTTXS(txq, i)) { txs = &txq->txq_soft[i]; printf("txs %d tx %d -> %d\n", i, txs->txs_firstdesc, txs->txs_lastdesc); @@ -3834,9 +3835,9 @@ wm_tick(void *arg) crcerrs + algnerrc + symerrc + rxerrc + sec + cexterr + rlec; /* - * WMREG_RNBC is incremented when there are no available buffers in host - * memory. It does not mean the number of dropped packets, because an - * Ethernet controller can receive packets in such case if there is + * WMREG_RNBC is incremented when there are no available buffers in + * host memory. It does not mean the number of dropped packets, because + * an Ethernet controller can receive packets in such case if there is * space in the phy's FIFO. * * If you want to know the nubmer of WMREG_RMBC, you should use such as @@ -4153,7 +4154,7 @@ wm_read_mac_addr(struct wm_softc *sc, ui return 0; - bad: +bad: return -1; } @@ -4442,10 +4443,10 @@ wm_set_filter(struct wm_softc *sc) goto setit; - allmulti: +allmulti: sc->sc_rctl |= RCTL_MPE; - setit: +setit: if (sc->sc_type >= WM_T_PCH2) { if (((ec->ec_capabilities & ETHERCAP_JUMBO_MTU) != 0) && (ifp->if_mtu > ETHERMTU)) @@ -4836,7 +4837,8 @@ wm_init_lcd_from_nvm(struct wm_softc *sc * LCD Write Enable bits are set in the NVM. When both NVM bits * are cleared, SW will configure them instead. */ - DPRINTF(sc, WM_DEBUG_INIT, ("%s: %s: Configure SMBus and LED\n", + DPRINTF(sc, WM_DEBUG_INIT, + ("%s: %s: Configure SMBus and LED\n", device_xname(sc->sc_dev), __func__)); if ((rv = wm_write_smbus_addr(sc)) != 0) goto release; @@ -5147,15 +5149,15 @@ wm_initialize_hardware_bits(struct wm_so CSR_WRITE(sc, WMREG_TARC0, tarc0); switch (sc->sc_type) { - /* - * 8257[12] Errata No.52, 82573 Errata No.43 and some others. - * Avoid RSS Hash Value bug. - */ case WM_T_82571: case WM_T_82572: case WM_T_82573: case WM_T_80003: case WM_T_ICH8: + /* + * 8257[12] Errata No.52, 82573 Errata No.43 and some + * others to avoid RSS Hash Value bug. + */ reg = CSR_READ(sc, WMREG_RFCTL); reg |= WMREG_RFCTL_NEWIPV6EXDIS |WMREG_RFCTL_IPV6EXDIS; CSR_WRITE(sc, WMREG_RFCTL, reg); @@ -5560,6 +5562,11 @@ wm_reset(struct wm_softc *sc) CSR_WRITE(sc, WMREG_CTRL, reg); /* Don't insert a completion barrier when reset */ delay(20*1000); + /* + * The EXTCNFCTR_MDIO_SW_OWNERSHIP bit is cleared by the reset, + * so don't use sc->phy.release(sc). Release sc_ich_phymtx + * only. See also wm_get_swflag_ich8lan(). + */ mutex_exit(sc->sc_ich_phymtx); break; case WM_T_82580: @@ -6181,7 +6188,7 @@ wm_setup_msix(struct wm_softc *sc) kcpuset_destroy(affinity); return 0; - fail: +fail: for (qidx = 0; qidx < txrx_established; qidx++) { struct wm_queue *wmq = &sc->sc_queue[qidx]; pci_intr_disestablish(sc->sc_pc,sc->sc_ihs[wmq->wmq_intr_idx]); @@ -6258,7 +6265,8 @@ wm_itrs_writereg(struct wm_softc *sc, st * So, overwrite counter field by software. */ if (sc->sc_type == WM_T_82575) - eitr |= __SHIFTIN(wmq->wmq_itr, EITR_COUNTER_MASK_82575); + eitr |= __SHIFTIN(wmq->wmq_itr, + EITR_COUNTER_MASK_82575); else eitr |= EITR_CNT_INGR; @@ -6359,7 +6367,8 @@ wm_init_sysctls(struct wm_softc *sc) goto err; rv = sysctl_createv(log, 0, &rnode, &cnode, CTLFLAG_READWRITE, - CTLTYPE_BOOL, "txrx_workqueue", SYSCTL_DESCR("Use workqueue for packet processing"), + CTLTYPE_BOOL, "txrx_workqueue", + SYSCTL_DESCR("Use workqueue for packet processing"), NULL, 0, &sc->sc_txrx_use_workqueue, 0, CTL_CREATE, CTL_EOL); if (rv != 0) goto teardown; @@ -7062,7 +7071,7 @@ wm_init_locked(struct ifnet *ifp) ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; - out: +out: /* Save last flags for the callback */ sc->sc_if_flags = ifp->if_flags; sc->sc_ec_capenable = ec->ec_capenable; @@ -7291,7 +7300,7 @@ wm_82547_txfifo_bugchk(struct wm_softc * return 1; } - send_packet: +send_packet: txq->txq_fifo_head += len; if (txq->txq_fifo_head >= txq->txq_fifo_size) txq->txq_fifo_head -= txq->txq_fifo_size; @@ -7356,14 +7365,14 @@ wm_alloc_tx_descs(struct wm_softc *sc, s return 0; - fail_3: +fail_3: bus_dmamap_destroy(sc->sc_dmat, txq->txq_desc_dmamap); - fail_2: +fail_2: bus_dmamem_unmap(sc->sc_dmat, (void *)txq->txq_descs_u, WM_TXDESCS_SIZE(txq)); - fail_1: +fail_1: bus_dmamem_free(sc->sc_dmat, &txq->txq_desc_seg, txq->txq_desc_rseg); - fail_0: +fail_0: return error; } @@ -7481,7 +7490,7 @@ wm_alloc_tx_buffer(struct wm_softc *sc, return 0; - fail: +fail: for (i = 0; i < WM_TXQUEUELEN(txq); i++) { if (txq->txq_soft[i].txs_dmamap != NULL) bus_dmamap_destroy(sc->sc_dmat, @@ -7672,7 +7681,7 @@ wm_alloc_txrx_queues(struct wm_softc *sc return 0; - fail_2: +fail_2: for (i = 0; i < rx_done; i++) { struct wm_rxqueue *rxq = &sc->sc_queue[i].wmq_rxq; wm_free_rx_buffer(sc, rxq); @@ -7680,7 +7689,7 @@ wm_alloc_txrx_queues(struct wm_softc *sc if (rxq->rxq_lock) mutex_obj_free(rxq->rxq_lock); } - fail_1: +fail_1: for (i = 0; i < tx_done; i++) { struct wm_txqueue *txq = &sc->sc_queue[i].wmq_txq; pcq_destroy(txq->txq_interq); @@ -7692,7 +7701,7 @@ wm_alloc_txrx_queues(struct wm_softc *sc kmem_free(sc->sc_queue, sizeof(struct wm_queue) * sc->sc_nqueues); - fail_0: +fail_0: return error; } @@ -8899,12 +8908,12 @@ wm_nq_tx_offload(struct wm_softc *sc, st * however it does not cause problems. */ /* Fill in the context descriptor. */ - txq->txq_nq_descs[txq->txq_next].nqrx_ctx.nqtxc_vl_len = + txq->txq_nq_descs[txq->txq_next].nqtx_ctx.nqtxc_vl_len = htole32(vl_len); - txq->txq_nq_descs[txq->txq_next].nqrx_ctx.nqtxc_sn = 0; - txq->txq_nq_descs[txq->txq_next].nqrx_ctx.nqtxc_cmd = + txq->txq_nq_descs[txq->txq_next].nqtx_ctx.nqtxc_sn = 0; + txq->txq_nq_descs[txq->txq_next].nqtx_ctx.nqtxc_cmd = htole32(cmdc); - txq->txq_nq_descs[txq->txq_next].nqrx_ctx.nqtxc_mssidx = + txq->txq_nq_descs[txq->txq_next].nqtx_ctx.nqtxc_mssidx = htole32(mssidx); wm_cdtxsync(txq, txq->txq_next, 1, BUS_DMASYNC_PREWRITE); DPRINTF(sc, WM_DEBUG_TX, @@ -9067,7 +9076,7 @@ wm_nq_send_common_locked(struct ifnet *i DPRINTF(sc, WM_DEBUG_TX, ("%s: TX: have packet to transmit: %p\n", - device_xname(sc->sc_dev), m0)); + device_xname(sc->sc_dev), m0)); txs = &txq->txq_soft[txq->txq_snext]; dmamap = txs->txs_dmamap; @@ -10288,9 +10297,13 @@ static inline void wm_sched_handle_queue(struct wm_softc *sc, struct wm_queue *wmq) { - if (wmq->wmq_txrx_use_workqueue) - workqueue_enqueue(sc->sc_queue_wq, &wmq->wmq_cookie, curcpu()); - else + if (wmq->wmq_txrx_use_workqueue) { + if (!wmq->wmq_wq_enqueued) { + wmq->wmq_wq_enqueued = true; + workqueue_enqueue(sc->sc_queue_wq, &wmq->wmq_cookie, + curcpu()); + } + } else softint_schedule(wmq->wmq_si); } @@ -10589,8 +10602,10 @@ wm_handle_queue_work(struct work *wk, vo struct wm_queue *wmq = container_of(wk, struct wm_queue, wmq_cookie); /* - * "enqueued flag" is not required here. + * Some qemu environment workaround. They don't stop interrupt + * immediately. */ + wmq->wmq_wq_enqueued = false; wm_handle_queue(wmq); } @@ -12073,7 +12088,7 @@ wm_disable_phy_wakeup_reg_access_bm(devi */ static int wm_access_phy_wakeup_reg_bm(device_t dev, int offset, int16_t *val, int rd, - bool page_set) + bool page_set) { struct wm_softc *sc = device_private(dev); uint16_t regnum = BM_PHY_REG_NUM(offset); @@ -12462,8 +12477,8 @@ wm_gmii_statchg(struct ifnet *ifp) CSR_WRITE(sc, WMREG_CTRL, sc->sc_ctrl); CSR_WRITE(sc, WMREG_TCTL, sc->sc_tctl); - CSR_WRITE(sc, (sc->sc_type < WM_T_82543) ? WMREG_OLD_FCRTL - : WMREG_FCRTL, sc->sc_fcrtl); + CSR_WRITE(sc, (sc->sc_type < WM_T_82543) ? + WMREG_OLD_FCRTL : WMREG_FCRTL, sc->sc_fcrtl); if (sc->sc_type == WM_T_80003) { switch (IFM_SUBTYPE(mii->mii_media_active)) { case IFM_1000_T: @@ -14571,7 +14586,7 @@ wm_nvm_validate_checksum(struct wm_softc DPRINTF(sc, WM_DEBUG_NVM, ("%s: NVM need to be updated (%04x != %04x)\n", device_xname(sc->sc_dev), eeprom_data, - valid_checksum)); + valid_checksum)); } if ((sc->sc_debug & WM_DEBUG_NVM) != 0) { @@ -15558,8 +15573,8 @@ wm_init_phy_workarounds_pchlan(struct wm /* Acquire PHY semaphore */ rv = sc->phy.acquire(sc); if (rv != 0) { - DPRINTF(sc, WM_DEBUG_INIT, ("%s: %s: failed\n", - device_xname(sc->sc_dev), __func__)); + DPRINTF(sc, WM_DEBUG_INIT, + ("%s: %s: failed\n", device_xname(sc->sc_dev), __func__)); return rv; } @@ -15805,8 +15820,8 @@ wm_ulp_disable(struct wm_softc *sc) /* Acquire semaphore */ rv = sc->phy.acquire(sc); if (rv != 0) { - DPRINTF(sc, WM_DEBUG_INIT, ("%s: %s: failed\n", - device_xname(sc->sc_dev), __func__)); + DPRINTF(sc, WM_DEBUG_INIT, + ("%s: %s: failed\n", device_xname(sc->sc_dev), __func__)); return rv; } @@ -15819,7 +15834,7 @@ wm_ulp_disable(struct wm_softc *sc) uint32_t reg2; aprint_debug_dev(sc->sc_dev, "%s: Force SMBus first.\n", - __func__); + __func__); reg2 = CSR_READ(sc, WMREG_CTRL_EXT); reg2 |= CTRL_EXT_FORCE_SMBUS; CSR_WRITE(sc, WMREG_CTRL_EXT, reg2); @@ -15845,7 +15860,7 @@ wm_ulp_disable(struct wm_softc *sc) wm_gmii_hv_writereg_locked(sc->sc_dev, 2, HV_PM_CTRL, phyreg); rv = wm_gmii_hv_readreg_locked(sc->sc_dev, 2, I218_ULP_CONFIG1, - &phyreg); + &phyreg); if (rv != 0) goto release; phyreg &= ~(I218_ULP_CONFIG1_IND Index: src/sys/dev/pci/if_wmreg.h diff -u src/sys/dev/pci/if_wmreg.h:1.115.2.6 src/sys/dev/pci/if_wmreg.h:1.115.2.7 --- src/sys/dev/pci/if_wmreg.h:1.115.2.6 Wed Sep 7 10:05:42 2022 +++ src/sys/dev/pci/if_wmreg.h Mon Jan 23 13:59:04 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: if_wmreg.h,v 1.115.2.6 2022/09/07 10:05:42 martin Exp $ */ +/* $NetBSD: if_wmreg.h,v 1.115.2.7 2023/01/23 13:59:04 martin Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -1707,7 +1707,7 @@ typedef union nq_txdesc { uint32_t nqtxc_sn; uint32_t nqtxc_cmd; uint32_t nqtxc_mssidx; - } nqrx_ctx; + } nqtx_ctx; } __packed nq_txdesc_t;