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