|
@@ -60,11 +60,11 @@ int mlx4_en_setup_tc(struct net_device *dev, u8 up)
|
|
|
int i;
|
|
|
unsigned int offset = 0;
|
|
|
|
|
|
- if (up && up != MLX4_EN_NUM_UP)
|
|
|
+ if (up && up != MLX4_EN_NUM_UP_HIGH)
|
|
|
return -EINVAL;
|
|
|
|
|
|
netdev_set_num_tc(dev, up);
|
|
|
-
|
|
|
+ netif_set_real_num_tx_queues(dev, priv->tx_ring_num[TX]);
|
|
|
/* Partition Tx queues evenly amongst UP's */
|
|
|
for (i = 0; i < up; i++) {
|
|
|
netdev_set_tc_queue(dev, i, priv->num_tx_rings_p_up, offset);
|
|
@@ -86,6 +86,50 @@ int mlx4_en_setup_tc(struct net_device *dev, u8 up)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+int mlx4_en_alloc_tx_queue_per_tc(struct net_device *dev, u8 tc)
|
|
|
+{
|
|
|
+ struct mlx4_en_priv *priv = netdev_priv(dev);
|
|
|
+ struct mlx4_en_dev *mdev = priv->mdev;
|
|
|
+ struct mlx4_en_port_profile new_prof;
|
|
|
+ struct mlx4_en_priv *tmp;
|
|
|
+ int port_up = 0;
|
|
|
+ int err = 0;
|
|
|
+
|
|
|
+ tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
|
|
|
+ if (!tmp)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ mutex_lock(&mdev->state_lock);
|
|
|
+ memcpy(&new_prof, priv->prof, sizeof(struct mlx4_en_port_profile));
|
|
|
+ new_prof.num_up = (tc == 0) ? MLX4_EN_NUM_UP_LOW :
|
|
|
+ MLX4_EN_NUM_UP_HIGH;
|
|
|
+ new_prof.tx_ring_num[TX] = new_prof.num_tx_rings_p_up *
|
|
|
+ new_prof.num_up;
|
|
|
+ err = mlx4_en_try_alloc_resources(priv, tmp, &new_prof, true);
|
|
|
+ if (err)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ if (priv->port_up) {
|
|
|
+ port_up = 1;
|
|
|
+ mlx4_en_stop_port(dev, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ mlx4_en_safe_replace_resources(priv, tmp);
|
|
|
+ if (port_up) {
|
|
|
+ err = mlx4_en_start_port(dev);
|
|
|
+ if (err) {
|
|
|
+ en_err(priv, "Failed starting port for setup TC\n");
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ err = mlx4_en_setup_tc(dev, tc);
|
|
|
+out:
|
|
|
+ mutex_unlock(&mdev->state_lock);
|
|
|
+ kfree(tmp);
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
static int __mlx4_en_setup_tc(struct net_device *dev, u32 handle,
|
|
|
u32 chain_index, __be16 proto,
|
|
|
struct tc_to_netdev *tc)
|
|
@@ -93,9 +137,12 @@ static int __mlx4_en_setup_tc(struct net_device *dev, u32 handle,
|
|
|
if (tc->type != TC_SETUP_MQPRIO)
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ if (tc->mqprio->num_tc && tc->mqprio->num_tc != MLX4_EN_NUM_UP_HIGH)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
tc->mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;
|
|
|
|
|
|
- return mlx4_en_setup_tc(dev, tc->mqprio->num_tc);
|
|
|
+ return mlx4_en_alloc_tx_queue_per_tc(dev, tc->mqprio->num_tc);
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_RFS_ACCEL
|
|
@@ -2144,7 +2191,7 @@ static int mlx4_en_copy_priv(struct mlx4_en_priv *dst,
|
|
|
|
|
|
memcpy(&dst->hwtstamp_config, &prof->hwtstamp_config,
|
|
|
sizeof(dst->hwtstamp_config));
|
|
|
- dst->num_tx_rings_p_up = src->mdev->profile.num_tx_rings_p_up;
|
|
|
+ dst->num_tx_rings_p_up = prof->num_tx_rings_p_up;
|
|
|
dst->rx_ring_num = prof->rx_ring_num;
|
|
|
dst->flags = prof->flags;
|
|
|
dst->mdev = src->mdev;
|
|
@@ -2197,6 +2244,7 @@ static void mlx4_en_update_priv(struct mlx4_en_priv *dst,
|
|
|
dst->tx_ring[t] = src->tx_ring[t];
|
|
|
dst->tx_cq[t] = src->tx_cq[t];
|
|
|
}
|
|
|
+ dst->num_tx_rings_p_up = src->num_tx_rings_p_up;
|
|
|
dst->rx_ring_num = src->rx_ring_num;
|
|
|
memcpy(dst->prof, src->prof, sizeof(struct mlx4_en_port_profile));
|
|
|
}
|
|
@@ -2780,7 +2828,7 @@ static int mlx4_xdp_set(struct net_device *dev, struct bpf_prog *prog)
|
|
|
if (priv->tx_ring_num[TX] + xdp_ring_num > MAX_TX_RINGS) {
|
|
|
tx_changed = 1;
|
|
|
new_prof.tx_ring_num[TX] =
|
|
|
- MAX_TX_RINGS - ALIGN(xdp_ring_num, MLX4_EN_NUM_UP);
|
|
|
+ MAX_TX_RINGS - ALIGN(xdp_ring_num, priv->prof->num_up);
|
|
|
en_warn(priv, "Reducing the number of TX rings, to not exceed the max total rings number.\n");
|
|
|
}
|
|
|
|
|
@@ -3271,7 +3319,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
|
|
|
priv->flags |= MLX4_EN_DCB_ENABLED;
|
|
|
priv->cee_config.pfc_state = false;
|
|
|
|
|
|
- for (i = 0; i < MLX4_EN_NUM_UP; i++)
|
|
|
+ for (i = 0; i < MLX4_EN_NUM_UP_HIGH; i++)
|
|
|
priv->cee_config.dcb_pfc[i] = pfc_disabled;
|
|
|
|
|
|
if (mdev->dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_ETS_CFG) {
|