rxr->rx_next_cons = 0xffff;
 }
 
+void bnxt_sched_reset_txr(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
+                         int idx)
+{
+       struct bnxt_napi *bnapi = txr->bnapi;
+
+       if (bnapi->tx_fault)
+               return;
+
+       netdev_err(bp->dev, "Invalid Tx completion (ring:%d tx_pkts:%d cons:%u prod:%u i:%d)",
+                  txr->txq_index, bnapi->tx_pkts,
+                  txr->tx_cons, txr->tx_prod, idx);
+       WARN_ON_ONCE(1);
+       bnapi->tx_fault = 1;
+       bnxt_queue_sp_work(bp, BNXT_RESET_TASK_SP_EVENT);
+}
+
 const u16 bnxt_lhint_arr[] = {
        TX_BD_FLAGS_LHINT_512_AND_SMALLER,
        TX_BD_FLAGS_LHINT_512_TO_1023,
                skb = tx_buf->skb;
                tx_buf->skb = NULL;
 
+               if (unlikely(!skb)) {
+                       bnxt_sched_reset_txr(bp, txr, i);
+                       return;
+               }
+
                tx_bytes += skb->len;
 
                if (tx_buf->is_push) {
 
 static void __bnxt_poll_work_done(struct bnxt *bp, struct bnxt_napi *bnapi)
 {
-       if (bnapi->tx_pkts) {
+       if (bnapi->tx_pkts && !bnapi->tx_fault) {
                bnapi->tx_int(bp, bnapi, bnapi->tx_pkts);
                bnapi->tx_pkts = 0;
        }
                struct bnxt_napi *bnapi = bp->bnapi[i];
                struct bnxt_cp_ring_info *cpr;
 
+               bnapi->tx_fault = 0;
+
                cpr = &bnapi->cp_ring;
                if (bnapi->in_reset)
                        cpr->sw_stats.rx.rx_resets++;
 
                                          int);
        int                     tx_pkts;
        u8                      events;
+       u8                      tx_fault:1;
 
        u32                     flags;
 #define BNXT_NAPI_FLAG_XDP     0x1
 int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init);
 void bnxt_tx_disable(struct bnxt *bp);
 void bnxt_tx_enable(struct bnxt *bp);
+void bnxt_sched_reset_txr(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
+                         int idx);
 void bnxt_report_link(struct bnxt *bp);
 int bnxt_update_link(struct bnxt *bp, bool chng_link_state);
 int bnxt_hwrm_set_pause(struct bnxt *);
 
                        tx_buf->action = 0;
                        tx_buf->xdpf = NULL;
                } else if (tx_buf->action == XDP_TX) {
+                       tx_buf->action = 0;
                        rx_doorbell_needed = true;
                        last_tx_cons = tx_cons;
 
                                tx_buf = &txr->tx_buf_ring[tx_cons];
                                page_pool_recycle_direct(rxr->page_pool, tx_buf->page);
                        }
+               } else {
+                       bnxt_sched_reset_txr(bp, txr, i);
+                       return;
                }
                tx_cons = NEXT_TX(tx_cons);
        }