enum mlxsw_reg_ppcnt_grp {
        MLXSW_REG_PPCNT_IEEE_8023_CNT = 0x0,
        MLXSW_REG_PPCNT_PRIO_CNT = 0x10,
+       MLXSW_REG_PPCNT_TC_CNT = 0x11,
 };
 
 /* reg_ppcnt_grp
  */
 MLXSW_ITEM64(reg, ppcnt, tx_pause_transition, 0x08 + 0x70, 0, 64);
 
+/* Ethernet Per Traffic Group Counters */
+
+/* reg_ppcnt_tc_transmit_queue
+ * Contains the transmit queue depth in cells of traffic class
+ * selected by prio_tc and the port selected by local_port.
+ * The field cannot be cleared.
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, tc_transmit_queue, 0x08 + 0x00, 0, 64);
+
+/* reg_ppcnt_tc_no_buffer_discard_uc
+ * The number of unicast packets dropped due to lack of shared
+ * buffer resources.
+ * Access: RO
+ */
+MLXSW_ITEM64(reg, ppcnt, tc_no_buffer_discard_uc, 0x08 + 0x08, 0, 64);
+
 static inline void mlxsw_reg_ppcnt_pack(char *payload, u8 local_port,
                                        enum mlxsw_reg_ppcnt_grp grp,
                                        u8 prio_tc)
 
 
 #define MLXSW_SP_PORT_HW_PRIO_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_prio_stats)
 
+static u64 mlxsw_reg_ppcnt_tc_transmit_queue_bytes_get(char *ppcnt_pl)
+{
+       u64 transmit_queue = mlxsw_reg_ppcnt_tc_transmit_queue_get(ppcnt_pl);
+
+       return MLXSW_SP_CELLS_TO_BYTES(transmit_queue);
+}
+
+static struct mlxsw_sp_port_hw_stats mlxsw_sp_port_hw_tc_stats[] = {
+       {
+               .str = "tc_transmit_queue_tc",
+               .getter = mlxsw_reg_ppcnt_tc_transmit_queue_bytes_get,
+       },
+       {
+               .str = "tc_no_buffer_discard_uc_tc",
+               .getter = mlxsw_reg_ppcnt_tc_no_buffer_discard_uc_get,
+       },
+};
+
+#define MLXSW_SP_PORT_HW_TC_STATS_LEN ARRAY_SIZE(mlxsw_sp_port_hw_tc_stats)
+
 #define MLXSW_SP_PORT_ETHTOOL_STATS_LEN (MLXSW_SP_PORT_HW_STATS_LEN + \
-                                        MLXSW_SP_PORT_HW_PRIO_STATS_LEN * \
+                                        (MLXSW_SP_PORT_HW_PRIO_STATS_LEN + \
+                                         MLXSW_SP_PORT_HW_TC_STATS_LEN) * \
                                         IEEE_8021QAZ_MAX_TCS)
 
 static void mlxsw_sp_port_get_prio_strings(u8 **p, int prio)
        }
 }
 
+static void mlxsw_sp_port_get_tc_strings(u8 **p, int tc)
+{
+       int i;
+
+       for (i = 0; i < MLXSW_SP_PORT_HW_TC_STATS_LEN; i++) {
+               snprintf(*p, ETH_GSTRING_LEN, "%s_%d",
+                        mlxsw_sp_port_hw_tc_stats[i].str, tc);
+               *p += ETH_GSTRING_LEN;
+       }
+}
+
 static void mlxsw_sp_port_get_strings(struct net_device *dev,
                                      u32 stringset, u8 *data)
 {
                for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
                        mlxsw_sp_port_get_prio_strings(&p, i);
 
+               for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
+                       mlxsw_sp_port_get_tc_strings(&p, i);
+
                break;
        }
 }
                *p_hw_stats = mlxsw_sp_port_hw_prio_stats;
                *p_len = MLXSW_SP_PORT_HW_PRIO_STATS_LEN;
                break;
+       case MLXSW_REG_PPCNT_TC_CNT:
+               *p_hw_stats = mlxsw_sp_port_hw_tc_stats;
+               *p_len = MLXSW_SP_PORT_HW_TC_STATS_LEN;
+               break;
        default:
                WARN_ON(1);
                return -ENOTSUPP;
                                          data, data_index);
                data_index += MLXSW_SP_PORT_HW_PRIO_STATS_LEN;
        }
+
+       /* Per-TC Counters */
+       for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
+               __mlxsw_sp_port_get_stats(dev, MLXSW_REG_PPCNT_TC_CNT, i,
+                                         data, data_index);
+               data_index += MLXSW_SP_PORT_HW_TC_STATS_LEN;
+       }
 }
 
 static int mlxsw_sp_port_get_sset_count(struct net_device *dev, int sset)