]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
drop some 6.5 patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 23 Sep 2023 08:17:26 +0000 (10:17 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 23 Sep 2023 08:17:26 +0000 (10:17 +0200)
queue-6.5/ata-libata-core-fetch-sense-data-for-successful-comm.patch
queue-6.5/ata-libata-remove-references-to-non-existing-error_h.patch [deleted file]
queue-6.5/net-stmmac-use-per-queue-64-bit-statistics-where-nec.patch [deleted file]
queue-6.5/series

index 11d4967f70f5db38f2fb05ae42380c6beafeb65b..db9f1d9821b5b3840edd5fff8ec6af5ce52d4ebc 100644 (file)
@@ -41,28 +41,24 @@ Fixes: 3ac873c76d79 ("ata: libata-core: fix when to fetch sense data for success
 Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
 Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
 Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 ---
- drivers/ata/libata-core.c | 7 ++-----
+ drivers/ata/libata-core.c |    7 ++-----
  1 file changed, 2 insertions(+), 5 deletions(-)
 
-diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
-index c7a29c3ac6701..291e128f4d2b4 100644
 --- a/drivers/ata/libata-core.c
 +++ b/drivers/ata/libata-core.c
-@@ -4919,11 +4919,8 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
-        * been aborted by the device due to a limit timeout using the policy
-        * 0xD. For these commands, invoke EH to get the command sense data.
-        */
--      if (qc->result_tf.status & ATA_SENSE &&
--          ((ata_is_ncq(qc->tf.protocol) &&
--            dev->flags & ATA_DFLAG_CDL_ENABLED) ||
--           (!ata_is_ncq(qc->tf.protocol) &&
--            ata_id_sense_reporting_enabled(dev->id)))) {
-+      if (qc->flags & ATA_QCFLAG_HAS_CDL &&
-+          qc->result_tf.status & ATA_SENSE) {
-               /*
-                * Tell SCSI EH to not overwrite scmd->result even if this
-                * command is finished with result SAM_STAT_GOOD.
--- 
-2.40.1
-
+@@ -4935,11 +4935,8 @@ void ata_qc_complete(struct ata_queued_c
+                * timeout using the policy 0xD. For these commands, invoke EH
+                * to get the command sense data.
+                */
+-              if (qc->result_tf.status & ATA_SENSE &&
+-                  ((ata_is_ncq(qc->tf.protocol) &&
+-                    dev->flags & ATA_DFLAG_CDL_ENABLED) ||
+-                   (!ata_is_ncq(qc->tf.protocol) &&
+-                    ata_id_sense_reporting_enabled(dev->id)))) {
++              if (qc->flags & ATA_QCFLAG_HAS_CDL &&
++                  qc->result_tf.status & ATA_SENSE) {
+                       /*
+                        * Tell SCSI EH to not overwrite scmd->result even if
+                        * this command is finished with result SAM_STAT_GOOD.
diff --git a/queue-6.5/ata-libata-remove-references-to-non-existing-error_h.patch b/queue-6.5/ata-libata-remove-references-to-non-existing-error_h.patch
deleted file mode 100644 (file)
index 5fe5c33..0000000
+++ /dev/null
@@ -1,925 +0,0 @@
-From 8df03fd2bc8c18590abf842bc2d997fb2972ceb4 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 31 Jul 2023 16:34:12 +0200
-Subject: ata: libata: remove references to non-existing error_handler()
-
-From: Hannes Reinecke <hare@suse.de>
-
-[ Upstream commit ff8072d589dcff7c1f0345a6ec98b5fc1e9ee2a1 ]
-
-With commit 65a15d6560df ("scsi: ipr: Remove SATA support") all
-libata drivers now have the error_handler() callback provided,
-so we can stop checking for non-existing error_handler callback.
-
-Signed-off-by: Hannes Reinecke <hare@suse.de>
-[niklas: fixed review comments, rebased, solved conflicts during rebase,
-fixed bug that unconditionally dumped all QCs, removed the now unused
-function ata_dump_status(), removed the now unreachable failure paths in
-atapi_qc_complete(), removed the non-EH function to request ATAPI sense]
-Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com>
-Reviewed-by: John Garry <john.g.garry@oracle.com>
-Reviewed-by: Jason Yan <yanaijie@huawei.com>
-Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
-Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
-Stable-dep-of: 5e35a9ac3fe3 ("ata: libata-core: fetch sense data for successful commands iff CDL enabled")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/ata/libata-core.c | 209 +++++++++++++++-----------------------
- drivers/ata/libata-eh.c   | 152 ++++++++++++---------------
- drivers/ata/libata-sata.c |   7 +-
- drivers/ata/libata-scsi.c | 161 ++---------------------------
- drivers/ata/libata-sff.c  |  30 ++----
- include/linux/libata.h    |   2 +-
- 6 files changed, 170 insertions(+), 391 deletions(-)
-
-diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
-index 04db0f2c683a7..c7a29c3ac6701 100644
---- a/drivers/ata/libata-core.c
-+++ b/drivers/ata/libata-core.c
-@@ -1586,13 +1586,11 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev,
-               }
-       }
--      if (ap->ops->error_handler)
--              ata_eh_release(ap);
-+      ata_eh_release(ap);
-       rc = wait_for_completion_timeout(&wait, msecs_to_jiffies(timeout));
--      if (ap->ops->error_handler)
--              ata_eh_acquire(ap);
-+      ata_eh_acquire(ap);
-       ata_sff_flush_pio_task(ap);
-@@ -1607,10 +1605,7 @@ static unsigned ata_exec_internal_sg(struct ata_device *dev,
-               if (qc->flags & ATA_QCFLAG_ACTIVE) {
-                       qc->err_mask |= AC_ERR_TIMEOUT;
--                      if (ap->ops->error_handler)
--                              ata_port_freeze(ap);
--                      else
--                              ata_qc_complete(qc);
-+                      ata_port_freeze(ap);
-                       ata_dev_warn(dev, "qc timeout after %u msecs (cmd 0x%x)\n",
-                                    timeout, command);
-@@ -4874,126 +4869,103 @@ static void ata_verify_xfer(struct ata_queued_cmd *qc)
- void ata_qc_complete(struct ata_queued_cmd *qc)
- {
-       struct ata_port *ap = qc->ap;
-+      struct ata_device *dev = qc->dev;
-+      struct ata_eh_info *ehi = &dev->link->eh_info;
-       /* Trigger the LED (if available) */
-       ledtrig_disk_activity(!!(qc->tf.flags & ATA_TFLAG_WRITE));
--      /* XXX: New EH and old EH use different mechanisms to
--       * synchronize EH with regular execution path.
--       *
--       * In new EH, a qc owned by EH is marked with ATA_QCFLAG_EH.
--       * Normal execution path is responsible for not accessing a
--       * qc owned by EH.  libata core enforces the rule by returning NULL
--       * from ata_qc_from_tag() for qcs owned by EH.
-+      /*
-+       * In order to synchronize EH with the regular execution path, a qc that
-+       * is owned by EH is marked with ATA_QCFLAG_EH.
-        *
--       * Old EH depends on ata_qc_complete() nullifying completion
--       * requests if ATA_QCFLAG_EH_SCHEDULED is set.  Old EH does
--       * not synchronize with interrupt handler.  Only PIO task is
--       * taken care of.
-+       * The normal execution path is responsible for not accessing a qc owned
-+       * by EH.  libata core enforces the rule by returning NULL from
-+       * ata_qc_from_tag() for qcs owned by EH.
-        */
--      if (ap->ops->error_handler) {
--              struct ata_device *dev = qc->dev;
--              struct ata_eh_info *ehi = &dev->link->eh_info;
--
--              if (unlikely(qc->err_mask))
--                      qc->flags |= ATA_QCFLAG_EH;
-+      if (unlikely(qc->err_mask))
-+              qc->flags |= ATA_QCFLAG_EH;
--              /*
--               * Finish internal commands without any further processing
--               * and always with the result TF filled.
--               */
--              if (unlikely(ata_tag_internal(qc->tag))) {
--                      fill_result_tf(qc);
--                      trace_ata_qc_complete_internal(qc);
--                      __ata_qc_complete(qc);
--                      return;
--              }
-+      /*
-+       * Finish internal commands without any further processing and always
-+       * with the result TF filled.
-+       */
-+      if (unlikely(ata_tag_internal(qc->tag))) {
-+              fill_result_tf(qc);
-+              trace_ata_qc_complete_internal(qc);
-+              __ata_qc_complete(qc);
-+              return;
-+      }
--              /*
--               * Non-internal qc has failed.  Fill the result TF and
--               * summon EH.
--               */
--              if (unlikely(qc->flags & ATA_QCFLAG_EH)) {
--                      fill_result_tf(qc);
--                      trace_ata_qc_complete_failed(qc);
--                      ata_qc_schedule_eh(qc);
--                      return;
--              }
-+      /* Non-internal qc has failed.  Fill the result TF and summon EH. */
-+      if (unlikely(qc->flags & ATA_QCFLAG_EH)) {
-+              fill_result_tf(qc);
-+              trace_ata_qc_complete_failed(qc);
-+              ata_qc_schedule_eh(qc);
-+              return;
-+      }
--              WARN_ON_ONCE(ata_port_is_frozen(ap));
-+      WARN_ON_ONCE(ata_port_is_frozen(ap));
--              /* read result TF if requested */
--              if (qc->flags & ATA_QCFLAG_RESULT_TF)
--                      fill_result_tf(qc);
-+      /* read result TF if requested */
-+      if (qc->flags & ATA_QCFLAG_RESULT_TF)
-+              fill_result_tf(qc);
--              trace_ata_qc_complete_done(qc);
-+      trace_ata_qc_complete_done(qc);
-+      /*
-+       * For CDL commands that completed without an error, check if we have
-+       * sense data (ATA_SENSE is set). If we do, then the command may have
-+       * been aborted by the device due to a limit timeout using the policy
-+       * 0xD. For these commands, invoke EH to get the command sense data.
-+       */
-+      if (qc->result_tf.status & ATA_SENSE &&
-+          ((ata_is_ncq(qc->tf.protocol) &&
-+            dev->flags & ATA_DFLAG_CDL_ENABLED) ||
-+           (!ata_is_ncq(qc->tf.protocol) &&
-+            ata_id_sense_reporting_enabled(dev->id)))) {
-               /*
--               * For CDL commands that completed without an error, check if
--               * we have sense data (ATA_SENSE is set). If we do, then the
--               * command may have been aborted by the device due to a limit
--               * timeout using the policy 0xD. For these commands, invoke EH
--               * to get the command sense data.
-+               * Tell SCSI EH to not overwrite scmd->result even if this
-+               * command is finished with result SAM_STAT_GOOD.
-                */
--              if (qc->result_tf.status & ATA_SENSE &&
--                  ((ata_is_ncq(qc->tf.protocol) &&
--                    dev->flags & ATA_DFLAG_CDL_ENABLED) ||
--                   (!ata_is_ncq(qc->tf.protocol) &&
--                    ata_id_sense_reporting_enabled(dev->id)))) {
--                      /*
--                       * Tell SCSI EH to not overwrite scmd->result even if
--                       * this command is finished with result SAM_STAT_GOOD.
--                       */
--                      qc->scsicmd->flags |= SCMD_FORCE_EH_SUCCESS;
--                      qc->flags |= ATA_QCFLAG_EH_SUCCESS_CMD;
--                      ehi->dev_action[dev->devno] |= ATA_EH_GET_SUCCESS_SENSE;
--
--                      /*
--                       * set pending so that ata_qc_schedule_eh() does not
--                       * trigger fast drain, and freeze the port.
--                       */
--                      ap->pflags |= ATA_PFLAG_EH_PENDING;
--                      ata_qc_schedule_eh(qc);
--                      return;
--              }
-+              qc->scsicmd->flags |= SCMD_FORCE_EH_SUCCESS;
-+              qc->flags |= ATA_QCFLAG_EH_SUCCESS_CMD;
-+              ehi->dev_action[dev->devno] |= ATA_EH_GET_SUCCESS_SENSE;
--              /* Some commands need post-processing after successful
--               * completion.
-+              /*
-+               * set pending so that ata_qc_schedule_eh() does not trigger
-+               * fast drain, and freeze the port.
-                */
--              switch (qc->tf.command) {
--              case ATA_CMD_SET_FEATURES:
--                      if (qc->tf.feature != SETFEATURES_WC_ON &&
--                          qc->tf.feature != SETFEATURES_WC_OFF &&
--                          qc->tf.feature != SETFEATURES_RA_ON &&
--                          qc->tf.feature != SETFEATURES_RA_OFF)
--                              break;
--                      fallthrough;
--              case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */
--              case ATA_CMD_SET_MULTI: /* multi_count changed */
--                      /* revalidate device */
--                      ehi->dev_action[dev->devno] |= ATA_EH_REVALIDATE;
--                      ata_port_schedule_eh(ap);
--                      break;
-+              ap->pflags |= ATA_PFLAG_EH_PENDING;
-+              ata_qc_schedule_eh(qc);
-+              return;
-+      }
--              case ATA_CMD_SLEEP:
--                      dev->flags |= ATA_DFLAG_SLEEPING;
-+      /* Some commands need post-processing after successful completion. */
-+      switch (qc->tf.command) {
-+      case ATA_CMD_SET_FEATURES:
-+              if (qc->tf.feature != SETFEATURES_WC_ON &&
-+                  qc->tf.feature != SETFEATURES_WC_OFF &&
-+                  qc->tf.feature != SETFEATURES_RA_ON &&
-+                  qc->tf.feature != SETFEATURES_RA_OFF)
-                       break;
--              }
--
--              if (unlikely(dev->flags & ATA_DFLAG_DUBIOUS_XFER))
--                      ata_verify_xfer(qc);
-+              fallthrough;
-+      case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */
-+      case ATA_CMD_SET_MULTI: /* multi_count changed */
-+              /* revalidate device */
-+              ehi->dev_action[dev->devno] |= ATA_EH_REVALIDATE;
-+              ata_port_schedule_eh(ap);
-+              break;
--              __ata_qc_complete(qc);
--      } else {
--              if (qc->flags & ATA_QCFLAG_EH_SCHEDULED)
--                      return;
-+      case ATA_CMD_SLEEP:
-+              dev->flags |= ATA_DFLAG_SLEEPING;
-+              break;
-+      }
--              /* read result TF if failed or requested */
--              if (qc->err_mask || qc->flags & ATA_QCFLAG_RESULT_TF)
--                      fill_result_tf(qc);
-+      if (unlikely(dev->flags & ATA_DFLAG_DUBIOUS_XFER))
-+              ata_verify_xfer(qc);
--              __ata_qc_complete(qc);
--      }
-+      __ata_qc_complete(qc);
- }
- EXPORT_SYMBOL_GPL(ata_qc_complete);
-@@ -5039,11 +5011,8 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
-       struct ata_link *link = qc->dev->link;
-       u8 prot = qc->tf.protocol;
--      /* Make sure only one non-NCQ command is outstanding.  The
--       * check is skipped for old EH because it reuses active qc to
--       * request ATAPI sense.
--       */
--      WARN_ON_ONCE(ap->ops->error_handler && ata_tag_valid(link->active_tag));
-+      /* Make sure only one non-NCQ command is outstanding. */
-+      WARN_ON_ONCE(ata_tag_valid(link->active_tag));
-       if (ata_is_ncq(prot)) {
-               WARN_ON_ONCE(link->sactive & (1 << qc->hw_tag));
-@@ -5917,15 +5886,9 @@ void __ata_port_probe(struct ata_port *ap)
- int ata_port_probe(struct ata_port *ap)
- {
--      int rc = 0;
--
--      if (ap->ops->error_handler) {
--              __ata_port_probe(ap);
--              ata_port_wait_eh(ap);
--      } else {
--              rc = ata_bus_probe(ap);
--      }
--      return rc;
-+      __ata_port_probe(ap);
-+      ata_port_wait_eh(ap);
-+      return 0;
- }
-@@ -6130,9 +6093,6 @@ static void ata_port_detach(struct ata_port *ap)
-       struct ata_link *link;
-       struct ata_device *dev;
--      if (!ap->ops->error_handler)
--              goto skip_eh;
--
-       /* tell EH we're leaving & flush EH */
-       spin_lock_irqsave(ap->lock, flags);
-       ap->pflags |= ATA_PFLAG_UNLOADING;
-@@ -6148,7 +6108,6 @@ static void ata_port_detach(struct ata_port *ap)
-       cancel_delayed_work_sync(&ap->hotplug_task);
-       cancel_delayed_work_sync(&ap->scsi_rescan_task);
-- skip_eh:
-       /* clean up zpodd on port removal */
-       ata_for_each_link(link, ap, HOST_FIRST) {
-               ata_for_each_dev(dev, link, ALL) {
-diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
-index 35e03679b0bfe..9d6affabf225a 100644
---- a/drivers/ata/libata-eh.c
-+++ b/drivers/ata/libata-eh.c
-@@ -571,13 +571,10 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap,
-       /* make sure sff pio task is not running */
-       ata_sff_flush_pio_task(ap);
--      if (!ap->ops->error_handler)
--              return;
--
-       /* synchronize with host lock and sort out timeouts */
-       /*
--       * For new EH, all qcs are finished in one of three ways -
-+       * For EH, all qcs are finished in one of three ways -
-        * normal completion, error completion, and SCSI timeout.
-        * Both completions can race against SCSI timeout.  When normal
-        * completion wins, the qc never reaches EH.  When error
-@@ -659,94 +656,87 @@ EXPORT_SYMBOL(ata_scsi_cmd_error_handler);
- void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap)
- {
-       unsigned long flags;
-+      struct ata_link *link;
--      /* invoke error handler */
--      if (ap->ops->error_handler) {
--              struct ata_link *link;
--
--              /* acquire EH ownership */
--              ata_eh_acquire(ap);
-+      /* acquire EH ownership */
-+      ata_eh_acquire(ap);
-  repeat:
--              /* kill fast drain timer */
--              del_timer_sync(&ap->fastdrain_timer);
-+      /* kill fast drain timer */
-+      del_timer_sync(&ap->fastdrain_timer);
--              /* process port resume request */
--              ata_eh_handle_port_resume(ap);
-+      /* process port resume request */
-+      ata_eh_handle_port_resume(ap);
--              /* fetch & clear EH info */
--              spin_lock_irqsave(ap->lock, flags);
-+      /* fetch & clear EH info */
-+      spin_lock_irqsave(ap->lock, flags);
--              ata_for_each_link(link, ap, HOST_FIRST) {
--                      struct ata_eh_context *ehc = &link->eh_context;
--                      struct ata_device *dev;
-+      ata_for_each_link(link, ap, HOST_FIRST) {
-+              struct ata_eh_context *ehc = &link->eh_context;
-+              struct ata_device *dev;
--                      memset(&link->eh_context, 0, sizeof(link->eh_context));
--                      link->eh_context.i = link->eh_info;
--                      memset(&link->eh_info, 0, sizeof(link->eh_info));
-+              memset(&link->eh_context, 0, sizeof(link->eh_context));
-+              link->eh_context.i = link->eh_info;
-+              memset(&link->eh_info, 0, sizeof(link->eh_info));
--                      ata_for_each_dev(dev, link, ENABLED) {
--                              int devno = dev->devno;
-+              ata_for_each_dev(dev, link, ENABLED) {
-+                      int devno = dev->devno;
--                              ehc->saved_xfer_mode[devno] = dev->xfer_mode;
--                              if (ata_ncq_enabled(dev))
--                                      ehc->saved_ncq_enabled |= 1 << devno;
--                      }
-+                      ehc->saved_xfer_mode[devno] = dev->xfer_mode;
-+                      if (ata_ncq_enabled(dev))
-+                              ehc->saved_ncq_enabled |= 1 << devno;
-               }
-+      }
--              ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS;
--              ap->pflags &= ~ATA_PFLAG_EH_PENDING;
--              ap->excl_link = NULL;   /* don't maintain exclusion over EH */
-+      ap->pflags |= ATA_PFLAG_EH_IN_PROGRESS;
-+      ap->pflags &= ~ATA_PFLAG_EH_PENDING;
-+      ap->excl_link = NULL;   /* don't maintain exclusion over EH */
--              spin_unlock_irqrestore(ap->lock, flags);
-+      spin_unlock_irqrestore(ap->lock, flags);
--              /* invoke EH, skip if unloading or suspended */
--              if (!(ap->pflags & (ATA_PFLAG_UNLOADING | ATA_PFLAG_SUSPENDED)))
--                      ap->ops->error_handler(ap);
--              else {
--                      /* if unloading, commence suicide */
--                      if ((ap->pflags & ATA_PFLAG_UNLOADING) &&
--                          !(ap->pflags & ATA_PFLAG_UNLOADED))
--                              ata_eh_unload(ap);
--                      ata_eh_finish(ap);
--              }
-+      /* invoke EH, skip if unloading or suspended */
-+      if (!(ap->pflags & (ATA_PFLAG_UNLOADING | ATA_PFLAG_SUSPENDED)))
-+              ap->ops->error_handler(ap);
-+      else {
-+              /* if unloading, commence suicide */
-+              if ((ap->pflags & ATA_PFLAG_UNLOADING) &&
-+                  !(ap->pflags & ATA_PFLAG_UNLOADED))
-+                      ata_eh_unload(ap);
-+              ata_eh_finish(ap);
-+      }
--              /* process port suspend request */
--              ata_eh_handle_port_suspend(ap);
-+      /* process port suspend request */
-+      ata_eh_handle_port_suspend(ap);
--              /* Exception might have happened after ->error_handler
--               * recovered the port but before this point.  Repeat
--               * EH in such case.
--               */
--              spin_lock_irqsave(ap->lock, flags);
-+      /*
-+       * Exception might have happened after ->error_handler recovered the
-+       * port but before this point.  Repeat EH in such case.
-+       */
-+      spin_lock_irqsave(ap->lock, flags);
--              if (ap->pflags & ATA_PFLAG_EH_PENDING) {
--                      if (--ap->eh_tries) {
--                              spin_unlock_irqrestore(ap->lock, flags);
--                              goto repeat;
--                      }
--                      ata_port_err(ap,
--                                   "EH pending after %d tries, giving up\n",
--                                   ATA_EH_MAX_TRIES);
--                      ap->pflags &= ~ATA_PFLAG_EH_PENDING;
-+      if (ap->pflags & ATA_PFLAG_EH_PENDING) {
-+              if (--ap->eh_tries) {
-+                      spin_unlock_irqrestore(ap->lock, flags);
-+                      goto repeat;
-               }
-+              ata_port_err(ap,
-+                           "EH pending after %d tries, giving up\n",
-+                           ATA_EH_MAX_TRIES);
-+              ap->pflags &= ~ATA_PFLAG_EH_PENDING;
-+      }
--              /* this run is complete, make sure EH info is clear */
--              ata_for_each_link(link, ap, HOST_FIRST)
--                      memset(&link->eh_info, 0, sizeof(link->eh_info));
-+      /* this run is complete, make sure EH info is clear */
-+      ata_for_each_link(link, ap, HOST_FIRST)
-+              memset(&link->eh_info, 0, sizeof(link->eh_info));
--              /* end eh (clear host_eh_scheduled) while holding
--               * ap->lock such that if exception occurs after this
--               * point but before EH completion, SCSI midlayer will
--               * re-initiate EH.
--               */
--              ap->ops->end_eh(ap);
-+      /*
-+       * end eh (clear host_eh_scheduled) while holding ap->lock such that if
-+       * exception occurs after this point but before EH completion, SCSI
-+       * midlayer will re-initiate EH.
-+       */
-+      ap->ops->end_eh(ap);
--              spin_unlock_irqrestore(ap->lock, flags);
--              ata_eh_release(ap);
--      } else {
--              WARN_ON(ata_qc_from_tag(ap, ap->link.active_tag) == NULL);
--              ap->ops->eng_timeout(ap);
--      }
-+      spin_unlock_irqrestore(ap->lock, flags);
-+      ata_eh_release(ap);
-       scsi_eh_flush_done_q(&ap->eh_done_q);
-@@ -912,8 +902,6 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc)
- {
-       struct ata_port *ap = qc->ap;
--      WARN_ON(!ap->ops->error_handler);
--
-       qc->flags |= ATA_QCFLAG_EH;
-       ata_eh_set_pending(ap, 1);
-@@ -934,8 +922,6 @@ void ata_qc_schedule_eh(struct ata_queued_cmd *qc)
-  */
- void ata_std_sched_eh(struct ata_port *ap)
- {
--      WARN_ON(!ap->ops->error_handler);
--
-       if (ap->pflags & ATA_PFLAG_INITIALIZING)
-               return;
-@@ -989,8 +975,6 @@ static int ata_do_link_abort(struct ata_port *ap, struct ata_link *link)
-       struct ata_queued_cmd *qc;
-       int tag, nr_aborted = 0;
--      WARN_ON(!ap->ops->error_handler);
--
-       /* we're gonna abort all commands, no need for fast drain */
-       ata_eh_set_pending(ap, 0);
-@@ -1065,8 +1049,6 @@ EXPORT_SYMBOL_GPL(ata_port_abort);
-  */
- static void __ata_port_freeze(struct ata_port *ap)
- {
--      WARN_ON(!ap->ops->error_handler);
--
-       if (ap->ops->freeze)
-               ap->ops->freeze(ap);
-@@ -1091,8 +1073,6 @@ static void __ata_port_freeze(struct ata_port *ap)
-  */
- int ata_port_freeze(struct ata_port *ap)
- {
--      WARN_ON(!ap->ops->error_handler);
--
-       __ata_port_freeze(ap);
-       return ata_port_abort(ap);
-@@ -1112,9 +1092,6 @@ void ata_eh_freeze_port(struct ata_port *ap)
- {
-       unsigned long flags;
--      if (!ap->ops->error_handler)
--              return;
--
-       spin_lock_irqsave(ap->lock, flags);
-       __ata_port_freeze(ap);
-       spin_unlock_irqrestore(ap->lock, flags);
-@@ -1134,9 +1111,6 @@ void ata_eh_thaw_port(struct ata_port *ap)
- {
-       unsigned long flags;
--      if (!ap->ops->error_handler)
--              return;
--
-       spin_lock_irqsave(ap->lock, flags);
-       ap->pflags &= ~ATA_PFLAG_FROZEN;
-diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c
-index 85e279a12f62c..99d4ab04bcce6 100644
---- a/drivers/ata/libata-sata.c
-+++ b/drivers/ata/libata-sata.c
-@@ -1158,12 +1158,7 @@ EXPORT_SYMBOL_GPL(ata_sas_port_alloc);
-  */
- int ata_sas_port_start(struct ata_port *ap)
- {
--      /*
--       * the port is marked as frozen at allocation time, but if we don't
--       * have new eh, we won't thaw it
--       */
--      if (!ap->ops->error_handler)
--              ap->pflags &= ~ATA_PFLAG_FROZEN;
-+      /* the port is marked as frozen at allocation time */
-       return 0;
- }
- EXPORT_SYMBOL_GPL(ata_sas_port_start);
-diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
-index c6ece32de8e31..e55db9a6826f3 100644
---- a/drivers/ata/libata-scsi.c
-+++ b/drivers/ata/libata-scsi.c
-@@ -709,47 +709,6 @@ static void ata_qc_set_pc_nbytes(struct ata_queued_cmd *qc)
-       qc->nbytes = scsi_bufflen(scmd) + qc->extrabytes;
- }
--/**
-- *    ata_dump_status - user friendly display of error info
-- *    @ap: the port in question
-- *    @tf: ptr to filled out taskfile
-- *
-- *    Decode and dump the ATA error/status registers for the user so
-- *    that they have some idea what really happened at the non
-- *    make-believe layer.
-- *
-- *    LOCKING:
-- *    inherited from caller
-- */
--static void ata_dump_status(struct ata_port *ap, struct ata_taskfile *tf)
--{
--      u8 stat = tf->status, err = tf->error;
--
--      if (stat & ATA_BUSY) {
--              ata_port_warn(ap, "status=0x%02x {Busy} ", stat);
--      } else {
--              ata_port_warn(ap, "status=0x%02x { %s%s%s%s%s%s%s} ", stat,
--                            stat & ATA_DRDY ? "DriveReady " : "",
--                            stat & ATA_DF ? "DeviceFault " : "",
--                            stat & ATA_DSC ? "SeekComplete " : "",
--                            stat & ATA_DRQ ? "DataRequest " : "",
--                            stat & ATA_CORR ? "CorrectedError " : "",
--                            stat & ATA_SENSE ? "Sense " : "",
--                            stat & ATA_ERR ? "Error " : "");
--              if (err)
--                      ata_port_warn(ap, "error=0x%02x {%s%s%s%s%s%s", err,
--                                    err & ATA_ABORTED ?
--                                    "DriveStatusError " : "",
--                                    err & ATA_ICRC ?
--                                    (err & ATA_ABORTED ?
--                                     "BadCRC " : "Sector ") : "",
--                                    err & ATA_UNC ? "UncorrectableError " : "",
--                                    err & ATA_IDNF ? "SectorIdNotFound " : "",
--                                    err & ATA_TRK0NF ? "TrackZeroNotFound " : "",
--                                    err & ATA_AMNF ? "AddrMarkNotFound " : "");
--      }
--}
--
- /**
-  *    ata_to_sense_error - convert ATA error to SCSI error
-  *    @id: ATA device number
-@@ -758,7 +717,6 @@ static void ata_dump_status(struct ata_port *ap, struct ata_taskfile *tf)
-  *    @sk: the sense key we'll fill out
-  *    @asc: the additional sense code we'll fill out
-  *    @ascq: the additional sense code qualifier we'll fill out
-- *    @verbose: be verbose
-  *
-  *    Converts an ATA error into a SCSI error.  Fill out pointers to
-  *    SK, ASC, and ASCQ bytes for later use in fixed or descriptor
-@@ -768,7 +726,7 @@ static void ata_dump_status(struct ata_port *ap, struct ata_taskfile *tf)
-  *    spin_lock_irqsave(host lock)
-  */
- static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk,
--                             u8 *asc, u8 *ascq, int verbose)
-+                             u8 *asc, u8 *ascq)
- {
-       int i;
-@@ -847,7 +805,7 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk,
-                               *sk = sense_table[i][1];
-                               *asc = sense_table[i][2];
-                               *ascq = sense_table[i][3];
--                              goto translate_done;
-+                              return;
-                       }
-               }
-       }
-@@ -862,7 +820,7 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk,
-                       *sk = stat_table[i][1];
-                       *asc = stat_table[i][2];
-                       *ascq = stat_table[i][3];
--                      goto translate_done;
-+                      return;
-               }
-       }
-@@ -873,12 +831,6 @@ static void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk,
-       *sk = ABORTED_COMMAND;
-       *asc = 0x00;
-       *ascq = 0x00;
--
-- translate_done:
--      if (verbose)
--              pr_err("ata%u: translated ATA stat/err 0x%02x/%02x to SCSI SK/ASC/ASCQ 0x%x/%02x/%02x\n",
--                     id, drv_stat, drv_err, *sk, *asc, *ascq);
--      return;
- }
- /*
-@@ -904,7 +856,6 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
-       struct ata_taskfile *tf = &qc->result_tf;
-       unsigned char *sb = cmd->sense_buffer;
-       unsigned char *desc = sb + 8;
--      int verbose = qc->ap->ops->error_handler == NULL;
-       u8 sense_key, asc, ascq;
-       memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
-@@ -916,7 +867,7 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
-       if (qc->err_mask ||
-           tf->status & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
-               ata_to_sense_error(qc->ap->print_id, tf->status, tf->error,
--                                 &sense_key, &asc, &ascq, verbose);
-+                                 &sense_key, &asc, &ascq);
-               ata_scsi_set_sense(qc->dev, cmd, sense_key, asc, ascq);
-       } else {
-               /*
-@@ -999,7 +950,6 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
-       struct scsi_cmnd *cmd = qc->scsicmd;
-       struct ata_taskfile *tf = &qc->result_tf;
-       unsigned char *sb = cmd->sense_buffer;
--      int verbose = qc->ap->ops->error_handler == NULL;
-       u64 block;
-       u8 sense_key, asc, ascq;
-@@ -1017,7 +967,7 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
-       if (qc->err_mask ||
-           tf->status & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
-               ata_to_sense_error(qc->ap->print_id, tf->status, tf->error,
--                                 &sense_key, &asc, &ascq, verbose);
-+                                 &sense_key, &asc, &ascq);
-               ata_scsi_set_sense(dev, cmd, sense_key, asc, ascq);
-       } else {
-               /* Could not decode error */
-@@ -1186,9 +1136,6 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
-       unsigned long flags;
-       struct ata_device *dev;
--      if (!ap->ops->error_handler)
--              return;
--
-       spin_lock_irqsave(ap->lock, flags);
-       dev = __ata_scsi_find_dev(ap, sdev);
-       if (dev && dev->sdev) {
-@@ -1675,7 +1622,6 @@ static void ata_qc_done(struct ata_queued_cmd *qc)
- static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
- {
--      struct ata_port *ap = qc->ap;
-       struct scsi_cmnd *cmd = qc->scsicmd;
-       u8 *cdb = cmd->cmnd;
-       int need_sense = (qc->err_mask != 0) &&
-@@ -1699,9 +1645,6 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
-               /* Keep the SCSI ML and status byte, clear host byte. */
-               cmd->result &= 0x0000ffff;
--      if (need_sense && !ap->ops->error_handler)
--              ata_dump_status(ap, &qc->result_tf);
--
-       ata_qc_done(qc);
- }
-@@ -2608,71 +2551,6 @@ static unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf)
-       return 0;
- }
--static void atapi_sense_complete(struct ata_queued_cmd *qc)
--{
--      if (qc->err_mask && ((qc->err_mask & AC_ERR_DEV) == 0)) {
--              /* FIXME: not quite right; we don't want the
--               * translation of taskfile registers into
--               * a sense descriptors, since that's only
--               * correct for ATA, not ATAPI
--               */
--              ata_gen_passthru_sense(qc);
--      }
--
--      ata_qc_done(qc);
--}
--
--/* is it pointless to prefer PIO for "safety reasons"? */
--static inline int ata_pio_use_silly(struct ata_port *ap)
--{
--      return (ap->flags & ATA_FLAG_PIO_DMA);
--}
--
--static void atapi_request_sense(struct ata_queued_cmd *qc)
--{
--      struct ata_port *ap = qc->ap;
--      struct scsi_cmnd *cmd = qc->scsicmd;
--
--      memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
--
--#ifdef CONFIG_ATA_SFF
--      if (ap->ops->sff_tf_read)
--              ap->ops->sff_tf_read(ap, &qc->tf);
--#endif
--
--      /* fill these in, for the case where they are -not- overwritten */
--      cmd->sense_buffer[0] = 0x70;
--      cmd->sense_buffer[2] = qc->tf.error >> 4;
--
--      ata_qc_reinit(qc);
--
--      /* setup sg table and init transfer direction */
--      sg_init_one(&qc->sgent, cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE);
--      ata_sg_init(qc, &qc->sgent, 1);
--      qc->dma_dir = DMA_FROM_DEVICE;
--
--      memset(&qc->cdb, 0, qc->dev->cdb_len);
--      qc->cdb[0] = REQUEST_SENSE;
--      qc->cdb[4] = SCSI_SENSE_BUFFERSIZE;
--
--      qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
--      qc->tf.command = ATA_CMD_PACKET;
--
--      if (ata_pio_use_silly(ap)) {
--              qc->tf.protocol = ATAPI_PROT_DMA;
--              qc->tf.feature |= ATAPI_PKT_DMA;
--      } else {
--              qc->tf.protocol = ATAPI_PROT_PIO;
--              qc->tf.lbam = SCSI_SENSE_BUFFERSIZE;
--              qc->tf.lbah = 0;
--      }
--      qc->nbytes = SCSI_SENSE_BUFFERSIZE;
--
--      qc->complete_fn = atapi_sense_complete;
--
--      ata_qc_issue(qc);
--}
--
- /*
-  * ATAPI devices typically report zero for their SCSI version, and sometimes
-  * deviate from the spec WRT response data format.  If SCSI version is
-@@ -2698,9 +2576,8 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
-       struct scsi_cmnd *cmd = qc->scsicmd;
-       unsigned int err_mask = qc->err_mask;
--      /* handle completion from new EH */
--      if (unlikely(qc->ap->ops->error_handler &&
--                   (err_mask || qc->flags & ATA_QCFLAG_SENSE_VALID))) {
-+      /* handle completion from EH */
-+      if (unlikely(err_mask || qc->flags & ATA_QCFLAG_SENSE_VALID)) {
-               if (!(qc->flags & ATA_QCFLAG_SENSE_VALID)) {
-                       /* FIXME: not quite right; we don't want the
-@@ -2732,23 +2609,10 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
-               return;
-       }
--      /* successful completion or old EH failure path */
--      if (unlikely(err_mask & AC_ERR_DEV)) {
--              cmd->result = SAM_STAT_CHECK_CONDITION;
--              atapi_request_sense(qc);
--              return;
--      } else if (unlikely(err_mask)) {
--              /* FIXME: not quite right; we don't want the
--               * translation of taskfile registers into
--               * a sense descriptors, since that's only
--               * correct for ATA, not ATAPI
--               */
--              ata_gen_passthru_sense(qc);
--      } else {
--              if (cmd->cmnd[0] == INQUIRY && (cmd->cmnd[1] & 0x03) == 0)
--                      atapi_fixup_inquiry(cmd);
--              cmd->result = SAM_STAT_GOOD;
--      }
-+      /* successful completion path */
-+      if (cmd->cmnd[0] == INQUIRY && (cmd->cmnd[1] & 0x03) == 0)
-+              atapi_fixup_inquiry(cmd);
-+      cmd->result = SAM_STAT_GOOD;
-       ata_qc_done(qc);
- }
-@@ -4797,9 +4661,6 @@ int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
-       unsigned long flags;
-       int devno, rc = 0;
--      if (!ap->ops->error_handler)
--              return -EOPNOTSUPP;
--
-       if (lun != SCAN_WILD_CARD && lun)
-               return -EINVAL;
-diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
-index 9d28badfe41d6..84471d92cd1b9 100644
---- a/drivers/ata/libata-sff.c
-+++ b/drivers/ata/libata-sff.c
-@@ -883,31 +883,21 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
- {
-       struct ata_port *ap = qc->ap;
--      if (ap->ops->error_handler) {
--              if (in_wq) {
--                      /* EH might have kicked in while host lock is
--                       * released.
--                       */
--                      qc = ata_qc_from_tag(ap, qc->tag);
--                      if (qc) {
--                              if (likely(!(qc->err_mask & AC_ERR_HSM))) {
--                                      ata_sff_irq_on(ap);
--                                      ata_qc_complete(qc);
--                              } else
--                                      ata_port_freeze(ap);
--                      }
--              } else {
--                      if (likely(!(qc->err_mask & AC_ERR_HSM)))
-+      if (in_wq) {
-+              /* EH might have kicked in while host lock is released. */
-+              qc = ata_qc_from_tag(ap, qc->tag);
-+              if (qc) {
-+                      if (likely(!(qc->err_mask & AC_ERR_HSM))) {
-+                              ata_sff_irq_on(ap);
-                               ata_qc_complete(qc);
--                      else
-+                      } else
-                               ata_port_freeze(ap);
-               }
-       } else {
--              if (in_wq) {
--                      ata_sff_irq_on(ap);
--                      ata_qc_complete(qc);
--              } else
-+              if (likely(!(qc->err_mask & AC_ERR_HSM)))
-                       ata_qc_complete(qc);
-+              else
-+                      ata_port_freeze(ap);
-       }
- }
-diff --git a/include/linux/libata.h b/include/linux/libata.h
-index 820f7a3a2749b..3eeea76c30de4 100644
---- a/include/linux/libata.h
-+++ b/include/linux/libata.h
-@@ -1785,7 +1785,7 @@ static inline struct ata_queued_cmd *ata_qc_from_tag(struct ata_port *ap,
- {
-       struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
--      if (unlikely(!qc) || !ap->ops->error_handler)
-+      if (unlikely(!qc))
-               return qc;
-       if ((qc->flags & (ATA_QCFLAG_ACTIVE |
--- 
-2.40.1
-
diff --git a/queue-6.5/net-stmmac-use-per-queue-64-bit-statistics-where-nec.patch b/queue-6.5/net-stmmac-use-per-queue-64-bit-statistics-where-nec.patch
deleted file mode 100644 (file)
index f2f0228..0000000
+++ /dev/null
@@ -1,1333 +0,0 @@
-From 9c9cd57351a2f9c85963dce9d5185a261237b2d3 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 18 Jul 2023 00:06:30 +0800
-Subject: net: stmmac: use per-queue 64 bit statistics where necessary
-
-From: Jisheng Zhang <jszhang@kernel.org>
-
-[ Upstream commit 133466c3bbe171f826294161db203f7670bb30c8 ]
-
-Currently, there are two major issues with stmmac driver statistics
-First of all, statistics in stmmac_extra_stats, stmmac_rxq_stats
-and stmmac_txq_stats are 32 bit variables on 32 bit platforms. This
-can cause some stats to overflow after several minutes of
-high traffic, for example rx_pkt_n, tx_pkt_n and so on.
-
-Secondly, if HW supports multiqueues, there are frequent cacheline
-ping pongs on some driver statistic vars, for example, normal_irq_n,
-tx_pkt_n and so on. What's more, frequent cacheline ping pongs on
-normal_irq_n happens in ISR, this makes the situation worse.
-
-To improve the driver, we convert those statistics to 64 bit, implement
-ndo_get_stats64 and update .get_ethtool_stats implementation
-accordingly. We also use per-queue statistics where necessary to remove
-the cacheline ping pongs as much as possible to make multiqueue
-operations faster. Those statistics which are not possible to overflow
-and not frequently updated are kept as is.
-
-Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
-Link: https://lore.kernel.org/r/20230717160630.1892-3-jszhang@kernel.org
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/net/ethernet/stmicro/stmmac/common.h  |  39 ++--
- .../net/ethernet/stmicro/stmmac/dwmac-sun8i.c |  12 +-
- .../ethernet/stmicro/stmmac/dwmac100_dma.c    |   7 +-
- .../ethernet/stmicro/stmmac/dwmac4_descs.c    |  16 +-
- .../net/ethernet/stmicro/stmmac/dwmac4_lib.c  |  15 +-
- .../net/ethernet/stmicro/stmmac/dwmac_lib.c   |  12 +-
- .../ethernet/stmicro/stmmac/dwxgmac2_descs.c  |   6 +-
- .../ethernet/stmicro/stmmac/dwxgmac2_dma.c    |  14 +-
- .../net/ethernet/stmicro/stmmac/enh_desc.c    |  20 +-
- drivers/net/ethernet/stmicro/stmmac/hwif.h    |  12 +-
- .../net/ethernet/stmicro/stmmac/norm_desc.c   |  15 +-
- drivers/net/ethernet/stmicro/stmmac/stmmac.h  |   2 +
- .../ethernet/stmicro/stmmac/stmmac_ethtool.c  | 123 ++++++++---
- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 200 ++++++++++++++----
- 14 files changed, 335 insertions(+), 158 deletions(-)
-
-diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
-index 16e67c18b6f71..57f2137bbe9d9 100644
---- a/drivers/net/ethernet/stmicro/stmmac/common.h
-+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
-@@ -59,13 +59,25 @@
- /* #define FRAME_FILTER_DEBUG */
- struct stmmac_txq_stats {
--      unsigned long tx_pkt_n;
--      unsigned long tx_normal_irq_n;
-+      u64 tx_bytes;
-+      u64 tx_packets;
-+      u64 tx_pkt_n;
-+      u64 tx_normal_irq_n;
-+      u64 napi_poll;
-+      u64 tx_clean;
-+      u64 tx_set_ic_bit;
-+      u64 tx_tso_frames;
-+      u64 tx_tso_nfrags;
-+      struct u64_stats_sync syncp;
- };
- struct stmmac_rxq_stats {
--      unsigned long rx_pkt_n;
--      unsigned long rx_normal_irq_n;
-+      u64 rx_bytes;
-+      u64 rx_packets;
-+      u64 rx_pkt_n;
-+      u64 rx_normal_irq_n;
-+      u64 napi_poll;
-+      struct u64_stats_sync syncp;
- };
- /* Extra statistic and debug information exposed by ethtool */
-@@ -81,6 +93,7 @@ struct stmmac_extra_stats {
-       unsigned long tx_frame_flushed;
-       unsigned long tx_payload_error;
-       unsigned long tx_ip_header_error;
-+      unsigned long tx_collision;
-       /* Receive errors */
-       unsigned long rx_desc;
-       unsigned long sa_filter_fail;
-@@ -113,14 +126,6 @@ struct stmmac_extra_stats {
-       /* Tx/Rx IRQ Events */
-       unsigned long rx_early_irq;
-       unsigned long threshold;
--      unsigned long tx_pkt_n;
--      unsigned long rx_pkt_n;
--      unsigned long normal_irq_n;
--      unsigned long rx_normal_irq_n;
--      unsigned long napi_poll;
--      unsigned long tx_normal_irq_n;
--      unsigned long tx_clean;
--      unsigned long tx_set_ic_bit;
-       unsigned long irq_receive_pmt_irq_n;
-       /* MMC info */
-       unsigned long mmc_tx_irq_n;
-@@ -190,18 +195,16 @@ struct stmmac_extra_stats {
-       unsigned long mtl_rx_fifo_ctrl_active;
-       unsigned long mac_rx_frame_ctrl_fifo;
-       unsigned long mac_gmii_rx_proto_engine;
--      /* TSO */
--      unsigned long tx_tso_frames;
--      unsigned long tx_tso_nfrags;
-       /* EST */
-       unsigned long mtl_est_cgce;
-       unsigned long mtl_est_hlbs;
-       unsigned long mtl_est_hlbf;
-       unsigned long mtl_est_btre;
-       unsigned long mtl_est_btrlm;
--      /* per queue statistics */
--      struct stmmac_txq_stats txq_stats[MTL_MAX_TX_QUEUES];
--      struct stmmac_rxq_stats rxq_stats[MTL_MAX_RX_QUEUES];
-+      unsigned long rx_dropped;
-+      unsigned long rx_errors;
-+      unsigned long tx_dropped;
-+      unsigned long tx_errors;
- };
- /* Safety Feature statistics exposed by ethtool */
-diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
-index 1e714380d1250..b20f8ba34efd9 100644
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
-@@ -440,8 +440,10 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv,
-                                    struct stmmac_extra_stats *x, u32 chan,
-                                    u32 dir)
- {
--      u32 v;
-+      struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[chan];
-+      struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan];
-       int ret = 0;
-+      u32 v;
-       v = readl(ioaddr + EMAC_INT_STA);
-@@ -452,7 +454,9 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv,
-       if (v & EMAC_TX_INT) {
-               ret |= handle_tx;
--              x->tx_normal_irq_n++;
-+              u64_stats_update_begin(&tx_q->txq_stats.syncp);
-+              tx_q->txq_stats.tx_normal_irq_n++;
-+              u64_stats_update_end(&tx_q->txq_stats.syncp);
-       }
-       if (v & EMAC_TX_DMA_STOP_INT)
-@@ -474,7 +478,9 @@ static int sun8i_dwmac_dma_interrupt(struct stmmac_priv *priv,
-       if (v & EMAC_RX_INT) {
-               ret |= handle_rx;
--              x->rx_normal_irq_n++;
-+              u64_stats_update_begin(&rx_q->rxq_stats.syncp);
-+              rx_q->rxq_stats.rx_normal_irq_n++;
-+              u64_stats_update_end(&rx_q->rxq_stats.syncp);
-       }
-       if (v & EMAC_RX_BUF_UA_INT)
-diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
-index 1c32b1788f02e..dea270f60cc3e 100644
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
-@@ -82,29 +82,24 @@ static void dwmac100_dump_dma_regs(struct stmmac_priv *priv,
- }
- /* DMA controller has two counters to track the number of the missed frames. */
--static void dwmac100_dma_diagnostic_fr(struct net_device_stats *stats,
--                                     struct stmmac_extra_stats *x,
-+static void dwmac100_dma_diagnostic_fr(struct stmmac_extra_stats *x,
-                                      void __iomem *ioaddr)
- {
-       u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
-       if (unlikely(csr8)) {
-               if (csr8 & DMA_MISSED_FRAME_OVE) {
--                      stats->rx_over_errors += 0x800;
-                       x->rx_overflow_cntr += 0x800;
-               } else {
-                       unsigned int ove_cntr;
-                       ove_cntr = ((csr8 & DMA_MISSED_FRAME_OVE_CNTR) >> 17);
--                      stats->rx_over_errors += ove_cntr;
-                       x->rx_overflow_cntr += ove_cntr;
-               }
-               if (csr8 & DMA_MISSED_FRAME_OVE_M) {
--                      stats->rx_missed_errors += 0xffff;
-                       x->rx_missed_cntr += 0xffff;
-               } else {
-                       unsigned int miss_f = (csr8 & DMA_MISSED_FRAME_M_CNTR);
--                      stats->rx_missed_errors += miss_f;
-                       x->rx_missed_cntr += miss_f;
-               }
-       }
-diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
-index 6a011d8633e8e..89a14084c6117 100644
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
-@@ -13,8 +13,7 @@
- #include "dwmac4.h"
- #include "dwmac4_descs.h"
--static int dwmac4_wrback_get_tx_status(struct net_device_stats *stats,
--                                     struct stmmac_extra_stats *x,
-+static int dwmac4_wrback_get_tx_status(struct stmmac_extra_stats *x,
-                                      struct dma_desc *p,
-                                      void __iomem *ioaddr)
- {
-@@ -40,15 +39,13 @@ static int dwmac4_wrback_get_tx_status(struct net_device_stats *stats,
-                       x->tx_frame_flushed++;
-               if (unlikely(tdes3 & TDES3_LOSS_CARRIER)) {
-                       x->tx_losscarrier++;
--                      stats->tx_carrier_errors++;
-               }
-               if (unlikely(tdes3 & TDES3_NO_CARRIER)) {
-                       x->tx_carrier++;
--                      stats->tx_carrier_errors++;
-               }
-               if (unlikely((tdes3 & TDES3_LATE_COLLISION) ||
-                            (tdes3 & TDES3_EXCESSIVE_COLLISION)))
--                      stats->collisions +=
-+                      x->tx_collision +=
-                           (tdes3 & TDES3_COLLISION_COUNT_MASK)
-                           >> TDES3_COLLISION_COUNT_SHIFT;
-@@ -73,8 +70,7 @@ static int dwmac4_wrback_get_tx_status(struct net_device_stats *stats,
-       return ret;
- }
--static int dwmac4_wrback_get_rx_status(struct net_device_stats *stats,
--                                     struct stmmac_extra_stats *x,
-+static int dwmac4_wrback_get_rx_status(struct stmmac_extra_stats *x,
-                                      struct dma_desc *p)
- {
-       unsigned int rdes1 = le32_to_cpu(p->des1);
-@@ -93,7 +89,7 @@ static int dwmac4_wrback_get_rx_status(struct net_device_stats *stats,
-       if (unlikely(rdes3 & RDES3_ERROR_SUMMARY)) {
-               if (unlikely(rdes3 & RDES3_GIANT_PACKET))
--                      stats->rx_length_errors++;
-+                      x->rx_length++;
-               if (unlikely(rdes3 & RDES3_OVERFLOW_ERROR))
-                       x->rx_gmac_overflow++;
-@@ -103,10 +99,8 @@ static int dwmac4_wrback_get_rx_status(struct net_device_stats *stats,
-               if (unlikely(rdes3 & RDES3_RECEIVE_ERROR))
-                       x->rx_mii++;
--              if (unlikely(rdes3 & RDES3_CRC_ERROR)) {
-+              if (unlikely(rdes3 & RDES3_CRC_ERROR))
-                       x->rx_crc_errors++;
--                      stats->rx_crc_errors++;
--              }
-               if (unlikely(rdes3 & RDES3_DRIBBLE_ERROR))
-                       x->dribbling_bit++;
-diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
-index 03ceb6a940732..980e5f8a37ec5 100644
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_lib.c
-@@ -171,6 +171,8 @@ int dwmac4_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
-       const struct dwmac4_addrs *dwmac4_addrs = priv->plat->dwmac4_addrs;
-       u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(dwmac4_addrs, chan));
-       u32 intr_en = readl(ioaddr + DMA_CHAN_INTR_ENA(dwmac4_addrs, chan));
-+      struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[chan];
-+      struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan];
-       int ret = 0;
-       if (dir == DMA_DIR_RX)
-@@ -198,18 +200,19 @@ int dwmac4_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
-               }
-       }
-       /* TX/RX NORMAL interrupts */
--      if (likely(intr_status & DMA_CHAN_STATUS_NIS))
--              x->normal_irq_n++;
-       if (likely(intr_status & DMA_CHAN_STATUS_RI)) {
--              x->rx_normal_irq_n++;
--              x->rxq_stats[chan].rx_normal_irq_n++;
-+              u64_stats_update_begin(&rx_q->rxq_stats.syncp);
-+              rx_q->rxq_stats.rx_normal_irq_n++;
-+              u64_stats_update_end(&rx_q->rxq_stats.syncp);
-               ret |= handle_rx;
-       }
-       if (likely(intr_status & DMA_CHAN_STATUS_TI)) {
--              x->tx_normal_irq_n++;
--              x->txq_stats[chan].tx_normal_irq_n++;
-+              u64_stats_update_begin(&tx_q->txq_stats.syncp);
-+              tx_q->txq_stats.tx_normal_irq_n++;
-+              u64_stats_update_end(&tx_q->txq_stats.syncp);
-               ret |= handle_tx;
-       }
-+
-       if (unlikely(intr_status & DMA_CHAN_STATUS_TBU))
-               ret |= handle_tx;
-       if (unlikely(intr_status & DMA_CHAN_STATUS_ERI))
-diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
-index 0b6f999a83052..aaa09b16b016f 100644
---- a/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
-@@ -10,6 +10,7 @@
- #include <linux/iopoll.h>
- #include "common.h"
- #include "dwmac_dma.h"
-+#include "stmmac.h"
- #define GMAC_HI_REG_AE                0x80000000
-@@ -161,6 +162,8 @@ static void show_rx_process_state(unsigned int status)
- int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
-                       struct stmmac_extra_stats *x, u32 chan, u32 dir)
- {
-+      struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[chan];
-+      struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan];
-       int ret = 0;
-       /* read the status register (CSR5) */
-       u32 intr_status = readl(ioaddr + DMA_STATUS);
-@@ -208,17 +211,20 @@ int dwmac_dma_interrupt(struct stmmac_priv *priv, void __iomem *ioaddr,
-       }
-       /* TX/RX NORMAL interrupts */
-       if (likely(intr_status & DMA_STATUS_NIS)) {
--              x->normal_irq_n++;
-               if (likely(intr_status & DMA_STATUS_RI)) {
-                       u32 value = readl(ioaddr + DMA_INTR_ENA);
-                       /* to schedule NAPI on real RIE event. */
-                       if (likely(value & DMA_INTR_ENA_RIE)) {
--                              x->rx_normal_irq_n++;
-+                              u64_stats_update_begin(&rx_q->rxq_stats.syncp);
-+                              rx_q->rxq_stats.rx_normal_irq_n++;
-+                              u64_stats_update_end(&rx_q->rxq_stats.syncp);
-                               ret |= handle_rx;
-                       }
-               }
-               if (likely(intr_status & DMA_STATUS_TI)) {
--                      x->tx_normal_irq_n++;
-+                      u64_stats_update_begin(&tx_q->txq_stats.syncp);
-+                      tx_q->txq_stats.tx_normal_irq_n++;
-+                      u64_stats_update_end(&tx_q->txq_stats.syncp);
-                       ret |= handle_tx;
-               }
-               if (unlikely(intr_status & DMA_STATUS_ERI))
-diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
-index 13c347ee8be9c..fc82862a612c7 100644
---- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c
-@@ -8,8 +8,7 @@
- #include "common.h"
- #include "dwxgmac2.h"
--static int dwxgmac2_get_tx_status(struct net_device_stats *stats,
--                                struct stmmac_extra_stats *x,
-+static int dwxgmac2_get_tx_status(struct stmmac_extra_stats *x,
-                                 struct dma_desc *p, void __iomem *ioaddr)
- {
-       unsigned int tdes3 = le32_to_cpu(p->des3);
-@@ -23,8 +22,7 @@ static int dwxgmac2_get_tx_status(struct net_device_stats *stats,
-       return ret;
- }
--static int dwxgmac2_get_rx_status(struct net_device_stats *stats,
--                                struct stmmac_extra_stats *x,
-+static int dwxgmac2_get_rx_status(struct stmmac_extra_stats *x,
-                                 struct dma_desc *p)
- {
-       unsigned int rdes3 = le32_to_cpu(p->des3);
-diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
-index 070bd912580b7..3b5f8c595219b 100644
---- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
-@@ -337,6 +337,8 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
-                                 struct stmmac_extra_stats *x, u32 chan,
-                                 u32 dir)
- {
-+      struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[chan];
-+      struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[chan];
-       u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan));
-       u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
-       int ret = 0;
-@@ -364,16 +366,16 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv,
-       /* TX/RX NORMAL interrupts */
-       if (likely(intr_status & XGMAC_NIS)) {
--              x->normal_irq_n++;
--
-               if (likely(intr_status & XGMAC_RI)) {
--                      x->rx_normal_irq_n++;
--                      x->rxq_stats[chan].rx_normal_irq_n++;
-+                      u64_stats_update_begin(&rx_q->rxq_stats.syncp);
-+                      rx_q->rxq_stats.rx_normal_irq_n++;
-+                      u64_stats_update_end(&rx_q->rxq_stats.syncp);
-                       ret |= handle_rx;
-               }
-               if (likely(intr_status & (XGMAC_TI | XGMAC_TBU))) {
--                      x->tx_normal_irq_n++;
--                      x->txq_stats[chan].tx_normal_irq_n++;
-+                      u64_stats_update_begin(&tx_q->txq_stats.syncp);
-+                      tx_q->txq_stats.tx_normal_irq_n++;
-+                      u64_stats_update_end(&tx_q->txq_stats.syncp);
-                       ret |= handle_tx;
-               }
-       }
-diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
-index a91d8f13a931d..937b7a0466fca 100644
---- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
-@@ -12,8 +12,7 @@
- #include "common.h"
- #include "descs_com.h"
--static int enh_desc_get_tx_status(struct net_device_stats *stats,
--                                struct stmmac_extra_stats *x,
-+static int enh_desc_get_tx_status(struct stmmac_extra_stats *x,
-                                 struct dma_desc *p, void __iomem *ioaddr)
- {
-       unsigned int tdes0 = le32_to_cpu(p->des0);
-@@ -38,15 +37,13 @@ static int enh_desc_get_tx_status(struct net_device_stats *stats,
-               if (unlikely(tdes0 & ETDES0_LOSS_CARRIER)) {
-                       x->tx_losscarrier++;
--                      stats->tx_carrier_errors++;
-               }
-               if (unlikely(tdes0 & ETDES0_NO_CARRIER)) {
-                       x->tx_carrier++;
--                      stats->tx_carrier_errors++;
-               }
-               if (unlikely((tdes0 & ETDES0_LATE_COLLISION) ||
-                            (tdes0 & ETDES0_EXCESSIVE_COLLISIONS)))
--                      stats->collisions +=
-+                      x->tx_collision +=
-                               (tdes0 & ETDES0_COLLISION_COUNT_MASK) >> 3;
-               if (unlikely(tdes0 & ETDES0_EXCESSIVE_DEFERRAL))
-@@ -117,8 +114,7 @@ static int enh_desc_coe_rdes0(int ipc_err, int type, int payload_err)
-       return ret;
- }
--static void enh_desc_get_ext_status(struct net_device_stats *stats,
--                                  struct stmmac_extra_stats *x,
-+static void enh_desc_get_ext_status(struct stmmac_extra_stats *x,
-                                   struct dma_extended_desc *p)
- {
-       unsigned int rdes0 = le32_to_cpu(p->basic.des0);
-@@ -182,8 +178,7 @@ static void enh_desc_get_ext_status(struct net_device_stats *stats,
-       }
- }
--static int enh_desc_get_rx_status(struct net_device_stats *stats,
--                                struct stmmac_extra_stats *x,
-+static int enh_desc_get_rx_status(struct stmmac_extra_stats *x,
-                                 struct dma_desc *p)
- {
-       unsigned int rdes0 = le32_to_cpu(p->des0);
-@@ -193,14 +188,14 @@ static int enh_desc_get_rx_status(struct net_device_stats *stats,
-               return dma_own;
-       if (unlikely(!(rdes0 & RDES0_LAST_DESCRIPTOR))) {
--              stats->rx_length_errors++;
-+              x->rx_length++;
-               return discard_frame;
-       }
-       if (unlikely(rdes0 & RDES0_ERROR_SUMMARY)) {
-               if (unlikely(rdes0 & RDES0_DESCRIPTOR_ERROR)) {
-                       x->rx_desc++;
--                      stats->rx_length_errors++;
-+                      x->rx_length++;
-               }
-               if (unlikely(rdes0 & RDES0_OVERFLOW_ERROR))
-                       x->rx_gmac_overflow++;
-@@ -209,7 +204,7 @@ static int enh_desc_get_rx_status(struct net_device_stats *stats,
-                       pr_err("\tIPC Csum Error/Giant frame\n");
-               if (unlikely(rdes0 & RDES0_COLLISION))
--                      stats->collisions++;
-+                      x->rx_collision++;
-               if (unlikely(rdes0 & RDES0_RECEIVE_WATCHDOG))
-                       x->rx_watchdog++;
-@@ -218,7 +213,6 @@ static int enh_desc_get_rx_status(struct net_device_stats *stats,
-               if (unlikely(rdes0 & RDES0_CRC_ERROR)) {
-                       x->rx_crc_errors++;
--                      stats->rx_crc_errors++;
-               }
-               ret = discard_frame;
-       }
-diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
-index 6ee7cf07cfd76..652af8f6e75ff 100644
---- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
-+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
-@@ -57,8 +57,7 @@ struct stmmac_desc_ops {
-       /* Last tx segment reports the transmit status */
-       int (*get_tx_ls)(struct dma_desc *p);
-       /* Return the transmit status looking at the TDES1 */
--      int (*tx_status)(struct net_device_stats *stats,
--                       struct stmmac_extra_stats *x,
-+      int (*tx_status)(struct stmmac_extra_stats *x,
-                        struct dma_desc *p, void __iomem *ioaddr);
-       /* Get the buffer size from the descriptor */
-       int (*get_tx_len)(struct dma_desc *p);
-@@ -67,11 +66,9 @@ struct stmmac_desc_ops {
-       /* Get the receive frame size */
-       int (*get_rx_frame_len)(struct dma_desc *p, int rx_coe_type);
-       /* Return the reception status looking at the RDES1 */
--      int (*rx_status)(struct net_device_stats *stats,
--                       struct stmmac_extra_stats *x,
-+      int (*rx_status)(struct stmmac_extra_stats *x,
-                        struct dma_desc *p);
--      void (*rx_extended_status)(struct net_device_stats *stats,
--                                 struct stmmac_extra_stats *x,
-+      void (*rx_extended_status)(struct stmmac_extra_stats *x,
-                                  struct dma_extended_desc *p);
-       /* Set tx timestamp enable bit */
-       void (*enable_tx_timestamp) (struct dma_desc *p);
-@@ -191,8 +188,7 @@ struct stmmac_dma_ops {
-       void (*dma_tx_mode)(struct stmmac_priv *priv, void __iomem *ioaddr,
-                           int mode, u32 channel, int fifosz, u8 qmode);
-       /* To track extra statistic (if supported) */
--      void (*dma_diagnostic_fr)(struct net_device_stats *stats,
--                                struct stmmac_extra_stats *x,
-+      void (*dma_diagnostic_fr)(struct stmmac_extra_stats *x,
-                                 void __iomem *ioaddr);
-       void (*enable_dma_transmission) (void __iomem *ioaddr);
-       void (*enable_dma_irq)(struct stmmac_priv *priv, void __iomem *ioaddr,
-diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
-index 350e6670a5766..68a7cfcb1d8f3 100644
---- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c
-@@ -12,8 +12,7 @@
- #include "common.h"
- #include "descs_com.h"
--static int ndesc_get_tx_status(struct net_device_stats *stats,
--                             struct stmmac_extra_stats *x,
-+static int ndesc_get_tx_status(struct stmmac_extra_stats *x,
-                              struct dma_desc *p, void __iomem *ioaddr)
- {
-       unsigned int tdes0 = le32_to_cpu(p->des0);
-@@ -31,15 +30,12 @@ static int ndesc_get_tx_status(struct net_device_stats *stats,
-       if (unlikely(tdes0 & TDES0_ERROR_SUMMARY)) {
-               if (unlikely(tdes0 & TDES0_UNDERFLOW_ERROR)) {
-                       x->tx_underflow++;
--                      stats->tx_fifo_errors++;
-               }
-               if (unlikely(tdes0 & TDES0_NO_CARRIER)) {
-                       x->tx_carrier++;
--                      stats->tx_carrier_errors++;
-               }
-               if (unlikely(tdes0 & TDES0_LOSS_CARRIER)) {
-                       x->tx_losscarrier++;
--                      stats->tx_carrier_errors++;
-               }
-               if (unlikely((tdes0 & TDES0_EXCESSIVE_DEFERRAL) ||
-                            (tdes0 & TDES0_EXCESSIVE_COLLISIONS) ||
-@@ -47,7 +43,7 @@ static int ndesc_get_tx_status(struct net_device_stats *stats,
-                       unsigned int collisions;
-                       collisions = (tdes0 & TDES0_COLLISION_COUNT_MASK) >> 3;
--                      stats->collisions += collisions;
-+                      x->tx_collision += collisions;
-               }
-               ret = tx_err;
-       }
-@@ -70,8 +66,7 @@ static int ndesc_get_tx_len(struct dma_desc *p)
-  * and, if required, updates the multicast statistics.
-  * In case of success, it returns good_frame because the GMAC device
-  * is supposed to be able to compute the csum in HW. */
--static int ndesc_get_rx_status(struct net_device_stats *stats,
--                             struct stmmac_extra_stats *x,
-+static int ndesc_get_rx_status(struct stmmac_extra_stats *x,
-                              struct dma_desc *p)
- {
-       int ret = good_frame;
-@@ -81,7 +76,7 @@ static int ndesc_get_rx_status(struct net_device_stats *stats,
-               return dma_own;
-       if (unlikely(!(rdes0 & RDES0_LAST_DESCRIPTOR))) {
--              stats->rx_length_errors++;
-+              x->rx_length++;
-               return discard_frame;
-       }
-@@ -96,11 +91,9 @@ static int ndesc_get_rx_status(struct net_device_stats *stats,
-                       x->ipc_csum_error++;
-               if (unlikely(rdes0 & RDES0_COLLISION)) {
-                       x->rx_collision++;
--                      stats->collisions++;
-               }
-               if (unlikely(rdes0 & RDES0_CRC_ERROR)) {
-                       x->rx_crc_errors++;
--                      stats->rx_crc_errors++;
-               }
-               ret = discard_frame;
-       }
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
-index 07ea5ab0a60ba..4ce5eaaae5135 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
-@@ -77,6 +77,7 @@ struct stmmac_tx_queue {
-       dma_addr_t dma_tx_phy;
-       dma_addr_t tx_tail_addr;
-       u32 mss;
-+      struct stmmac_txq_stats txq_stats;
- };
- struct stmmac_rx_buffer {
-@@ -121,6 +122,7 @@ struct stmmac_rx_queue {
-               unsigned int len;
-               unsigned int error;
-       } state;
-+      struct stmmac_rxq_stats rxq_stats;
- };
- struct stmmac_channel {
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
-index 2ae73ab842d45..b7ac7abecdd35 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
-@@ -89,14 +89,6 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
-       /* Tx/Rx IRQ Events */
-       STMMAC_STAT(rx_early_irq),
-       STMMAC_STAT(threshold),
--      STMMAC_STAT(tx_pkt_n),
--      STMMAC_STAT(rx_pkt_n),
--      STMMAC_STAT(normal_irq_n),
--      STMMAC_STAT(rx_normal_irq_n),
--      STMMAC_STAT(napi_poll),
--      STMMAC_STAT(tx_normal_irq_n),
--      STMMAC_STAT(tx_clean),
--      STMMAC_STAT(tx_set_ic_bit),
-       STMMAC_STAT(irq_receive_pmt_irq_n),
-       /* MMC info */
-       STMMAC_STAT(mmc_tx_irq_n),
-@@ -163,9 +155,6 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
-       STMMAC_STAT(mtl_rx_fifo_ctrl_active),
-       STMMAC_STAT(mac_rx_frame_ctrl_fifo),
-       STMMAC_STAT(mac_gmii_rx_proto_engine),
--      /* TSO */
--      STMMAC_STAT(tx_tso_frames),
--      STMMAC_STAT(tx_tso_nfrags),
-       /* EST */
-       STMMAC_STAT(mtl_est_cgce),
-       STMMAC_STAT(mtl_est_hlbs),
-@@ -175,6 +164,23 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = {
- };
- #define STMMAC_STATS_LEN ARRAY_SIZE(stmmac_gstrings_stats)
-+/* statistics collected in queue which will be summed up for all TX or RX
-+ * queues, or summed up for both TX and RX queues(napi_poll, normal_irq_n).
-+ */
-+static const char stmmac_qstats_string[][ETH_GSTRING_LEN] = {
-+      "rx_pkt_n",
-+      "rx_normal_irq_n",
-+      "tx_pkt_n",
-+      "tx_normal_irq_n",
-+      "tx_clean",
-+      "tx_set_ic_bit",
-+      "tx_tso_frames",
-+      "tx_tso_nfrags",
-+      "normal_irq_n",
-+      "napi_poll",
-+};
-+#define STMMAC_QSTATS ARRAY_SIZE(stmmac_qstats_string)
-+
- /* HW MAC Management counters (if supported) */
- #define STMMAC_MMC_STAT(m)    \
-       { #m, sizeof_field(struct stmmac_counters, m),  \
-@@ -535,23 +541,44 @@ static void stmmac_get_per_qstats(struct stmmac_priv *priv, u64 *data)
- {
-       u32 tx_cnt = priv->plat->tx_queues_to_use;
-       u32 rx_cnt = priv->plat->rx_queues_to_use;
-+      unsigned int start;
-       int q, stat;
-+      u64 *pos;
-       char *p;
-+      pos = data;
-       for (q = 0; q < tx_cnt; q++) {
--              p = (char *)priv + offsetof(struct stmmac_priv,
--                                          xstats.txq_stats[q].tx_pkt_n);
-+              struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[q];
-+              struct stmmac_txq_stats snapshot;
-+
-+              data = pos;
-+              do {
-+                      start = u64_stats_fetch_begin(&tx_q->txq_stats.syncp);
-+                      snapshot = tx_q->txq_stats;
-+              } while (u64_stats_fetch_retry(&tx_q->txq_stats.syncp, start));
-+
-+              p = (char *)&snapshot + offsetof(struct stmmac_txq_stats, tx_pkt_n);
-               for (stat = 0; stat < STMMAC_TXQ_STATS; stat++) {
--                      *data++ = (*(unsigned long *)p);
--                      p += sizeof(unsigned long);
-+                      *data++ += (*(u64 *)p);
-+                      p += sizeof(u64);
-               }
-       }
-+
-+      pos = data;
-       for (q = 0; q < rx_cnt; q++) {
--              p = (char *)priv + offsetof(struct stmmac_priv,
--                                          xstats.rxq_stats[q].rx_pkt_n);
-+              struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[q];
-+              struct stmmac_rxq_stats snapshot;
-+
-+              data = pos;
-+              do {
-+                      start = u64_stats_fetch_begin(&rx_q->rxq_stats.syncp);
-+                      snapshot = rx_q->rxq_stats;
-+              } while (u64_stats_fetch_retry(&rx_q->rxq_stats.syncp, start));
-+
-+              p = (char *)&snapshot + offsetof(struct stmmac_rxq_stats, rx_pkt_n);
-               for (stat = 0; stat < STMMAC_RXQ_STATS; stat++) {
--                      *data++ = (*(unsigned long *)p);
--                      p += sizeof(unsigned long);
-+                      *data++ += (*(u64 *)p);
-+                      p += sizeof(u64);
-               }
-       }
- }
-@@ -562,8 +589,10 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
-       struct stmmac_priv *priv = netdev_priv(dev);
-       u32 rx_queues_count = priv->plat->rx_queues_to_use;
-       u32 tx_queues_count = priv->plat->tx_queues_to_use;
-+      u64 napi_poll = 0, normal_irq_n = 0;
-+      int i, j = 0, pos, ret;
-       unsigned long count;
--      int i, j = 0, ret;
-+      unsigned int start;
-       if (priv->dma_cap.asp) {
-               for (i = 0; i < STMMAC_SAFETY_FEAT_SIZE; i++) {
-@@ -574,8 +603,7 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
-       }
-       /* Update the DMA HW counters for dwmac10/100 */
--      ret = stmmac_dma_diagnostic_fr(priv, &dev->stats, (void *) &priv->xstats,
--                      priv->ioaddr);
-+      ret = stmmac_dma_diagnostic_fr(priv, &priv->xstats, priv->ioaddr);
-       if (ret) {
-               /* If supported, for new GMAC chips expose the MMC counters */
-               if (priv->dma_cap.rmon) {
-@@ -606,6 +634,48 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
-               data[j++] = (stmmac_gstrings_stats[i].sizeof_stat ==
-                            sizeof(u64)) ? (*(u64 *)p) : (*(u32 *)p);
-       }
-+
-+      pos = j;
-+      for (i = 0; i < rx_queues_count; i++) {
-+              struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[i];
-+              struct stmmac_rxq_stats snapshot;
-+
-+              j = pos;
-+              do {
-+                      start = u64_stats_fetch_begin(&rx_q->rxq_stats.syncp);
-+                      snapshot = rx_q->rxq_stats;
-+              } while (u64_stats_fetch_retry(&rx_q->rxq_stats.syncp, start));
-+
-+              data[j++] += snapshot.rx_pkt_n;
-+              data[j++] += snapshot.rx_normal_irq_n;
-+              normal_irq_n += snapshot.rx_normal_irq_n;
-+              napi_poll += snapshot.napi_poll;
-+      }
-+
-+      pos = j;
-+      for (i = 0; i < tx_queues_count; i++) {
-+              struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[i];
-+              struct stmmac_txq_stats snapshot;
-+
-+              j = pos;
-+              do {
-+                      start = u64_stats_fetch_begin(&tx_q->txq_stats.syncp);
-+                      snapshot = tx_q->txq_stats;
-+              } while (u64_stats_fetch_retry(&tx_q->txq_stats.syncp, start));
-+
-+              data[j++] += snapshot.tx_pkt_n;
-+              data[j++] += snapshot.tx_normal_irq_n;
-+              normal_irq_n += snapshot.tx_normal_irq_n;
-+              data[j++] += snapshot.tx_clean;
-+              data[j++] += snapshot.tx_set_ic_bit;
-+              data[j++] += snapshot.tx_tso_frames;
-+              data[j++] += snapshot.tx_tso_nfrags;
-+              napi_poll += snapshot.napi_poll;
-+      }
-+      normal_irq_n += priv->xstats.rx_early_irq;
-+      data[j++] = normal_irq_n;
-+      data[j++] = napi_poll;
-+
-       stmmac_get_per_qstats(priv, &data[j]);
- }
-@@ -618,7 +688,7 @@ static int stmmac_get_sset_count(struct net_device *netdev, int sset)
-       switch (sset) {
-       case ETH_SS_STATS:
--              len = STMMAC_STATS_LEN +
-+              len = STMMAC_STATS_LEN + STMMAC_QSTATS +
-                     STMMAC_TXQ_STATS * tx_cnt +
-                     STMMAC_RXQ_STATS * rx_cnt;
-@@ -691,8 +761,11 @@ static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)
-                               p += ETH_GSTRING_LEN;
-                       }
-               for (i = 0; i < STMMAC_STATS_LEN; i++) {
--                      memcpy(p, stmmac_gstrings_stats[i].stat_string,
--                              ETH_GSTRING_LEN);
-+                      memcpy(p, stmmac_gstrings_stats[i].stat_string, ETH_GSTRING_LEN);
-+                      p += ETH_GSTRING_LEN;
-+              }
-+              for (i = 0; i < STMMAC_QSTATS; i++) {
-+                      memcpy(p, stmmac_qstats_string[i], ETH_GSTRING_LEN);
-                       p += ETH_GSTRING_LEN;
-               }
-               stmmac_get_qstats_string(priv, p);
-diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-index 6931973028aef..def490a1e2120 100644
---- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
-@@ -2432,6 +2432,8 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
-       struct dma_desc *tx_desc = NULL;
-       struct xdp_desc xdp_desc;
-       bool work_done = true;
-+      u32 tx_set_ic_bit = 0;
-+      unsigned long flags;
-       /* Avoids TX time-out as we are sharing with slow path */
-       txq_trans_cond_update(nq);
-@@ -2492,7 +2494,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
-               if (set_ic) {
-                       tx_q->tx_count_frames = 0;
-                       stmmac_set_tx_ic(priv, tx_desc);
--                      priv->xstats.tx_set_ic_bit++;
-+                      tx_set_ic_bit++;
-               }
-               stmmac_prepare_tx_desc(priv, tx_desc, 1, xdp_desc.len,
-@@ -2504,6 +2506,9 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
-               tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
-               entry = tx_q->cur_tx;
-       }
-+      flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp);
-+      tx_q->txq_stats.tx_set_ic_bit += tx_set_ic_bit;
-+      u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags);
-       if (tx_desc) {
-               stmmac_flush_tx_descriptors(priv, queue);
-@@ -2545,11 +2550,11 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
-       struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
-       unsigned int bytes_compl = 0, pkts_compl = 0;
-       unsigned int entry, xmits = 0, count = 0;
-+      u32 tx_packets = 0, tx_errors = 0;
-+      unsigned long flags;
-       __netif_tx_lock_bh(netdev_get_tx_queue(priv->dev, queue));
--      priv->xstats.tx_clean++;
--
-       tx_q->xsk_frames_done = 0;
-       entry = tx_q->dirty_tx;
-@@ -2580,8 +2585,7 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
-               else
-                       p = tx_q->dma_tx + entry;
--              status = stmmac_tx_status(priv, &priv->dev->stats,
--                              &priv->xstats, p, priv->ioaddr);
-+              status = stmmac_tx_status(priv, &priv->xstats, p, priv->ioaddr);
-               /* Check if the descriptor is owned by the DMA */
-               if (unlikely(status & tx_dma_own))
-                       break;
-@@ -2597,13 +2601,11 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
-               if (likely(!(status & tx_not_ls))) {
-                       /* ... verify the status error condition */
-                       if (unlikely(status & tx_err)) {
--                              priv->dev->stats.tx_errors++;
-+                              tx_errors++;
-                               if (unlikely(status & tx_err_bump_tc))
-                                       stmmac_bump_dma_threshold(priv, queue);
-                       } else {
--                              priv->dev->stats.tx_packets++;
--                              priv->xstats.tx_pkt_n++;
--                              priv->xstats.txq_stats[queue].tx_pkt_n++;
-+                              tx_packets++;
-                       }
-                       if (skb)
-                               stmmac_get_tx_hwtstamp(priv, p, skb);
-@@ -2705,6 +2707,14 @@ static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
-       if (tx_q->dirty_tx != tx_q->cur_tx)
-               stmmac_tx_timer_arm(priv, queue);
-+      flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp);
-+      tx_q->txq_stats.tx_packets += tx_packets;
-+      tx_q->txq_stats.tx_pkt_n += tx_packets;
-+      tx_q->txq_stats.tx_clean++;
-+      u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags);
-+
-+      priv->xstats.tx_errors += tx_errors;
-+
-       __netif_tx_unlock_bh(netdev_get_tx_queue(priv->dev, queue));
-       /* Combine decisions from TX clean and XSK TX */
-@@ -2732,7 +2742,7 @@ static void stmmac_tx_err(struct stmmac_priv *priv, u32 chan)
-                           tx_q->dma_tx_phy, chan);
-       stmmac_start_tx_dma(priv, chan);
--      priv->dev->stats.tx_errors++;
-+      priv->xstats.tx_errors++;
-       netif_tx_wake_queue(netdev_get_tx_queue(priv->dev, chan));
- }
-@@ -4112,6 +4122,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
-       struct stmmac_tx_queue *tx_q;
-       bool has_vlan, set_ic;
-       u8 proto_hdr_len, hdr;
-+      unsigned long flags;
-       u32 pay_len, mss;
-       dma_addr_t des;
-       int i;
-@@ -4260,7 +4271,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
-               tx_q->tx_count_frames = 0;
-               stmmac_set_tx_ic(priv, desc);
--              priv->xstats.tx_set_ic_bit++;
-       }
-       /* We've used all descriptors we need for this skb, however,
-@@ -4276,9 +4286,13 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
-               netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue));
-       }
--      dev->stats.tx_bytes += skb->len;
--      priv->xstats.tx_tso_frames++;
--      priv->xstats.tx_tso_nfrags += nfrags;
-+      flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp);
-+      tx_q->txq_stats.tx_bytes += skb->len;
-+      tx_q->txq_stats.tx_tso_frames++;
-+      tx_q->txq_stats.tx_tso_nfrags += nfrags;
-+      if (set_ic)
-+              tx_q->txq_stats.tx_set_ic_bit++;
-+      u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags);
-       if (priv->sarc_type)
-               stmmac_set_desc_sarc(priv, first, priv->sarc_type);
-@@ -4328,7 +4342,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
- dma_map_err:
-       dev_err(priv->device, "Tx dma map failed\n");
-       dev_kfree_skb(skb);
--      priv->dev->stats.tx_dropped++;
-+      priv->xstats.tx_dropped++;
-       return NETDEV_TX_OK;
- }
-@@ -4354,6 +4368,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
-       struct stmmac_tx_queue *tx_q;
-       bool has_vlan, set_ic;
-       int entry, first_tx;
-+      unsigned long flags;
-       dma_addr_t des;
-       tx_q = &priv->dma_conf.tx_queue[queue];
-@@ -4482,7 +4497,6 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
-               tx_q->tx_count_frames = 0;
-               stmmac_set_tx_ic(priv, desc);
--              priv->xstats.tx_set_ic_bit++;
-       }
-       /* We've used all descriptors we need for this skb, however,
-@@ -4509,7 +4523,11 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
-               netif_tx_stop_queue(netdev_get_tx_queue(priv->dev, queue));
-       }
--      dev->stats.tx_bytes += skb->len;
-+      flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp);
-+      tx_q->txq_stats.tx_bytes += skb->len;
-+      if (set_ic)
-+              tx_q->txq_stats.tx_set_ic_bit++;
-+      u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags);
-       if (priv->sarc_type)
-               stmmac_set_desc_sarc(priv, first, priv->sarc_type);
-@@ -4571,7 +4589,7 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
- dma_map_err:
-       netdev_err(priv->dev, "Tx DMA map failed\n");
-       dev_kfree_skb(skb);
--      priv->dev->stats.tx_dropped++;
-+      priv->xstats.tx_dropped++;
-       return NETDEV_TX_OK;
- }
-@@ -4772,9 +4790,12 @@ static int stmmac_xdp_xmit_xdpf(struct stmmac_priv *priv, int queue,
-               set_ic = false;
-       if (set_ic) {
-+              unsigned long flags;
-               tx_q->tx_count_frames = 0;
-               stmmac_set_tx_ic(priv, tx_desc);
--              priv->xstats.tx_set_ic_bit++;
-+              flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp);
-+              tx_q->txq_stats.tx_set_ic_bit++;
-+              u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags);
-       }
-       stmmac_enable_dma_transmission(priv, priv->ioaddr);
-@@ -4919,16 +4940,18 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue,
-                                  struct dma_desc *p, struct dma_desc *np,
-                                  struct xdp_buff *xdp)
- {
-+      struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
-       struct stmmac_channel *ch = &priv->channel[queue];
-       unsigned int len = xdp->data_end - xdp->data;
-       enum pkt_hash_types hash_type;
-       int coe = priv->hw->rx_csum;
-+      unsigned long flags;
-       struct sk_buff *skb;
-       u32 hash;
-       skb = stmmac_construct_skb_zc(ch, xdp);
-       if (!skb) {
--              priv->dev->stats.rx_dropped++;
-+              priv->xstats.rx_dropped++;
-               return;
-       }
-@@ -4947,8 +4970,10 @@ static void stmmac_dispatch_skb_zc(struct stmmac_priv *priv, u32 queue,
-       skb_record_rx_queue(skb, queue);
-       napi_gro_receive(&ch->rxtx_napi, skb);
--      priv->dev->stats.rx_packets++;
--      priv->dev->stats.rx_bytes += len;
-+      flags = u64_stats_update_begin_irqsave(&rx_q->rxq_stats.syncp);
-+      rx_q->rxq_stats.rx_pkt_n++;
-+      rx_q->rxq_stats.rx_bytes += len;
-+      u64_stats_update_end_irqrestore(&rx_q->rxq_stats.syncp, flags);
- }
- static bool stmmac_rx_refill_zc(struct stmmac_priv *priv, u32 queue, u32 budget)
-@@ -5025,9 +5050,11 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
-       unsigned int count = 0, error = 0, len = 0;
-       int dirty = stmmac_rx_dirty(priv, queue);
-       unsigned int next_entry = rx_q->cur_rx;
-+      u32 rx_errors = 0, rx_dropped = 0;
-       unsigned int desc_size;
-       struct bpf_prog *prog;
-       bool failure = false;
-+      unsigned long flags;
-       int xdp_status = 0;
-       int status = 0;
-@@ -5083,8 +5110,7 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
-                       p = rx_q->dma_rx + entry;
-               /* read the status of the incoming frame */
--              status = stmmac_rx_status(priv, &priv->dev->stats,
--                                        &priv->xstats, p);
-+              status = stmmac_rx_status(priv, &priv->xstats, p);
-               /* check if managed by the DMA otherwise go ahead */
-               if (unlikely(status & dma_own))
-                       break;
-@@ -5106,8 +5132,7 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
-                       break;
-               if (priv->extend_desc)
--                      stmmac_rx_extended_status(priv, &priv->dev->stats,
--                                                &priv->xstats,
-+                      stmmac_rx_extended_status(priv, &priv->xstats,
-                                                 rx_q->dma_erx + entry);
-               if (unlikely(status == discard_frame)) {
-                       xsk_buff_free(buf->xdp);
-@@ -5115,7 +5140,7 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
-                       dirty++;
-                       error = 1;
-                       if (!priv->hwts_rx_en)
--                              priv->dev->stats.rx_errors++;
-+                              rx_errors++;
-               }
-               if (unlikely(error && (status & rx_not_ls)))
-@@ -5163,7 +5188,7 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
-                       break;
-               case STMMAC_XDP_CONSUMED:
-                       xsk_buff_free(buf->xdp);
--                      priv->dev->stats.rx_dropped++;
-+                      rx_dropped++;
-                       break;
-               case STMMAC_XDP_TX:
-               case STMMAC_XDP_REDIRECT:
-@@ -5184,8 +5209,12 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
-       stmmac_finalize_xdp_rx(priv, xdp_status);
--      priv->xstats.rx_pkt_n += count;
--      priv->xstats.rxq_stats[queue].rx_pkt_n += count;
-+      flags = u64_stats_update_begin_irqsave(&rx_q->rxq_stats.syncp);
-+      rx_q->rxq_stats.rx_pkt_n += count;
-+      u64_stats_update_end_irqrestore(&rx_q->rxq_stats.syncp, flags);
-+
-+      priv->xstats.rx_dropped += rx_dropped;
-+      priv->xstats.rx_errors += rx_errors;
-       if (xsk_uses_need_wakeup(rx_q->xsk_pool)) {
-               if (failure || stmmac_rx_dirty(priv, queue) > 0)
-@@ -5209,6 +5238,7 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue)
-  */
- static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
- {
-+      u32 rx_errors = 0, rx_dropped = 0, rx_bytes = 0, rx_packets = 0;
-       struct stmmac_rx_queue *rx_q = &priv->dma_conf.rx_queue[queue];
-       struct stmmac_channel *ch = &priv->channel[queue];
-       unsigned int count = 0, error = 0, len = 0;
-@@ -5218,6 +5248,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
-       unsigned int desc_size;
-       struct sk_buff *skb = NULL;
-       struct stmmac_xdp_buff ctx;
-+      unsigned long flags;
-       int xdp_status = 0;
-       int buf_sz;
-@@ -5273,8 +5304,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
-                       p = rx_q->dma_rx + entry;
-               /* read the status of the incoming frame */
--              status = stmmac_rx_status(priv, &priv->dev->stats,
--                              &priv->xstats, p);
-+              status = stmmac_rx_status(priv, &priv->xstats, p);
-               /* check if managed by the DMA otherwise go ahead */
-               if (unlikely(status & dma_own))
-                       break;
-@@ -5291,14 +5321,13 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
-               prefetch(np);
-               if (priv->extend_desc)
--                      stmmac_rx_extended_status(priv, &priv->dev->stats,
--                                      &priv->xstats, rx_q->dma_erx + entry);
-+                      stmmac_rx_extended_status(priv, &priv->xstats, rx_q->dma_erx + entry);
-               if (unlikely(status == discard_frame)) {
-                       page_pool_recycle_direct(rx_q->page_pool, buf->page);
-                       buf->page = NULL;
-                       error = 1;
-                       if (!priv->hwts_rx_en)
--                              priv->dev->stats.rx_errors++;
-+                              rx_errors++;
-               }
-               if (unlikely(error && (status & rx_not_ls)))
-@@ -5366,7 +5395,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
-                                                          virt_to_head_page(ctx.xdp.data),
-                                                          sync_len, true);
-                                       buf->page = NULL;
--                                      priv->dev->stats.rx_dropped++;
-+                                      rx_dropped++;
-                                       /* Clear skb as it was set as
-                                        * status by XDP program.
-@@ -5395,7 +5424,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
-                       skb = napi_alloc_skb(&ch->rx_napi, buf1_len);
-                       if (!skb) {
--                              priv->dev->stats.rx_dropped++;
-+                              rx_dropped++;
-                               count++;
-                               goto drain_data;
-                       }
-@@ -5455,8 +5484,8 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
-               napi_gro_receive(&ch->rx_napi, skb);
-               skb = NULL;
--              priv->dev->stats.rx_packets++;
--              priv->dev->stats.rx_bytes += len;
-+              rx_packets++;
-+              rx_bytes += len;
-               count++;
-       }
-@@ -5471,8 +5500,14 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
-       stmmac_rx_refill(priv, queue);
--      priv->xstats.rx_pkt_n += count;
--      priv->xstats.rxq_stats[queue].rx_pkt_n += count;
-+      flags = u64_stats_update_begin_irqsave(&rx_q->rxq_stats.syncp);
-+      rx_q->rxq_stats.rx_packets += rx_packets;
-+      rx_q->rxq_stats.rx_bytes += rx_bytes;
-+      rx_q->rxq_stats.rx_pkt_n += count;
-+      u64_stats_update_end_irqrestore(&rx_q->rxq_stats.syncp, flags);
-+
-+      priv->xstats.rx_dropped += rx_dropped;
-+      priv->xstats.rx_errors += rx_errors;
-       return count;
- }
-@@ -5482,10 +5517,15 @@ static int stmmac_napi_poll_rx(struct napi_struct *napi, int budget)
-       struct stmmac_channel *ch =
-               container_of(napi, struct stmmac_channel, rx_napi);
-       struct stmmac_priv *priv = ch->priv_data;
-+      struct stmmac_rx_queue *rx_q;
-       u32 chan = ch->index;
-+      unsigned long flags;
-       int work_done;
--      priv->xstats.napi_poll++;
-+      rx_q = &priv->dma_conf.rx_queue[chan];
-+      flags = u64_stats_update_begin_irqsave(&rx_q->rxq_stats.syncp);
-+      rx_q->rxq_stats.napi_poll++;
-+      u64_stats_update_end_irqrestore(&rx_q->rxq_stats.syncp, flags);
-       work_done = stmmac_rx(priv, budget, chan);
-       if (work_done < budget && napi_complete_done(napi, work_done)) {
-@@ -5504,10 +5544,15 @@ static int stmmac_napi_poll_tx(struct napi_struct *napi, int budget)
-       struct stmmac_channel *ch =
-               container_of(napi, struct stmmac_channel, tx_napi);
-       struct stmmac_priv *priv = ch->priv_data;
-+      struct stmmac_tx_queue *tx_q;
-       u32 chan = ch->index;
-+      unsigned long flags;
-       int work_done;
--      priv->xstats.napi_poll++;
-+      tx_q = &priv->dma_conf.tx_queue[chan];
-+      flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp);
-+      tx_q->txq_stats.napi_poll++;
-+      u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags);
-       work_done = stmmac_tx_clean(priv, budget, chan);
-       work_done = min(work_done, budget);
-@@ -5529,9 +5574,20 @@ static int stmmac_napi_poll_rxtx(struct napi_struct *napi, int budget)
-               container_of(napi, struct stmmac_channel, rxtx_napi);
-       struct stmmac_priv *priv = ch->priv_data;
-       int rx_done, tx_done, rxtx_done;
-+      struct stmmac_rx_queue *rx_q;
-+      struct stmmac_tx_queue *tx_q;
-       u32 chan = ch->index;
-+      unsigned long flags;
-+
-+      rx_q = &priv->dma_conf.rx_queue[chan];
-+      flags = u64_stats_update_begin_irqsave(&rx_q->rxq_stats.syncp);
-+      rx_q->rxq_stats.napi_poll++;
-+      u64_stats_update_end_irqrestore(&rx_q->rxq_stats.syncp, flags);
--      priv->xstats.napi_poll++;
-+      tx_q = &priv->dma_conf.tx_queue[chan];
-+      flags = u64_stats_update_begin_irqsave(&tx_q->txq_stats.syncp);
-+      tx_q->txq_stats.napi_poll++;
-+      u64_stats_update_end_irqrestore(&tx_q->txq_stats.syncp, flags);
-       tx_done = stmmac_tx_clean(priv, budget, chan);
-       tx_done = min(tx_done, budget);
-@@ -6790,6 +6846,56 @@ int stmmac_xsk_wakeup(struct net_device *dev, u32 queue, u32 flags)
-       return 0;
- }
-+static void stmmac_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
-+{
-+      struct stmmac_priv *priv = netdev_priv(dev);
-+      u32 tx_cnt = priv->plat->tx_queues_to_use;
-+      u32 rx_cnt = priv->plat->rx_queues_to_use;
-+      unsigned int start;
-+      int q;
-+
-+      for (q = 0; q < tx_cnt; q++) {
-+              struct stmmac_txq_stats *txq_stats = &priv->dma_conf.tx_queue[q].txq_stats;
-+              u64 tx_packets;
-+              u64 tx_bytes;
-+
-+              do {
-+                      start = u64_stats_fetch_begin(&txq_stats->syncp);
-+                      tx_packets = txq_stats->tx_packets;
-+                      tx_bytes   = txq_stats->tx_bytes;
-+              } while (u64_stats_fetch_retry(&txq_stats->syncp, start));
-+
-+              stats->tx_packets += tx_packets;
-+              stats->tx_bytes += tx_bytes;
-+      }
-+
-+      for (q = 0; q < rx_cnt; q++) {
-+              struct stmmac_rxq_stats *rxq_stats = &priv->dma_conf.rx_queue[q].rxq_stats;
-+              u64 rx_packets;
-+              u64 rx_bytes;
-+
-+              do {
-+                      start = u64_stats_fetch_begin(&rxq_stats->syncp);
-+                      rx_packets = rxq_stats->rx_packets;
-+                      rx_bytes   = rxq_stats->rx_bytes;
-+              } while (u64_stats_fetch_retry(&rxq_stats->syncp, start));
-+
-+              stats->rx_packets += rx_packets;
-+              stats->rx_bytes += rx_bytes;
-+      }
-+
-+      stats->rx_dropped = priv->xstats.rx_dropped;
-+      stats->rx_errors = priv->xstats.rx_errors;
-+      stats->tx_dropped = priv->xstats.tx_dropped;
-+      stats->tx_errors = priv->xstats.tx_errors;
-+      stats->tx_carrier_errors = priv->xstats.tx_losscarrier + priv->xstats.tx_carrier;
-+      stats->collisions = priv->xstats.tx_collision + priv->xstats.rx_collision;
-+      stats->rx_length_errors = priv->xstats.rx_length;
-+      stats->rx_crc_errors = priv->xstats.rx_crc_errors;
-+      stats->rx_over_errors = priv->xstats.rx_overflow_cntr;
-+      stats->rx_missed_errors = priv->xstats.rx_missed_cntr;
-+}
-+
- static const struct net_device_ops stmmac_netdev_ops = {
-       .ndo_open = stmmac_open,
-       .ndo_start_xmit = stmmac_xmit,
-@@ -6800,6 +6906,7 @@ static const struct net_device_ops stmmac_netdev_ops = {
-       .ndo_set_rx_mode = stmmac_set_rx_mode,
-       .ndo_tx_timeout = stmmac_tx_timeout,
-       .ndo_eth_ioctl = stmmac_ioctl,
-+      .ndo_get_stats64 = stmmac_get_stats64,
-       .ndo_setup_tc = stmmac_setup_tc,
-       .ndo_select_queue = stmmac_select_queue,
- #ifdef CONFIG_NET_POLL_CONTROLLER
-@@ -7162,6 +7269,11 @@ int stmmac_dvr_probe(struct device *device,
-       priv->device = device;
-       priv->dev = ndev;
-+      for (i = 0; i < MTL_MAX_RX_QUEUES; i++)
-+              u64_stats_init(&priv->dma_conf.rx_queue[i].rxq_stats.syncp);
-+      for (i = 0; i < MTL_MAX_TX_QUEUES; i++)
-+              u64_stats_init(&priv->dma_conf.tx_queue[i].txq_stats.syncp);
-+
-       stmmac_set_ethtool_ops(ndev);
-       priv->pause = pause;
-       priv->plat = plat_dat;
--- 
-2.40.1
-
index 90bf1dbb1723247ef79819b51be694b917f3589e..f7b56f508dea8f2895a05048d2957ba1339b1a0c 100644 (file)
@@ -22,7 +22,6 @@ selftests-nolibc-prevent-out-of-bounds-access-in-exp.patch
 spi-sun6i-add-quirk-for-dual-and-quad-spi-modes-supp.patch
 devlink-remove-reload-failed-checks-in-params-get-se.patch
 crypto-lrw-xts-replace-strlcpy-with-strscpy.patch
-net-stmmac-use-per-queue-64-bit-statistics-where-nec.patch
 ice-don-t-tx-before-switchdev-is-fully-configured.patch
 wifi-ath9k-fix-fortify-warnings.patch
 wifi-ath9k-fix-printk-specifier.patch
@@ -155,7 +154,6 @@ x86-sched-restore-the-sd_asym_packing-flag-in-the-di.patch
 scsi-target-core-fix-target_cmd_counter-leak.patch
 scsi-lpfc-fix-the-null-vs-is_err-bug-for-debugfs_cre.patch
 panic-reenable-preemption-in-warn-slowpath.patch
-ata-libata-remove-references-to-non-existing-error_h.patch
 ata-libata-core-fetch-sense-data-for-successful-comm.patch
 x86-boot-compressed-reserve-more-memory-for-page-tab.patch
 x86-purgatory-remove-lto-flags.patch