static int bnxt_hwrm_port_qstats_ext(struct bnxt *bp)
 {
        struct hwrm_port_qstats_ext_output *resp = bp->hwrm_cmd_resp_addr;
+       struct hwrm_queue_pri2cos_qcfg_input req2 = {0};
        struct hwrm_port_qstats_ext_input req = {0};
        struct bnxt_pf_info *pf = &bp->pf;
        int rc;
                bp->fw_rx_stats_ext_size = 0;
                bp->fw_tx_stats_ext_size = 0;
        }
+       if (bp->fw_tx_stats_ext_size <=
+           offsetof(struct tx_port_stats_ext, pfc_pri0_tx_duration_us) / 8) {
+               mutex_unlock(&bp->hwrm_cmd_lock);
+               bp->pri2cos_valid = 0;
+               return rc;
+       }
+
+       bnxt_hwrm_cmd_hdr_init(bp, &req2, HWRM_QUEUE_PRI2COS_QCFG, -1, -1);
+       req2.flags = cpu_to_le32(QUEUE_PRI2COS_QCFG_REQ_FLAGS_IVLAN);
+
+       rc = _hwrm_send_message(bp, &req2, sizeof(req2), HWRM_CMD_TIMEOUT);
+       if (!rc) {
+               struct hwrm_queue_pri2cos_qcfg_output *resp2;
+               u8 *pri2cos;
+               int i, j;
+
+               resp2 = bp->hwrm_cmd_resp_addr;
+               pri2cos = &resp2->pri0_cos_queue_id;
+               for (i = 0; i < 8; i++) {
+                       u8 queue_id = pri2cos[i];
+
+                       for (j = 0; j < bp->max_q; j++) {
+                               if (bp->q_ids[j] == queue_id)
+                                       bp->pri2cos[i] = j;
+                       }
+               }
+               bp->pri2cos_valid = 1;
+       }
        mutex_unlock(&bp->hwrm_cmd_lock);
        return rc;
 }
 
        BNXT_TX_STATS_EXT_COS_ENTRY(6),                         \
        BNXT_TX_STATS_EXT_COS_ENTRY(7)                          \
 
+#define BNXT_RX_STATS_PRI_ENTRY(counter, n)            \
+       { BNXT_RX_STATS_EXT_OFFSET(counter##_cos0),     \
+         __stringify(counter##_pri##n) }
+
+#define BNXT_TX_STATS_PRI_ENTRY(counter, n)            \
+       { BNXT_TX_STATS_EXT_OFFSET(counter##_cos0),     \
+         __stringify(counter##_pri##n) }
+
+#define BNXT_RX_STATS_PRI_ENTRIES(counter)             \
+       BNXT_RX_STATS_PRI_ENTRY(counter, 0),            \
+       BNXT_RX_STATS_PRI_ENTRY(counter, 1),            \
+       BNXT_RX_STATS_PRI_ENTRY(counter, 2),            \
+       BNXT_RX_STATS_PRI_ENTRY(counter, 3),            \
+       BNXT_RX_STATS_PRI_ENTRY(counter, 4),            \
+       BNXT_RX_STATS_PRI_ENTRY(counter, 5),            \
+       BNXT_RX_STATS_PRI_ENTRY(counter, 6),            \
+       BNXT_RX_STATS_PRI_ENTRY(counter, 7)
+
+#define BNXT_TX_STATS_PRI_ENTRIES(counter)             \
+       BNXT_TX_STATS_PRI_ENTRY(counter, 0),            \
+       BNXT_TX_STATS_PRI_ENTRY(counter, 1),            \
+       BNXT_TX_STATS_PRI_ENTRY(counter, 2),            \
+       BNXT_TX_STATS_PRI_ENTRY(counter, 3),            \
+       BNXT_TX_STATS_PRI_ENTRY(counter, 4),            \
+       BNXT_TX_STATS_PRI_ENTRY(counter, 5),            \
+       BNXT_TX_STATS_PRI_ENTRY(counter, 6),            \
+       BNXT_TX_STATS_PRI_ENTRY(counter, 7)
+
 enum {
        RX_TOTAL_DISCARDS,
        TX_TOTAL_DISCARDS,
        BNXT_TX_STATS_EXT_PFC_ENTRIES,
 };
 
+static const struct {
+       long base_off;
+       char string[ETH_GSTRING_LEN];
+} bnxt_rx_bytes_pri_arr[] = {
+       BNXT_RX_STATS_PRI_ENTRIES(rx_bytes),
+};
+
+static const struct {
+       long base_off;
+       char string[ETH_GSTRING_LEN];
+} bnxt_rx_pkts_pri_arr[] = {
+       BNXT_RX_STATS_PRI_ENTRIES(rx_packets),
+};
+
+static const struct {
+       long base_off;
+       char string[ETH_GSTRING_LEN];
+} bnxt_tx_bytes_pri_arr[] = {
+       BNXT_TX_STATS_PRI_ENTRIES(tx_bytes),
+};
+
+static const struct {
+       long base_off;
+       char string[ETH_GSTRING_LEN];
+} bnxt_tx_pkts_pri_arr[] = {
+       BNXT_TX_STATS_PRI_ENTRIES(tx_packets),
+};
+
 #define BNXT_NUM_SW_FUNC_STATS ARRAY_SIZE(bnxt_sw_func_stats)
 #define BNXT_NUM_PORT_STATS ARRAY_SIZE(bnxt_port_stats_arr)
+#define BNXT_NUM_STATS_PRI                     \
+       (ARRAY_SIZE(bnxt_rx_bytes_pri_arr) +    \
+        ARRAY_SIZE(bnxt_rx_pkts_pri_arr) +     \
+        ARRAY_SIZE(bnxt_tx_bytes_pri_arr) +    \
+        ARRAY_SIZE(bnxt_tx_pkts_pri_arr))
 
 static int bnxt_get_num_stats(struct bnxt *bp)
 {
        if (bp->flags & BNXT_FLAG_PORT_STATS)
                num_stats += BNXT_NUM_PORT_STATS;
 
-       if (bp->flags & BNXT_FLAG_PORT_STATS_EXT)
+       if (bp->flags & BNXT_FLAG_PORT_STATS_EXT) {
                num_stats += bp->fw_rx_stats_ext_size +
                             bp->fw_tx_stats_ext_size;
+               if (bp->pri2cos_valid)
+                       num_stats += BNXT_NUM_STATS_PRI;
+       }
 
        return num_stats;
 }
                        buf[j] = le64_to_cpu(*(tx_port_stats_ext +
                                        bnxt_tx_port_stats_ext_arr[i].offset));
                }
+               if (bp->pri2cos_valid) {
+                       for (i = 0; i < 8; i++, j++) {
+                               long n = bnxt_rx_bytes_pri_arr[i].base_off +
+                                        bp->pri2cos[i];
+
+                               buf[j] = le64_to_cpu(*(rx_port_stats_ext + n));
+                       }
+                       for (i = 0; i < 8; i++, j++) {
+                               long n = bnxt_rx_pkts_pri_arr[i].base_off +
+                                        bp->pri2cos[i];
+
+                               buf[j] = le64_to_cpu(*(rx_port_stats_ext + n));
+                       }
+                       for (i = 0; i < 8; i++, j++) {
+                               long n = bnxt_tx_bytes_pri_arr[i].base_off +
+                                        bp->pri2cos[i];
+
+                               buf[j] = le64_to_cpu(*(tx_port_stats_ext + n));
+                       }
+                       for (i = 0; i < 8; i++, j++) {
+                               long n = bnxt_tx_pkts_pri_arr[i].base_off +
+                                        bp->pri2cos[i];
+
+                               buf[j] = le64_to_cpu(*(tx_port_stats_ext + n));
+                       }
+               }
        }
 }
 
                                       bnxt_tx_port_stats_ext_arr[i].string);
                                buf += ETH_GSTRING_LEN;
                        }
+                       if (bp->pri2cos_valid) {
+                               for (i = 0; i < 8; i++) {
+                                       strcpy(buf,
+                                              bnxt_rx_bytes_pri_arr[i].string);
+                                       buf += ETH_GSTRING_LEN;
+                               }
+                               for (i = 0; i < 8; i++) {
+                                       strcpy(buf,
+                                              bnxt_rx_pkts_pri_arr[i].string);
+                                       buf += ETH_GSTRING_LEN;
+                               }
+                               for (i = 0; i < 8; i++) {
+                                       strcpy(buf,
+                                              bnxt_tx_bytes_pri_arr[i].string);
+                                       buf += ETH_GSTRING_LEN;
+                               }
+                               for (i = 0; i < 8; i++) {
+                                       strcpy(buf,
+                                              bnxt_tx_pkts_pri_arr[i].string);
+                                       buf += ETH_GSTRING_LEN;
+                               }
+                       }
                }
                break;
        case ETH_SS_TEST: