Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-9]: src/sys/dev/pci Pull up the following revisions, requested by...
details: https://anonhg.NetBSD.org/src/rev/2dfdff3a279f
branches: netbsd-9
changeset: 935839:2dfdff3a279f
user: martin <martin%NetBSD.org@localhost>
date: Fri Jul 10 10:45:56 2020 +0000
description:
Pull up the following revisions, requested by msaitoh in ticket #994:
sys/dev/pci/if_wm.c 1.655-1.658, 1.660, 1.662, 1.664-1.668,
1.671-1.674, 1.678,1.680-1.681 via patch
sys/dev/pci/if_wmreg.c 1.118-1.119
sys/dev/pci/if_wmvar.c 1.45
- Add SFP support. Module insertion/removal is not supported yet.
Currently, SFP detection is only done in the driver's attach phase.
- Detect the Media Auto Sense feature. Not supported yet.
- Fix SFF_SFP_ETH_FLAGS_100FX. It's not 0x10 but 0x20.
- Add extra delay in wm_serdes_power_up_link_82575().
- Add Intel I219 LM10-LM15 and V10-V14.
- wm(4) can use workqueue as deferred Rx/Tx handler.
Set hw.wm*.txrx_workqueue=1 to use workqueue instead of softint.
The default value of hw.wm*.txrx_workqueue is 0 which use softint
as before.
- Unset RSS UDP flags like ixg(4) and other OSes. To handle IP
fragmented UDP, first packet and second packet should be processed
in the same Rx queue.
- It's useless to not to set PCI_PMCSR_PME_STS bit when writing because
the bit is W1C. Instead, always write PCI_PMCSR_PME_STS bit to clear
in case it's already set.
- Actually writing always the checksum offload context descriptor
makes the HW do extra processing, avoid doing that if possible.
- Fix a bug that the WMREG_EEARBC_I210 register is incorrectly set if
the system uses iNVM.
- "wmX: 0" on 82542 is difficult to understand, so don't print it.
- Rename some macros and function.
- KNF. Add comment.
diffstat:
sys/dev/pci/if_wm.c | 565 ++++++++++++++++++++++++++++++++++++++----------
sys/dev/pci/if_wmreg.h | 8 +-
sys/dev/pci/if_wmvar.h | 7 +-
3 files changed, 451 insertions(+), 129 deletions(-)
diffs (truncated from 1313 to 300 lines):
diff -r 969ebe8156a7 -r 2dfdff3a279f sys/dev/pci/if_wm.c
--- a/sys/dev/pci/if_wm.c Fri Jul 10 10:36:56 2020 +0000
+++ b/sys/dev/pci/if_wm.c Fri Jul 10 10:45:56 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_wm.c,v 1.645.2.4 2020/01/26 11:13:27 martin Exp $ */
+/* $NetBSD: if_wm.c,v 1.645.2.5 2020/07/10 10:45:56 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.4 2020/01/26 11:13:27 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wm.c,v 1.645.2.5 2020/07/10 10:45:56 martin Exp $");
#ifdef _KERNEL_OPT
#include "opt_net_mpsafe.h"
@@ -105,6 +105,8 @@
#include <sys/interrupt.h>
#include <sys/cpu.h>
#include <sys/pcq.h>
+#include <sys/sysctl.h>
+#include <sys/workqueue.h>
#include <sys/rndsource.h>
@@ -156,7 +158,6 @@
#define WM_DEBUG_LOCK __BIT(7)
int wm_debug = WM_DEBUG_TX | WM_DEBUG_RX | WM_DEBUG_LINK | WM_DEBUG_GMII
| WM_DEBUG_MANAGE | WM_DEBUG_NVM | WM_DEBUG_INIT | WM_DEBUG_LOCK;
-
#define DPRINTF(x, y) do { if (wm_debug & (x)) printf y; } while (0)
#else
#define DPRINTF(x, y) __nothing
@@ -164,11 +165,17 @@
#ifdef NET_MPSAFE
#define WM_MPSAFE 1
-#define CALLOUT_FLAGS CALLOUT_MPSAFE
+#define WM_CALLOUT_FLAGS CALLOUT_MPSAFE
+#define WM_SOFTINT_FLAGS SOFTINT_MPSAFE
+#define WM_WORKQUEUE_FLAGS WQ_PERCPU | WQ_MPSAFE
#else
-#define CALLOUT_FLAGS 0
+#define WM_CALLOUT_FLAGS 0
+#define WM_SOFTINT_FLAGS 0
+#define WM_WORKQUEUE_FLAGS WQ_PERCPU
#endif
+#define WM_WORKQUEUE_PRI PRI_SOFTNET
+
/*
* This device driver's max interrupt numbers.
*/
@@ -374,6 +381,12 @@
bool txq_sending;
time_t txq_lastsent;
+ /* Checksum flags used for previous packet */
+ uint32_t txq_last_hw_cmd;
+ uint8_t txq_last_hw_fields;
+ uint16_t txq_last_hw_ipcs;
+ uint16_t txq_last_hw_tucs;
+
uint32_t txq_packets; /* for AIM */
uint32_t txq_bytes; /* for AIM */
#ifdef WM_EVENT_COUNTERS
@@ -398,6 +411,7 @@
WM_Q_EVCNT_DEFINE(txq, toomanyseg) /* Pkt dropped(toomany DMA segs) */
WM_Q_EVCNT_DEFINE(txq, defrag) /* m_defrag() */
WM_Q_EVCNT_DEFINE(txq, underrun) /* Tx underrun */
+ WM_Q_EVCNT_DEFINE(txq, skipcontext) /* Tx skip wring cksum context */
char txq_txseg_evcnt_names[WM_NTXSEGS][sizeof("txqXXtxsegXXX")];
struct evcnt txq_ev_txseg[WM_NTXSEGS]; /* Tx packets w/ N segments */
@@ -457,6 +471,8 @@
struct wm_txqueue wmq_txq;
struct wm_rxqueue wmq_rxq;
+ bool wmq_txrx_use_workqueue;
+ struct work wmq_cookie;
void *wmq_si;
krndsource_t rnd_source; /* random source */
};
@@ -467,6 +483,7 @@
int (*readreg_locked)(device_t, int, int, uint16_t *);
int (*writereg_locked)(device_t, int, int, uint16_t);
int reset_delay_us;
+ bool no_errprint;
};
struct wm_nvmop {
@@ -507,6 +524,7 @@
wm_chip_type sc_type; /* MAC type */
int sc_rev; /* MAC revision */
wm_phy_type sc_phytype; /* PHY type */
+ uint8_t sc_sfptype; /* SFP type */
uint32_t sc_mediatype; /* Media type (Copper, Fiber, SERDES)*/
#define WM_MEDIATYPE_UNKNOWN 0x00
#define WM_MEDIATYPE_FIBER 0x01
@@ -551,6 +569,8 @@
u_int sc_tx_intr_process_limit; /* Tx proc. repeat limit in H/W intr */
u_int sc_rx_process_limit; /* Rx proc. repeat limit in softint */
u_int sc_rx_intr_process_limit; /* Rx proc. repeat limit in H/W intr */
+ struct workqueue *sc_queue_wq;
+ bool sc_txrx_use_workqueue;
int sc_affinity_offset;
@@ -566,6 +586,8 @@
struct evcnt sc_ev_rx_macctl; /* Rx Unsupported */
#endif /* WM_EVENT_COUNTERS */
+ struct sysctllog *sc_sysctllog;
+
/* This variable are used only on the 82547. */
callout_t sc_txfifo_ch; /* Tx FIFO stall work-around timer */
@@ -737,11 +759,12 @@
static void wm_adjust_qnum(struct wm_softc *, int);
static inline bool wm_is_using_msix(struct wm_softc *);
static inline bool wm_is_using_multiqueue(struct wm_softc *);
-static int wm_softint_establish(struct wm_softc *, int, int);
+static int wm_softint_establish_queue(struct wm_softc *, int, int);
static int wm_setup_legacy(struct wm_softc *);
static int wm_setup_msix(struct wm_softc *);
static int wm_init(struct ifnet *);
static int wm_init_locked(struct ifnet *);
+static void wm_init_sysctls(struct wm_softc *);
static void wm_unset_stopping_flags(struct wm_softc *);
static void wm_set_stopping_flags(struct wm_softc *);
static void wm_stop(struct ifnet *, int);
@@ -774,7 +797,7 @@
static void wm_free_txrx_queues(struct wm_softc *);
static int wm_init_txrx_queues(struct wm_softc *);
/* Start */
-static int wm_tx_offload(struct wm_softc *, struct wm_txqueue *,
+static void wm_tx_offload(struct wm_softc *, struct wm_txqueue *,
struct wm_txsoft *, uint32_t *, uint8_t *);
static inline int wm_select_txqueue(struct ifnet *, struct mbuf *);
static void wm_start(struct ifnet *);
@@ -783,7 +806,7 @@
static void wm_transmit_locked(struct ifnet *, struct wm_txqueue *);
static void wm_send_common_locked(struct ifnet *, struct wm_txqueue *,
bool);
-static int wm_nq_tx_offload(struct wm_softc *, struct wm_txqueue *,
+static void wm_nq_tx_offload(struct wm_softc *, struct wm_txqueue *,
struct wm_txsoft *, uint32_t *, uint32_t *, bool *);
static void wm_nq_start(struct ifnet *);
static void wm_nq_start_locked(struct ifnet *);
@@ -793,6 +816,7 @@
bool);
static void wm_deferred_start_locked(struct wm_txqueue *);
static void wm_handle_queue(void *);
+static void wm_handle_queue_work(struct work *, void *);
/* Interrupt */
static bool wm_txeof(struct wm_txqueue *, u_int);
static bool wm_rxeof(struct wm_rxqueue *, u_int);
@@ -1184,23 +1208,23 @@
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82571GB_QUAD_COPPER,
"Intel PRO/1000 PT Quad Port Server Adapter",
- WM_T_82571, WMP_F_COPPER, },
+ WM_T_82571, WMP_F_COPPER },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82571PT_QUAD_COPPER,
"Intel Gigabit PT Quad Port Server ExpressModule",
- WM_T_82571, WMP_F_COPPER, },
+ WM_T_82571, WMP_F_COPPER },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82571EB_DUAL_SERDES,
"Intel 82571EB Dual Gigabit Ethernet (SERDES)",
- WM_T_82571, WMP_F_SERDES, },
+ WM_T_82571, WMP_F_SERDES },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82571EB_QUAD_SERDES,
"Intel 82571EB Quad Gigabit Ethernet (SERDES)",
- WM_T_82571, WMP_F_SERDES, },
+ WM_T_82571, WMP_F_SERDES },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82571EB_QUAD_FIBER,
"Intel 82571EB Quad 1000baseX Ethernet",
- WM_T_82571, WMP_F_FIBER, },
+ WM_T_82571, WMP_F_FIBER },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82572EI_COPPER,
"Intel i82572EI 1000baseT Ethernet",
@@ -1554,6 +1578,24 @@
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_LM9,
"I219 LM Ethernet Connection",
WM_T_PCH_CNP, WMP_F_COPPER },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_LM10,
+ "I219 LM Ethernet Connection",
+ WM_T_PCH_CNP, WMP_F_COPPER },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_LM11,
+ "I219 LM Ethernet Connection",
+ WM_T_PCH_CNP, WMP_F_COPPER },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_LM12,
+ "I219 LM Ethernet Connection",
+ WM_T_PCH_SPT, WMP_F_COPPER },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_LM13,
+ "I219 LM Ethernet Connection",
+ WM_T_PCH_CNP, WMP_F_COPPER },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_LM14,
+ "I219 LM Ethernet Connection",
+ WM_T_PCH_CNP, WMP_F_COPPER },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_LM15,
+ "I219 LM Ethernet Connection",
+ WM_T_PCH_CNP, WMP_F_COPPER },
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_V,
"I219 V Ethernet Connection",
WM_T_PCH_SPT, WMP_F_COPPER },
@@ -1578,6 +1620,21 @@
{ PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_V9,
"I219 V Ethernet Connection",
WM_T_PCH_CNP, WMP_F_COPPER },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_V10,
+ "I219 V Ethernet Connection",
+ WM_T_PCH_CNP, WMP_F_COPPER },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_V11,
+ "I219 V Ethernet Connection",
+ WM_T_PCH_CNP, WMP_F_COPPER },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_V12,
+ "I219 V Ethernet Connection",
+ WM_T_PCH_SPT, WMP_F_COPPER },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_V13,
+ "I219 V Ethernet Connection",
+ WM_T_PCH_CNP, WMP_F_COPPER },
+ { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_I219_V14,
+ "I219 V Ethernet Connection",
+ WM_T_PCH_CNP, WMP_F_COPPER },
{ 0, 0,
NULL,
0, 0 },
@@ -1774,6 +1831,7 @@
prop_number_t pn;
uint8_t enaddr[ETHER_ADDR_LEN];
char buf[256];
+ char wqname[MAXCOMLEN];
uint16_t cfg1, cfg2, swdpin, nvmword;
pcireg_t preg, memtype;
uint16_t eeprom_data, apme_mask;
@@ -1782,7 +1840,7 @@
uint32_t reg;
sc->sc_dev = self;
- callout_init(&sc->sc_tick_ch, CALLOUT_FLAGS);
+ callout_init(&sc->sc_tick_ch, WM_CALLOUT_FLAGS);
sc->sc_core_stopping = false;
wmp = wm_lookup(pa);
@@ -2007,6 +2065,16 @@
}
}
+ snprintf(wqname, sizeof(wqname), "%sTxRx", device_xname(sc->sc_dev));
+ error = workqueue_create(&sc->sc_queue_wq, wqname,
+ wm_handle_queue_work, sc, WM_WORKQUEUE_PRI, IPL_NET,
+ WM_WORKQUEUE_FLAGS);
+ if (error) {
+ aprint_error_dev(sc->sc_dev,
+ "unable to create workqueue\n");
+ goto out;
+ }
+
/*
* Check the function ID (unit number of the chip).
*/
@@ -2036,7 +2104,7 @@
aprint_verbose_dev(sc->sc_dev,
"Communication Streaming Architecture\n");
if (sc->sc_type == WM_T_82547) {
- callout_init(&sc->sc_txfifo_ch, CALLOUT_FLAGS);
+ callout_init(&sc->sc_txfifo_ch, WM_CALLOUT_FLAGS);
callout_setfunc(&sc->sc_txfifo_ch,
wm_82547_txfifo_stall, sc);
aprint_verbose_dev(sc->sc_dev,
@@ -2604,11 +2672,22 @@
break;
}
- if ((sc->sc_type == WM_T_82575) || (sc->sc_type == WM_T_82576)) {
- /* Check NVM for autonegotiation */
+ if (sc->sc_type >= WM_T_82575) {
if (wm_nvm_read(sc, NVM_OFF_COMPAT, 1, &nvmword) == 0) {
- if ((nvmword & NVM_COMPAT_SERDES_FORCE_MODE) != 0)
- sc->sc_flags |= WM_F_PCS_DIS_AUTONEGO;
+ aprint_debug_dev(sc->sc_dev, "COMPAT = %hx\n",
+ nvmword);
+ if ((sc->sc_type == WM_T_82575) ||
+ (sc->sc_type == WM_T_82576)) {
+ /* Check NVM for autonegotiation */
+ if ((nvmword & NVM_COMPAT_SERDES_FORCE_MODE)
+ != 0)
+ sc->sc_flags |= WM_F_PCS_DIS_AUTONEGO;
+ }
+ if ((sc->sc_type == WM_T_82575) ||
+ (sc->sc_type == WM_T_I350)) {
+ if (nvmword & NVM_COMPAT_MAS_EN(sc->sc_funcid))
Home |
Main Index |
Thread Index |
Old Index