]> Git Repo - linux.git/commitdiff
Merge tag 'arm64-mmiowb' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
authorLinus Torvalds <[email protected]>
Mon, 6 May 2019 23:57:52 +0000 (16:57 -0700)
committerLinus Torvalds <[email protected]>
Mon, 6 May 2019 23:57:52 +0000 (16:57 -0700)
Pull mmiowb removal from Will Deacon:
 "Remove Mysterious Macro Intended to Obscure Weird Behaviours (mmiowb())

  Remove mmiowb() from the kernel memory barrier API and instead, for
  architectures that need it, hide the barrier inside spin_unlock() when
  MMIO has been performed inside the critical section.

  The only relatively recent changes have been addressing review
  comments on the documentation, which is in a much better shape thanks
  to the efforts of Ben and Ingo.

  I was initially planning to split this into two pull requests so that
  you could run the coccinelle script yourself, however it's been plain
  sailing in linux-next so I've just included the whole lot here to keep
  things simple"

* tag 'arm64-mmiowb' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (23 commits)
  docs/memory-barriers.txt: Update I/O section to be clearer about CPU vs thread
  docs/memory-barriers.txt: Fix style, spacing and grammar in I/O section
  arch: Remove dummy mmiowb() definitions from arch code
  net/ethernet/silan/sc92031: Remove stale comment about mmiowb()
  i40iw: Redefine i40iw_mmiowb() to do nothing
  scsi/qla1280: Remove stale comment about mmiowb()
  drivers: Remove explicit invocations of mmiowb()
  drivers: Remove useless trailing comments from mmiowb() invocations
  Documentation: Kill all references to mmiowb()
  riscv/mmiowb: Hook up mmwiob() implementation to asm-generic code
  powerpc/mmiowb: Hook up mmwiob() implementation to asm-generic code
  ia64/mmiowb: Add unconditional mmiowb() to arch_spin_unlock()
  mips/mmiowb: Add unconditional mmiowb() to arch_spin_unlock()
  sh/mmiowb: Add unconditional mmiowb() to arch_spin_unlock()
  m68k/io: Remove useless definition of mmiowb()
  nds32/io: Remove useless definition of mmiowb()
  x86/io: Remove useless definition of mmiowb()
  arm64/io: Remove useless definition of mmiowb()
  ARM/io: Remove useless definition of mmiowb()
  mmiowb: Hook up mmiowb helpers to spinlocks and generic I/O accessors
  ...

21 files changed:
1  2 
arch/arm/include/asm/Kbuild
arch/arm64/include/asm/Kbuild
arch/hexagon/include/asm/Kbuild
arch/powerpc/Kconfig
arch/riscv/Kconfig
arch/s390/include/asm/Kbuild
arch/sparc/include/asm/Kbuild
arch/xtensa/include/asm/Kbuild
drivers/infiniband/hw/hfi1/chip.c
drivers/infiniband/hw/mlx5/qp.c
drivers/mmc/host/alcor.c
drivers/net/ethernet/atheros/atlx/atl1.c
drivers/net/ethernet/atheros/atlx/atl2.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/intel/fm10k/fm10k_main.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/qlogic/qed/qed_int.c
drivers/net/wireless/intel/iwlwifi/pcie/trans.c
kernel/Kconfig.locks

index 8fb51b7bf1d587499f2f782d1f699c47adc91b7d,a3fc0a230a68a62bb27e7db8cb1afd6068495323..41deac2451af48ada5b7f59ccea8091bdc78be18
@@@ -9,9 -9,11 +9,10 @@@ generic-y += kdebug.
  generic-y += local.h
  generic-y += local64.h
  generic-y += mm-arch-hooks.h
+ generic-y += mmiowb.h
  generic-y += msi.h
  generic-y += parport.h
  generic-y += preempt.h
 -generic-y += rwsem.h
  generic-y += seccomp.h
  generic-y += segment.h
  generic-y += serial.h
index 60a933b070019a9d8cd43a9d779d92e802b1c08b,3dae4fd028cf453ffe5954bea31c0ec2ca3112c1..eb0df239a759fcaa7ffb8db7b092b5246b446092
@@@ -13,9 -13,11 +13,10 @@@ generic-y += local.
  generic-y += local64.h
  generic-y += mcs_spinlock.h
  generic-y += mm-arch-hooks.h
+ generic-y += mmiowb.h
  generic-y += msi.h
  generic-y += qrwlock.h
  generic-y += qspinlock.h
 -generic-y += rwsem.h
  generic-y += segment.h
  generic-y += serial.h
  generic-y += set_memory.h
index 3ff5f297acda7783d4d1494098636ad8e017fb1a,d53704d561e6a1b7d845df53b5924c773025b5dd..6234a303d2a3bb75cb0870aa9e92e82ae06bc108
@@@ -24,9 -24,11 +24,10 @@@ generic-y += local.
  generic-y += local64.h
  generic-y += mcs_spinlock.h
  generic-y += mm-arch-hooks.h
+ generic-y += mmiowb.h
  generic-y += pci.h
  generic-y += percpu.h
  generic-y += preempt.h
 -generic-y += rwsem.h
  generic-y += sections.h
  generic-y += segment.h
  generic-y += serial.h
diff --combined arch/powerpc/Kconfig
index 88a4fb3647a2eb80acc7a686b5f87dc94ac82300,5e3d0853c31d238272d047ca55f9bd0d4ca8d56e..fa7219ffeadc96b0d11d625b87cd0b7f3dc5b1d4
@@@ -103,6 -103,13 +103,6 @@@ config LOCKDEP_SUPPOR
        bool
        default y
  
 -config RWSEM_GENERIC_SPINLOCK
 -      bool
 -
 -config RWSEM_XCHGADD_ALGORITHM
 -      bool
 -      default y
 -
  config GENERIC_LOCKBREAK
        bool
        default y
@@@ -125,6 -132,7 +125,7 @@@ config PP
        select ARCH_HAS_FORTIFY_SOURCE
        select ARCH_HAS_GCOV_PROFILE_ALL
        select ARCH_HAS_KCOV
+       select ARCH_HAS_MMIOWB                  if PPC64
        select ARCH_HAS_PHYS_TO_DMA
        select ARCH_HAS_PMEM_API                if PPC64
        select ARCH_HAS_PTE_SPECIAL
        select HAVE_PERF_REGS
        select HAVE_PERF_USER_STACK_DUMP
        select HAVE_RCU_TABLE_FREE              if SMP
 +      select HAVE_RCU_TABLE_NO_INVALIDATE     if HAVE_RCU_TABLE_FREE
 +      select HAVE_MMU_GATHER_PAGE_SIZE
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_RELIABLE_STACKTRACE         if PPC_BOOK3S_64 && CPU_LITTLE_ENDIAN
        select HAVE_SYSCALL_TRACEPOINTS
@@@ -313,10 -319,6 +314,10 @@@ config ARCH_SUSPEND_POSSIBL
                   (PPC_85xx && !PPC_E500MC) || PPC_86xx || PPC_PSERIES \
                   || 44x || 40x
  
 +config ARCH_SUSPEND_NONZERO_CPU
 +      def_bool y
 +      depends on PPC_POWERNV || PPC_PSERIES
 +
  config PPC_DCR_NATIVE
        bool
  
diff --combined arch/riscv/Kconfig
index 0582260fb6c20f31a68075c217382d30b4a0852c,6e30e8126799f1e7bb453c01353c6e39a457765f..e66745decea1734388b48f3395404e523a9a7888
@@@ -48,6 -48,7 +48,7 @@@ config RISC
        select RISCV_TIMER
        select GENERIC_IRQ_MULTI_HANDLER
        select ARCH_HAS_PTE_SPECIAL
+       select ARCH_HAS_MMIOWB
        select HAVE_EBPF_JIT if 64BIT
  
  config MMU
@@@ -69,6 -70,9 +70,6 @@@ config STACKTRACE_SUPPOR
  config TRACE_IRQFLAGS_SUPPORT
        def_bool y
  
 -config RWSEM_GENERIC_SPINLOCK
 -      def_bool y
 -
  config GENERIC_BUG
        def_bool y
        depends on BUG
index d5fadefea33ca862c3074e070669e6ff65d95a8f,bdc4f06a04c5067f07cca776d72af0a532c8e605..2531f673f099cb6ccdac14ff153f65eb59fcdc46
@@@ -20,6 -20,8 +20,7 @@@ generic-y += local.
  generic-y += local64.h
  generic-y += mcs_spinlock.h
  generic-y += mm-arch-hooks.h
 -generic-y += rwsem.h
+ generic-y += mmiowb.h
  generic-y += trace_clock.h
  generic-y += unaligned.h
  generic-y += word-at-a-time.h
index 2ca3200d3616abb950e87c7570937f46426df311,468440db66575df7e1641183244c46c6790dad0a..95c44380b1d6748a54fd31863b6043c9c6782025
@@@ -15,9 -15,11 +15,10 @@@ generic-y += local.
  generic-y += local64.h
  generic-y += mcs_spinlock.h
  generic-y += mm-arch-hooks.h
+ generic-y += mmiowb.h
  generic-y += module.h
  generic-y += msi.h
  generic-y += preempt.h
 -generic-y += rwsem.h
  generic-y += serial.h
  generic-y += trace_clock.h
  generic-y += word-at-a-time.h
index 4148090cafb00a05a6fe5c7158190eba803a79db,794e461785e1687af5102a85b2e084a65c1b9bb7..35f83c4bf23935b8c707532793d1626568351f04
@@@ -20,11 -20,13 +20,12 @@@ generic-y += local.
  generic-y += local64.h
  generic-y += mcs_spinlock.h
  generic-y += mm-arch-hooks.h
+ generic-y += mmiowb.h
  generic-y += param.h
  generic-y += percpu.h
  generic-y += preempt.h
  generic-y += qrwlock.h
  generic-y += qspinlock.h
 -generic-y += rwsem.h
  generic-y += sections.h
  generic-y += socket.h
  generic-y += topology.h
index 9784c6c0d2ecfbbca031871f54fcc415602029fc,8f270459b63efdc9511e8389728576677666557d..addefae16c9c9ec1a21a403ed108b7e6da1ed86b
@@@ -8365,7 -8365,6 +8365,6 @@@ static inline void clear_recv_intr(stru
        struct hfi1_devdata *dd = rcd->dd;
        u32 addr = CCE_INT_CLEAR + (8 * rcd->ireg);
  
-       mmiowb();       /* make sure everything before is written */
        write_csr(dd, addr, rcd->imask);
        /* force the above write on the chip and get a value back */
        (void)read_csr(dd, addr);
@@@ -11803,12 -11802,10 +11802,10 @@@ void update_usrhead(struct hfi1_ctxtdat
                        << RCV_EGR_INDEX_HEAD_HEAD_SHIFT;
                write_uctxt_csr(dd, ctxt, RCV_EGR_INDEX_HEAD, reg);
        }
-       mmiowb();
        reg = ((u64)rcv_intr_count << RCV_HDR_HEAD_COUNTER_SHIFT) |
                (((u64)hd & RCV_HDR_HEAD_HEAD_MASK)
                        << RCV_HDR_HEAD_HEAD_SHIFT);
        write_uctxt_csr(dd, ctxt, RCV_HDR_HEAD, reg);
-       mmiowb();
  }
  
  u32 hdrqempty(struct hfi1_ctxtdata *rcd)
@@@ -13232,7 -13229,7 +13229,7 @@@ static int set_up_context_variables(str
        int total_contexts;
        int ret;
        unsigned ngroups;
 -      int qos_rmt_count;
 +      int rmt_count;
        int user_rmt_reduced;
        u32 n_usr_ctxts;
        u32 send_contexts = chip_send_contexts(dd);
                n_usr_ctxts = rcv_contexts - total_contexts;
        }
  
 -      /* each user context requires an entry in the RMT */
 -      qos_rmt_count = qos_rmt_entries(dd, NULL, NULL);
 -      if (qos_rmt_count + n_usr_ctxts > NUM_MAP_ENTRIES) {
 -              user_rmt_reduced = NUM_MAP_ENTRIES - qos_rmt_count;
 +      /*
 +       * The RMT entries are currently allocated as shown below:
 +       * 1. QOS (0 to 128 entries);
 +       * 2. FECN for PSM (num_user_contexts + num_vnic_contexts);
 +       * 3. VNIC (num_vnic_contexts).
 +       * It should be noted that PSM FECN oversubscribe num_vnic_contexts
 +       * entries of RMT because both VNIC and PSM could allocate any receive
 +       * context between dd->first_dyn_alloc_text and dd->num_rcv_contexts,
 +       * and PSM FECN must reserve an RMT entry for each possible PSM receive
 +       * context.
 +       */
 +      rmt_count = qos_rmt_entries(dd, NULL, NULL) + (num_vnic_contexts * 2);
 +      if (rmt_count + n_usr_ctxts > NUM_MAP_ENTRIES) {
 +              user_rmt_reduced = NUM_MAP_ENTRIES - rmt_count;
                dd_dev_err(dd,
                           "RMT size is reducing the number of user receive contexts from %u to %d\n",
                           n_usr_ctxts,
@@@ -14295,11 -14282,9 +14292,11 @@@ static void init_user_fecn_handling(str
        u64 reg;
        int i, idx, regoff, regidx;
        u8 offset;
 +      u32 total_cnt;
  
        /* there needs to be enough room in the map table */
 -      if (rmt->used + dd->num_user_contexts >= NUM_MAP_ENTRIES) {
 +      total_cnt = dd->num_rcv_contexts - dd->first_dyn_alloc_ctxt;
 +      if (rmt->used + total_cnt >= NUM_MAP_ENTRIES) {
                dd_dev_err(dd, "User FECN handling disabled - too many user contexts allocated\n");
                return;
        }
        /* add rule 1 */
        add_rsm_rule(dd, RSM_INS_FECN, &rrd);
  
 -      rmt->used += dd->num_user_contexts;
 +      rmt->used += total_cnt;
  }
  
  /* Initialize RSM for VNIC */
index 8870c350fda0b109cc4cb98c9787fd0452821865,b680be1f3f473956dd415235c9d97a3672550fcb..8aafb2208899302ab71aaae3d099d844ef375b9d
@@@ -1818,16 -1818,13 +1818,16 @@@ static void configure_responder_scat_cq
  
        rcqe_sz = mlx5_ib_get_cqe_size(init_attr->recv_cq);
  
 -      if (rcqe_sz == 128) {
 -              MLX5_SET(qpc, qpc, cs_res, MLX5_RES_SCAT_DATA64_CQE);
 +      if (init_attr->qp_type == MLX5_IB_QPT_DCT) {
 +              if (rcqe_sz == 128)
 +                      MLX5_SET(dctc, qpc, cs_res, MLX5_RES_SCAT_DATA64_CQE);
 +
                return;
        }
  
 -      if (init_attr->qp_type != MLX5_IB_QPT_DCT)
 -              MLX5_SET(qpc, qpc, cs_res, MLX5_RES_SCAT_DATA32_CQE);
 +      MLX5_SET(qpc, qpc, cs_res,
 +               rcqe_sz == 128 ? MLX5_RES_SCAT_DATA64_CQE :
 +                                MLX5_RES_SCAT_DATA32_CQE);
  }
  
  static void configure_requester_scat_cqe(struct mlx5_ib_dev *dev,
@@@ -5126,7 -5123,6 +5126,6 @@@ out
                /* Make sure doorbells don't leak out of SQ spinlock
                 * and reach the HCA out of order.
                 */
-               mmiowb();
                bf->offset ^= bf->buf_size;
        }
  
diff --combined drivers/mmc/host/alcor.c
index 7c8f203f9a24d38bbd1c2b870644e511a1db76d3,546b1fc30e7d812d050c05570e670de07f5f780b..6e6b7ade4b602183eeeefdf7b84fb68d64be8545
@@@ -48,6 -48,7 +48,6 @@@ struct alcor_sdmmc_host 
        struct mmc_command *cmd;
        struct mmc_data *data;
        unsigned int dma_on:1;
 -      unsigned int early_data:1;
  
        struct mutex cmd_mutex;
  
@@@ -143,7 -144,8 +143,7 @@@ static void alcor_data_set_dma(struct a
        host->sg_count--;
  }
  
 -static void alcor_trigger_data_transfer(struct alcor_sdmmc_host *host,
 -                                      bool early)
 +static void alcor_trigger_data_transfer(struct alcor_sdmmc_host *host)
  {
        struct alcor_pci_priv *priv = host->alcor_pci;
        struct mmc_data *data = host->data;
                ctrl |= AU6601_DATA_WRITE;
  
        if (data->host_cookie == COOKIE_MAPPED) {
 -              if (host->early_data) {
 -                      host->early_data = false;
 -                      return;
 -              }
 -
 -              host->early_data = early;
 -
                alcor_data_set_dma(host);
                ctrl |= AU6601_DATA_DMA_MODE;
                host->dma_on = 1;
@@@ -222,7 -231,6 +222,7 @@@ static void alcor_prepare_sg_miter(stru
  static void alcor_prepare_data(struct alcor_sdmmc_host *host,
                               struct mmc_command *cmd)
  {
 +      struct alcor_pci_priv *priv = host->alcor_pci;
        struct mmc_data *data = cmd->data;
  
        if (!data)
        if (data->host_cookie != COOKIE_MAPPED)
                alcor_prepare_sg_miter(host);
  
 -      alcor_trigger_data_transfer(host, true);
 +      alcor_write8(priv, 0, AU6601_DATA_XFER_CTRL);
  }
  
  static void alcor_send_cmd(struct alcor_sdmmc_host *host,
@@@ -427,7 -435,7 +427,7 @@@ static int alcor_cmd_irq_done(struct al
        if (!host->data)
                return false;
  
 -      alcor_trigger_data_transfer(host, false);
 +      alcor_trigger_data_transfer(host);
        host->cmd = NULL;
        return true;
  }
@@@ -448,7 -456,7 +448,7 @@@ static void alcor_cmd_irq_thread(struc
        if (!host->data)
                alcor_request_complete(host, 1);
        else
 -              alcor_trigger_data_transfer(host, false);
 +              alcor_trigger_data_transfer(host);
        host->cmd = NULL;
  }
  
@@@ -479,9 -487,15 +479,9 @@@ static int alcor_data_irq_done(struct a
                break;
        case AU6601_INT_READ_BUF_RDY:
                alcor_trf_block_pio(host, true);
 -              if (!host->blocks)
 -                      break;
 -              alcor_trigger_data_transfer(host, false);
                return 1;
        case AU6601_INT_WRITE_BUF_RDY:
                alcor_trf_block_pio(host, false);
 -              if (!host->blocks)
 -                      break;
 -              alcor_trigger_data_transfer(host, false);
                return 1;
        case AU6601_INT_DMA_END:
                if (!host->sg_count)
                break;
        }
  
 -      if (intmask & AU6601_INT_DATA_END)
 -              return 0;
 +      if (intmask & AU6601_INT_DATA_END) {
 +              if (!host->dma_on && host->blocks) {
 +                      alcor_trigger_data_transfer(host);
 +                      return 1;
 +              } else {
 +                      return 0;
 +              }
 +      }
  
        return 1;
  }
@@@ -959,7 -967,6 +959,6 @@@ static void alcor_timeout_timer(struct 
                alcor_request_complete(host, 0);
        }
  
-       mmiowb();
        mutex_unlock(&host->cmd_mutex);
  }
  
index 156fbc5601ca3ece9b07c7ab14314ff4883127f7,f7583c5d9509751dc8bb7092c49f2b1061ac6080..f35c9a75be50a16c508e54266f3137917fbcf62e
@@@ -1721,7 -1721,7 +1721,7 @@@ static void atl1_inc_smb(struct atl1_ad
        adapter->soft_stats.scc += smb->tx_1_col;
        adapter->soft_stats.mcc += smb->tx_2_col;
        adapter->soft_stats.latecol += smb->tx_late_col;
 -      adapter->soft_stats.tx_underun += smb->tx_underrun;
 +      adapter->soft_stats.tx_underrun += smb->tx_underrun;
        adapter->soft_stats.tx_trunc += smb->tx_trunc;
        adapter->soft_stats.tx_pause += smb->tx_pause;
  
@@@ -2439,7 -2439,6 +2439,6 @@@ static netdev_tx_t atl1_xmit_frame(stru
        atl1_tx_map(adapter, skb, ptpd);
        atl1_tx_queue(adapter, count, ptpd);
        atl1_update_mailbox(adapter);
-       mmiowb();
        return NETDEV_TX_OK;
  }
  
@@@ -3179,7 -3178,7 +3178,7 @@@ static struct atl1_stats atl1_gstrings_
        {"tx_deferred_ok", ATL1_STAT(soft_stats.deffer)},
        {"tx_single_coll_ok", ATL1_STAT(soft_stats.scc)},
        {"tx_multi_coll_ok", ATL1_STAT(soft_stats.mcc)},
 -      {"tx_underun", ATL1_STAT(soft_stats.tx_underun)},
 +      {"tx_underrun", ATL1_STAT(soft_stats.tx_underrun)},
        {"tx_trunc", ATL1_STAT(soft_stats.tx_trunc)},
        {"tx_pause", ATL1_STAT(soft_stats.tx_pause)},
        {"rx_pause", ATL1_STAT(soft_stats.rx_pause)},
index 98da0fa27192ddbab7c04651854b0fd94baa6b2a,1474cac7e892455a969d9d1464f3a3ebb4c9e62c..dd81c58631117fd13fef3abb51af007f24ef0818
@@@ -553,7 -553,7 +553,7 @@@ static void atl2_intr_tx(struct atl2_ad
                        netdev->stats.tx_aborted_errors++;
                if (txs->late_col)
                        netdev->stats.tx_window_errors++;
 -              if (txs->underun)
 +              if (txs->underrun)
                        netdev->stats.tx_fifo_errors++;
        } while (1);
  
@@@ -908,7 -908,6 +908,6 @@@ static netdev_tx_t atl2_xmit_frame(stru
        ATL2_WRITE_REGW(&adapter->hw, REG_MB_TXD_WR_IDX,
                (adapter->txd_write_ptr >> 2));
  
-       mmiowb();
        dev_consume_skb_any(skb);
        return NETDEV_TX_OK;
  }
index 10ff37d6dc783b796c690a4d73bc90caa4cad931,672b57f0b84d9a4ed877325887b13fd2930a3d51..0752b7fa4d9c005db32f7b537c43ffcd9df51f31
@@@ -172,8 -172,6 +172,6 @@@ static int bnx2x_send_msg2pf(struct bnx
        /* Trigger the PF FW */
        writeb_relaxed(1, &zone_data->trigger.vf_pf_channel.addr_valid);
  
-       mmiowb();
        /* Wait for PF to complete */
        while ((tout >= 0) && (!*done)) {
                msleep(interval);
@@@ -957,7 -955,7 +955,7 @@@ int bnx2x_vfpf_update_vlan(struct bnx2
        bnx2x_sample_bulletin(bp);
  
        if (bp->shadow_bulletin.content.valid_bitmap & 1 << VLAN_VALID) {
 -              BNX2X_ERR("Hypervisor will dicline the request, avoiding\n");
 +              BNX2X_ERR("Hypervisor will decline the request, avoiding\n");
                rc = -EINVAL;
                goto out;
        }
@@@ -1179,7 -1177,6 +1177,6 @@@ static void bnx2x_vf_mbx_resp_send_msg(
  
        /* ack the FW */
        storm_memset_vf_mbx_ack(bp, vf->abs_vfid);
-       mmiowb();
  
        /* copy the response header including status-done field,
         * must be last dmae, must be after FW is acked
@@@ -2174,7 -2171,6 +2171,6 @@@ static void bnx2x_vf_mbx_request(struc
                 */
                storm_memset_vf_mbx_ack(bp, vf->abs_vfid);
                /* Firmware ack should be written before unlocking channel */
-               mmiowb();
                bnx2x_unlock_vf_pf_channel(bp, vf, mbx->first_tlv.tl.type);
        }
  }
index 52ade133b57cf68940327aeea75eeb9ee974dd86,b8b68d408ad0516a72c1bc04d9df3b2380b644ce..2a4341708c0fb04304e79338556df9fdd4a72bc9
@@@ -556,8 -556,6 +556,6 @@@ normal_tx
  
  tx_done:
  
-       mmiowb();
        if (unlikely(bnxt_tx_avail(bp, txr) <= MAX_SKB_FRAGS + 1)) {
                if (skb->xmit_more && !tx_buf->is_push)
                        bnxt_db_write(bp, &txr->tx_db, prod);
@@@ -1133,8 -1131,6 +1131,8 @@@ static void bnxt_tpa_start(struct bnxt 
        tpa_info = &rxr->rx_tpa[agg_id];
  
        if (unlikely(cons != rxr->rx_next_cons)) {
 +              netdev_warn(bp->dev, "TPA cons %x != expected cons %x\n",
 +                          cons, rxr->rx_next_cons);
                bnxt_sched_reset(bp, rxr);
                return;
        }
@@@ -1587,17 -1583,15 +1585,17 @@@ static int bnxt_rx_pkt(struct bnxt *bp
        }
  
        cons = rxcmp->rx_cmp_opaque;
 -      rx_buf = &rxr->rx_buf_ring[cons];
 -      data = rx_buf->data;
 -      data_ptr = rx_buf->data_ptr;
        if (unlikely(cons != rxr->rx_next_cons)) {
                int rc1 = bnxt_discard_rx(bp, cpr, raw_cons, rxcmp);
  
 +              netdev_warn(bp->dev, "RX cons %x != expected cons %x\n",
 +                          cons, rxr->rx_next_cons);
                bnxt_sched_reset(bp, rxr);
                return rc1;
        }
 +      rx_buf = &rxr->rx_buf_ring[cons];
 +      data = rx_buf->data;
 +      data_ptr = rx_buf->data_ptr;
        prefetch(data_ptr);
  
        misc = le32_to_cpu(rxcmp->rx_cmp_misc_v1);
  
        rx_buf->data = NULL;
        if (rxcmp1->rx_cmp_cfa_code_errors_v2 & RX_CMP_L2_ERRORS) {
 +              u32 rx_err = le32_to_cpu(rxcmp1->rx_cmp_cfa_code_errors_v2);
 +
                bnxt_reuse_rx_data(rxr, cons, data);
                if (agg_bufs)
                        bnxt_reuse_rx_agg_bufs(cpr, cp_cons, agg_bufs);
  
                rc = -EIO;
 -              goto next_rx;
 +              if (rx_err & RX_CMPL_ERRORS_BUFFER_ERROR_MASK) {
 +                      netdev_warn(bp->dev, "RX buffer error %x\n", rx_err);
 +                      bnxt_sched_reset(bp, rxr);
 +              }
 +              goto next_rx_no_len;
        }
  
        len = le32_to_cpu(rxcmp->rx_cmp_len_flags_type) >> RX_CMP_LEN_SHIFT;
        rc = 1;
  
  next_rx:
 -      rxr->rx_prod = NEXT_RX(prod);
 -      rxr->rx_next_cons = NEXT_RX(cons);
 -
        cpr->rx_packets += 1;
        cpr->rx_bytes += len;
  
 +next_rx_no_len:
 +      rxr->rx_prod = NEXT_RX(prod);
 +      rxr->rx_next_cons = NEXT_RX(cons);
 +
  next_rx_no_prod_no_len:
        *raw_cons = tmp_raw_cons;
  
@@@ -2134,7 -2121,6 +2132,6 @@@ static int bnxt_poll(struct napi_struc
                               &dim_sample);
                net_dim(&cpr->dim, dim_sample);
        }
-       mmiowb();
        return work_done;
  }
  
@@@ -5136,10 -5122,10 +5133,10 @@@ static void bnxt_hwrm_ring_free(struct 
        for (i = 0; i < bp->tx_nr_rings; i++) {
                struct bnxt_tx_ring_info *txr = &bp->tx_ring[i];
                struct bnxt_ring_struct *ring = &txr->tx_ring_struct;
 -              u32 cmpl_ring_id;
  
 -              cmpl_ring_id = bnxt_cp_ring_for_tx(bp, txr);
                if (ring->fw_ring_id != INVALID_HW_RING_ID) {
 +                      u32 cmpl_ring_id = bnxt_cp_ring_for_tx(bp, txr);
 +
                        hwrm_ring_free_send_msg(bp, ring,
                                                RING_FREE_REQ_RING_TYPE_TX,
                                                close_path ? cmpl_ring_id :
                struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
                struct bnxt_ring_struct *ring = &rxr->rx_ring_struct;
                u32 grp_idx = rxr->bnapi->index;
 -              u32 cmpl_ring_id;
  
 -              cmpl_ring_id = bnxt_cp_ring_for_rx(bp, rxr);
                if (ring->fw_ring_id != INVALID_HW_RING_ID) {
 +                      u32 cmpl_ring_id = bnxt_cp_ring_for_rx(bp, rxr);
 +
                        hwrm_ring_free_send_msg(bp, ring,
                                                RING_FREE_REQ_RING_TYPE_RX,
                                                close_path ? cmpl_ring_id :
                struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
                struct bnxt_ring_struct *ring = &rxr->rx_agg_ring_struct;
                u32 grp_idx = rxr->bnapi->index;
 -              u32 cmpl_ring_id;
  
 -              cmpl_ring_id = bnxt_cp_ring_for_rx(bp, rxr);
                if (ring->fw_ring_id != INVALID_HW_RING_ID) {
 +                      u32 cmpl_ring_id = bnxt_cp_ring_for_rx(bp, rxr);
 +
                        hwrm_ring_free_send_msg(bp, ring, type,
                                                close_path ? cmpl_ring_id :
                                                INVALID_HW_RING_ID);
@@@ -5316,16 -5302,17 +5313,16 @@@ __bnxt_hwrm_reserve_pf_rings(struct bnx
        req->num_tx_rings = cpu_to_le16(tx_rings);
        if (BNXT_NEW_RM(bp)) {
                enables |= rx_rings ? FUNC_CFG_REQ_ENABLES_NUM_RX_RINGS : 0;
 +              enables |= stats ? FUNC_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0;
                if (bp->flags & BNXT_FLAG_CHIP_P5) {
                        enables |= cp_rings ? FUNC_CFG_REQ_ENABLES_NUM_MSIX : 0;
                        enables |= tx_rings + ring_grps ?
 -                                 FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS |
 -                                 FUNC_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0;
 +                                 FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS : 0;
                        enables |= rx_rings ?
                                FUNC_CFG_REQ_ENABLES_NUM_RSSCOS_CTXS : 0;
                } else {
                        enables |= cp_rings ?
 -                                 FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS |
 -                                 FUNC_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0;
 +                                 FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS : 0;
                        enables |= ring_grps ?
                                   FUNC_CFG_REQ_ENABLES_NUM_HW_RING_GRPS |
                                   FUNC_CFG_REQ_ENABLES_NUM_RSSCOS_CTXS : 0;
@@@ -5365,13 -5352,14 +5362,13 @@@ __bnxt_hwrm_reserve_vf_rings(struct bnx
        enables |= tx_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_TX_RINGS : 0;
        enables |= rx_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_RX_RINGS |
                              FUNC_VF_CFG_REQ_ENABLES_NUM_RSSCOS_CTXS : 0;
 +      enables |= stats ? FUNC_VF_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0;
        if (bp->flags & BNXT_FLAG_CHIP_P5) {
                enables |= tx_rings + ring_grps ?
 -                         FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS |
 -                         FUNC_VF_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0;
 +                         FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS : 0;
        } else {
                enables |= cp_rings ?
 -                         FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS |
 -                         FUNC_VF_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0;
 +                         FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS : 0;
                enables |= ring_grps ?
                           FUNC_VF_CFG_REQ_ENABLES_NUM_HW_RING_GRPS : 0;
        }
@@@ -6752,7 -6740,6 +6749,7 @@@ static int bnxt_hwrm_port_qstats_ext(st
        struct hwrm_queue_pri2cos_qcfg_input req2 = {0};
        struct hwrm_port_qstats_ext_input req = {0};
        struct bnxt_pf_info *pf = &bp->pf;
 +      u32 tx_stat_size;
        int rc;
  
        if (!(bp->flags & BNXT_FLAG_PORT_STATS_EXT))
        req.port_id = cpu_to_le16(pf->port_id);
        req.rx_stat_size = cpu_to_le16(sizeof(struct rx_port_stats_ext));
        req.rx_stat_host_addr = cpu_to_le64(bp->hw_rx_port_stats_ext_map);
 -      req.tx_stat_size = cpu_to_le16(sizeof(struct tx_port_stats_ext));
 +      tx_stat_size = bp->hw_tx_port_stats_ext ?
 +                     sizeof(*bp->hw_tx_port_stats_ext) : 0;
 +      req.tx_stat_size = cpu_to_le16(tx_stat_size);
        req.tx_stat_host_addr = cpu_to_le64(bp->hw_tx_port_stats_ext_map);
        mutex_lock(&bp->hwrm_cmd_lock);
        rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
        if (!rc) {
                bp->fw_rx_stats_ext_size = le16_to_cpu(resp->rx_stat_size) / 8;
 -              bp->fw_tx_stats_ext_size = le16_to_cpu(resp->tx_stat_size) / 8;
 +              bp->fw_tx_stats_ext_size = tx_stat_size ?
 +                      le16_to_cpu(resp->tx_stat_size) / 8 : 0;
        } else {
                bp->fw_rx_stats_ext_size = 0;
                bp->fw_tx_stats_ext_size = 0;
@@@ -8964,15 -8948,8 +8961,15 @@@ static int bnxt_cfg_rx_mode(struct bnx
  
  skip_uc:
        rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, 0);
 +      if (rc && vnic->mc_list_count) {
 +              netdev_info(bp->dev, "Failed setting MC filters rc: %d, turning on ALL_MCAST mode\n",
 +                          rc);
 +              vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST;
 +              vnic->mc_list_count = 0;
 +              rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, 0);
 +      }
        if (rc)
 -              netdev_err(bp->dev, "HWRM cfa l2 rx mask failure rc: %x\n",
 +              netdev_err(bp->dev, "HWRM cfa l2 rx mask failure rc: %d\n",
                           rc);
  
        return rc;
@@@ -10695,7 -10672,6 +10692,7 @@@ init_err_cleanup_tc
        bnxt_clear_int_mode(bp);
  
  init_err_pci_clean:
 +      bnxt_free_hwrm_short_cmd_req(bp);
        bnxt_free_hwrm_resources(bp);
        bnxt_free_ctx_mem(bp);
        kfree(bp->ctx);
index 060a6f386104ac5511a381a9ef308f956fc6f551,821bccc0915c64f9b0c652c1688b40007d2bdc1c..2aebd4bbb67dc420096a775d8c6c46ffa44e46c9
@@@ -1073,7 -1073,6 +1073,6 @@@ static void tg3_int_reenable(struct tg3
        struct tg3 *tp = tnapi->tp;
  
        tw32_mailbox(tnapi->int_mbox, tnapi->last_tag << 24);
-       mmiowb();
  
        /* When doing tagged status, this work check is unnecessary.
         * The last_tag we write above tells the chip which piece of
@@@ -4283,7 -4282,7 +4282,7 @@@ static void tg3_power_down(struct tg3 *
        pci_set_power_state(tp->pdev, PCI_D3hot);
  }
  
 -static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u16 *speed, u8 *duplex)
 +static void tg3_aux_stat_to_speed_duplex(struct tg3 *tp, u32 val, u32 *speed, u8 *duplex)
  {
        switch (val & MII_TG3_AUX_STAT_SPDMASK) {
        case MII_TG3_AUX_STAT_10HALF:
@@@ -4787,7 -4786,7 +4786,7 @@@ static int tg3_setup_copper_phy(struct 
        bool current_link_up;
        u32 bmsr, val;
        u32 lcl_adv, rmt_adv;
 -      u16 current_speed;
 +      u32 current_speed;
        u8 current_duplex;
        int i, err;
  
@@@ -5719,7 -5718,7 +5718,7 @@@ out
  static int tg3_setup_fiber_phy(struct tg3 *tp, bool force_reset)
  {
        u32 orig_pause_cfg;
 -      u16 orig_active_speed;
 +      u32 orig_active_speed;
        u8 orig_active_duplex;
        u32 mac_status;
        bool current_link_up;
@@@ -5823,7 -5822,7 +5822,7 @@@ static int tg3_setup_fiber_mii_phy(stru
  {
        int err = 0;
        u32 bmsr, bmcr;
 -      u16 current_speed = SPEED_UNKNOWN;
 +      u32 current_speed = SPEED_UNKNOWN;
        u8 current_duplex = DUPLEX_UNKNOWN;
        bool current_link_up = false;
        u32 local_adv, remote_adv, sgsr;
@@@ -6999,7 -6998,6 +6998,6 @@@ next_pkt_nopost
                        tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG,
                                     tpr->rx_jmb_prod_idx);
                }
-               mmiowb();
        } else if (work_mask) {
                /* rx_std_buffers[] and rx_jmb_buffers[] entries must be
                 * updated before the producer indices can be updated.
@@@ -7210,8 -7208,6 +7208,6 @@@ static int tg3_poll_work(struct tg3_nap
                        tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG,
                                     dpr->rx_jmb_prod_idx);
  
-               mmiowb();
                if (err)
                        tw32_f(HOSTCC_MODE, tp->coal_now);
        }
@@@ -7278,7 -7274,6 +7274,6 @@@ static int tg3_poll_msix(struct napi_st
                                                  HOSTCC_MODE_ENABLE |
                                                  tnapi->coal_now);
                        }
-                       mmiowb();
                        break;
                }
        }
@@@ -8159,7 -8154,6 +8154,6 @@@ static netdev_tx_t tg3_start_xmit(struc
        if (!skb->xmit_more || netif_xmit_stopped(txq)) {
                /* Packets are ready, update Tx producer idx on card. */
                tw32_tx_mbox(tnapi->prodmbox, entry);
-               mmiowb();
        }
  
        return NETDEV_TX_OK;
index ecef949f3baae022d46082f4a1dc32d18cb082ec,1f48298f01e6584b3b19cb71d6be7675391e5edd..cbf76a96e94e32f5944f1631e3b757589d37433d
@@@ -41,8 -41,6 +41,8 @@@ static int __init fm10k_init_module(voi
        /* create driver workqueue */
        fm10k_workqueue = alloc_workqueue("%s", WQ_MEM_RECLAIM, 0,
                                          fm10k_driver_name);
 +      if (!fm10k_workqueue)
 +              return -ENOMEM;
  
        fm10k_dbg_init();
  
@@@ -1039,11 -1037,6 +1039,6 @@@ static void fm10k_tx_map(struct fm10k_r
        /* notify HW of packet */
        if (netif_xmit_stopped(txring_txq(tx_ring)) || !skb->xmit_more) {
                writel(i, tx_ring->tail);
-               /* we need this if more than one processor can write to our tail
-                * at a time, it synchronizes IO on IA64/Altix systems
-                */
-               mmiowb();
        }
  
        return;
index 3269d8e94744f61808893267e1e305122bedd3c5,09ba94496742394b3388db04208dd2b8051c22e8..1d71ec360b1c8203e9b4f815ee561d3e4c141475
@@@ -6028,11 -6028,6 +6028,6 @@@ static int igb_tx_map(struct igb_ring *
  
        if (netif_xmit_stopped(txring_txq(tx_ring)) || !skb->xmit_more) {
                writel(i, tx_ring->tail);
-               /* we need this if more than one processor can write to our tail
-                * at a time, it synchronizes IO on IA64/Altix systems
-                */
-               mmiowb();
        }
        return 0;
  
@@@ -8740,7 -8735,9 +8735,7 @@@ static int __igb_shutdown(struct pci_de
        struct e1000_hw *hw = &adapter->hw;
        u32 ctrl, rctl, status;
        u32 wufc = runtime ? E1000_WUFC_LNKC : adapter->wol;
 -#ifdef CONFIG_PM
 -      int retval = 0;
 -#endif
 +      bool wake;
  
        rtnl_lock();
        netif_device_detach(netdev);
        igb_clear_interrupt_scheme(adapter);
        rtnl_unlock();
  
 -#ifdef CONFIG_PM
 -      if (!runtime) {
 -              retval = pci_save_state(pdev);
 -              if (retval)
 -                      return retval;
 -      }
 -#endif
 -
        status = rd32(E1000_STATUS);
        if (status & E1000_STATUS_LU)
                wufc &= ~E1000_WUFC_LNKC;
                }
  
                ctrl = rd32(E1000_CTRL);
 -              /* advertise wake from D3Cold */
 -              #define E1000_CTRL_ADVD3WUC 0x00100000
 -              /* phy power management enable */
 -              #define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
                ctrl |= E1000_CTRL_ADVD3WUC;
                wr32(E1000_CTRL, ctrl);
  
                wr32(E1000_WUFC, 0);
        }
  
 -      *enable_wake = wufc || adapter->en_mng_pt;
 -      if (!*enable_wake)
 +      wake = wufc || adapter->en_mng_pt;
 +      if (!wake)
                igb_power_down_link(adapter);
        else
                igb_power_up_link(adapter);
  
 +      if (enable_wake)
 +              *enable_wake = wake;
 +
        /* Release control of h/w to f/w.  If f/w is AMT enabled, this
         * would have already happened in close and is redundant.
         */
@@@ -8833,7 -8839,22 +8828,7 @@@ static void igb_deliver_wake_packet(str
  
  static int __maybe_unused igb_suspend(struct device *dev)
  {
 -      int retval;
 -      bool wake;
 -      struct pci_dev *pdev = to_pci_dev(dev);
 -
 -      retval = __igb_shutdown(pdev, &wake, 0);
 -      if (retval)
 -              return retval;
 -
 -      if (wake) {
 -              pci_prepare_to_sleep(pdev);
 -      } else {
 -              pci_wake_from_d3(pdev, false);
 -              pci_set_power_state(pdev, PCI_D3hot);
 -      }
 -
 -      return 0;
 +      return __igb_shutdown(to_pci_dev(dev), NULL, 0);
  }
  
  static int __maybe_unused igb_resume(struct device *dev)
@@@ -8904,7 -8925,22 +8899,7 @@@ static int __maybe_unused igb_runtime_i
  
  static int __maybe_unused igb_runtime_suspend(struct device *dev)
  {
 -      struct pci_dev *pdev = to_pci_dev(dev);
 -      int retval;
 -      bool wake;
 -
 -      retval = __igb_shutdown(pdev, &wake, 1);
 -      if (retval)
 -              return retval;
 -
 -      if (wake) {
 -              pci_prepare_to_sleep(pdev);
 -      } else {
 -              pci_wake_from_d3(pdev, false);
 -              pci_set_power_state(pdev, PCI_D3hot);
 -      }
 -
 -      return 0;
 +      return __igb_shutdown(to_pci_dev(dev), NULL, 1);
  }
  
  static int __maybe_unused igb_runtime_resume(struct device *dev)
index 8848d5bed6e5c58a188900bf9ad5710529d66b51,69e6a90edf2fecd1e9c80035eabe8ef404c5f01b..fdfedbc8e43115fdaaae9cb34f1809797b94a440
@@@ -378,9 -378,6 +378,9 @@@ static int qed_db_rec_flush_queue(struc
        u32 count = QED_DB_REC_COUNT;
        u32 usage = 1;
  
 +      /* Flush any pending (e)dpms as they may never arrive */
 +      qed_wr(p_hwfn, p_ptt, DORQ_REG_DPM_FORCE_ABORT, 0x1);
 +
        /* wait for usage to zero or count to run out. This is necessary since
         * EDPM doorbell transactions can take multiple 64b cycles, and as such
         * can "split" over the pci. Possibly, the doorbell drop can happen with
  
  int qed_db_rec_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
  {
 -      u32 overflow;
 +      u32 attn_ovfl, cur_ovfl;
        int rc;
  
 -      overflow = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY);
 -      DP_NOTICE(p_hwfn, "PF Overflow sticky 0x%x\n", overflow);
 -      if (!overflow) {
 -              qed_db_recovery_execute(p_hwfn, DB_REC_ONCE);
 +      attn_ovfl = test_and_clear_bit(QED_OVERFLOW_BIT,
 +                                     &p_hwfn->db_recovery_info.overflow);
 +      cur_ovfl = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY);
 +      if (!cur_ovfl && !attn_ovfl)
                return 0;
 -      }
  
 -      if (qed_edpm_enabled(p_hwfn)) {
 +      DP_NOTICE(p_hwfn, "PF Overflow sticky: attn %u current %u\n",
 +                attn_ovfl, cur_ovfl);
 +
 +      if (cur_ovfl && !p_hwfn->db_bar_no_edpm) {
                rc = qed_db_rec_flush_queue(p_hwfn, p_ptt);
                if (rc)
                        return rc;
        }
  
 -      /* Flush any pending (e)dpm as they may never arrive */
 -      qed_wr(p_hwfn, p_ptt, DORQ_REG_DPM_FORCE_ABORT, 0x1);
 -
        /* Release overflow sticky indication (stop silently dropping everything) */
        qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY, 0x0);
  
        /* Repeat all last doorbells (doorbell drop recovery) */
 -      qed_db_recovery_execute(p_hwfn, DB_REC_REAL_DEAL);
 +      qed_db_recovery_execute(p_hwfn);
  
        return 0;
  }
  
 -static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)
 +static void qed_dorq_attn_overflow(struct qed_hwfn *p_hwfn)
  {
 -      u32 int_sts, first_drop_reason, details, address, all_drops_reason;
        struct qed_ptt *p_ptt = p_hwfn->p_dpc_ptt;
 +      u32 overflow;
        int rc;
  
 -      int_sts = qed_rd(p_hwfn, p_ptt, DORQ_REG_INT_STS);
 -      DP_NOTICE(p_hwfn->cdev, "DORQ attention. int_sts was %x\n", int_sts);
 +      overflow = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY);
 +      if (!overflow)
 +              goto out;
 +
 +      /* Run PF doorbell recovery in next periodic handler */
 +      set_bit(QED_OVERFLOW_BIT, &p_hwfn->db_recovery_info.overflow);
 +
 +      if (!p_hwfn->db_bar_no_edpm) {
 +              rc = qed_db_rec_flush_queue(p_hwfn, p_ptt);
 +              if (rc)
 +                      goto out;
 +      }
 +
 +      qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY, 0x0);
 +out:
 +      /* Schedule the handler even if overflow was not detected */
 +      qed_periodic_db_rec_start(p_hwfn);
 +}
 +
 +static int qed_dorq_attn_int_sts(struct qed_hwfn *p_hwfn)
 +{
 +      u32 int_sts, first_drop_reason, details, address, all_drops_reason;
 +      struct qed_ptt *p_ptt = p_hwfn->p_dpc_ptt;
  
        /* int_sts may be zero since all PFs were interrupted for doorbell
         * overflow but another one already handled it. Can abort here. If
         * This PF also requires overflow recovery we will be interrupted again.
         * The masked almost full indication may also be set. Ignoring.
         */
 +      int_sts = qed_rd(p_hwfn, p_ptt, DORQ_REG_INT_STS);
        if (!(int_sts & ~DORQ_REG_INT_STS_DORQ_FIFO_AFULL))
                return 0;
  
 +      DP_NOTICE(p_hwfn->cdev, "DORQ attention. int_sts was %x\n", int_sts);
 +
        /* check if db_drop or overflow happened */
        if (int_sts & (DORQ_REG_INT_STS_DB_DROP |
                       DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR)) {
                          GET_FIELD(details, QED_DORQ_ATTENTION_SIZE) * 4,
                          first_drop_reason, all_drops_reason);
  
 -              rc = qed_db_rec_handler(p_hwfn, p_ptt);
 -              qed_periodic_db_rec_start(p_hwfn);
 -              if (rc)
 -                      return rc;
 -
                /* Clear the doorbell drop details and prepare for next drop */
                qed_wr(p_hwfn, p_ptt, DORQ_REG_DB_DROP_DETAILS_REL, 0);
  
        return -EINVAL;
  }
  
 +static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)
 +{
 +      p_hwfn->db_recovery_info.dorq_attn = true;
 +      qed_dorq_attn_overflow(p_hwfn);
 +
 +      return qed_dorq_attn_int_sts(p_hwfn);
 +}
 +
 +static void qed_dorq_attn_handler(struct qed_hwfn *p_hwfn)
 +{
 +      if (p_hwfn->db_recovery_info.dorq_attn)
 +              goto out;
 +
 +      /* Call DORQ callback if the attention was missed */
 +      qed_dorq_attn_cb(p_hwfn);
 +out:
 +      p_hwfn->db_recovery_info.dorq_attn = false;
 +}
 +
  /* Instead of major changes to the data-structure, we have a some 'special'
   * identifiers for sources that changed meaning between adapters.
   */
@@@ -814,18 -774,12 +814,12 @@@ static inline u16 qed_attn_update_idx(s
  {
        u16 rc = 0, index;
  
-       /* Make certain HW write took affect */
-       mmiowb();
        index = le16_to_cpu(p_sb_desc->sb_attn->sb_index);
        if (p_sb_desc->index != index) {
                p_sb_desc->index        = index;
                rc                    = QED_SB_ATT_IDX;
        }
  
-       /* Make certain we got a consistent view with HW */
-       mmiowb();
        return rc;
  }
  
@@@ -1120,9 -1074,6 +1114,9 @@@ static int qed_int_deassertion(struct q
                }
        }
  
 +      /* Handle missed DORQ attention */
 +      qed_dorq_attn_handler(p_hwfn);
 +
        /* Clear IGU indication for the deasserted bits */
        DIRECT_REG_WR((u8 __iomem *)p_hwfn->regview +
                                    GTT_BAR0_MAP_REG_IGU_CMD +
@@@ -1213,7 -1164,6 +1207,6 @@@ static void qed_sb_ack_attn(struct qed_
        /* Both segments (interrupts & acks) are written to same place address;
         * Need to guarantee all commands will be received (in-order) by HW.
         */
-       mmiowb();
        barrier();
  }
  
@@@ -1848,9 -1798,6 +1841,6 @@@ static void qed_int_igu_enable_attn(str
        qed_wr(p_hwfn, p_ptt, IGU_REG_TRAILING_EDGE_LATCH, 0xfff);
        qed_wr(p_hwfn, p_ptt, IGU_REG_ATTENTION_ENABLE, 0xfff);
  
-       /* Flush the writes to IGU */
-       mmiowb();
        /* Unmask AEU signals toward IGU */
        qed_wr(p_hwfn, p_ptt, MISC_REG_AEU_MASK_ATTN_IGU, 0xff);
  }
@@@ -1914,9 -1861,6 +1904,6 @@@ static void qed_int_igu_cleanup_sb(stru
  
        qed_wr(p_hwfn, p_ptt, IGU_REG_COMMAND_REG_CTRL, cmd_ctrl);
  
-       /* Flush the write to IGU */
-       mmiowb();
        /* calculate where to read the status bit from */
        sb_bit = 1 << (igu_sb_id % 32);
        sb_bit_addr = igu_sb_id / 32 * sizeof(u32);
index c4375b868901d092cc76c9b31d3d0b5f96b4f044,abbfc9cc80fc3b92f307434e7ce566e5e5e2bf6a..4f5eec7e44bd4fb997474520b687aba868307668
@@@ -2067,7 -2067,6 +2067,6 @@@ static void iwl_trans_pcie_release_nic_
         * MAC_ACCESS_REQ bit to be performed before any other writes
         * scheduled on different CPUs (after we drop reg_lock).
         */
-       mmiowb();
  out:
        spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags);
  }
@@@ -3318,8 -3317,7 +3317,8 @@@ static void iwl_trans_pcie_resume(struc
        .unref = iwl_trans_pcie_unref,                                  \
        .dump_data = iwl_trans_pcie_dump_data,                          \
        .d3_suspend = iwl_trans_pcie_d3_suspend,                        \
 -      .d3_resume = iwl_trans_pcie_d3_resume
 +      .d3_resume = iwl_trans_pcie_d3_resume,                          \
 +      .sync_nmi = iwl_trans_pcie_sync_nmi
  
  #ifdef CONFIG_PM_SLEEP
  #define IWL_TRANS_PM_OPS                                              \
@@@ -3543,10 -3541,6 +3542,10 @@@ struct iwl_trans *iwl_trans_pcie_alloc(
                }
        } else if (cfg == &iwl_ax101_cfg_qu_hr) {
                if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
 +                  CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
 +                  trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0) {
 +                      trans->cfg = &iwl22000_2ax_cfg_qnj_hr_b0;
 +              } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
                    CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR)) {
                        trans->cfg = &iwl_ax101_cfg_qu_hr;
                } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
                }
        } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
                   CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
 -                 (trans->cfg != &iwl22260_2ax_cfg ||
 +                 (trans->cfg != &iwl_ax200_cfg_cc ||
                    trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) {
                u32 hw_status;
  
@@@ -3642,29 -3636,22 +3641,29 @@@ out_no_pci
        return ERR_PTR(ret);
  }
  
 -void iwl_trans_sync_nmi(struct iwl_trans *trans)
 +void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans)
  {
 +      struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
        unsigned long timeout = jiffies + IWL_TRANS_NMI_TIMEOUT;
 +      u32 inta_addr, sw_err_bit;
 +
 +      if (trans_pcie->msix_enabled) {
 +              inta_addr = CSR_MSIX_HW_INT_CAUSES_AD;
 +              sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR;
 +      } else {
 +              inta_addr = CSR_INT;
 +              sw_err_bit = CSR_INT_BIT_SW_ERR;
 +      }
  
        iwl_disable_interrupts(trans);
        iwl_force_nmi(trans);
        while (time_after(timeout, jiffies)) {
 -              u32 inta_hw = iwl_read32(trans,
 -                                       CSR_MSIX_HW_INT_CAUSES_AD);
 +              u32 inta_hw = iwl_read32(trans, inta_addr);
  
                /* Error detected by uCode */
 -              if (inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR) {
 +              if (inta_hw & sw_err_bit) {
                        /* Clear causes register */
 -                      iwl_write32(trans, CSR_MSIX_HW_INT_CAUSES_AD,
 -                                  inta_hw &
 -                                  MSIX_HW_INT_CAUSES_REG_SW_ERR);
 +                      iwl_write32(trans, inta_addr, inta_hw & sw_err_bit);
                        break;
                }
  
diff --combined kernel/Kconfig.locks
index e335953fa70407c39b18243f9aad7d1634e9b68a,6ba2570eddad194a895eeae4b0451ba2da288bac..bf770d7556f70218f26f45cb53eb3330616af9a9
@@@ -229,7 -229,7 +229,7 @@@ config MUTEX_SPIN_ON_OWNE
  
  config RWSEM_SPIN_ON_OWNER
         def_bool y
 -       depends on SMP && RWSEM_XCHGADD_ALGORITHM && ARCH_SUPPORTS_ATOMIC_RMW
 +       depends on SMP && ARCH_SUPPORTS_ATOMIC_RMW
  
  config LOCK_SPIN_ON_OWNER
         def_bool y
@@@ -251,3 -251,10 +251,10 @@@ config ARCH_USE_QUEUED_RWLOCK
  config QUEUED_RWLOCKS
        def_bool y if ARCH_USE_QUEUED_RWLOCKS
        depends on SMP
+ config ARCH_HAS_MMIOWB
+       bool
+ config MMIOWB
+       def_bool y if ARCH_HAS_MMIOWB
+       depends on SMP
This page took 0.22305 seconds and 4 git commands to generate.