diff options
author | Mohamad Haj Yahia <mohamad@mellanox.com> | 2016-08-11 04:28:21 -0400 |
---|---|---|
committer | Leon Romanovsky <leon@kernel.org> | 2016-10-30 09:43:13 -0400 |
commit | bd77bf1cb595477528f06f5c52f913f70acd73bb (patch) | |
tree | 090e5215d779191f6fb61ac4fda07d3ed35b0f72 | |
parent | 1bd27b11c1df33a1dc3277e2a0abbf6bd33cc817 (diff) |
net/mlx5: Add SRIOV VF max rate configuration support
Implement the vf set rate ndo by modifying the TSAR vport rate limit.
Signed-off-by: Mohamad Haj Yahia <mohamad@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 15 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 63 | ||||
-rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 2 |
3 files changed, 80 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 7eaf38020a8f..7f763d2f63bb 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c | |||
@@ -2945,6 +2945,20 @@ static int mlx5e_set_vf_trust(struct net_device *dev, int vf, bool setting) | |||
2945 | 2945 | ||
2946 | return mlx5_eswitch_set_vport_trust(mdev->priv.eswitch, vf + 1, setting); | 2946 | return mlx5_eswitch_set_vport_trust(mdev->priv.eswitch, vf + 1, setting); |
2947 | } | 2947 | } |
2948 | |||
2949 | static int mlx5e_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate, | ||
2950 | int max_tx_rate) | ||
2951 | { | ||
2952 | struct mlx5e_priv *priv = netdev_priv(dev); | ||
2953 | struct mlx5_core_dev *mdev = priv->mdev; | ||
2954 | |||
2955 | if (min_tx_rate) | ||
2956 | return -EOPNOTSUPP; | ||
2957 | |||
2958 | return mlx5_eswitch_set_vport_rate(mdev->priv.eswitch, vf + 1, | ||
2959 | max_tx_rate); | ||
2960 | } | ||
2961 | |||
2948 | static int mlx5_vport_link2ifla(u8 esw_link) | 2962 | static int mlx5_vport_link2ifla(u8 esw_link) |
2949 | { | 2963 | { |
2950 | switch (esw_link) { | 2964 | switch (esw_link) { |
@@ -3252,6 +3266,7 @@ static const struct net_device_ops mlx5e_netdev_ops_sriov = { | |||
3252 | .ndo_set_vf_vlan = mlx5e_set_vf_vlan, | 3266 | .ndo_set_vf_vlan = mlx5e_set_vf_vlan, |
3253 | .ndo_set_vf_spoofchk = mlx5e_set_vf_spoofchk, | 3267 | .ndo_set_vf_spoofchk = mlx5e_set_vf_spoofchk, |
3254 | .ndo_set_vf_trust = mlx5e_set_vf_trust, | 3268 | .ndo_set_vf_trust = mlx5e_set_vf_trust, |
3269 | .ndo_set_vf_rate = mlx5e_set_vf_rate, | ||
3255 | .ndo_get_vf_config = mlx5e_get_vf_config, | 3270 | .ndo_get_vf_config = mlx5e_get_vf_config, |
3256 | .ndo_set_vf_link_state = mlx5e_set_vf_link_state, | 3271 | .ndo_set_vf_link_state = mlx5e_set_vf_link_state, |
3257 | .ndo_get_vf_stats = mlx5e_get_vf_stats, | 3272 | .ndo_get_vf_stats = mlx5e_get_vf_stats, |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c index 2e11a94d8365..9ef01d1bea06 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | |||
@@ -1451,6 +1451,47 @@ static void esw_vport_disable_qos(struct mlx5_eswitch *esw, int vport_num) | |||
1451 | vport->qos.enabled = false; | 1451 | vport->qos.enabled = false; |
1452 | } | 1452 | } |
1453 | 1453 | ||
1454 | static int esw_vport_qos_config(struct mlx5_eswitch *esw, int vport_num, | ||
1455 | u32 max_rate) | ||
1456 | { | ||
1457 | u32 sched_ctx[MLX5_ST_SZ_DW(scheduling_context)] = {0}; | ||
1458 | struct mlx5_vport *vport = &esw->vports[vport_num]; | ||
1459 | struct mlx5_core_dev *dev = esw->dev; | ||
1460 | void *vport_elem; | ||
1461 | u32 bitmask = 0; | ||
1462 | int err = 0; | ||
1463 | |||
1464 | if (!MLX5_CAP_GEN(dev, qos) || !MLX5_CAP_QOS(dev, esw_scheduling)) | ||
1465 | return -EOPNOTSUPP; | ||
1466 | |||
1467 | if (!vport->qos.enabled) | ||
1468 | return -EIO; | ||
1469 | |||
1470 | MLX5_SET(scheduling_context, &sched_ctx, element_type, | ||
1471 | SCHEDULING_CONTEXT_ELEMENT_TYPE_VPORT); | ||
1472 | vport_elem = MLX5_ADDR_OF(scheduling_context, &sched_ctx, | ||
1473 | element_attributes); | ||
1474 | MLX5_SET(vport_element, vport_elem, vport_number, vport_num); | ||
1475 | MLX5_SET(scheduling_context, &sched_ctx, parent_element_id, | ||
1476 | esw->qos.root_tsar_id); | ||
1477 | MLX5_SET(scheduling_context, &sched_ctx, max_average_bw, | ||
1478 | max_rate); | ||
1479 | bitmask |= MODIFY_SCHEDULING_ELEMENT_IN_MODIFY_BITMASK_MAX_AVERAGE_BW; | ||
1480 | |||
1481 | err = mlx5_modify_scheduling_element_cmd(dev, | ||
1482 | SCHEDULING_HIERARCHY_E_SWITCH, | ||
1483 | &sched_ctx, | ||
1484 | vport->qos.esw_tsar_ix, | ||
1485 | bitmask); | ||
1486 | if (err) { | ||
1487 | esw_warn(esw->dev, "E-Switch modify TSAR vport element failed (vport=%d,err=%d)\n", | ||
1488 | vport_num, err); | ||
1489 | return err; | ||
1490 | } | ||
1491 | |||
1492 | return 0; | ||
1493 | } | ||
1494 | |||
1454 | static void node_guid_gen_from_mac(u64 *node_guid, u8 mac[ETH_ALEN]) | 1495 | static void node_guid_gen_from_mac(u64 *node_guid, u8 mac[ETH_ALEN]) |
1455 | { | 1496 | { |
1456 | ((u8 *)node_guid)[7] = mac[0]; | 1497 | ((u8 *)node_guid)[7] = mac[0]; |
@@ -1888,6 +1929,7 @@ int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw, | |||
1888 | ivi->qos = evport->info.qos; | 1929 | ivi->qos = evport->info.qos; |
1889 | ivi->spoofchk = evport->info.spoofchk; | 1930 | ivi->spoofchk = evport->info.spoofchk; |
1890 | ivi->trusted = evport->info.trusted; | 1931 | ivi->trusted = evport->info.trusted; |
1932 | ivi->max_tx_rate = evport->info.max_rate; | ||
1891 | mutex_unlock(&esw->state_lock); | 1933 | mutex_unlock(&esw->state_lock); |
1892 | 1934 | ||
1893 | return 0; | 1935 | return 0; |
@@ -1981,6 +2023,27 @@ int mlx5_eswitch_set_vport_trust(struct mlx5_eswitch *esw, | |||
1981 | return 0; | 2023 | return 0; |
1982 | } | 2024 | } |
1983 | 2025 | ||
2026 | int mlx5_eswitch_set_vport_rate(struct mlx5_eswitch *esw, | ||
2027 | int vport, u32 max_rate) | ||
2028 | { | ||
2029 | struct mlx5_vport *evport; | ||
2030 | int err = 0; | ||
2031 | |||
2032 | if (!ESW_ALLOWED(esw)) | ||
2033 | return -EPERM; | ||
2034 | if (!LEGAL_VPORT(esw, vport)) | ||
2035 | return -EINVAL; | ||
2036 | |||
2037 | mutex_lock(&esw->state_lock); | ||
2038 | evport = &esw->vports[vport]; | ||
2039 | err = esw_vport_qos_config(esw, vport, max_rate); | ||
2040 | if (!err) | ||
2041 | evport->info.max_rate = max_rate; | ||
2042 | |||
2043 | mutex_unlock(&esw->state_lock); | ||
2044 | return err; | ||
2045 | } | ||
2046 | |||
1984 | int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, | 2047 | int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, |
1985 | int vport, | 2048 | int vport, |
1986 | struct ifla_vf_stats *vf_stats) | 2049 | struct ifla_vf_stats *vf_stats) |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h index fb8de34b6baf..ddae90c1f15b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | |||
@@ -246,6 +246,8 @@ int mlx5_eswitch_set_vport_spoofchk(struct mlx5_eswitch *esw, | |||
246 | int vport, bool spoofchk); | 246 | int vport, bool spoofchk); |
247 | int mlx5_eswitch_set_vport_trust(struct mlx5_eswitch *esw, | 247 | int mlx5_eswitch_set_vport_trust(struct mlx5_eswitch *esw, |
248 | int vport_num, bool setting); | 248 | int vport_num, bool setting); |
249 | int mlx5_eswitch_set_vport_rate(struct mlx5_eswitch *esw, | ||
250 | int vport, u32 max_rate); | ||
249 | int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw, | 251 | int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw, |
250 | int vport, struct ifla_vf_info *ivi); | 252 | int vport, struct ifla_vf_info *ivi); |
251 | int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, | 253 | int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, |