Saeed Mahameed says: ==================== mlx5 fixes 2020-07-02 This series introduces some fixes to mlx5 driver. V1->v2: - Drop "ip -s" patch and mirred device hold reference patch. - Will revise them in a later submission. Please pull and let me know if there is any problem. For -stable v5.2 ('net/mlx5: Fix eeprom support for SFP module') For -stable v5.4 ('net/mlx5e: Fix 50G per lane indication') For -stable v5.5 ('net/mlx5e: Fix CPU mapping after function reload to avoid aRFS RX crash') ('net/mlx5e: Fix VXLAN configuration restore after function reload') For -stable v5.7 ('net/mlx5e: CT: Fix memory leak in cleanup') ====================
Unified · Split
| @@ -29,6 +29,7 @@ struct mlx5e_dcbx { · 28 unmodified lines | ||
| 29 | 29 | bool manual_buffer; |
| 30 | 30 | u32 cable_len; |
| 31 | 31 | u32 xoff; |
| 32 | + u16 port_buff_cell_sz; | |
| 32 | 33 | }; |
| 33 | 34 | |
| 34 | 35 | #define MLX5E_MAX_DSCP (64) |
| @@ -78,11 +78,26 @@ static const u32 mlx5e_ext_link_speed[MLX5E_EXT_LINK_MODES_NUMBER] = { · 77 unmodified lines | ||
| 78 | 78 | [MLX5E_400GAUI_8] = 400000, |
| 79 | 79 | }; |
| 80 | 80 | |
| 81 | +bool mlx5e_ptys_ext_supported(struct mlx5_core_dev *mdev) | |
| 82 | +{ | |
| 83 | + struct mlx5e_port_eth_proto eproto; | |
| 84 | + int err; | |
| 85 | + | |
| 86 | + if (MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet)) | |
| 87 | + return true; | |
| 88 | + | |
| 89 | + err = mlx5_port_query_eth_proto(mdev, 1, true, &eproto); | |
| 90 | + if (err) | |
| 91 | + return false; | |
| 92 | + | |
| 93 | + return !!eproto.cap; | |
| 94 | +} | |
| 95 | + | |
| 81 | 96 | static void mlx5e_port_get_speed_arr(struct mlx5_core_dev *mdev, |
| 82 | 97 | const u32 **arr, u32 *size, |
| 83 | 98 | bool force_legacy) |
| 84 | 99 | { |
| 85 | − bool ext = force_legacy ? false : MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); | |
| 100 | + bool ext = force_legacy ? false : mlx5e_ptys_ext_supported(mdev); | |
| 86 | 101 | |
| 87 | 102 | *size = ext ? ARRAY_SIZE(mlx5e_ext_link_speed) : |
| 88 | 103 | ARRAY_SIZE(mlx5e_link_speed); |
| @@ -177,7 +192,7 @@ int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed) · 88 unmodified lines | ||
| 177 | 192 | bool ext; |
| 178 | 193 | int err; |
| 179 | 194 | |
| 180 | − ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); | |
| 195 | + ext = mlx5e_ptys_ext_supported(mdev); | |
| 181 | 196 | err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto); |
| 182 | 197 | if (err) |
| 183 | 198 | goto out; |
| @@ -205,7 +220,7 @@ int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed) · 21 unmodified lines | ||
| 205 | 220 | int err; |
| 206 | 221 | int i; |
| 207 | 222 | |
| 208 | − ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); | |
| 223 | + ext = mlx5e_ptys_ext_supported(mdev); | |
| 209 | 224 | err = mlx5_port_query_eth_proto(mdev, 1, ext, &eproto); |
| 210 | 225 | if (err) |
| 211 | 226 | return err; |
| @@ -54,7 +54,7 @@ int mlx5e_port_linkspeed(struct mlx5_core_dev *mdev, u32 *speed); · 53 unmodified lines | ||
| 54 | 54 | int mlx5e_port_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed); |
| 55 | 55 | u32 mlx5e_port_speed2linkmodes(struct mlx5_core_dev *mdev, u32 speed, |
| 56 | 56 | bool force_legacy); |
| 57 | − | |
| 57 | +bool mlx5e_ptys_ext_supported(struct mlx5_core_dev *mdev); | |
| 58 | 58 | int mlx5e_port_query_pbmc(struct mlx5_core_dev *mdev, void *out); |
| 59 | 59 | int mlx5e_port_set_pbmc(struct mlx5_core_dev *mdev, void *in); |
| 60 | 60 | int mlx5e_port_query_priority2buffer(struct mlx5_core_dev *mdev, u8 *buffer); |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | int mlx5e_port_query_buffer(struct mlx5e_priv *priv, |
| 35 | 35 | struct mlx5e_port_buffer *port_buffer) |
| 36 | 36 | { |
| 37 | + u16 port_buff_cell_sz = priv->dcbx.port_buff_cell_sz; | |
| 37 | 38 | struct mlx5_core_dev *mdev = priv->mdev; |
| 38 | 39 | int sz = MLX5_ST_SZ_BYTES(pbmc_reg); |
| 39 | 40 | u32 total_used = 0; |
| @@ -57,11 +58,11 @@ int mlx5e_port_query_buffer(struct mlx5e_priv *priv, · 17 unmodified lines | ||
| 57 | 58 | port_buffer->buffer[i].epsb = |
| 58 | 59 | MLX5_GET(bufferx_reg, buffer, epsb); |
| 59 | 60 | port_buffer->buffer[i].size = |
| 60 | − MLX5_GET(bufferx_reg, buffer, size) << MLX5E_BUFFER_CELL_SHIFT; | |
| 61 | + MLX5_GET(bufferx_reg, buffer, size) * port_buff_cell_sz; | |
| 61 | 62 | port_buffer->buffer[i].xon = |
| 62 | − MLX5_GET(bufferx_reg, buffer, xon_threshold) << MLX5E_BUFFER_CELL_SHIFT; | |
| 63 | + MLX5_GET(bufferx_reg, buffer, xon_threshold) * port_buff_cell_sz; | |
| 63 | 64 | port_buffer->buffer[i].xoff = |
| 64 | − MLX5_GET(bufferx_reg, buffer, xoff_threshold) << MLX5E_BUFFER_CELL_SHIFT; | |
| 65 | + MLX5_GET(bufferx_reg, buffer, xoff_threshold) * port_buff_cell_sz; | |
| 65 | 66 | total_used += port_buffer->buffer[i].size; |
| 66 | 67 | |
| 67 | 68 | mlx5e_dbg(HW, priv, "buffer %d: size=%d, xon=%d, xoff=%d, epsb=%d, lossy=%d\n", i, |
| @@ -73,7 +74,7 @@ int mlx5e_port_query_buffer(struct mlx5e_priv *priv, · 5 unmodified lines | ||
| 73 | 74 | } |
| 74 | 75 | |
| 75 | 76 | port_buffer->port_buffer_size = |
| 76 | − MLX5_GET(pbmc_reg, out, port_buffer_size) << MLX5E_BUFFER_CELL_SHIFT; | |
| 77 | + MLX5_GET(pbmc_reg, out, port_buffer_size) * port_buff_cell_sz; | |
| 77 | 78 | port_buffer->spare_buffer_size = |
| 78 | 79 | port_buffer->port_buffer_size - total_used; |
| 79 | 80 | |
| @@ -88,9 +89,9 @@ out: · 8 unmodified lines | ||
| 88 | 89 | static int port_set_buffer(struct mlx5e_priv *priv, |
| 89 | 90 | struct mlx5e_port_buffer *port_buffer) |
| 90 | 91 | { |
| 92 | + u16 port_buff_cell_sz = priv->dcbx.port_buff_cell_sz; | |
| 91 | 93 | struct mlx5_core_dev *mdev = priv->mdev; |
| 92 | 94 | int sz = MLX5_ST_SZ_BYTES(pbmc_reg); |
| 93 | − void *buffer; | |
| 94 | 95 | void *in; |
| 95 | 96 | int err; |
| 96 | 97 | int i; |
| @@ -104,16 +105,18 @@ static int port_set_buffer(struct mlx5e_priv *priv, · 7 unmodified lines | ||
| 104 | 105 | goto out; |
| 105 | 106 | |
| 106 | 107 | for (i = 0; i < MLX5E_MAX_BUFFER; i++) { |
| 107 | − buffer = MLX5_ADDR_OF(pbmc_reg, in, buffer[i]); | |
| 108 | − | |
| 109 | − MLX5_SET(bufferx_reg, buffer, size, | |
| 110 | − port_buffer->buffer[i].size >> MLX5E_BUFFER_CELL_SHIFT); | |
| 111 | − MLX5_SET(bufferx_reg, buffer, lossy, | |
| 112 | − port_buffer->buffer[i].lossy); | |
| 113 | − MLX5_SET(bufferx_reg, buffer, xoff_threshold, | |
| 114 | − port_buffer->buffer[i].xoff >> MLX5E_BUFFER_CELL_SHIFT); | |
| 115 | − MLX5_SET(bufferx_reg, buffer, xon_threshold, | |
| 116 | − port_buffer->buffer[i].xon >> MLX5E_BUFFER_CELL_SHIFT); | |
| 108 | + void *buffer = MLX5_ADDR_OF(pbmc_reg, in, buffer[i]); | |
| 109 | + u64 size = port_buffer->buffer[i].size; | |
| 110 | + u64 xoff = port_buffer->buffer[i].xoff; | |
| 111 | + u64 xon = port_buffer->buffer[i].xon; | |
| 112 | + | |
| 113 | + do_div(size, port_buff_cell_sz); | |
| 114 | + do_div(xoff, port_buff_cell_sz); | |
| 115 | + do_div(xon, port_buff_cell_sz); | |
| 116 | + MLX5_SET(bufferx_reg, buffer, size, size); | |
| 117 | + MLX5_SET(bufferx_reg, buffer, lossy, port_buffer->buffer[i].lossy); | |
| 118 | + MLX5_SET(bufferx_reg, buffer, xoff_threshold, xoff); | |
| 119 | + MLX5_SET(bufferx_reg, buffer, xon_threshold, xon); | |
| 117 | 120 | } |
| 118 | 121 | |
| 119 | 122 | err = mlx5e_port_set_pbmc(mdev, in); |
| @@ -143,7 +146,7 @@ static u32 calculate_xoff(struct mlx5e_priv *priv, unsigned int mtu) · 23 unmodified lines | ||
| 143 | 146 | } |
| 144 | 147 | |
| 145 | 148 | static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer, |
| 146 | − u32 xoff, unsigned int max_mtu) | |
| 149 | + u32 xoff, unsigned int max_mtu, u16 port_buff_cell_sz) | |
| 147 | 150 | { |
| 148 | 151 | int i; |
| 149 | 152 | |
| @@ -155,7 +158,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer, · 5 unmodified lines | ||
| 155 | 158 | } |
| 156 | 159 | |
| 157 | 160 | if (port_buffer->buffer[i].size < |
| 158 | − (xoff + max_mtu + (1 << MLX5E_BUFFER_CELL_SHIFT))) { | |
| 161 | + (xoff + max_mtu + port_buff_cell_sz)) { | |
| 159 | 162 | pr_err("buffer_size[%d]=%d is not enough for lossless buffer\n", |
| 160 | 163 | i, port_buffer->buffer[i].size); |
| 161 | 164 | return -ENOMEM; |
| @@ -175,6 +178,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer, · 13 unmodified lines | ||
| 175 | 178 | * @pfc_en: <input> current pfc configuration |
| 176 | 179 | * @buffer: <input> current prio to buffer mapping |
| 177 | 180 | * @xoff: <input> xoff value |
| 181 | + * @port_buff_cell_sz: <input> port buffer cell_size | |
| 178 | 182 | * @port_buffer: <output> port receive buffer configuration |
| 179 | 183 | * @change: <output> |
| 180 | 184 | * |
| @@ -189,7 +193,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer, · 8 unmodified lines | ||
| 189 | 193 | * sets change to true if buffer configuration was modified. |
| 190 | 194 | */ |
| 191 | 195 | static int update_buffer_lossy(unsigned int max_mtu, |
| 192 | − u8 pfc_en, u8 *buffer, u32 xoff, | |
| 196 | + u8 pfc_en, u8 *buffer, u32 xoff, u16 port_buff_cell_sz, | |
| 193 | 197 | struct mlx5e_port_buffer *port_buffer, |
| 194 | 198 | bool *change) |
| 195 | 199 | { |
| @@ -225,7 +229,7 @@ static int update_buffer_lossy(unsigned int max_mtu, · 29 unmodified lines | ||
| 225 | 229 | } |
| 226 | 230 | |
| 227 | 231 | if (changed) { |
| 228 | − err = update_xoff_threshold(port_buffer, xoff, max_mtu); | |
| 232 | + err = update_xoff_threshold(port_buffer, xoff, max_mtu, port_buff_cell_sz); | |
| 229 | 233 | if (err) |
| 230 | 234 | return err; |
| 231 | 235 | |
| @@ -262,6 +266,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, · 30 unmodified lines | ||
| 262 | 266 | u32 *buffer_size, |
| 263 | 267 | u8 *prio2buffer) |
| 264 | 268 | { |
| 269 | + u16 port_buff_cell_sz = priv->dcbx.port_buff_cell_sz; | |
| 265 | 270 | struct mlx5e_port_buffer port_buffer; |
| 266 | 271 | u32 xoff = calculate_xoff(priv, mtu); |
| 267 | 272 | bool update_prio2buffer = false; |
| @@ -282,7 +287,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, · 14 unmodified lines | ||
| 282 | 287 | |
| 283 | 288 | if (change & MLX5E_PORT_BUFFER_CABLE_LEN) { |
| 284 | 289 | update_buffer = true; |
| 285 | − err = update_xoff_threshold(&port_buffer, xoff, max_mtu); | |
| 290 | + err = update_xoff_threshold(&port_buffer, xoff, max_mtu, port_buff_cell_sz); | |
| 286 | 291 | if (err) |
| 287 | 292 | return err; |
| 288 | 293 | } |
| @@ -292,7 +297,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, · 3 unmodified lines | ||
| 292 | 297 | if (err) |
| 293 | 298 | return err; |
| 294 | 299 | |
| 295 | − err = update_buffer_lossy(max_mtu, pfc->pfc_en, buffer, xoff, | |
| 300 | + err = update_buffer_lossy(max_mtu, pfc->pfc_en, buffer, xoff, port_buff_cell_sz, | |
| 296 | 301 | &port_buffer, &update_buffer); |
| 297 | 302 | if (err) |
| 298 | 303 | return err; |
| @@ -304,7 +309,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, · 5 unmodified lines | ||
| 304 | 309 | if (err) |
| 305 | 310 | return err; |
| 306 | 311 | |
| 307 | − err = update_buffer_lossy(max_mtu, curr_pfc_en, prio2buffer, | |
| 312 | + err = update_buffer_lossy(max_mtu, curr_pfc_en, prio2buffer, port_buff_cell_sz, | |
| 308 | 313 | xoff, &port_buffer, &update_buffer); |
| 309 | 314 | if (err) |
| 310 | 315 | return err; |
| @@ -329,7 +334,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, · 18 unmodified lines | ||
| 329 | 334 | return -EINVAL; |
| 330 | 335 | |
| 331 | 336 | update_buffer = true; |
| 332 | − err = update_xoff_threshold(&port_buffer, xoff, max_mtu); | |
| 337 | + err = update_xoff_threshold(&port_buffer, xoff, max_mtu, port_buff_cell_sz); | |
| 333 | 338 | if (err) |
| 334 | 339 | return err; |
| 335 | 340 | } |
| @@ -337,7 +342,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, · 1 unmodified line | ||
| 337 | 342 | /* Need to update buffer configuration if xoff value is changed */ |
| 338 | 343 | if (!update_buffer && xoff != priv->dcbx.xoff) { |
| 339 | 344 | update_buffer = true; |
| 340 | − err = update_xoff_threshold(&port_buffer, xoff, max_mtu); | |
| 345 | + err = update_xoff_threshold(&port_buffer, xoff, max_mtu, port_buff_cell_sz); | |
| 341 | 346 | if (err) |
| 342 | 347 | return err; |
| 343 | 348 | } |
| @@ -36,7 +36,6 @@ · 35 unmodified lines | ||
| 36 | 36 | #include "port.h" |
| 37 | 37 | |
| 38 | 38 | #define MLX5E_MAX_BUFFER 8 |
| 39 | −#define MLX5E_BUFFER_CELL_SHIFT 7 | |
| 40 | 39 | #define MLX5E_DEFAULT_CABLE_LEN 7 /* 7 meters */ |
| 41 | 40 | |
| 42 | 41 | #define MLX5_BUFFER_SUPPORTED(mdev) (MLX5_CAP_GEN(mdev, pcam_reg) && \ |
| @@ -1097,6 +1097,7 @@ mlx5_tc_ct_flush_ft_entry(void *ptr, void *arg) · 1096 unmodified lines | ||
| 1097 | 1097 | struct mlx5_ct_entry *entry = ptr; |
| 1098 | 1098 | |
| 1099 | 1099 | mlx5_tc_ct_entry_del_rules(ct_priv, entry); |
| 1100 | + kfree(entry); | |
| 1100 | 1101 | } |
| 1101 | 1102 | |
| 1102 | 1103 | static void |
| @@ -1217,6 +1217,24 @@ static int mlx5e_trust_initialize(struct mlx5e_priv *priv) · 1216 unmodified lines | ||
| 1217 | 1217 | return 0; |
| 1218 | 1218 | } |
| 1219 | 1219 | |
| 1220 | +#define MLX5E_BUFFER_CELL_SHIFT 7 | |
| 1221 | + | |
| 1222 | +static u16 mlx5e_query_port_buffers_cell_size(struct mlx5e_priv *priv) | |
| 1223 | +{ | |
| 1224 | + struct mlx5_core_dev *mdev = priv->mdev; | |
| 1225 | + u32 out[MLX5_ST_SZ_DW(sbcam_reg)] = {}; | |
| 1226 | + u32 in[MLX5_ST_SZ_DW(sbcam_reg)] = {}; | |
| 1227 | + | |
| 1228 | + if (!MLX5_CAP_GEN(mdev, sbcam_reg)) | |
| 1229 | + return (1 << MLX5E_BUFFER_CELL_SHIFT); | |
| 1230 | + | |
| 1231 | + if (mlx5_core_access_reg(mdev, in, sizeof(in), out, sizeof(out), | |
| 1232 | + MLX5_REG_SBCAM, 0, 0)) | |
| 1233 | + return (1 << MLX5E_BUFFER_CELL_SHIFT); | |
| 1234 | + | |
| 1235 | + return MLX5_GET(sbcam_reg, out, cap_cell_size); | |
| 1236 | +} | |
| 1237 | + | |
| 1220 | 1238 | void mlx5e_dcbnl_initialize(struct mlx5e_priv *priv) |
| 1221 | 1239 | { |
| 1222 | 1240 | struct mlx5e_dcbx *dcbx = &priv->dcbx; |
| @@ -1234,6 +1252,7 @@ void mlx5e_dcbnl_initialize(struct mlx5e_priv *priv) · 11 unmodified lines | ||
| 1234 | 1252 | if (priv->dcbx.mode == MLX5E_DCBX_PARAM_VER_OPER_HOST) |
| 1235 | 1253 | priv->dcbx.cap |= DCB_CAP_DCBX_HOST; |
| 1236 | 1254 | |
| 1255 | + priv->dcbx.port_buff_cell_sz = mlx5e_query_port_buffers_cell_size(priv); | |
| 1237 | 1256 | priv->dcbx.manual_buffer = false; |
| 1238 | 1257 | priv->dcbx.cable_len = MLX5E_DEFAULT_CABLE_LEN; |
| 1239 | 1258 | |
| @@ -200,7 +200,7 @@ static void mlx5e_ethtool_get_speed_arr(struct mlx5_core_dev *mdev, · 199 unmodified lines | ||
| 200 | 200 | struct ptys2ethtool_config **arr, |
| 201 | 201 | u32 *size) |
| 202 | 202 | { |
| 203 | − bool ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); | |
| 203 | + bool ext = mlx5e_ptys_ext_supported(mdev); | |
| 204 | 204 | |
| 205 | 205 | *arr = ext ? ptys2ext_ethtool_table : ptys2legacy_ethtool_table; |
| 206 | 206 | *size = ext ? ARRAY_SIZE(ptys2ext_ethtool_table) : |
| @@ -883,7 +883,7 @@ static void get_lp_advertising(struct mlx5_core_dev *mdev, u32 eth_proto_lp, · 676 unmodified lines | ||
| 883 | 883 | struct ethtool_link_ksettings *link_ksettings) |
| 884 | 884 | { |
| 885 | 885 | unsigned long *lp_advertising = link_ksettings->link_modes.lp_advertising; |
| 886 | − bool ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); | |
| 886 | + bool ext = mlx5e_ptys_ext_supported(mdev); | |
| 887 | 887 | |
| 888 | 888 | ptys2ethtool_adver_link(lp_advertising, eth_proto_lp, ext); |
| 889 | 889 | } |
| @@ -913,7 +913,7 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv, · 23 unmodified lines | ||
| 913 | 913 | __func__, err); |
| 914 | 914 | goto err_query_regs; |
| 915 | 915 | } |
| 916 | − ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); | |
| 916 | + ext = !!MLX5_GET_ETH_PROTO(ptys_reg, out, true, eth_proto_capability); | |
| 917 | 917 | eth_proto_cap = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, |
| 918 | 918 | eth_proto_capability); |
| 919 | 919 | eth_proto_admin = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, |
| @@ -1066,7 +1066,7 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv, · 146 unmodified lines | ||
| 1066 | 1066 | autoneg = link_ksettings->base.autoneg; |
| 1067 | 1067 | speed = link_ksettings->base.speed; |
| 1068 | 1068 | |
| 1069 | − ext_supported = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); | |
| 1069 | + ext_supported = mlx5e_ptys_ext_supported(mdev); | |
| 1070 | 1070 | ext = ext_requested(autoneg, adver, ext_supported); |
| 1071 | 1071 | if (!ext_supported && ext) |
| 1072 | 1072 | return -EOPNOTSUPP; |
| @@ -3104,9 +3104,6 @@ int mlx5e_open(struct net_device *netdev) · 3103 unmodified lines | ||
| 3104 | 3104 | mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_UP); |
| 3105 | 3105 | mutex_unlock(&priv->state_lock); |
| 3106 | 3106 | |
| 3107 | − if (mlx5_vxlan_allowed(priv->mdev->vxlan)) | |
| 3108 | − udp_tunnel_get_rx_info(netdev); | |
| 3109 | − | |
| 3110 | 3107 | return err; |
| 3111 | 3108 | } |
| 3112 | 3109 | |
| @@ -5121,6 +5118,10 @@ static int mlx5e_init_nic_rx(struct mlx5e_priv *priv) · 2008 unmodified lines | ||
| 5121 | 5118 | if (err) |
| 5122 | 5119 | goto err_destroy_flow_steering; |
| 5123 | 5120 | |
| 5121 | +#ifdef CONFIG_MLX5_EN_ARFS | |
| 5122 | + priv->netdev->rx_cpu_rmap = mlx5_eq_table_get_rmap(priv->mdev); | |
| 5123 | +#endif | |
| 5124 | + | |
| 5124 | 5125 | return 0; |
| 5125 | 5126 | |
| 5126 | 5127 | err_destroy_flow_steering: |
| @@ -5202,6 +5203,8 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv) · 75 unmodified lines | ||
| 5202 | 5203 | rtnl_lock(); |
| 5203 | 5204 | if (netif_running(netdev)) |
| 5204 | 5205 | mlx5e_open(netdev); |
| 5206 | + if (mlx5_vxlan_allowed(priv->mdev->vxlan)) | |
| 5207 | + udp_tunnel_get_rx_info(netdev); | |
| 5205 | 5208 | netif_device_attach(netdev); |
| 5206 | 5209 | rtnl_unlock(); |
| 5207 | 5210 | } |
| @@ -5216,6 +5219,8 @@ static void mlx5e_nic_disable(struct mlx5e_priv *priv) · 8 unmodified lines | ||
| 5216 | 5219 | rtnl_lock(); |
| 5217 | 5220 | if (netif_running(priv->netdev)) |
| 5218 | 5221 | mlx5e_close(priv->netdev); |
| 5222 | + if (mlx5_vxlan_allowed(priv->mdev->vxlan)) | |
| 5223 | + udp_tunnel_drop_rx_info(priv->netdev); | |
| 5219 | 5224 | netif_device_detach(priv->netdev); |
| 5220 | 5225 | rtnl_unlock(); |
| 5221 | 5226 | |
| @@ -5288,10 +5293,6 @@ int mlx5e_netdev_init(struct net_device *netdev, · 66 unmodified lines | ||
| 5288 | 5293 | /* netdev init */ |
| 5289 | 5294 | netif_carrier_off(netdev); |
| 5290 | 5295 | |
| 5291 | −#ifdef CONFIG_MLX5_EN_ARFS | |
| 5292 | − netdev->rx_cpu_rmap = mlx5_eq_table_get_rmap(mdev); | |
| 5293 | −#endif | |
| 5294 | − | |
| 5295 | 5296 | return 0; |
| 5296 | 5297 | |
| 5297 | 5298 | err_free_cpumask: |
| @@ -4670,9 +4670,10 @@ static bool is_flow_rule_duplicate_allowed(struct net_device *dev, · 4669 unmodified lines | ||
| 4670 | 4670 | struct mlx5e_rep_priv *rpriv) |
| 4671 | 4671 | { |
| 4672 | 4672 | /* Offloaded flow rule is allowed to duplicate on non-uplink representor |
| 4673 | − * sharing tc block with other slaves of a lag device. | |
| 4673 | + * sharing tc block with other slaves of a lag device. Rpriv can be NULL if this | |
| 4674 | + * function is called from NIC mode. | |
| 4674 | 4675 | */ |
| 4675 | − return netif_is_lag_port(dev) && rpriv->rep->vport != MLX5_VPORT_UPLINK; | |
| 4676 | + return netif_is_lag_port(dev) && rpriv && rpriv->rep->vport != MLX5_VPORT_UPLINK; | |
| 4676 | 4677 | } |
| 4677 | 4678 | |
| 4678 | 4679 | int mlx5e_configure_flower(struct net_device *dev, struct mlx5e_priv *priv, |
| @@ -4686,13 +4687,12 @@ int mlx5e_configure_flower(struct net_device *dev, struct mlx5e_priv *priv, · 7 unmodified lines | ||
| 4686 | 4687 | |
| 4687 | 4688 | rcu_read_lock(); |
| 4688 | 4689 | flow = rhashtable_lookup(tc_ht, &f->cookie, tc_ht_params); |
| 4689 | − rcu_read_unlock(); | |
| 4690 | 4690 | if (flow) { |
| 4691 | 4691 | /* Same flow rule offloaded to non-uplink representor sharing tc block, |
| 4692 | 4692 | * just return 0. |
| 4693 | 4693 | */ |
| 4694 | 4694 | if (is_flow_rule_duplicate_allowed(dev, rpriv) && flow->orig_dev != dev) |
| 4695 | − goto out; | |
| 4695 | + goto rcu_unlock; | |
| 4696 | 4696 | |
| 4697 | 4697 | NL_SET_ERR_MSG_MOD(extack, |
| 4698 | 4698 | "flow cookie already exists, ignoring"); |
| @@ -4700,8 +4700,12 @@ int mlx5e_configure_flower(struct net_device *dev, struct mlx5e_priv *priv, · 1 unmodified line | ||
| 4700 | 4700 | "flow cookie %lx already exists, ignoring\n", |
| 4701 | 4701 | f->cookie); |
| 4702 | 4702 | err = -EEXIST; |
| 4703 | − goto out; | |
| 4703 | + goto rcu_unlock; | |
| 4704 | 4704 | } |
| 4705 | +rcu_unlock: | |
| 4706 | + rcu_read_unlock(); | |
| 4707 | + if (flow) | |
| 4708 | + goto out; | |
| 4705 | 4709 | |
| 4706 | 4710 | trace_mlx5e_configure_flower(f); |
| 4707 | 4711 | err = mlx5e_tc_add_flow(priv, f, flags, dev, &flow); |
| @@ -217,7 +217,6 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw, · 216 unmodified lines | ||
| 217 | 217 | } |
| 218 | 218 | |
| 219 | 219 | /* Create ingress allow rule */ |
| 220 | − memset(spec, 0, sizeof(*spec)); | |
| 221 | 220 | spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; |
| 222 | 221 | flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW; |
| 223 | 222 | vport->ingress.allow_rule = mlx5_add_flow_rules(vport->ingress.acl, spec, |
| @@ -293,7 +293,40 @@ static int mlx5_query_module_num(struct mlx5_core_dev *dev, int *module_num) · 292 unmodified lines | ||
| 293 | 293 | return 0; |
| 294 | 294 | } |
| 295 | 295 | |
| 296 | −static int mlx5_eeprom_page(int offset) | |
| 296 | +static int mlx5_query_module_id(struct mlx5_core_dev *dev, int module_num, | |
| 297 | + u8 *module_id) | |
| 298 | +{ | |
| 299 | + u32 in[MLX5_ST_SZ_DW(mcia_reg)] = {}; | |
| 300 | + u32 out[MLX5_ST_SZ_DW(mcia_reg)]; | |
| 301 | + int err, status; | |
| 302 | + u8 *ptr; | |
| 303 | + | |
| 304 | + MLX5_SET(mcia_reg, in, i2c_device_address, MLX5_I2C_ADDR_LOW); | |
| 305 | + MLX5_SET(mcia_reg, in, module, module_num); | |
| 306 | + MLX5_SET(mcia_reg, in, device_address, 0); | |
| 307 | + MLX5_SET(mcia_reg, in, page_number, 0); | |
| 308 | + MLX5_SET(mcia_reg, in, size, 1); | |
| 309 | + MLX5_SET(mcia_reg, in, l, 0); | |
| 310 | + | |
| 311 | + err = mlx5_core_access_reg(dev, in, sizeof(in), out, | |
| 312 | + sizeof(out), MLX5_REG_MCIA, 0, 0); | |
| 313 | + if (err) | |
| 314 | + return err; | |
| 315 | + | |
| 316 | + status = MLX5_GET(mcia_reg, out, status); | |
| 317 | + if (status) { | |
| 318 | + mlx5_core_err(dev, "query_mcia_reg failed: status: 0x%x\n", | |
| 319 | + status); | |
| 320 | + return -EIO; | |
| 321 | + } | |
| 322 | + ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0); | |
| 323 | + | |
| 324 | + *module_id = ptr[0]; | |
| 325 | + | |
| 326 | + return 0; | |
| 327 | +} | |
| 328 | + | |
| 329 | +static int mlx5_qsfp_eeprom_page(u16 offset) | |
| 297 | 330 | { |
| 298 | 331 | if (offset < MLX5_EEPROM_PAGE_LENGTH) |
| 299 | 332 | /* Addresses between 0-255 - page 00 */ |
| @@ -307,7 +340,7 @@ static int mlx5_eeprom_page(int offset) · 7 unmodified lines | ||
| 307 | 340 | MLX5_EEPROM_HIGH_PAGE_LENGTH); |
| 308 | 341 | } |
| 309 | 342 | |
| 310 | −static int mlx5_eeprom_high_page_offset(int page_num) | |
| 343 | +static int mlx5_qsfp_eeprom_high_page_offset(int page_num) | |
| 311 | 344 | { |
| 312 | 345 | if (!page_num) /* Page 0 always start from low page */ |
| 313 | 346 | return 0; |
| @@ -316,35 +349,62 @@ static int mlx5_eeprom_high_page_offset(int page_num) · 2 unmodified lines | ||
| 316 | 349 | return page_num * MLX5_EEPROM_HIGH_PAGE_LENGTH; |
| 317 | 350 | } |
| 318 | 351 | |
| 352 | +static void mlx5_qsfp_eeprom_params_set(u16 *i2c_addr, int *page_num, u16 *offset) | |
| 353 | +{ | |
| 354 | + *i2c_addr = MLX5_I2C_ADDR_LOW; | |
| 355 | + *page_num = mlx5_qsfp_eeprom_page(*offset); | |
| 356 | + *offset -= mlx5_qsfp_eeprom_high_page_offset(*page_num); | |
| 357 | +} | |
| 358 | + | |
| 359 | +static void mlx5_sfp_eeprom_params_set(u16 *i2c_addr, int *page_num, u16 *offset) | |
| 360 | +{ | |
| 361 | + *i2c_addr = MLX5_I2C_ADDR_LOW; | |
| 362 | + *page_num = 0; | |
| 363 | + | |
| 364 | + if (*offset < MLX5_EEPROM_PAGE_LENGTH) | |
| 365 | + return; | |
| 366 | + | |
| 367 | + *i2c_addr = MLX5_I2C_ADDR_HIGH; | |
| 368 | + *offset -= MLX5_EEPROM_PAGE_LENGTH; | |
| 369 | +} | |
| 370 | + | |
| 319 | 371 | int mlx5_query_module_eeprom(struct mlx5_core_dev *dev, |
| 320 | 372 | u16 offset, u16 size, u8 *data) |
| 321 | 373 | { |
| 322 | − int module_num, page_num, status, err; | |
| 374 | + int module_num, status, err, page_num = 0; | |
| 375 | + u32 in[MLX5_ST_SZ_DW(mcia_reg)] = {}; | |
| 323 | 376 | u32 out[MLX5_ST_SZ_DW(mcia_reg)]; |
| 324 | − u32 in[MLX5_ST_SZ_DW(mcia_reg)]; | |
| 325 | − u16 i2c_addr; | |
| 326 | − void *ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0); | |
| 377 | + u16 i2c_addr = 0; | |
| 378 | + u8 module_id; | |
| 379 | + void *ptr; | |
| 327 | 380 | |
| 328 | 381 | err = mlx5_query_module_num(dev, &module_num); |
| 329 | 382 | if (err) |
| 330 | 383 | return err; |
| 331 | 384 | |
| 332 | − memset(in, 0, sizeof(in)); | |
| 333 | − size = min_t(int, size, MLX5_EEPROM_MAX_BYTES); | |
| 334 | − | |
| 335 | − /* Get the page number related to the given offset */ | |
| 336 | − page_num = mlx5_eeprom_page(offset); | |
| 385 | + err = mlx5_query_module_id(dev, module_num, &module_id); | |
| 386 | + if (err) | |
| 387 | + return err; | |
| 337 | 388 | |
| 338 | − /* Set the right offset according to the page number, | |
| 339 | − * For page_num > 0, relative offset is always >= 128 (high page). | |
| 340 | − */ | |
| 341 | − offset -= mlx5_eeprom_high_page_offset(page_num); | |
| 389 | + switch (module_id) { | |
| 390 | + case MLX5_MODULE_ID_SFP: | |
| 391 | + mlx5_sfp_eeprom_params_set(&i2c_addr, &page_num, &offset); | |
| 392 | + break; | |
| 393 | + case MLX5_MODULE_ID_QSFP: | |
| 394 | + case MLX5_MODULE_ID_QSFP_PLUS: | |
| 395 | + case MLX5_MODULE_ID_QSFP28: | |
| 396 | + mlx5_qsfp_eeprom_params_set(&i2c_addr, &page_num, &offset); | |
| 397 | + break; | |
| 398 | + default: | |
| 399 | + mlx5_core_err(dev, "Module ID not recognized: 0x%x\n", module_id); | |
| 400 | + return -EINVAL; | |
| 401 | + } | |
| 342 | 402 | |
| 343 | 403 | if (offset + size > MLX5_EEPROM_PAGE_LENGTH) |
| 344 | 404 | /* Cross pages read, read until offset 256 in low page */ |
| 345 | 405 | size -= offset + size - MLX5_EEPROM_PAGE_LENGTH; |
| 346 | 406 | |
| 347 | − i2c_addr = MLX5_I2C_ADDR_LOW; | |
| 407 | + size = min_t(int, size, MLX5_EEPROM_MAX_BYTES); | |
| 348 | 408 | |
| 349 | 409 | MLX5_SET(mcia_reg, in, l, 0); |
| 350 | 410 | MLX5_SET(mcia_reg, in, module, module_num); |
| @@ -365,6 +425,7 @@ int mlx5_query_module_eeprom(struct mlx5_core_dev *dev, · 14 unmodified lines | ||
| 365 | 425 | return -EIO; |
| 366 | 426 | } |
| 367 | 427 | |
| 428 | + ptr = MLX5_ADDR_OF(mcia_reg, out, dword_0); | |
| 368 | 429 | memcpy(data, ptr, size); |
| 369 | 430 | |
| 370 | 431 | return size; |
| @@ -147,6 +147,7 @@ enum { · 146 unmodified lines | ||
| 147 | 147 | MLX5_REG_MCDA = 0x9063, |
| 148 | 148 | MLX5_REG_MCAM = 0x907f, |
| 149 | 149 | MLX5_REG_MIRC = 0x9162, |
| 150 | + MLX5_REG_SBCAM = 0xB01F, | |
| 150 | 151 | MLX5_REG_RESOURCE_DUMP = 0xC000, |
| 151 | 152 | }; |
| 152 | 153 | |
| @@ -9960,6 +9960,34 @@ struct mlx5_ifc_pptb_reg_bits { · 9959 unmodified lines | ||
| 9960 | 9960 | u8 untagged_buff[0x4]; |
| 9961 | 9961 | }; |
| 9962 | 9962 | |
| 9963 | +struct mlx5_ifc_sbcam_reg_bits { | |
| 9964 | + u8 reserved_at_0[0x8]; | |
| 9965 | + u8 feature_group[0x8]; | |
| 9966 | + u8 reserved_at_10[0x8]; | |
| 9967 | + u8 access_reg_group[0x8]; | |
| 9968 | + | |
| 9969 | + u8 reserved_at_20[0x20]; | |
| 9970 | + | |
| 9971 | + u8 sb_access_reg_cap_mask[4][0x20]; | |
| 9972 | + | |
| 9973 | + u8 reserved_at_c0[0x80]; | |
| 9974 | + | |
| 9975 | + u8 sb_feature_cap_mask[4][0x20]; | |
| 9976 | + | |
| 9977 | + u8 reserved_at_1c0[0x40]; | |
| 9978 | + | |
| 9979 | + u8 cap_total_buffer_size[0x20]; | |
| 9980 | + | |
| 9981 | + u8 cap_cell_size[0x10]; | |
| 9982 | + u8 cap_max_pg_buffers[0x8]; | |
| 9983 | + u8 cap_num_pool_supported[0x8]; | |
| 9984 | + | |
| 9985 | + u8 reserved_at_240[0x8]; | |
| 9986 | + u8 cap_sbsr_stat_size[0x8]; | |
| 9987 | + u8 cap_max_tclass_data[0x8]; | |
| 9988 | + u8 cap_max_cpu_ingress_tclass_sb[0x8]; | |
| 9989 | +}; | |
| 9990 | + | |
| 9963 | 9991 | struct mlx5_ifc_pbmc_reg_bits { |
| 9964 | 9992 | u8 reserved_at_0[0x8]; |
| 9965 | 9993 | u8 local_port[0x8]; |