return n;
 }
 
+static size_t efx_describe_per_queue_stats(struct efx_nic *efx, u8 *strings)
+{
+       size_t n_stats = 0;
+       struct efx_channel *channel;
+
+       efx_for_each_channel(channel, efx) {
+               if (efx_channel_has_tx_queues(channel)) {
+                       n_stats++;
+                       if (strings != NULL) {
+                               snprintf(strings, ETH_GSTRING_LEN,
+                                        "tx-%u.tx_packets",
+                                        channel->tx_queue[0].queue /
+                                        EFX_TXQ_TYPES);
+
+                               strings += ETH_GSTRING_LEN;
+                       }
+               }
+       }
+       efx_for_each_channel(channel, efx) {
+               if (efx_channel_has_rx_queue(channel)) {
+                       n_stats++;
+                       if (strings != NULL) {
+                               snprintf(strings, ETH_GSTRING_LEN,
+                                        "rx-%d.rx_packets", channel->channel);
+                               strings += ETH_GSTRING_LEN;
+                       }
+               }
+       }
+       return n_stats;
+}
+
 static int efx_ethtool_get_sset_count(struct net_device *net_dev,
                                      int string_set)
 {
        switch (string_set) {
        case ETH_SS_STATS:
                return efx->type->describe_stats(efx, NULL) +
-                       EFX_ETHTOOL_SW_STAT_COUNT +
-                       efx_ptp_describe_stats(efx, NULL);
+                      EFX_ETHTOOL_SW_STAT_COUNT +
+                      efx_describe_per_queue_stats(efx, NULL) +
+                      efx_ptp_describe_stats(efx, NULL);
        case ETH_SS_TEST:
                return efx_ethtool_fill_self_tests(efx, NULL, NULL, NULL);
        default:
                        strlcpy(strings + i * ETH_GSTRING_LEN,
                                efx_sw_stat_desc[i].name, ETH_GSTRING_LEN);
                strings += EFX_ETHTOOL_SW_STAT_COUNT * ETH_GSTRING_LEN;
+               strings += (efx_describe_per_queue_stats(efx, strings) *
+                           ETH_GSTRING_LEN);
                efx_ptp_describe_stats(efx, strings);
                break;
        case ETH_SS_TEST:
        const struct efx_sw_stat_desc *stat;
        struct efx_channel *channel;
        struct efx_tx_queue *tx_queue;
+       struct efx_rx_queue *rx_queue;
        int i;
 
        spin_lock_bh(&efx->stats_lock);
 
        spin_unlock_bh(&efx->stats_lock);
 
+       efx_for_each_channel(channel, efx) {
+               if (efx_channel_has_tx_queues(channel)) {
+                       *data = 0;
+                       efx_for_each_channel_tx_queue(tx_queue, channel) {
+                               *data += tx_queue->tx_packets;
+                       }
+                       data++;
+               }
+       }
+       efx_for_each_channel(channel, efx) {
+               if (efx_channel_has_rx_queue(channel)) {
+                       *data = 0;
+                       efx_for_each_channel_rx_queue(rx_queue, channel) {
+                               *data += rx_queue->rx_packets;
+                       }
+                       data++;
+               }
+       }
+
        efx_ptp_update_stats(efx, data);
 }
 
 
        unsigned int tso_packets;
        unsigned int pushes;
        unsigned int pio_packets;
+       /* Statistics to supplement MAC stats */
+       unsigned long tx_packets;
 
        /* Members shared between paths and sometimes updated */
        unsigned int empty_read_count ____cacheline_aligned_in_smp;
        unsigned int recycle_count;
        struct timer_list slow_fill;
        unsigned int slow_fill_count;
+       /* Statistics to supplement MAC stats */
+       unsigned long rx_packets;
 };
 
 enum efx_sync_events_state {