enum mlx5e_dma_map_type type;
 };
 
+/* Keep this enum consistent with with the corresponding strings array
+ * declared in en/reporter_tx.c
+ */
 enum {
-       MLX5E_SQ_STATE_ENABLED,
+       MLX5E_SQ_STATE_ENABLED = 0,
        MLX5E_SQ_STATE_MPWQE,
        MLX5E_SQ_STATE_RECOVERING,
        MLX5E_SQ_STATE_IPSEC,
        MLX5E_SQ_STATE_PENDING_XSK_TX,
        MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC,
        MLX5E_SQ_STATE_XDP_MULTIBUF,
+       MLX5E_NUM_SQ_STATES, /* Must be kept last */
 };
 
 struct mlx5e_tx_mpwqe {
 
 #include "en/devlink.h"
 #include "lib/tout.h"
 
+/* Keep this string array consistent with the MLX5E_SQ_STATE_* enums in en.h */
+static const char * const sq_sw_state_type_name[] = {
+       [MLX5E_SQ_STATE_ENABLED] = "enabled",
+       [MLX5E_SQ_STATE_MPWQE] = "mpwqe",
+       [MLX5E_SQ_STATE_RECOVERING] = "recovering",
+       [MLX5E_SQ_STATE_IPSEC] = "ipsec",
+       [MLX5E_SQ_STATE_DIM] = "dim",
+       [MLX5E_SQ_STATE_VLAN_NEED_L2_INLINE] = "vlan_need_l2_inline",
+       [MLX5E_SQ_STATE_PENDING_XSK_TX] = "pending_xsk_tx",
+       [MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC] = "pending_tls_rx_resync",
+       [MLX5E_SQ_STATE_XDP_MULTIBUF] = "xdp_multibuf",
+};
+
 static int mlx5e_wait_for_sq_flush(struct mlx5e_txqsq *sq)
 {
        struct mlx5_core_dev *dev = sq->mdev;
        sq->pc = 0;
 }
 
+static int mlx5e_health_sq_put_sw_state(struct devlink_fmsg *fmsg, struct mlx5e_txqsq *sq)
+{
+       int err;
+       int i;
+
+       BUILD_BUG_ON_MSG(ARRAY_SIZE(sq_sw_state_type_name) != MLX5E_NUM_SQ_STATES,
+                        "sq_sw_state_type_name string array must be consistent with MLX5E_SQ_STATE_* enum in en.h");
+       err = devlink_fmsg_obj_nest_start(fmsg);
+       if (err)
+               return err;
+
+       err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "SW State");
+       if (err)
+               return err;
+
+       for (i = 0; i < ARRAY_SIZE(sq_sw_state_type_name); ++i) {
+               err = devlink_fmsg_u32_pair_put(fmsg, sq_sw_state_type_name[i],
+                                               test_bit(i, &sq->state));
+               if (err)
+                       return err;
+       }
+
+       err = mlx5e_health_fmsg_named_obj_nest_end(fmsg);
+       if (err)
+               return err;
+
+       return devlink_fmsg_obj_nest_end(fmsg);
+}
+
 static int mlx5e_tx_reporter_err_cqe_recover(void *ctx)
 {
        struct mlx5_core_dev *mdev;
        if (err)
                return err;
 
+       err = mlx5e_health_sq_put_sw_state(fmsg, sq);
+       if (err)
+               return err;
+
        err = mlx5e_health_cq_diag_fmsg(&sq->cq, fmsg);
        if (err)
                return err;