#define MLX5E_MIN_NUM_CHANNELS         0x1
 #define MLX5E_MAX_NUM_CHANNELS         (MLX5E_INDIR_RQT_SIZE / 2)
-#define MLX5E_MAX_NUM_SQS              (MLX5E_MAX_NUM_CHANNELS * MLX5E_MAX_NUM_TC)
 #define MLX5E_TX_CQ_POLL_BUDGET        128
 #define MLX5E_TX_XSK_POLL_BUDGET       64
 #define MLX5E_SQ_RECOVER_MIN_INTERVAL  500 /* msecs */
 
 struct mlx5e_priv {
        /* priv data path fields - start */
-       /* +1 for port ptp ts */
-       struct mlx5e_txqsq *txq2sq[(MLX5E_MAX_NUM_CHANNELS + 1) * MLX5E_MAX_NUM_TC +
-                                  MLX5E_QOS_MAX_LEAF_NODES];
-       int channel_tc2realtxq[MLX5E_MAX_NUM_CHANNELS][MLX5E_MAX_NUM_TC];
+       struct mlx5e_txqsq **txq2sq;
+       int **channel_tc2realtxq;
        int port_ptp_tc2realtxq[MLX5E_MAX_NUM_TC];
 #ifdef CONFIG_MLX5_CORE_EN_DCB
        struct mlx5e_dcbx_dp       dcbx_dp;
        struct mlx5e_channels      channels;
        u32                        tisn[MLX5_MAX_PORTS][MLX5E_MAX_NUM_TC];
        struct mlx5e_rx_res       *rx_res;
-       u32                        tx_rates[MLX5E_MAX_NUM_SQS];
+       u32                       *tx_rates;
 
        struct mlx5e_flow_steering fs;
 
        struct net_device         *netdev;
        struct mlx5e_trap         *en_trap;
        struct mlx5e_stats         stats;
-       struct mlx5e_channel_stats channel_stats[MLX5E_MAX_NUM_CHANNELS];
+       struct mlx5e_channel_stats *channel_stats;
        struct mlx5e_channel_stats trap_stats;
        struct mlx5e_ptp_stats     ptp_stats;
        u16                        stats_nch;
 
                    struct net_device *netdev,
                    struct mlx5_core_dev *mdev)
 {
+       int nch, num_txqs, node, i;
+
+       num_txqs = netdev->num_tx_queues;
+       nch = mlx5e_calc_max_nch(mdev, netdev, profile);
+       node = dev_to_node(mlx5_core_dma_dev(mdev));
+
        /* priv init */
        priv->mdev        = mdev;
        priv->netdev      = netdev;
        priv->msglevel    = MLX5E_MSG_LEVEL;
-       priv->max_nch     = mlx5e_calc_max_nch(mdev, netdev, profile);
-       priv->stats_nch   = priv->max_nch;
+       priv->max_nch     = nch;
+       priv->stats_nch   = nch;
        priv->max_opened_tc = 1;
 
        if (!alloc_cpumask_var(&priv->scratchpad.cpumask, GFP_KERNEL))
        if (!priv->wq)
                goto err_free_cpumask;
 
+       priv->txq2sq = kcalloc_node(num_txqs, sizeof(*priv->txq2sq), GFP_KERNEL, node);
+       if (!priv->txq2sq)
+               goto err_destroy_workqueue;
+
+       priv->tx_rates = kcalloc_node(num_txqs, sizeof(*priv->tx_rates), GFP_KERNEL, node);
+       if (!priv->tx_rates)
+               goto err_free_txq2sq;
+
+       priv->channel_tc2realtxq =
+               kcalloc_node(nch, sizeof(*priv->channel_tc2realtxq), GFP_KERNEL, node);
+       if (!priv->channel_tc2realtxq)
+               goto err_free_tx_rates;
+
+       for (i = 0; i < nch; i++) {
+               priv->channel_tc2realtxq[i] =
+                       kcalloc_node(profile->max_tc, sizeof(**priv->channel_tc2realtxq),
+                                    GFP_KERNEL, node);
+               if (!priv->channel_tc2realtxq[i])
+                       goto err_free_channel_tc2realtxq;
+       }
+
+       priv->channel_stats =
+               kcalloc_node(nch, sizeof(*priv->channel_stats), GFP_KERNEL, node);
+       if (!priv->channel_stats)
+               goto err_free_channel_tc2realtxq;
+
        return 0;
 
+err_free_channel_tc2realtxq:
+       while (--i >= 0)
+               kfree(priv->channel_tc2realtxq[i]);
+       kfree(priv->channel_tc2realtxq);
+err_free_tx_rates:
+       kfree(priv->tx_rates);
+err_free_txq2sq:
+       kfree(priv->txq2sq);
+err_destroy_workqueue:
+       destroy_workqueue(priv->wq);
 err_free_cpumask:
        free_cpumask_var(priv->scratchpad.cpumask);
-
        return -ENOMEM;
 }
 
        if (!priv->mdev)
                return;
 
+       kfree(priv->channel_stats);
+       for (i = 0; i < priv->max_nch; i++)
+               kfree(priv->channel_tc2realtxq[i]);
+       kfree(priv->channel_tc2realtxq);
+       kfree(priv->tx_rates);
+       kfree(priv->txq2sq);
        destroy_workqueue(priv->wq);
        free_cpumask_var(priv->scratchpad.cpumask);