DECLARE_BITMAP(state, MLX5E_CHANNEL_NUM_STATES);
        int                        ix;
        int                        vec_ix;
+       int                        sd_ix;
        int                        cpu;
        /* Sync between icosq recovery and XSK enable/disable. */
        struct mutex               icosq_recovery_lock;
        bool                       tx_ptp_opened;
        bool                       rx_ptp_opened;
        struct hwtstamp_config     tstamp;
-       u16                        q_counter;
+       u16                        q_counter[MLX5_SD_MAX_GROUP_SZ];
        u16                        drop_rq_q_counter;
        struct notifier_block      events_nb;
        struct notifier_block      blocking_events_nb;
 
 struct mlx5e_rq_param;
 int mlx5e_open_rq(struct mlx5e_params *params, struct mlx5e_rq_param *param,
-                 struct mlx5e_xsk_param *xsk, int node,
+                 struct mlx5e_xsk_param *xsk, int node, u16 q_counter,
                  struct mlx5e_rq *rq);
 #define MLX5E_RQ_WQES_TIMEOUT 20000 /* msecs */
 int mlx5e_wait_for_min_rx_wqes(struct mlx5e_rq *rq, int wait_time);
 void mlx5e_close_rq(struct mlx5e_rq *rq);
-int mlx5e_create_rq(struct mlx5e_rq *rq, struct mlx5e_rq_param *param);
+int mlx5e_create_rq(struct mlx5e_rq *rq, struct mlx5e_rq_param *param, u16 q_counter);
 void mlx5e_destroy_rq(struct mlx5e_rq *rq);
 
 struct mlx5e_sq_param;
 
 #define NUM_REQ_PPCNT_COUNTER_S1 MLX5_CMD_SET_MONITOR_NUM_PPCNT_COUNTER_SET1
 #define NUM_REQ_Q_COUNTERS_S1    MLX5_CMD_SET_MONITOR_NUM_Q_COUNTERS_SET1
 
-int mlx5e_monitor_counter_supported(struct mlx5e_priv *priv)
+static int mlx5e_monitor_counter_cap(struct mlx5_core_dev *mdev)
 {
-       struct mlx5_core_dev *mdev = priv->mdev;
-
        if (!MLX5_CAP_GEN(mdev, max_num_of_monitor_counters))
                return false;
        if (MLX5_CAP_PCAM_REG(mdev, ppcnt) &&
        return true;
 }
 
-static void mlx5e_monitor_counter_arm(struct mlx5e_priv *priv)
+int mlx5e_monitor_counter_supported(struct mlx5e_priv *priv)
+{
+       struct mlx5_core_dev *pos;
+       int i;
+
+       mlx5_sd_for_each_dev(i, priv->mdev, pos)
+               if (!mlx5e_monitor_counter_cap(pos))
+                       return false;
+       return true;
+}
+
+static void mlx5e_monitor_counter_arm(struct mlx5_core_dev *mdev)
 {
        u32 in[MLX5_ST_SZ_DW(arm_monitor_counter_in)] = {};
 
        MLX5_SET(arm_monitor_counter_in, in, opcode,
                 MLX5_CMD_OP_ARM_MONITOR_COUNTER);
-       mlx5_cmd_exec_in(priv->mdev, arm_monitor_counter, in);
+       mlx5_cmd_exec_in(mdev, arm_monitor_counter, in);
 }
 
 static void mlx5e_monitor_counters_work(struct work_struct *work)
 {
        struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
                                               monitor_counters_work);
+       struct mlx5_core_dev *pos;
+       int i;
 
        mutex_lock(&priv->state_lock);
        mlx5e_stats_update_ndo_stats(priv);
        mutex_unlock(&priv->state_lock);
-       mlx5e_monitor_counter_arm(priv);
+       mlx5_sd_for_each_dev(i, priv->mdev, pos)
+               mlx5e_monitor_counter_arm(pos);
 }
 
 static int mlx5e_monitor_event_handler(struct notifier_block *nb,
 }
 
 /* check if mlx5e_monitor_counter_supported before calling this function*/
-static void mlx5e_set_monitor_counter(struct mlx5e_priv *priv)
+static void mlx5e_set_monitor_counter(struct mlx5_core_dev *mdev, int q_counter)
 {
-       struct mlx5_core_dev *mdev = priv->mdev;
        int max_num_of_counters = MLX5_CAP_GEN(mdev, max_num_of_monitor_counters);
        int num_q_counters      = MLX5_CAP_GEN(mdev, num_q_monitor_counters);
        int num_ppcnt_counters  = !MLX5_CAP_PCAM_REG(mdev, ppcnt) ? 0 :
                                  MLX5_CAP_GEN(mdev, num_ppcnt_monitor_counters);
        u32 in[MLX5_ST_SZ_DW(set_monitor_counter_in)] = {};
-       int q_counter = priv->q_counter;
        int cnt = 0;
 
        if (num_ppcnt_counters  >=  NUM_REQ_PPCNT_COUNTER_S1 &&
 /* check if mlx5e_monitor_counter_supported before calling this function*/
 void mlx5e_monitor_counter_init(struct mlx5e_priv *priv)
 {
+       struct mlx5_core_dev *pos;
+       int i;
+
        INIT_WORK(&priv->monitor_counters_work, mlx5e_monitor_counters_work);
        MLX5_NB_INIT(&priv->monitor_counters_nb, mlx5e_monitor_event_handler,
                     MONITOR_COUNTER);
-       mlx5_eq_notifier_register(priv->mdev, &priv->monitor_counters_nb);
-
-       mlx5e_set_monitor_counter(priv);
-       mlx5e_monitor_counter_arm(priv);
+       mlx5_sd_for_each_dev(i, priv->mdev, pos) {
+               mlx5_eq_notifier_register(pos, &priv->monitor_counters_nb);
+               mlx5e_set_monitor_counter(pos, priv->q_counter[i]);
+               mlx5e_monitor_counter_arm(pos);
+       }
        queue_work(priv->wq, &priv->update_stats_work);
 }
 
 void mlx5e_monitor_counter_cleanup(struct mlx5e_priv *priv)
 {
        u32 in[MLX5_ST_SZ_DW(set_monitor_counter_in)] = {};
+       struct mlx5_core_dev *pos;
+       int i;
 
        MLX5_SET(set_monitor_counter_in, in, opcode,
                 MLX5_CMD_OP_SET_MONITOR_COUNTER);
 
-       mlx5_cmd_exec_in(priv->mdev, set_monitor_counter, in);
-       mlx5_eq_notifier_unregister(priv->mdev, &priv->monitor_counters_nb);
+       mlx5_sd_for_each_dev(i, priv->mdev, pos) {
+               mlx5_cmd_exec_in(pos, set_monitor_counter, in);
+               mlx5_eq_notifier_unregister(pos, &priv->monitor_counters_nb);
+       }
        cancel_work_sync(&priv->monitor_counters_work);
 }
 
 int mlx5e_build_rq_param(struct mlx5_core_dev *mdev,
                         struct mlx5e_params *params,
                         struct mlx5e_xsk_param *xsk,
-                        u16 q_counter,
                         struct mlx5e_rq_param *param)
 {
        void *rqc = param->rqc;
        MLX5_SET(wq, wq, log_wq_stride,
                 mlx5e_get_rqwq_log_stride(params->rq_wq_type, ndsegs));
        MLX5_SET(wq, wq, pd,               mdev->mlx5e_res.hw_objs.pdn);
-       MLX5_SET(rqc, rqc, counter_set_id, q_counter);
        MLX5_SET(rqc, rqc, vsd,            params->vlan_strip_disable);
        MLX5_SET(rqc, rqc, scatter_fcs,    params->scatter_fcs_en);
 
 }
 
 void mlx5e_build_drop_rq_param(struct mlx5_core_dev *mdev,
-                              u16 q_counter,
                               struct mlx5e_rq_param *param)
 {
        void *rqc = param->rqc;
        MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_CYCLIC);
        MLX5_SET(wq, wq, log_wq_stride,
                 mlx5e_get_rqwq_log_stride(MLX5_WQ_TYPE_CYCLIC, 1));
-       MLX5_SET(rqc, rqc, counter_set_id, q_counter);
 
        param->wq.buf_numa_node = dev_to_node(mlx5_core_dma_dev(mdev));
 }
 
 int mlx5e_build_channel_param(struct mlx5_core_dev *mdev,
                              struct mlx5e_params *params,
-                             u16 q_counter,
                              struct mlx5e_channel_param *cparam)
 {
        u8 icosq_log_wq_sz, async_icosq_log_wq_sz;
        int err;
 
-       err = mlx5e_build_rq_param(mdev, params, NULL, q_counter, &cparam->rq);
+       err = mlx5e_build_rq_param(mdev, params, NULL, &cparam->rq);
        if (err)
                return err;
 
 
 int mlx5e_build_rq_param(struct mlx5_core_dev *mdev,
                         struct mlx5e_params *params,
                         struct mlx5e_xsk_param *xsk,
-                        u16 q_counter,
                         struct mlx5e_rq_param *param);
 void mlx5e_build_drop_rq_param(struct mlx5_core_dev *mdev,
-                              u16 q_counter,
                               struct mlx5e_rq_param *param);
 void mlx5e_build_sq_param_common(struct mlx5_core_dev *mdev,
                                 struct mlx5e_sq_param *param);
                             struct mlx5e_sq_param *param);
 int mlx5e_build_channel_param(struct mlx5_core_dev *mdev,
                              struct mlx5e_params *params,
-                             u16 q_counter,
                              struct mlx5e_channel_param *cparam);
 
 u16 mlx5e_calc_sq_stop_room(struct mlx5_core_dev *mdev, struct mlx5e_params *params);
 
 
 static void mlx5e_ptp_build_rq_param(struct mlx5_core_dev *mdev,
                                     struct net_device *netdev,
-                                    u16 q_counter,
                                     struct mlx5e_ptp_params *ptp_params)
 {
        struct mlx5e_rq_param *rq_params = &ptp_params->rq_param;
        params->rq_wq_type = MLX5_WQ_TYPE_CYCLIC;
        mlx5e_init_rq_type_params(mdev, params);
        params->sw_mtu = netdev->max_mtu;
-       mlx5e_build_rq_param(mdev, params, NULL, q_counter, rq_params);
+       mlx5e_build_rq_param(mdev, params, NULL, rq_params);
 }
 
 static void mlx5e_ptp_build_params(struct mlx5e_ptp *c,
        /* RQ */
        if (test_bit(MLX5E_PTP_STATE_RX, c->state)) {
                params->vlan_strip_disable = orig->vlan_strip_disable;
-               mlx5e_ptp_build_rq_param(c->mdev, c->netdev, c->priv->q_counter, cparams);
+               mlx5e_ptp_build_rq_param(c->mdev, c->netdev, cparams);
        }
 }
 
                             struct mlx5e_rq_param *rq_param)
 {
        int node = dev_to_node(c->mdev->device);
-       int err;
+       int err, sd_ix;
+       u16 q_counter;
 
        err = mlx5e_init_ptp_rq(c, params, &c->rq);
        if (err)
                return err;
 
-       return mlx5e_open_rq(params, rq_param, NULL, node, &c->rq);
+       sd_ix = mlx5_sd_ch_ix_get_dev_ix(c->mdev, MLX5E_PTP_CHANNEL_IX);
+       q_counter = c->priv->q_counter[sd_ix];
+       return mlx5e_open_rq(params, rq_param, NULL, node, q_counter, &c->rq);
 }
 
 static int mlx5e_ptp_open_queues(struct mlx5e_ptp *c,
 
        struct mlx5e_create_cq_param ccp = {};
        struct dim_cq_moder trap_moder = {};
        struct mlx5e_rq *rq = &t->rq;
+       u16 q_counter;
        int node;
        int err;
 
        node = dev_to_node(mdev->device);
+       q_counter = priv->q_counter[0];
 
        ccp.netdev   = priv->netdev;
        ccp.wq       = priv->wq;
                return err;
 
        mlx5e_init_trap_rq(t, &t->params, rq);
-       err = mlx5e_open_rq(&t->params, rq_param, NULL, node, rq);
+       err = mlx5e_open_rq(&t->params, rq_param, NULL, node, q_counter, rq);
        if (err)
                goto err_destroy_cq;
 
 }
 
 static void mlx5e_build_trap_params(struct mlx5_core_dev *mdev,
-                                   int max_mtu, u16 q_counter,
-                                   struct mlx5e_trap *t)
+                                   int max_mtu, struct mlx5e_trap *t)
 {
        struct mlx5e_params *params = &t->params;
 
        params->rq_wq_type = MLX5_WQ_TYPE_CYCLIC;
        mlx5e_init_rq_type_params(mdev, params);
        params->sw_mtu = max_mtu;
-       mlx5e_build_rq_param(mdev, params, NULL, q_counter, &t->rq_param);
+       mlx5e_build_rq_param(mdev, params, NULL, &t->rq_param);
 }
 
 static struct mlx5e_trap *mlx5e_open_trap(struct mlx5e_priv *priv)
        if (!t)
                return ERR_PTR(-ENOMEM);
 
-       mlx5e_build_trap_params(priv->mdev, netdev->max_mtu, priv->q_counter, t);
+       mlx5e_build_trap_params(priv->mdev, netdev->max_mtu, t);
 
        t->priv     = priv;
        t->mdev     = priv->mdev;
 
 static void mlx5e_build_xsk_cparam(struct mlx5_core_dev *mdev,
                                   struct mlx5e_params *params,
                                   struct mlx5e_xsk_param *xsk,
-                                  u16 q_counter,
                                   struct mlx5e_channel_param *cparam)
 {
-       mlx5e_build_rq_param(mdev, params, xsk, q_counter, &cparam->rq);
+       mlx5e_build_rq_param(mdev, params, xsk, &cparam->rq);
        mlx5e_build_xdpsq_param(mdev, params, xsk, &cparam->xdp_sq);
 }
 
                             struct mlx5e_rq_param *rq_params, struct xsk_buff_pool *pool,
                             struct mlx5e_xsk_param *xsk)
 {
+       u16 q_counter = c->priv->q_counter[c->sd_ix];
        struct mlx5e_rq *xskrq = &c->xskrq;
        int err;
 
        if (err)
                return err;
 
-       err = mlx5e_open_rq(params, rq_params, xsk, cpu_to_node(c->cpu), xskrq);
+       err = mlx5e_open_rq(params, rq_params, xsk, cpu_to_node(c->cpu), q_counter, xskrq);
        if (err)
                return err;
 
        if (!cparam)
                return -ENOMEM;
 
-       mlx5e_build_xsk_cparam(priv->mdev, params, xsk, priv->q_counter, cparam);
+       mlx5e_build_xsk_cparam(priv->mdev, params, xsk, cparam);
 
        err = mlx5e_open_cq(c->mdev, params->rx_cq_moderation, &cparam->rq.cqp, &ccp,
                            &c->xskrq.cq);
 
        mlx5_wq_destroy(&rq->wq_ctrl);
 }
 
-int mlx5e_create_rq(struct mlx5e_rq *rq, struct mlx5e_rq_param *param)
+int mlx5e_create_rq(struct mlx5e_rq *rq, struct mlx5e_rq_param *param, u16 q_counter)
 {
        struct mlx5_core_dev *mdev = rq->mdev;
        u8 ts_format;
        MLX5_SET(rqc,  rqc, cqn,                rq->cq.mcq.cqn);
        MLX5_SET(rqc,  rqc, state,              MLX5_RQC_STATE_RST);
        MLX5_SET(rqc,  rqc, ts_format,          ts_format);
+       MLX5_SET(rqc,  rqc, counter_set_id,     q_counter);
        MLX5_SET(wq,   wq,  log_wq_pg_sz,       rq->wq_ctrl.buf.page_shift -
                                                MLX5_ADAPTER_PAGE_SHIFT);
        MLX5_SET64(wq, wq,  dbr_addr,           rq->wq_ctrl.db.dma);
 }
 
 int mlx5e_open_rq(struct mlx5e_params *params, struct mlx5e_rq_param *param,
-                 struct mlx5e_xsk_param *xsk, int node,
+                 struct mlx5e_xsk_param *xsk, int node, u16 q_counter,
                  struct mlx5e_rq *rq)
 {
        struct mlx5_core_dev *mdev = rq->mdev;
        if (err)
                return err;
 
-       err = mlx5e_create_rq(rq, param);
+       err = mlx5e_create_rq(rq, param, q_counter);
        if (err)
                goto err_free_rq;
 
 static int mlx5e_open_rxq_rq(struct mlx5e_channel *c, struct mlx5e_params *params,
                             struct mlx5e_rq_param *rq_params)
 {
+       u16 q_counter = c->priv->q_counter[c->sd_ix];
        int err;
 
        err = mlx5e_init_rxq_rq(c, params, rq_params->xdp_frag_size, &c->rq);
        if (err)
                return err;
 
-       return mlx5e_open_rq(params, rq_params, NULL, cpu_to_node(c->cpu), &c->rq);
+       return mlx5e_open_rq(params, rq_params, NULL, cpu_to_node(c->cpu), q_counter, &c->rq);
 }
 
 static int mlx5e_open_queues(struct mlx5e_channel *c,
        c->tstamp   = &priv->tstamp;
        c->ix       = ix;
        c->vec_ix   = vec_ix;
+       c->sd_ix    = mlx5_sd_ch_ix_get_dev_ix(mdev, ix);
        c->cpu      = cpu;
        c->pdev     = mlx5_core_dma_dev(mdev);
        c->netdev   = priv->netdev;
        if (!chs->c || !cparam)
                goto err_free;
 
-       err = mlx5e_build_channel_param(priv->mdev, &chs->params, priv->q_counter, cparam);
+       err = mlx5e_build_channel_param(priv->mdev, &chs->params, cparam);
        if (err)
                goto err_free;
 
        struct mlx5e_cq *cq = &drop_rq->cq;
        int err;
 
-       mlx5e_build_drop_rq_param(mdev, priv->drop_rq_q_counter, &rq_param);
+       mlx5e_build_drop_rq_param(mdev, &rq_param);
 
        err = mlx5e_alloc_drop_cq(priv, cq, &cq_param);
        if (err)
        if (err)
                goto err_destroy_cq;
 
-       err = mlx5e_create_rq(drop_rq, &rq_param);
+       err = mlx5e_create_rq(drop_rq, &rq_param, priv->drop_rq_q_counter);
        if (err)
                goto err_free_rq;
 
        u32 out[MLX5_ST_SZ_DW(alloc_q_counter_out)] = {};
        u32 in[MLX5_ST_SZ_DW(alloc_q_counter_in)] = {};
        struct mlx5_core_dev *mdev = priv->mdev;
-       int err;
+       struct mlx5_core_dev *pos;
+       int err, i;
 
        MLX5_SET(alloc_q_counter_in, in, opcode, MLX5_CMD_OP_ALLOC_Q_COUNTER);
-       err = mlx5_cmd_exec_inout(mdev, alloc_q_counter, in, out);
-       if (!err)
-               priv->q_counter =
-                       MLX5_GET(alloc_q_counter_out, out, counter_set_id);
+
+       mlx5_sd_for_each_dev(i, mdev, pos) {
+               err = mlx5_cmd_exec_inout(pos, alloc_q_counter, in, out);
+               if (!err)
+                       priv->q_counter[i] =
+                               MLX5_GET(alloc_q_counter_out, out, counter_set_id);
+       }
 
        err = mlx5_cmd_exec_inout(mdev, alloc_q_counter, in, out);
        if (!err)
 void mlx5e_destroy_q_counters(struct mlx5e_priv *priv)
 {
        u32 in[MLX5_ST_SZ_DW(dealloc_q_counter_in)] = {};
+       struct mlx5_core_dev *pos;
+       int i;
 
        MLX5_SET(dealloc_q_counter_in, in, opcode,
                 MLX5_CMD_OP_DEALLOC_Q_COUNTER);
-       if (priv->q_counter) {
-               MLX5_SET(dealloc_q_counter_in, in, counter_set_id,
-                        priv->q_counter);
-               mlx5_cmd_exec_in(priv->mdev, dealloc_q_counter, in);
+       mlx5_sd_for_each_dev(i, priv->mdev, pos) {
+               if (priv->q_counter[i]) {
+                       MLX5_SET(dealloc_q_counter_in, in, counter_set_id,
+                                priv->q_counter[i]);
+                       mlx5_cmd_exec_in(pos, dealloc_q_counter, in);
+               }
        }
 
        if (priv->drop_rq_q_counter) {
 
 #define NUM_Q_COUNTERS                 ARRAY_SIZE(q_stats_desc)
 #define NUM_DROP_RQ_COUNTERS           ARRAY_SIZE(drop_rq_stats_desc)
 
+static bool q_counter_any(struct mlx5e_priv *priv)
+{
+       struct mlx5_core_dev *pos;
+       int i;
+
+       mlx5_sd_for_each_dev(i, priv->mdev, pos)
+               if (priv->q_counter[i++])
+                       return true;
+
+       return false;
+}
+
 static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(qcnt)
 {
        int num_stats = 0;
 
-       if (priv->q_counter)
+       if (q_counter_any(priv))
                num_stats += NUM_Q_COUNTERS;
 
        if (priv->drop_rq_q_counter)
 {
        int i;
 
-       for (i = 0; i < NUM_Q_COUNTERS && priv->q_counter; i++)
+       for (i = 0; i < NUM_Q_COUNTERS && q_counter_any(priv); i++)
                strcpy(data + (idx++) * ETH_GSTRING_LEN,
                       q_stats_desc[i].format);
 
 {
        int i;
 
-       for (i = 0; i < NUM_Q_COUNTERS && priv->q_counter; i++)
+       for (i = 0; i < NUM_Q_COUNTERS && q_counter_any(priv); i++)
                data[idx++] = MLX5E_READ_CTR32_CPU(&priv->stats.qcnt,
                                                   q_stats_desc, i);
        for (i = 0; i < NUM_DROP_RQ_COUNTERS && priv->drop_rq_q_counter; i++)
        struct mlx5e_qcounter_stats *qcnt = &priv->stats.qcnt;
        u32 out[MLX5_ST_SZ_DW(query_q_counter_out)] = {};
        u32 in[MLX5_ST_SZ_DW(query_q_counter_in)] = {};
-       int ret;
+       struct mlx5_core_dev *pos;
+       u32 rx_out_of_buffer = 0;
+       int ret, i;
 
        MLX5_SET(query_q_counter_in, in, opcode, MLX5_CMD_OP_QUERY_Q_COUNTER);
 
-       if (priv->q_counter) {
-               MLX5_SET(query_q_counter_in, in, counter_set_id,
-                        priv->q_counter);
-               ret = mlx5_cmd_exec_inout(priv->mdev, query_q_counter, in, out);
-               if (!ret)
-                       qcnt->rx_out_of_buffer = MLX5_GET(query_q_counter_out,
-                                                         out, out_of_buffer);
+       mlx5_sd_for_each_dev(i, priv->mdev, pos) {
+               if (priv->q_counter[i]) {
+                       MLX5_SET(query_q_counter_in, in, counter_set_id,
+                                priv->q_counter[i]);
+                       ret = mlx5_cmd_exec_inout(pos, query_q_counter, in, out);
+                       if (!ret)
+                               rx_out_of_buffer += MLX5_GET(query_q_counter_out,
+                                                            out, out_of_buffer);
+               }
        }
+       qcnt->rx_out_of_buffer = rx_out_of_buffer;
 
        if (priv->drop_rq_q_counter) {
                MLX5_SET(query_q_counter_in, in, counter_set_id,
 
                        MLX5_CAP_GEN(priv->mdev, log_min_hairpin_wq_data_sz),
                        MLX5_CAP_GEN(priv->mdev, log_max_hairpin_wq_data_sz));
 
-       params.q_counter = priv->q_counter;
+       params.q_counter = priv->q_counter[0];
        err = devl_param_driverinit_value_get(
                devlink, MLX5_DEVLINK_PARAM_ID_HAIRPIN_NUM_QUEUES, &val);
        if (err) {