|
3 | 3 |
|
4 | 4 | #include "lib/sd.h"
|
5 | 5 | #include "mlx5_core.h"
|
| 6 | +#include "lib/mlx5.h" |
| 7 | +#include <linux/mlx5/vport.h> |
6 | 8 |
|
7 | 9 | #define sd_info(__dev, format, ...) \
|
8 | 10 | dev_info((__dev)->device, "Socket-Direct: " format, ##__VA_ARGS__)
|
9 | 11 | #define sd_warn(__dev, format, ...) \
|
10 | 12 | dev_warn((__dev)->device, "Socket-Direct: " format, ##__VA_ARGS__)
|
11 | 13 |
|
12 | 14 | struct mlx5_sd {
|
| 15 | + u32 group_id; |
| 16 | + u8 host_buses; |
13 | 17 | };
|
14 | 18 |
|
15 | 19 | static int mlx5_sd_get_host_buses(struct mlx5_core_dev *dev)
|
16 | 20 | {
|
17 |
| - return 1; |
| 21 | + struct mlx5_sd *sd = mlx5_get_sd(dev); |
| 22 | + |
| 23 | + if (!sd) |
| 24 | + return 1; |
| 25 | + |
| 26 | + return sd->host_buses; |
18 | 27 | }
|
19 | 28 |
|
20 | 29 | struct mlx5_core_dev *
|
@@ -43,13 +52,109 @@ struct mlx5_core_dev *mlx5_sd_ch_ix_get_dev(struct mlx5_core_dev *primary, int c
|
43 | 52 | return mlx5_sd_primary_get_peer(primary, mdev_idx);
|
44 | 53 | }
|
45 | 54 |
|
| 55 | +static bool mlx5_sd_is_supported(struct mlx5_core_dev *dev, u8 host_buses) |
| 56 | +{ |
| 57 | + /* Feature is currently implemented for PFs only */ |
| 58 | + if (!mlx5_core_is_pf(dev)) |
| 59 | + return false; |
| 60 | + |
| 61 | + /* Honor the SW implementation limit */ |
| 62 | + if (host_buses > MLX5_SD_MAX_GROUP_SZ) |
| 63 | + return false; |
| 64 | + |
| 65 | + return true; |
| 66 | +} |
| 67 | + |
| 68 | +static int mlx5_query_sd(struct mlx5_core_dev *dev, bool *sdm, |
| 69 | + u8 *host_buses, u8 *sd_group) |
| 70 | +{ |
| 71 | + u32 out[MLX5_ST_SZ_DW(mpir_reg)]; |
| 72 | + int err; |
| 73 | + |
| 74 | + err = mlx5_query_mpir_reg(dev, out); |
| 75 | + if (err) |
| 76 | + return err; |
| 77 | + |
| 78 | + err = mlx5_query_nic_vport_sd_group(dev, sd_group); |
| 79 | + if (err) |
| 80 | + return err; |
| 81 | + |
| 82 | + *sdm = MLX5_GET(mpir_reg, out, sdm); |
| 83 | + *host_buses = MLX5_GET(mpir_reg, out, host_buses); |
| 84 | + |
| 85 | + return 0; |
| 86 | +} |
| 87 | + |
| 88 | +static u32 mlx5_sd_group_id(struct mlx5_core_dev *dev, u8 sd_group) |
| 89 | +{ |
| 90 | + return (u32)((MLX5_CAP_GEN(dev, native_port_num) << 8) | sd_group); |
| 91 | +} |
| 92 | + |
| 93 | +static int sd_init(struct mlx5_core_dev *dev) |
| 94 | +{ |
| 95 | + u8 host_buses, sd_group; |
| 96 | + struct mlx5_sd *sd; |
| 97 | + u32 group_id; |
| 98 | + bool sdm; |
| 99 | + int err; |
| 100 | + |
| 101 | + err = mlx5_query_sd(dev, &sdm, &host_buses, &sd_group); |
| 102 | + if (err) |
| 103 | + return err; |
| 104 | + |
| 105 | + if (!sdm) |
| 106 | + return 0; |
| 107 | + |
| 108 | + if (!sd_group) |
| 109 | + return 0; |
| 110 | + |
| 111 | + group_id = mlx5_sd_group_id(dev, sd_group); |
| 112 | + |
| 113 | + if (!mlx5_sd_is_supported(dev, host_buses)) { |
| 114 | + sd_warn(dev, "can't support requested netdev combining for group id 0x%x), skipping\n", |
| 115 | + group_id); |
| 116 | + return 0; |
| 117 | + } |
| 118 | + |
| 119 | + sd = kzalloc(sizeof(*sd), GFP_KERNEL); |
| 120 | + if (!sd) |
| 121 | + return -ENOMEM; |
| 122 | + |
| 123 | + sd->host_buses = host_buses; |
| 124 | + sd->group_id = group_id; |
| 125 | + |
| 126 | + mlx5_set_sd(dev, sd); |
| 127 | + |
| 128 | + return 0; |
| 129 | +} |
| 130 | + |
| 131 | +static void sd_cleanup(struct mlx5_core_dev *dev) |
| 132 | +{ |
| 133 | + struct mlx5_sd *sd = mlx5_get_sd(dev); |
| 134 | + |
| 135 | + mlx5_set_sd(dev, NULL); |
| 136 | + kfree(sd); |
| 137 | +} |
| 138 | + |
46 | 139 | int mlx5_sd_init(struct mlx5_core_dev *dev)
|
47 | 140 | {
|
| 141 | + int err; |
| 142 | + |
| 143 | + err = sd_init(dev); |
| 144 | + if (err) |
| 145 | + return err; |
| 146 | + |
48 | 147 | return 0;
|
49 | 148 | }
|
50 | 149 |
|
51 | 150 | void mlx5_sd_cleanup(struct mlx5_core_dev *dev)
|
52 | 151 | {
|
| 152 | + struct mlx5_sd *sd = mlx5_get_sd(dev); |
| 153 | + |
| 154 | + if (!sd) |
| 155 | + return; |
| 156 | + |
| 157 | + sd_cleanup(dev); |
53 | 158 | }
|
54 | 159 |
|
55 | 160 | struct auxiliary_device *mlx5_sd_get_adev(struct mlx5_core_dev *dev,
|
|
0 commit comments