int i;
 
        params->udp_rss = udp_rss;
+       params->num_tx_rings_p_up = min_t(int, num_online_cpus(),
+                       MLX4_EN_MAX_TX_RING_P_UP);
        if (params->udp_rss && !(mdev->dev->caps.flags
                                        & MLX4_DEV_CAP_FLAG_UDP_RSS)) {
                mlx4_warn(mdev, "UDP RSS is not supported on this device.\n");
                params->prof[i].tx_ppp = pfctx;
                params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE;
                params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE;
-               params->prof[i].tx_ring_num = MLX4_EN_NUM_TX_RINGS +
-                       MLX4_EN_NUM_PPP_RINGS;
+               params->prof[i].tx_ring_num = params->num_tx_rings_p_up *
+                       MLX4_EN_NUM_UP;
                params->prof[i].rss_rings = 0;
        }
 
 
 
 static int mlx4_en_setup_tc(struct net_device *dev, u8 up)
 {
-       if (up != MLX4_EN_NUM_UP)
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       int i;
+       unsigned int q, offset = 0;
+
+       if (up && up != MLX4_EN_NUM_UP)
                return -EINVAL;
 
+       netdev_set_num_tc(dev, up);
+
+       /* Partition Tx queues evenly amongst UP's */
+       q = priv->tx_ring_num / up;
+       for (i = 0; i < up; i++) {
+               netdev_set_tc_queue(dev, i, q, offset);
+               offset += q;
+       }
+
        return 0;
 }
 
                /* Configure ring */
                tx_ring = &priv->tx_ring[i];
                err = mlx4_en_activate_tx_ring(priv, tx_ring, cq->mcq.cqn,
-                               max(0, i - MLX4_EN_NUM_TX_RINGS));
+                       i / priv->mdev->profile.num_tx_rings_p_up);
                if (err) {
                        en_err(priv, "Failed allocating Tx ring\n");
                        mlx4_en_deactivate_cq(priv, cq);
 
        mlx4_en_free_resources(priv);
 
+       kfree(priv->tx_ring);
+       kfree(priv->tx_cq);
+
        free_netdev(dev);
 }
 
        priv->ctrl_flags = cpu_to_be32(MLX4_WQE_CTRL_CQ_UPDATE |
                        MLX4_WQE_CTRL_SOLICITED);
        priv->tx_ring_num = prof->tx_ring_num;
+       priv->tx_ring = kzalloc(sizeof(struct mlx4_en_tx_ring) *
+                       priv->tx_ring_num, GFP_KERNEL);
+       if (!priv->tx_ring) {
+               err = -ENOMEM;
+               goto out;
+       }
+       priv->tx_cq = kzalloc(sizeof(struct mlx4_en_cq) * priv->tx_ring_num,
+                       GFP_KERNEL);
+       if (!priv->tx_cq) {
+               err = -ENOMEM;
+               goto out;
+       }
        priv->rx_ring_num = prof->rx_ring_num;
        priv->mac_index = -1;
        priv->msg_enable = MLX4_EN_MSG_LEVEL;
        netif_set_real_num_tx_queues(dev, priv->tx_ring_num);
        netif_set_real_num_rx_queues(dev, priv->rx_ring_num);
 
-       netdev_set_num_tc(dev, MLX4_EN_NUM_UP);
-
-       /* First 9 rings are for UP 0 */
-       netdev_set_tc_queue(dev, 0, MLX4_EN_NUM_TX_RINGS + 1, 0);
-
-       /* Partition Tx queues evenly amongst UP's 1-7 */
-       for (i = 1; i < MLX4_EN_NUM_UP; i++)
-               netdev_set_tc_queue(dev, i, 1, MLX4_EN_NUM_TX_RINGS + i);
-
        SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops);
 
        /* Set defualt MAC */
 
 
 u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb)
 {
-       u16 vlan_tag = 0;
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       u16 rings_p_up = priv->mdev->profile.num_tx_rings_p_up;
+       u8 up = 0;
 
-       if (vlan_tx_tag_present(skb)) {
-               vlan_tag = vlan_tx_tag_get(skb);
-               return MLX4_EN_NUM_TX_RINGS + (vlan_tag >> 13);
-       }
+       if (dev->num_tc)
+               return skb_tx_hash(dev, skb);
+
+       if (vlan_tx_tag_present(skb))
+               up = vlan_tx_tag_get(skb) >> VLAN_PRIO_SHIFT;
 
-       return skb_tx_hash(dev, skb);
+       return __skb_tx_hash(dev, skb, rings_p_up) + up * rings_p_up;
 }
 
 static void mlx4_bf_copy(void __iomem *dst, unsigned long *src, unsigned bytecnt)
 
 #define MLX4_EN_MIN_TX_SIZE    (4096 / TXBB_SIZE)
 
 #define MLX4_EN_SMALL_PKT_SIZE         64
-#define MLX4_EN_NUM_TX_RINGS           8
-#define MLX4_EN_NUM_PPP_RINGS          8
-#define MAX_TX_RINGS                   (MLX4_EN_NUM_TX_RINGS + MLX4_EN_NUM_PPP_RINGS)
+#define MLX4_EN_MAX_TX_RING_P_UP       32
 #define MLX4_EN_NUM_UP                 8
 #define MLX4_EN_DEF_TX_RING_SIZE       512
 #define MLX4_EN_DEF_RX_RING_SIZE       1024
        u32 active_ports;
        u32 small_pkt_int;
        u8 no_reset;
+       u8 num_tx_rings_p_up;
        struct mlx4_en_port_profile prof[MLX4_MAX_PORTS + 1];
 };
 
        u16 num_frags;
        u16 log_rx_info;
 
-       struct mlx4_en_tx_ring tx_ring[MAX_TX_RINGS];
+       struct mlx4_en_tx_ring *tx_ring;
        struct mlx4_en_rx_ring rx_ring[MAX_RX_RINGS];
-       struct mlx4_en_cq tx_cq[MAX_TX_RINGS];
+       struct mlx4_en_cq *tx_cq;
        struct mlx4_en_cq rx_cq[MAX_RX_RINGS];
        struct work_struct mcast_task;
        struct work_struct mac_task;