forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
....@@ -35,28 +35,50 @@
3535 #include <net/switchdev.h>
3636 #include <net/pkt_cls.h>
3737 #include <net/act_api.h>
38
-#include <net/netevent.h>
39
-#include <net/arp.h>
38
+#include <net/devlink.h>
39
+#include <net/ipv6_stubs.h>
4040
4141 #include "eswitch.h"
4242 #include "en.h"
4343 #include "en_rep.h"
44
+#include "en/txrx.h"
4445 #include "en_tc.h"
46
+#include "en/rep/tc.h"
47
+#include "en/rep/neigh.h"
4548 #include "fs_core.h"
49
+#include "lib/mlx5.h"
50
+#define CREATE_TRACE_POINTS
51
+#include "diag/en_rep_tracepoint.h"
4652
47
-#define MLX5E_REP_PARAMS_LOG_SQ_SIZE \
48
- max(0x6, MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)
49
-#define MLX5E_REP_PARAMS_LOG_RQ_SIZE \
50
- max(0x6, MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE)
53
+#define MLX5E_REP_PARAMS_DEF_LOG_SQ_SIZE \
54
+ max(0x7, MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)
55
+#define MLX5E_REP_PARAMS_DEF_NUM_CHANNELS 1
5156
5257 static const char mlx5e_rep_driver_name[] = "mlx5e_rep";
5358
5459 static void mlx5e_rep_get_drvinfo(struct net_device *dev,
5560 struct ethtool_drvinfo *drvinfo)
5661 {
62
+ struct mlx5e_priv *priv = netdev_priv(dev);
63
+ struct mlx5_core_dev *mdev = priv->mdev;
64
+
5765 strlcpy(drvinfo->driver, mlx5e_rep_driver_name,
5866 sizeof(drvinfo->driver));
5967 strlcpy(drvinfo->version, UTS_RELEASE, sizeof(drvinfo->version));
68
+ snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
69
+ "%d.%d.%04d (%.16s)",
70
+ fw_rev_maj(mdev), fw_rev_min(mdev),
71
+ fw_rev_sub(mdev), mdev->board_id);
72
+}
73
+
74
+static void mlx5e_uplink_rep_get_drvinfo(struct net_device *dev,
75
+ struct ethtool_drvinfo *drvinfo)
76
+{
77
+ struct mlx5e_priv *priv = netdev_priv(dev);
78
+
79
+ mlx5e_rep_get_drvinfo(dev, drvinfo);
80
+ strlcpy(drvinfo->bus_info, pci_name(priv->mdev->pdev),
81
+ sizeof(drvinfo->bus_info));
6082 }
6183
6284 static const struct counter_desc sw_rep_stats_desc[] = {
....@@ -83,24 +105,71 @@
83105 #define NUM_VPORT_REP_SW_COUNTERS ARRAY_SIZE(sw_rep_stats_desc)
84106 #define NUM_VPORT_REP_HW_COUNTERS ARRAY_SIZE(vport_rep_stats_desc)
85107
86
-static void mlx5e_rep_get_strings(struct net_device *dev,
87
- u32 stringset, uint8_t *data)
108
+static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(sw_rep)
88109 {
89
- int i, j;
90
-
91
- switch (stringset) {
92
- case ETH_SS_STATS:
93
- for (i = 0; i < NUM_VPORT_REP_SW_COUNTERS; i++)
94
- strcpy(data + (i * ETH_GSTRING_LEN),
95
- sw_rep_stats_desc[i].format);
96
- for (j = 0; j < NUM_VPORT_REP_HW_COUNTERS; j++, i++)
97
- strcpy(data + (i * ETH_GSTRING_LEN),
98
- vport_rep_stats_desc[j].format);
99
- break;
100
- }
110
+ return NUM_VPORT_REP_SW_COUNTERS;
101111 }
102112
103
-static void mlx5e_rep_update_hw_counters(struct mlx5e_priv *priv)
113
+static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(sw_rep)
114
+{
115
+ int i;
116
+
117
+ for (i = 0; i < NUM_VPORT_REP_SW_COUNTERS; i++)
118
+ strcpy(data + (idx++) * ETH_GSTRING_LEN,
119
+ sw_rep_stats_desc[i].format);
120
+ return idx;
121
+}
122
+
123
+static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(sw_rep)
124
+{
125
+ int i;
126
+
127
+ for (i = 0; i < NUM_VPORT_REP_SW_COUNTERS; i++)
128
+ data[idx++] = MLX5E_READ_CTR64_CPU(&priv->stats.sw,
129
+ sw_rep_stats_desc, i);
130
+ return idx;
131
+}
132
+
133
+static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(sw_rep)
134
+{
135
+ struct mlx5e_sw_stats *s = &priv->stats.sw;
136
+ struct rtnl_link_stats64 stats64 = {};
137
+
138
+ memset(s, 0, sizeof(*s));
139
+ mlx5e_fold_sw_stats64(priv, &stats64);
140
+
141
+ s->rx_packets = stats64.rx_packets;
142
+ s->rx_bytes = stats64.rx_bytes;
143
+ s->tx_packets = stats64.tx_packets;
144
+ s->tx_bytes = stats64.tx_bytes;
145
+ s->tx_queue_dropped = stats64.tx_dropped;
146
+}
147
+
148
+static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(vport_rep)
149
+{
150
+ return NUM_VPORT_REP_HW_COUNTERS;
151
+}
152
+
153
+static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(vport_rep)
154
+{
155
+ int i;
156
+
157
+ for (i = 0; i < NUM_VPORT_REP_HW_COUNTERS; i++)
158
+ strcpy(data + (idx++) * ETH_GSTRING_LEN, vport_rep_stats_desc[i].format);
159
+ return idx;
160
+}
161
+
162
+static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(vport_rep)
163
+{
164
+ int i;
165
+
166
+ for (i = 0; i < NUM_VPORT_REP_HW_COUNTERS; i++)
167
+ data[idx++] = MLX5E_READ_CTR64_CPU(&priv->stats.vf_vport,
168
+ vport_rep_stats_desc, i);
169
+ return idx;
170
+}
171
+
172
+static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(vport_rep)
104173 {
105174 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
106175 struct mlx5e_rep_priv *rpriv = priv->ppriv;
....@@ -111,7 +180,8 @@
111180
112181 err = mlx5_eswitch_get_vport_stats(esw, rep->vport, &vf_stats);
113182 if (err) {
114
- pr_warn("vport %d error %d reading stats\n", rep->vport, err);
183
+ netdev_warn(priv->netdev, "vport %d error %d reading stats\n",
184
+ rep->vport, err);
115185 return;
116186 }
117187
....@@ -123,29 +193,15 @@
123193 vport_stats->tx_bytes = vf_stats.rx_bytes;
124194 }
125195
126
-static void mlx5e_rep_update_sw_counters(struct mlx5e_priv *priv)
196
+static void mlx5e_rep_get_strings(struct net_device *dev,
197
+ u32 stringset, uint8_t *data)
127198 {
128
- struct mlx5e_sw_stats *s = &priv->stats.sw;
129
- struct mlx5e_rq_stats *rq_stats;
130
- struct mlx5e_sq_stats *sq_stats;
131
- int i, j;
199
+ struct mlx5e_priv *priv = netdev_priv(dev);
132200
133
- memset(s, 0, sizeof(*s));
134
- for (i = 0; i < priv->channels.num; i++) {
135
- struct mlx5e_channel *c = priv->channels.c[i];
136
-
137
- rq_stats = c->rq.stats;
138
-
139
- s->rx_packets += rq_stats->packets;
140
- s->rx_bytes += rq_stats->bytes;
141
-
142
- for (j = 0; j < priv->channels.params.num_tc; j++) {
143
- sq_stats = c->sq[j].stats;
144
-
145
- s->tx_packets += sq_stats->packets;
146
- s->tx_bytes += sq_stats->bytes;
147
- s->tx_queue_dropped += sq_stats->dropped;
148
- }
201
+ switch (stringset) {
202
+ case ETH_SS_STATS:
203
+ mlx5e_stats_fill_strings(priv, data);
204
+ break;
149205 }
150206 }
151207
....@@ -153,65 +209,170 @@
153209 struct ethtool_stats *stats, u64 *data)
154210 {
155211 struct mlx5e_priv *priv = netdev_priv(dev);
156
- int i, j;
157212
158
- if (!data)
159
- return;
160
-
161
- mutex_lock(&priv->state_lock);
162
- if (test_bit(MLX5E_STATE_OPENED, &priv->state))
163
- mlx5e_rep_update_sw_counters(priv);
164
- mlx5e_rep_update_hw_counters(priv);
165
- mutex_unlock(&priv->state_lock);
166
-
167
- for (i = 0; i < NUM_VPORT_REP_SW_COUNTERS; i++)
168
- data[i] = MLX5E_READ_CTR64_CPU(&priv->stats.sw,
169
- sw_rep_stats_desc, i);
170
-
171
- for (j = 0; j < NUM_VPORT_REP_HW_COUNTERS; j++, i++)
172
- data[i] = MLX5E_READ_CTR64_CPU(&priv->stats.vf_vport,
173
- vport_rep_stats_desc, j);
213
+ mlx5e_ethtool_get_ethtool_stats(priv, stats, data);
174214 }
175215
176216 static int mlx5e_rep_get_sset_count(struct net_device *dev, int sset)
177217 {
218
+ struct mlx5e_priv *priv = netdev_priv(dev);
219
+
178220 switch (sset) {
179221 case ETH_SS_STATS:
180
- return NUM_VPORT_REP_SW_COUNTERS + NUM_VPORT_REP_HW_COUNTERS;
222
+ return mlx5e_stats_total_num(priv);
181223 default:
182224 return -EOPNOTSUPP;
183225 }
184226 }
185227
228
+static void mlx5e_rep_get_ringparam(struct net_device *dev,
229
+ struct ethtool_ringparam *param)
230
+{
231
+ struct mlx5e_priv *priv = netdev_priv(dev);
232
+
233
+ mlx5e_ethtool_get_ringparam(priv, param);
234
+}
235
+
236
+static int mlx5e_rep_set_ringparam(struct net_device *dev,
237
+ struct ethtool_ringparam *param)
238
+{
239
+ struct mlx5e_priv *priv = netdev_priv(dev);
240
+
241
+ return mlx5e_ethtool_set_ringparam(priv, param);
242
+}
243
+
244
+static void mlx5e_rep_get_channels(struct net_device *dev,
245
+ struct ethtool_channels *ch)
246
+{
247
+ struct mlx5e_priv *priv = netdev_priv(dev);
248
+
249
+ mlx5e_ethtool_get_channels(priv, ch);
250
+}
251
+
252
+static int mlx5e_rep_set_channels(struct net_device *dev,
253
+ struct ethtool_channels *ch)
254
+{
255
+ struct mlx5e_priv *priv = netdev_priv(dev);
256
+
257
+ return mlx5e_ethtool_set_channels(priv, ch);
258
+}
259
+
260
+static int mlx5e_rep_get_coalesce(struct net_device *netdev,
261
+ struct ethtool_coalesce *coal)
262
+{
263
+ struct mlx5e_priv *priv = netdev_priv(netdev);
264
+
265
+ return mlx5e_ethtool_get_coalesce(priv, coal);
266
+}
267
+
268
+static int mlx5e_rep_set_coalesce(struct net_device *netdev,
269
+ struct ethtool_coalesce *coal)
270
+{
271
+ struct mlx5e_priv *priv = netdev_priv(netdev);
272
+
273
+ return mlx5e_ethtool_set_coalesce(priv, coal);
274
+}
275
+
276
+static u32 mlx5e_rep_get_rxfh_key_size(struct net_device *netdev)
277
+{
278
+ struct mlx5e_priv *priv = netdev_priv(netdev);
279
+
280
+ return mlx5e_ethtool_get_rxfh_key_size(priv);
281
+}
282
+
283
+static u32 mlx5e_rep_get_rxfh_indir_size(struct net_device *netdev)
284
+{
285
+ struct mlx5e_priv *priv = netdev_priv(netdev);
286
+
287
+ return mlx5e_ethtool_get_rxfh_indir_size(priv);
288
+}
289
+
290
+static void mlx5e_uplink_rep_get_pause_stats(struct net_device *netdev,
291
+ struct ethtool_pause_stats *stats)
292
+{
293
+ struct mlx5e_priv *priv = netdev_priv(netdev);
294
+
295
+ mlx5e_stats_pause_get(priv, stats);
296
+}
297
+
298
+static void mlx5e_uplink_rep_get_pauseparam(struct net_device *netdev,
299
+ struct ethtool_pauseparam *pauseparam)
300
+{
301
+ struct mlx5e_priv *priv = netdev_priv(netdev);
302
+
303
+ mlx5e_ethtool_get_pauseparam(priv, pauseparam);
304
+}
305
+
306
+static int mlx5e_uplink_rep_set_pauseparam(struct net_device *netdev,
307
+ struct ethtool_pauseparam *pauseparam)
308
+{
309
+ struct mlx5e_priv *priv = netdev_priv(netdev);
310
+
311
+ return mlx5e_ethtool_set_pauseparam(priv, pauseparam);
312
+}
313
+
314
+static int mlx5e_uplink_rep_get_link_ksettings(struct net_device *netdev,
315
+ struct ethtool_link_ksettings *link_ksettings)
316
+{
317
+ struct mlx5e_priv *priv = netdev_priv(netdev);
318
+
319
+ return mlx5e_ethtool_get_link_ksettings(priv, link_ksettings);
320
+}
321
+
322
+static int mlx5e_uplink_rep_set_link_ksettings(struct net_device *netdev,
323
+ const struct ethtool_link_ksettings *link_ksettings)
324
+{
325
+ struct mlx5e_priv *priv = netdev_priv(netdev);
326
+
327
+ return mlx5e_ethtool_set_link_ksettings(priv, link_ksettings);
328
+}
329
+
186330 static const struct ethtool_ops mlx5e_rep_ethtool_ops = {
331
+ .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
332
+ ETHTOOL_COALESCE_MAX_FRAMES |
333
+ ETHTOOL_COALESCE_USE_ADAPTIVE,
187334 .get_drvinfo = mlx5e_rep_get_drvinfo,
188335 .get_link = ethtool_op_get_link,
189336 .get_strings = mlx5e_rep_get_strings,
190337 .get_sset_count = mlx5e_rep_get_sset_count,
191338 .get_ethtool_stats = mlx5e_rep_get_ethtool_stats,
339
+ .get_ringparam = mlx5e_rep_get_ringparam,
340
+ .set_ringparam = mlx5e_rep_set_ringparam,
341
+ .get_channels = mlx5e_rep_get_channels,
342
+ .set_channels = mlx5e_rep_set_channels,
343
+ .get_coalesce = mlx5e_rep_get_coalesce,
344
+ .set_coalesce = mlx5e_rep_set_coalesce,
345
+ .get_rxfh_key_size = mlx5e_rep_get_rxfh_key_size,
346
+ .get_rxfh_indir_size = mlx5e_rep_get_rxfh_indir_size,
192347 };
193348
194
-int mlx5e_attr_get(struct net_device *dev, struct switchdev_attr *attr)
195
-{
196
- struct mlx5e_priv *priv = netdev_priv(dev);
197
- struct mlx5e_rep_priv *rpriv = priv->ppriv;
198
- struct mlx5_eswitch_rep *rep = rpriv->rep;
199
- struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
200
-
201
- if (esw->mode != SRIOV_OFFLOADS)
202
- return -EOPNOTSUPP;
203
-
204
- switch (attr->id) {
205
- case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
206
- attr->u.ppid.id_len = ETH_ALEN;
207
- ether_addr_copy(attr->u.ppid.id, rep->hw_id);
208
- break;
209
- default:
210
- return -EOPNOTSUPP;
211
- }
212
-
213
- return 0;
214
-}
349
+static const struct ethtool_ops mlx5e_uplink_rep_ethtool_ops = {
350
+ .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
351
+ ETHTOOL_COALESCE_MAX_FRAMES |
352
+ ETHTOOL_COALESCE_USE_ADAPTIVE,
353
+ .get_drvinfo = mlx5e_uplink_rep_get_drvinfo,
354
+ .get_link = ethtool_op_get_link,
355
+ .get_strings = mlx5e_rep_get_strings,
356
+ .get_sset_count = mlx5e_rep_get_sset_count,
357
+ .get_ethtool_stats = mlx5e_rep_get_ethtool_stats,
358
+ .get_ringparam = mlx5e_rep_get_ringparam,
359
+ .set_ringparam = mlx5e_rep_set_ringparam,
360
+ .get_channels = mlx5e_rep_get_channels,
361
+ .set_channels = mlx5e_rep_set_channels,
362
+ .get_coalesce = mlx5e_rep_get_coalesce,
363
+ .set_coalesce = mlx5e_rep_set_coalesce,
364
+ .get_link_ksettings = mlx5e_uplink_rep_get_link_ksettings,
365
+ .set_link_ksettings = mlx5e_uplink_rep_set_link_ksettings,
366
+ .get_rxfh_key_size = mlx5e_rep_get_rxfh_key_size,
367
+ .get_rxfh_indir_size = mlx5e_rep_get_rxfh_indir_size,
368
+ .get_rxfh = mlx5e_get_rxfh,
369
+ .set_rxfh = mlx5e_set_rxfh,
370
+ .get_rxnfc = mlx5e_get_rxnfc,
371
+ .set_rxnfc = mlx5e_set_rxnfc,
372
+ .get_pause_stats = mlx5e_uplink_rep_get_pause_stats,
373
+ .get_pauseparam = mlx5e_uplink_rep_get_pauseparam,
374
+ .set_pauseparam = mlx5e_uplink_rep_set_pauseparam,
375
+};
215376
216377 static void mlx5e_sqs2vport_stop(struct mlx5_eswitch *esw,
217378 struct mlx5_eswitch_rep *rep)
....@@ -219,7 +380,7 @@
219380 struct mlx5e_rep_sq *rep_sq, *tmp;
220381 struct mlx5e_rep_priv *rpriv;
221382
222
- if (esw->mode != SRIOV_OFFLOADS)
383
+ if (esw->mode != MLX5_ESWITCH_OFFLOADS)
223384 return;
224385
225386 rpriv = mlx5e_rep_to_rep_priv(rep);
....@@ -240,7 +401,7 @@
240401 int err;
241402 int i;
242403
243
- if (esw->mode != SRIOV_OFFLOADS)
404
+ if (esw->mode != MLX5_ESWITCH_OFFLOADS)
244405 return 0;
245406
246407 rpriv = mlx5e_rep_to_rep_priv(rep);
....@@ -308,384 +469,6 @@
308469 mlx5e_sqs2vport_stop(esw, rep);
309470 }
310471
311
-static void mlx5e_rep_neigh_update_init_interval(struct mlx5e_rep_priv *rpriv)
312
-{
313
-#if IS_ENABLED(CONFIG_IPV6)
314
- unsigned long ipv6_interval = NEIGH_VAR(&nd_tbl.parms,
315
- DELAY_PROBE_TIME);
316
-#else
317
- unsigned long ipv6_interval = ~0UL;
318
-#endif
319
- unsigned long ipv4_interval = NEIGH_VAR(&arp_tbl.parms,
320
- DELAY_PROBE_TIME);
321
- struct net_device *netdev = rpriv->netdev;
322
- struct mlx5e_priv *priv = netdev_priv(netdev);
323
-
324
- rpriv->neigh_update.min_interval = min_t(unsigned long, ipv6_interval, ipv4_interval);
325
- mlx5_fc_update_sampling_interval(priv->mdev, rpriv->neigh_update.min_interval);
326
-}
327
-
328
-void mlx5e_rep_queue_neigh_stats_work(struct mlx5e_priv *priv)
329
-{
330
- struct mlx5e_rep_priv *rpriv = priv->ppriv;
331
- struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
332
-
333
- mlx5_fc_queue_stats_work(priv->mdev,
334
- &neigh_update->neigh_stats_work,
335
- neigh_update->min_interval);
336
-}
337
-
338
-static void mlx5e_rep_neigh_stats_work(struct work_struct *work)
339
-{
340
- struct mlx5e_rep_priv *rpriv = container_of(work, struct mlx5e_rep_priv,
341
- neigh_update.neigh_stats_work.work);
342
- struct net_device *netdev = rpriv->netdev;
343
- struct mlx5e_priv *priv = netdev_priv(netdev);
344
- struct mlx5e_neigh_hash_entry *nhe;
345
-
346
- rtnl_lock();
347
- if (!list_empty(&rpriv->neigh_update.neigh_list))
348
- mlx5e_rep_queue_neigh_stats_work(priv);
349
-
350
- list_for_each_entry(nhe, &rpriv->neigh_update.neigh_list, neigh_list)
351
- mlx5e_tc_update_neigh_used_value(nhe);
352
-
353
- rtnl_unlock();
354
-}
355
-
356
-static void mlx5e_rep_neigh_entry_hold(struct mlx5e_neigh_hash_entry *nhe)
357
-{
358
- refcount_inc(&nhe->refcnt);
359
-}
360
-
361
-static void mlx5e_rep_neigh_entry_release(struct mlx5e_neigh_hash_entry *nhe)
362
-{
363
- if (refcount_dec_and_test(&nhe->refcnt))
364
- kfree(nhe);
365
-}
366
-
367
-static void mlx5e_rep_update_flows(struct mlx5e_priv *priv,
368
- struct mlx5e_encap_entry *e,
369
- bool neigh_connected,
370
- unsigned char ha[ETH_ALEN])
371
-{
372
- struct ethhdr *eth = (struct ethhdr *)e->encap_header;
373
-
374
- ASSERT_RTNL();
375
-
376
- if ((!neigh_connected && (e->flags & MLX5_ENCAP_ENTRY_VALID)) ||
377
- !ether_addr_equal(e->h_dest, ha))
378
- mlx5e_tc_encap_flows_del(priv, e);
379
-
380
- if (neigh_connected && !(e->flags & MLX5_ENCAP_ENTRY_VALID)) {
381
- ether_addr_copy(e->h_dest, ha);
382
- ether_addr_copy(eth->h_dest, ha);
383
-
384
- mlx5e_tc_encap_flows_add(priv, e);
385
- }
386
-}
387
-
388
-static void mlx5e_rep_neigh_update(struct work_struct *work)
389
-{
390
- struct mlx5e_neigh_hash_entry *nhe =
391
- container_of(work, struct mlx5e_neigh_hash_entry, neigh_update_work);
392
- struct neighbour *n = nhe->n;
393
- struct mlx5e_encap_entry *e;
394
- unsigned char ha[ETH_ALEN];
395
- struct mlx5e_priv *priv;
396
- bool neigh_connected;
397
- bool encap_connected;
398
- u8 nud_state, dead;
399
-
400
- rtnl_lock();
401
-
402
- /* If these parameters are changed after we release the lock,
403
- * we'll receive another event letting us know about it.
404
- * We use this lock to avoid inconsistency between the neigh validity
405
- * and it's hw address.
406
- */
407
- read_lock_bh(&n->lock);
408
- memcpy(ha, n->ha, ETH_ALEN);
409
- nud_state = n->nud_state;
410
- dead = n->dead;
411
- read_unlock_bh(&n->lock);
412
-
413
- neigh_connected = (nud_state & NUD_VALID) && !dead;
414
-
415
- list_for_each_entry(e, &nhe->encap_list, encap_list) {
416
- encap_connected = !!(e->flags & MLX5_ENCAP_ENTRY_VALID);
417
- priv = netdev_priv(e->out_dev);
418
-
419
- if (encap_connected != neigh_connected ||
420
- !ether_addr_equal(e->h_dest, ha))
421
- mlx5e_rep_update_flows(priv, e, neigh_connected, ha);
422
- }
423
- mlx5e_rep_neigh_entry_release(nhe);
424
- rtnl_unlock();
425
- neigh_release(n);
426
-}
427
-
428
-static struct mlx5e_neigh_hash_entry *
429
-mlx5e_rep_neigh_entry_lookup(struct mlx5e_priv *priv,
430
- struct mlx5e_neigh *m_neigh);
431
-
432
-static int mlx5e_rep_netevent_event(struct notifier_block *nb,
433
- unsigned long event, void *ptr)
434
-{
435
- struct mlx5e_rep_priv *rpriv = container_of(nb, struct mlx5e_rep_priv,
436
- neigh_update.netevent_nb);
437
- struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
438
- struct net_device *netdev = rpriv->netdev;
439
- struct mlx5e_priv *priv = netdev_priv(netdev);
440
- struct mlx5e_neigh_hash_entry *nhe = NULL;
441
- struct mlx5e_neigh m_neigh = {};
442
- struct neigh_parms *p;
443
- struct neighbour *n;
444
- bool found = false;
445
-
446
- switch (event) {
447
- case NETEVENT_NEIGH_UPDATE:
448
- n = ptr;
449
-#if IS_ENABLED(CONFIG_IPV6)
450
- if (n->tbl != &nd_tbl && n->tbl != &arp_tbl)
451
-#else
452
- if (n->tbl != &arp_tbl)
453
-#endif
454
- return NOTIFY_DONE;
455
-
456
- m_neigh.dev = n->dev;
457
- m_neigh.family = n->ops->family;
458
- memcpy(&m_neigh.dst_ip, n->primary_key, n->tbl->key_len);
459
-
460
- /* We are in atomic context and can't take RTNL mutex, so use
461
- * spin_lock_bh to lookup the neigh table. bh is used since
462
- * netevent can be called from a softirq context.
463
- */
464
- spin_lock_bh(&neigh_update->encap_lock);
465
- nhe = mlx5e_rep_neigh_entry_lookup(priv, &m_neigh);
466
- if (!nhe) {
467
- spin_unlock_bh(&neigh_update->encap_lock);
468
- return NOTIFY_DONE;
469
- }
470
-
471
- /* This assignment is valid as long as the the neigh reference
472
- * is taken
473
- */
474
- nhe->n = n;
475
-
476
- /* Take a reference to ensure the neighbour and mlx5 encap
477
- * entry won't be destructed until we drop the reference in
478
- * delayed work.
479
- */
480
- neigh_hold(n);
481
- mlx5e_rep_neigh_entry_hold(nhe);
482
-
483
- if (!queue_work(priv->wq, &nhe->neigh_update_work)) {
484
- mlx5e_rep_neigh_entry_release(nhe);
485
- neigh_release(n);
486
- }
487
- spin_unlock_bh(&neigh_update->encap_lock);
488
- break;
489
-
490
- case NETEVENT_DELAY_PROBE_TIME_UPDATE:
491
- p = ptr;
492
-
493
- /* We check the device is present since we don't care about
494
- * changes in the default table, we only care about changes
495
- * done per device delay prob time parameter.
496
- */
497
-#if IS_ENABLED(CONFIG_IPV6)
498
- if (!p->dev || (p->tbl != &nd_tbl && p->tbl != &arp_tbl))
499
-#else
500
- if (!p->dev || p->tbl != &arp_tbl)
501
-#endif
502
- return NOTIFY_DONE;
503
-
504
- /* We are in atomic context and can't take RTNL mutex,
505
- * so use spin_lock_bh to walk the neigh list and look for
506
- * the relevant device. bh is used since netevent can be
507
- * called from a softirq context.
508
- */
509
- spin_lock_bh(&neigh_update->encap_lock);
510
- list_for_each_entry(nhe, &neigh_update->neigh_list, neigh_list) {
511
- if (p->dev == nhe->m_neigh.dev) {
512
- found = true;
513
- break;
514
- }
515
- }
516
- spin_unlock_bh(&neigh_update->encap_lock);
517
- if (!found)
518
- return NOTIFY_DONE;
519
-
520
- neigh_update->min_interval = min_t(unsigned long,
521
- NEIGH_VAR(p, DELAY_PROBE_TIME),
522
- neigh_update->min_interval);
523
- mlx5_fc_update_sampling_interval(priv->mdev,
524
- neigh_update->min_interval);
525
- break;
526
- }
527
- return NOTIFY_DONE;
528
-}
529
-
530
-static const struct rhashtable_params mlx5e_neigh_ht_params = {
531
- .head_offset = offsetof(struct mlx5e_neigh_hash_entry, rhash_node),
532
- .key_offset = offsetof(struct mlx5e_neigh_hash_entry, m_neigh),
533
- .key_len = sizeof(struct mlx5e_neigh),
534
- .automatic_shrinking = true,
535
-};
536
-
537
-static int mlx5e_rep_neigh_init(struct mlx5e_rep_priv *rpriv)
538
-{
539
- struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
540
- int err;
541
-
542
- err = rhashtable_init(&neigh_update->neigh_ht, &mlx5e_neigh_ht_params);
543
- if (err)
544
- return err;
545
-
546
- INIT_LIST_HEAD(&neigh_update->neigh_list);
547
- spin_lock_init(&neigh_update->encap_lock);
548
- INIT_DELAYED_WORK(&neigh_update->neigh_stats_work,
549
- mlx5e_rep_neigh_stats_work);
550
- mlx5e_rep_neigh_update_init_interval(rpriv);
551
-
552
- rpriv->neigh_update.netevent_nb.notifier_call = mlx5e_rep_netevent_event;
553
- err = register_netevent_notifier(&rpriv->neigh_update.netevent_nb);
554
- if (err)
555
- goto out_err;
556
- return 0;
557
-
558
-out_err:
559
- rhashtable_destroy(&neigh_update->neigh_ht);
560
- return err;
561
-}
562
-
563
-static void mlx5e_rep_neigh_cleanup(struct mlx5e_rep_priv *rpriv)
564
-{
565
- struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
566
- struct mlx5e_priv *priv = netdev_priv(rpriv->netdev);
567
-
568
- unregister_netevent_notifier(&neigh_update->netevent_nb);
569
-
570
- flush_workqueue(priv->wq); /* flush neigh update works */
571
-
572
- cancel_delayed_work_sync(&rpriv->neigh_update.neigh_stats_work);
573
-
574
- rhashtable_destroy(&neigh_update->neigh_ht);
575
-}
576
-
577
-static int mlx5e_rep_neigh_entry_insert(struct mlx5e_priv *priv,
578
- struct mlx5e_neigh_hash_entry *nhe)
579
-{
580
- struct mlx5e_rep_priv *rpriv = priv->ppriv;
581
- int err;
582
-
583
- err = rhashtable_insert_fast(&rpriv->neigh_update.neigh_ht,
584
- &nhe->rhash_node,
585
- mlx5e_neigh_ht_params);
586
- if (err)
587
- return err;
588
-
589
- list_add(&nhe->neigh_list, &rpriv->neigh_update.neigh_list);
590
-
591
- return err;
592
-}
593
-
594
-static void mlx5e_rep_neigh_entry_remove(struct mlx5e_priv *priv,
595
- struct mlx5e_neigh_hash_entry *nhe)
596
-{
597
- struct mlx5e_rep_priv *rpriv = priv->ppriv;
598
-
599
- spin_lock_bh(&rpriv->neigh_update.encap_lock);
600
-
601
- list_del(&nhe->neigh_list);
602
-
603
- rhashtable_remove_fast(&rpriv->neigh_update.neigh_ht,
604
- &nhe->rhash_node,
605
- mlx5e_neigh_ht_params);
606
- spin_unlock_bh(&rpriv->neigh_update.encap_lock);
607
-}
608
-
609
-/* This function must only be called under RTNL lock or under the
610
- * representor's encap_lock in case RTNL mutex can't be held.
611
- */
612
-static struct mlx5e_neigh_hash_entry *
613
-mlx5e_rep_neigh_entry_lookup(struct mlx5e_priv *priv,
614
- struct mlx5e_neigh *m_neigh)
615
-{
616
- struct mlx5e_rep_priv *rpriv = priv->ppriv;
617
- struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
618
-
619
- return rhashtable_lookup_fast(&neigh_update->neigh_ht, m_neigh,
620
- mlx5e_neigh_ht_params);
621
-}
622
-
623
-static int mlx5e_rep_neigh_entry_create(struct mlx5e_priv *priv,
624
- struct mlx5e_encap_entry *e,
625
- struct mlx5e_neigh_hash_entry **nhe)
626
-{
627
- int err;
628
-
629
- *nhe = kzalloc(sizeof(**nhe), GFP_KERNEL);
630
- if (!*nhe)
631
- return -ENOMEM;
632
-
633
- memcpy(&(*nhe)->m_neigh, &e->m_neigh, sizeof(e->m_neigh));
634
- INIT_WORK(&(*nhe)->neigh_update_work, mlx5e_rep_neigh_update);
635
- INIT_LIST_HEAD(&(*nhe)->encap_list);
636
- refcount_set(&(*nhe)->refcnt, 1);
637
-
638
- err = mlx5e_rep_neigh_entry_insert(priv, *nhe);
639
- if (err)
640
- goto out_free;
641
- return 0;
642
-
643
-out_free:
644
- kfree(*nhe);
645
- return err;
646
-}
647
-
648
-static void mlx5e_rep_neigh_entry_destroy(struct mlx5e_priv *priv,
649
- struct mlx5e_neigh_hash_entry *nhe)
650
-{
651
- /* The neigh hash entry must be removed from the hash table regardless
652
- * of the reference count value, so it won't be found by the next
653
- * neigh notification call. The neigh hash entry reference count is
654
- * incremented only during creation and neigh notification calls and
655
- * protects from freeing the nhe struct.
656
- */
657
- mlx5e_rep_neigh_entry_remove(priv, nhe);
658
- mlx5e_rep_neigh_entry_release(nhe);
659
-}
660
-
661
-int mlx5e_rep_encap_entry_attach(struct mlx5e_priv *priv,
662
- struct mlx5e_encap_entry *e)
663
-{
664
- struct mlx5e_neigh_hash_entry *nhe;
665
- int err;
666
-
667
- nhe = mlx5e_rep_neigh_entry_lookup(priv, &e->m_neigh);
668
- if (!nhe) {
669
- err = mlx5e_rep_neigh_entry_create(priv, e, &nhe);
670
- if (err)
671
- return err;
672
- }
673
- list_add(&e->encap_list, &nhe->encap_list);
674
- return 0;
675
-}
676
-
677
-void mlx5e_rep_encap_entry_detach(struct mlx5e_priv *priv,
678
- struct mlx5e_encap_entry *e)
679
-{
680
- struct mlx5e_neigh_hash_entry *nhe;
681
-
682
- list_del(&e->encap_list);
683
- nhe = mlx5e_rep_neigh_entry_lookup(priv, &e->m_neigh);
684
-
685
- if (list_empty(&nhe->encap_list))
686
- mlx5e_rep_neigh_entry_destroy(priv, nhe);
687
-}
688
-
689472 static int mlx5e_rep_open(struct net_device *dev)
690473 {
691474 struct mlx5e_priv *priv = netdev_priv(dev);
....@@ -700,7 +483,8 @@
700483
701484 if (!mlx5_modify_vport_admin_state(priv->mdev,
702485 MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
703
- rep->vport, MLX5_VPORT_ADMIN_STATE_UP))
486
+ rep->vport, 1,
487
+ MLX5_VPORT_ADMIN_STATE_UP))
704488 netif_carrier_on(dev);
705489
706490 unlock:
....@@ -718,145 +502,32 @@
718502 mutex_lock(&priv->state_lock);
719503 mlx5_modify_vport_admin_state(priv->mdev,
720504 MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
721
- rep->vport, MLX5_VPORT_ADMIN_STATE_DOWN);
505
+ rep->vport, 1,
506
+ MLX5_VPORT_ADMIN_STATE_DOWN);
722507 ret = mlx5e_close_locked(dev);
723508 mutex_unlock(&priv->state_lock);
724509 return ret;
725510 }
726511
727
-static int mlx5e_rep_get_phys_port_name(struct net_device *dev,
728
- char *buf, size_t len)
729
-{
730
- struct mlx5e_priv *priv = netdev_priv(dev);
731
- struct mlx5e_rep_priv *rpriv = priv->ppriv;
732
- struct mlx5_eswitch_rep *rep = rpriv->rep;
733
- int ret;
734
-
735
- ret = snprintf(buf, len, "%d", rep->vport - 1);
736
- if (ret >= len)
737
- return -EOPNOTSUPP;
738
-
739
- return 0;
740
-}
741
-
742
-static int
743
-mlx5e_rep_setup_tc_cls_flower(struct mlx5e_priv *priv,
744
- struct tc_cls_flower_offload *cls_flower, int flags)
745
-{
746
- switch (cls_flower->command) {
747
- case TC_CLSFLOWER_REPLACE:
748
- return mlx5e_configure_flower(priv, cls_flower, flags);
749
- case TC_CLSFLOWER_DESTROY:
750
- return mlx5e_delete_flower(priv, cls_flower, flags);
751
- case TC_CLSFLOWER_STATS:
752
- return mlx5e_stats_flower(priv, cls_flower, flags);
753
- default:
754
- return -EOPNOTSUPP;
755
- }
756
-}
757
-
758
-static int mlx5e_rep_setup_tc_cb_egdev(enum tc_setup_type type, void *type_data,
759
- void *cb_priv)
760
-{
761
- struct mlx5e_priv *priv = cb_priv;
762
-
763
- if (!tc_cls_can_offload_and_chain0(priv->netdev, type_data))
764
- return -EOPNOTSUPP;
765
-
766
- switch (type) {
767
- case TC_SETUP_CLSFLOWER:
768
- return mlx5e_rep_setup_tc_cls_flower(priv, type_data, MLX5E_TC_EGRESS);
769
- default:
770
- return -EOPNOTSUPP;
771
- }
772
-}
773
-
774
-static int mlx5e_rep_setup_tc_cb(enum tc_setup_type type, void *type_data,
775
- void *cb_priv)
776
-{
777
- struct mlx5e_priv *priv = cb_priv;
778
-
779
- if (!tc_cls_can_offload_and_chain0(priv->netdev, type_data))
780
- return -EOPNOTSUPP;
781
-
782
- switch (type) {
783
- case TC_SETUP_CLSFLOWER:
784
- return mlx5e_rep_setup_tc_cls_flower(priv, type_data, MLX5E_TC_INGRESS);
785
- default:
786
- return -EOPNOTSUPP;
787
- }
788
-}
789
-
790
-static int mlx5e_rep_setup_tc_block(struct net_device *dev,
791
- struct tc_block_offload *f)
792
-{
793
- struct mlx5e_priv *priv = netdev_priv(dev);
794
-
795
- if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
796
- return -EOPNOTSUPP;
797
-
798
- switch (f->command) {
799
- case TC_BLOCK_BIND:
800
- return tcf_block_cb_register(f->block, mlx5e_rep_setup_tc_cb,
801
- priv, priv, f->extack);
802
- case TC_BLOCK_UNBIND:
803
- tcf_block_cb_unregister(f->block, mlx5e_rep_setup_tc_cb, priv);
804
- return 0;
805
- default:
806
- return -EOPNOTSUPP;
807
- }
808
-}
809
-
810
-static int mlx5e_rep_setup_tc(struct net_device *dev, enum tc_setup_type type,
811
- void *type_data)
812
-{
813
- switch (type) {
814
- case TC_SETUP_BLOCK:
815
- return mlx5e_rep_setup_tc_block(dev, type_data);
816
- default:
817
- return -EOPNOTSUPP;
818
- }
819
-}
820
-
821512 bool mlx5e_is_uplink_rep(struct mlx5e_priv *priv)
822513 {
823
- struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
824514 struct mlx5e_rep_priv *rpriv = priv->ppriv;
825515 struct mlx5_eswitch_rep *rep;
826516
827517 if (!MLX5_ESWITCH_MANAGER(priv->mdev))
828518 return false;
829519
830
- rep = rpriv->rep;
831
- if (esw->mode == SRIOV_OFFLOADS &&
832
- rep && rep->vport == FDB_UPLINK_VPORT)
833
- return true;
834
-
835
- return false;
836
-}
837
-
838
-static bool mlx5e_is_vf_vport_rep(struct mlx5e_priv *priv)
839
-{
840
- struct mlx5e_rep_priv *rpriv = priv->ppriv;
841
- struct mlx5_eswitch_rep *rep;
842
-
843
- if (!MLX5_ESWITCH_MANAGER(priv->mdev))
520
+ if (!rpriv) /* non vport rep mlx5e instances don't use this field */
844521 return false;
845522
846523 rep = rpriv->rep;
847
- if (rep && rep->vport != FDB_UPLINK_VPORT)
848
- return true;
849
-
850
- return false;
524
+ return (rep->vport == MLX5_VPORT_UPLINK);
851525 }
852526
853
-bool mlx5e_has_offload_stats(const struct net_device *dev, int attr_id)
527
+static bool mlx5e_rep_has_offload_stats(const struct net_device *dev, int attr_id)
854528 {
855
- struct mlx5e_priv *priv = netdev_priv(dev);
856
-
857529 switch (attr_id) {
858530 case IFLA_OFFLOAD_XSTATS_CPU_HIT:
859
- if (mlx5e_is_vf_vport_rep(priv) || mlx5e_is_uplink_rep(priv))
860531 return true;
861532 }
862533
....@@ -868,22 +539,13 @@
868539 struct rtnl_link_stats64 *stats)
869540 {
870541 struct mlx5e_priv *priv = netdev_priv(dev);
871
- struct mlx5e_sw_stats *sstats = &priv->stats.sw;
872542
873
- mlx5e_rep_update_sw_counters(priv);
874
-
875
- stats->rx_packets = sstats->rx_packets;
876
- stats->rx_bytes = sstats->rx_bytes;
877
- stats->tx_packets = sstats->tx_packets;
878
- stats->tx_bytes = sstats->tx_bytes;
879
-
880
- stats->tx_dropped = sstats->tx_queue_dropped;
881
-
543
+ mlx5e_fold_sw_stats64(priv, stats);
882544 return 0;
883545 }
884546
885
-int mlx5e_get_offload_stats(int attr_id, const struct net_device *dev,
886
- void *sp)
547
+static int mlx5e_rep_get_offload_stats(int attr_id, const struct net_device *dev,
548
+ void *sp)
887549 {
888550 switch (attr_id) {
889551 case IFLA_OFFLOAD_XSTATS_CPU_HIT:
....@@ -899,149 +561,465 @@
899561 struct mlx5e_priv *priv = netdev_priv(dev);
900562
901563 /* update HW stats in background for next time */
902
- queue_delayed_work(priv->wq, &priv->update_stats_work, 0);
903
-
564
+ mlx5e_queue_update_stats(priv);
904565 memcpy(stats, &priv->stats.vf_vport, sizeof(*stats));
905566 }
906567
907
-static const struct switchdev_ops mlx5e_rep_switchdev_ops = {
908
- .switchdev_port_attr_get = mlx5e_attr_get,
909
-};
910
-
911
-static int mlx5e_change_rep_mtu(struct net_device *netdev, int new_mtu)
568
+static int mlx5e_rep_change_mtu(struct net_device *netdev, int new_mtu)
912569 {
913570 return mlx5e_change_mtu(netdev, new_mtu, NULL);
571
+}
572
+
573
+static int mlx5e_uplink_rep_change_mtu(struct net_device *netdev, int new_mtu)
574
+{
575
+ return mlx5e_change_mtu(netdev, new_mtu, mlx5e_set_dev_port_mtu_ctx);
576
+}
577
+
578
+static int mlx5e_uplink_rep_set_mac(struct net_device *netdev, void *addr)
579
+{
580
+ struct sockaddr *saddr = addr;
581
+
582
+ if (!is_valid_ether_addr(saddr->sa_data))
583
+ return -EADDRNOTAVAIL;
584
+
585
+ ether_addr_copy(netdev->dev_addr, saddr->sa_data);
586
+ return 0;
587
+}
588
+
589
+static int mlx5e_uplink_rep_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos,
590
+ __be16 vlan_proto)
591
+{
592
+ netdev_warn_once(dev, "legacy vf vlan setting isn't supported in switchdev mode\n");
593
+
594
+ if (vlan != 0)
595
+ return -EOPNOTSUPP;
596
+
597
+ /* allow setting 0-vid for compatibility with libvirt */
598
+ return 0;
599
+}
600
+
601
+static struct devlink_port *mlx5e_rep_get_devlink_port(struct net_device *netdev)
602
+{
603
+ struct mlx5e_priv *priv = netdev_priv(netdev);
604
+ struct mlx5e_rep_priv *rpriv = priv->ppriv;
605
+ struct mlx5_core_dev *dev = priv->mdev;
606
+
607
+ return mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
608
+}
609
+
610
+static int mlx5e_rep_change_carrier(struct net_device *dev, bool new_carrier)
611
+{
612
+ struct mlx5e_priv *priv = netdev_priv(dev);
613
+ struct mlx5e_rep_priv *rpriv = priv->ppriv;
614
+ struct mlx5_eswitch_rep *rep = rpriv->rep;
615
+ int err;
616
+
617
+ if (new_carrier) {
618
+ err = mlx5_modify_vport_admin_state(priv->mdev, MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
619
+ rep->vport, 1, MLX5_VPORT_ADMIN_STATE_UP);
620
+ if (err)
621
+ return err;
622
+ netif_carrier_on(dev);
623
+ } else {
624
+ err = mlx5_modify_vport_admin_state(priv->mdev, MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
625
+ rep->vport, 1, MLX5_VPORT_ADMIN_STATE_DOWN);
626
+ if (err)
627
+ return err;
628
+ netif_carrier_off(dev);
629
+ }
630
+ return 0;
914631 }
915632
916633 static const struct net_device_ops mlx5e_netdev_ops_rep = {
917634 .ndo_open = mlx5e_rep_open,
918635 .ndo_stop = mlx5e_rep_close,
919636 .ndo_start_xmit = mlx5e_xmit,
920
- .ndo_get_phys_port_name = mlx5e_rep_get_phys_port_name,
921637 .ndo_setup_tc = mlx5e_rep_setup_tc,
638
+ .ndo_get_devlink_port = mlx5e_rep_get_devlink_port,
922639 .ndo_get_stats64 = mlx5e_rep_get_stats,
923
- .ndo_has_offload_stats = mlx5e_has_offload_stats,
924
- .ndo_get_offload_stats = mlx5e_get_offload_stats,
925
- .ndo_change_mtu = mlx5e_change_rep_mtu,
640
+ .ndo_has_offload_stats = mlx5e_rep_has_offload_stats,
641
+ .ndo_get_offload_stats = mlx5e_rep_get_offload_stats,
642
+ .ndo_change_mtu = mlx5e_rep_change_mtu,
643
+ .ndo_change_carrier = mlx5e_rep_change_carrier,
926644 };
927645
928
-static void mlx5e_build_rep_params(struct mlx5_core_dev *mdev,
929
- struct mlx5e_params *params, u16 mtu)
646
+static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
647
+ .ndo_open = mlx5e_open,
648
+ .ndo_stop = mlx5e_close,
649
+ .ndo_start_xmit = mlx5e_xmit,
650
+ .ndo_set_mac_address = mlx5e_uplink_rep_set_mac,
651
+ .ndo_setup_tc = mlx5e_rep_setup_tc,
652
+ .ndo_get_devlink_port = mlx5e_rep_get_devlink_port,
653
+ .ndo_get_stats64 = mlx5e_get_stats,
654
+ .ndo_has_offload_stats = mlx5e_rep_has_offload_stats,
655
+ .ndo_get_offload_stats = mlx5e_rep_get_offload_stats,
656
+ .ndo_change_mtu = mlx5e_uplink_rep_change_mtu,
657
+ .ndo_udp_tunnel_add = udp_tunnel_nic_add_port,
658
+ .ndo_udp_tunnel_del = udp_tunnel_nic_del_port,
659
+ .ndo_features_check = mlx5e_features_check,
660
+ .ndo_set_vf_mac = mlx5e_set_vf_mac,
661
+ .ndo_set_vf_rate = mlx5e_set_vf_rate,
662
+ .ndo_get_vf_config = mlx5e_get_vf_config,
663
+ .ndo_get_vf_stats = mlx5e_get_vf_stats,
664
+ .ndo_set_vf_vlan = mlx5e_uplink_rep_set_vf_vlan,
665
+ .ndo_set_features = mlx5e_set_features,
666
+};
667
+
668
+bool mlx5e_eswitch_uplink_rep(struct net_device *netdev)
930669 {
670
+ return netdev->netdev_ops == &mlx5e_netdev_ops_uplink_rep;
671
+}
672
+
673
+bool mlx5e_eswitch_vf_rep(struct net_device *netdev)
674
+{
675
+ return netdev->netdev_ops == &mlx5e_netdev_ops_rep;
676
+}
677
+
678
+static void mlx5e_build_rep_params(struct net_device *netdev)
679
+{
680
+ struct mlx5e_priv *priv = netdev_priv(netdev);
681
+ struct mlx5e_rep_priv *rpriv = priv->ppriv;
682
+ struct mlx5_eswitch_rep *rep = rpriv->rep;
683
+ struct mlx5_core_dev *mdev = priv->mdev;
684
+ struct mlx5e_params *params;
685
+
931686 u8 cq_period_mode = MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ?
932687 MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
933688 MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
934689
690
+ params = &priv->channels.params;
935691 params->hard_mtu = MLX5E_ETH_HARD_MTU;
936
- params->sw_mtu = mtu;
937
- params->log_sq_size = MLX5E_REP_PARAMS_LOG_SQ_SIZE;
938
- params->rq_wq_type = MLX5_WQ_TYPE_CYCLIC;
939
- params->log_rq_mtu_frames = MLX5E_REP_PARAMS_LOG_RQ_SIZE;
692
+ params->sw_mtu = netdev->mtu;
940693
694
+ /* SQ */
695
+ if (rep->vport == MLX5_VPORT_UPLINK)
696
+ params->log_sq_size = MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
697
+ else
698
+ params->log_sq_size = MLX5E_REP_PARAMS_DEF_LOG_SQ_SIZE;
699
+
700
+ /* RQ */
701
+ mlx5e_build_rq_params(mdev, params);
702
+
703
+ /* CQ moderation params */
941704 params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
942705 mlx5e_set_rx_cq_mode_params(params, cq_period_mode);
943706
944707 params->num_tc = 1;
945
- params->lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;
708
+ params->tunneled_offload_en = false;
709
+ if (rep->vport != MLX5_VPORT_UPLINK)
710
+ params->vlan_strip_disable = true;
946711
947712 mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
713
+
714
+ /* RSS */
715
+ mlx5e_build_rss_params(&priv->rss_params, params->num_channels);
948716 }
949717
950718 static void mlx5e_build_rep_netdev(struct net_device *netdev)
951719 {
952720 struct mlx5e_priv *priv = netdev_priv(netdev);
721
+ struct mlx5e_rep_priv *rpriv = priv->ppriv;
722
+ struct mlx5_eswitch_rep *rep = rpriv->rep;
953723 struct mlx5_core_dev *mdev = priv->mdev;
954
- u16 max_mtu;
955724
956
- netdev->netdev_ops = &mlx5e_netdev_ops_rep;
725
+ SET_NETDEV_DEV(netdev, mdev->device);
726
+ if (rep->vport == MLX5_VPORT_UPLINK) {
727
+ netdev->netdev_ops = &mlx5e_netdev_ops_uplink_rep;
728
+ /* we want a persistent mac for the uplink rep */
729
+ mlx5_query_mac_address(mdev, netdev->dev_addr);
730
+ netdev->ethtool_ops = &mlx5e_uplink_rep_ethtool_ops;
731
+ mlx5e_vxlan_set_netdev_info(priv);
732
+ mlx5e_dcbnl_build_rep_netdev(netdev);
733
+ } else {
734
+ netdev->netdev_ops = &mlx5e_netdev_ops_rep;
735
+ eth_hw_addr_random(netdev);
736
+ netdev->ethtool_ops = &mlx5e_rep_ethtool_ops;
737
+ }
957738
958739 netdev->watchdog_timeo = 15 * HZ;
959740
960
- netdev->ethtool_ops = &mlx5e_rep_ethtool_ops;
741
+ netdev->features |= NETIF_F_NETNS_LOCAL;
961742
962
- netdev->switchdev_ops = &mlx5e_rep_switchdev_ops;
743
+#if IS_ENABLED(CONFIG_MLX5_CLS_ACT)
744
+ netdev->hw_features |= NETIF_F_HW_TC;
745
+#endif
746
+ netdev->hw_features |= NETIF_F_SG;
747
+ netdev->hw_features |= NETIF_F_IP_CSUM;
748
+ netdev->hw_features |= NETIF_F_IPV6_CSUM;
749
+ netdev->hw_features |= NETIF_F_GRO;
750
+ netdev->hw_features |= NETIF_F_TSO;
751
+ netdev->hw_features |= NETIF_F_TSO6;
752
+ netdev->hw_features |= NETIF_F_RXCSUM;
963753
964
- netdev->features |= NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_TC | NETIF_F_NETNS_LOCAL;
965
- netdev->hw_features |= NETIF_F_HW_TC;
754
+ if (rep->vport == MLX5_VPORT_UPLINK)
755
+ netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
756
+ else
757
+ netdev->features |= NETIF_F_VLAN_CHALLENGED;
966758
967
- eth_hw_addr_random(netdev);
968
-
969
- netdev->min_mtu = ETH_MIN_MTU;
970
- mlx5_query_port_max_mtu(mdev, &max_mtu, 1);
971
- netdev->max_mtu = MLX5E_HW2SW_MTU(&priv->channels.params, max_mtu);
759
+ netdev->features |= netdev->hw_features;
972760 }
973761
974
-static void mlx5e_init_rep(struct mlx5_core_dev *mdev,
975
- struct net_device *netdev,
976
- const struct mlx5e_profile *profile,
977
- void *ppriv)
762
+static int mlx5e_init_rep(struct mlx5_core_dev *mdev,
763
+ struct net_device *netdev,
764
+ const struct mlx5e_profile *profile,
765
+ void *ppriv)
978766 {
979767 struct mlx5e_priv *priv = netdev_priv(netdev);
768
+ int err;
980769
981
- priv->mdev = mdev;
982
- priv->netdev = netdev;
983
- priv->profile = profile;
984
- priv->ppriv = ppriv;
770
+ err = mlx5e_netdev_init(netdev, priv, mdev, profile, ppriv);
771
+ if (err)
772
+ return err;
985773
986
- mutex_init(&priv->state_lock);
774
+ priv->channels.params.num_channels = MLX5E_REP_PARAMS_DEF_NUM_CHANNELS;
987775
988
- INIT_DELAYED_WORK(&priv->update_stats_work, mlx5e_update_stats_work);
989
-
990
- priv->channels.params.num_channels = profile->max_nch(mdev);
991
-
992
- mlx5e_build_rep_params(mdev, &priv->channels.params, netdev->mtu);
776
+ mlx5e_build_rep_params(netdev);
993777 mlx5e_build_rep_netdev(netdev);
994778
995779 mlx5e_timestamp_init(priv);
780
+
781
+ return 0;
996782 }
997783
998
-static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
784
+static void mlx5e_cleanup_rep(struct mlx5e_priv *priv)
785
+{
786
+ mlx5e_netdev_cleanup(priv->netdev, priv);
787
+}
788
+
789
+static int mlx5e_create_rep_ttc_table(struct mlx5e_priv *priv)
790
+{
791
+ struct mlx5e_rep_priv *rpriv = priv->ppriv;
792
+ struct mlx5_eswitch_rep *rep = rpriv->rep;
793
+ struct ttc_params ttc_params = {};
794
+ int tt, err;
795
+
796
+ priv->fs.ns = mlx5_get_flow_namespace(priv->mdev,
797
+ MLX5_FLOW_NAMESPACE_KERNEL);
798
+
799
+ /* The inner_ttc in the ttc params is intentionally not set */
800
+ ttc_params.any_tt_tirn = priv->direct_tir[0].tirn;
801
+ mlx5e_set_ttc_ft_params(&ttc_params);
802
+
803
+ if (rep->vport != MLX5_VPORT_UPLINK)
804
+ /* To give uplik rep TTC a lower level for chaining from root ft */
805
+ ttc_params.ft_attr.level = MLX5E_TTC_FT_LEVEL + 1;
806
+
807
+ for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
808
+ ttc_params.indir_tirn[tt] = priv->indir_tir[tt].tirn;
809
+
810
+ err = mlx5e_create_ttc_table(priv, &ttc_params, &priv->fs.ttc);
811
+ if (err) {
812
+ netdev_err(priv->netdev, "Failed to create rep ttc table, err=%d\n", err);
813
+ return err;
814
+ }
815
+ return 0;
816
+}
817
+
818
+static int mlx5e_create_rep_root_ft(struct mlx5e_priv *priv)
819
+{
820
+ struct mlx5e_rep_priv *rpriv = priv->ppriv;
821
+ struct mlx5_eswitch_rep *rep = rpriv->rep;
822
+ struct mlx5_flow_table_attr ft_attr = {};
823
+ struct mlx5_flow_namespace *ns;
824
+ int err = 0;
825
+
826
+ if (rep->vport != MLX5_VPORT_UPLINK) {
827
+ /* non uplik reps will skip any bypass tables and go directly to
828
+ * their own ttc
829
+ */
830
+ rpriv->root_ft = priv->fs.ttc.ft.t;
831
+ return 0;
832
+ }
833
+
834
+ /* uplink root ft will be used to auto chain, to ethtool or ttc tables */
835
+ ns = mlx5_get_flow_namespace(priv->mdev, MLX5_FLOW_NAMESPACE_OFFLOADS);
836
+ if (!ns) {
837
+ netdev_err(priv->netdev, "Failed to get reps offloads namespace\n");
838
+ return -EOPNOTSUPP;
839
+ }
840
+
841
+ ft_attr.max_fte = 0; /* Empty table, miss rule will always point to next table */
842
+ ft_attr.prio = 1;
843
+ ft_attr.level = 1;
844
+
845
+ rpriv->root_ft = mlx5_create_flow_table(ns, &ft_attr);
846
+ if (IS_ERR(rpriv->root_ft)) {
847
+ err = PTR_ERR(rpriv->root_ft);
848
+ rpriv->root_ft = NULL;
849
+ }
850
+
851
+ return err;
852
+}
853
+
854
+static void mlx5e_destroy_rep_root_ft(struct mlx5e_priv *priv)
855
+{
856
+ struct mlx5e_rep_priv *rpriv = priv->ppriv;
857
+ struct mlx5_eswitch_rep *rep = rpriv->rep;
858
+
859
+ if (rep->vport != MLX5_VPORT_UPLINK)
860
+ return;
861
+ mlx5_destroy_flow_table(rpriv->root_ft);
862
+}
863
+
864
+static int mlx5e_create_rep_vport_rx_rule(struct mlx5e_priv *priv)
999865 {
1000866 struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
1001867 struct mlx5e_rep_priv *rpriv = priv->ppriv;
1002868 struct mlx5_eswitch_rep *rep = rpriv->rep;
1003869 struct mlx5_flow_handle *flow_rule;
870
+ struct mlx5_flow_destination dest;
871
+
872
+ dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
873
+ dest.ft = rpriv->root_ft;
874
+
875
+ flow_rule = mlx5_eswitch_create_vport_rx_rule(esw, rep->vport, &dest);
876
+ if (IS_ERR(flow_rule))
877
+ return PTR_ERR(flow_rule);
878
+ rpriv->vport_rx_rule = flow_rule;
879
+ return 0;
880
+}
881
+
882
+static void rep_vport_rx_rule_destroy(struct mlx5e_priv *priv)
883
+{
884
+ struct mlx5e_rep_priv *rpriv = priv->ppriv;
885
+
886
+ if (!rpriv->vport_rx_rule)
887
+ return;
888
+
889
+ mlx5_del_flow_rules(rpriv->vport_rx_rule);
890
+ rpriv->vport_rx_rule = NULL;
891
+}
892
+
893
+int mlx5e_rep_bond_update(struct mlx5e_priv *priv, bool cleanup)
894
+{
895
+ rep_vport_rx_rule_destroy(priv);
896
+
897
+ return cleanup ? 0 : mlx5e_create_rep_vport_rx_rule(priv);
898
+}
899
+
900
+static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
901
+{
902
+ struct mlx5_core_dev *mdev = priv->mdev;
1004903 int err;
1005904
1006905 mlx5e_init_l2_addr(priv);
1007906
1008
- err = mlx5e_create_direct_rqts(priv);
1009
- if (err)
907
+ err = mlx5e_open_drop_rq(priv, &priv->drop_rq);
908
+ if (err) {
909
+ mlx5_core_err(mdev, "open drop rq failed, %d\n", err);
1010910 return err;
911
+ }
1011912
1012
- err = mlx5e_create_direct_tirs(priv);
913
+ err = mlx5e_create_indirect_rqt(priv);
914
+ if (err)
915
+ goto err_close_drop_rq;
916
+
917
+ err = mlx5e_create_direct_rqts(priv, priv->direct_tir);
918
+ if (err)
919
+ goto err_destroy_indirect_rqts;
920
+
921
+ err = mlx5e_create_indirect_tirs(priv, false);
1013922 if (err)
1014923 goto err_destroy_direct_rqts;
1015924
1016
- flow_rule = mlx5_eswitch_create_vport_rx_rule(esw,
1017
- rep->vport,
1018
- priv->direct_tir[0].tirn);
1019
- if (IS_ERR(flow_rule)) {
1020
- err = PTR_ERR(flow_rule);
925
+ err = mlx5e_create_direct_tirs(priv, priv->direct_tir);
926
+ if (err)
927
+ goto err_destroy_indirect_tirs;
928
+
929
+ err = mlx5e_create_rep_ttc_table(priv);
930
+ if (err)
1021931 goto err_destroy_direct_tirs;
1022
- }
1023
- rpriv->vport_rx_rule = flow_rule;
932
+
933
+ err = mlx5e_create_rep_root_ft(priv);
934
+ if (err)
935
+ goto err_destroy_ttc_table;
936
+
937
+ err = mlx5e_create_rep_vport_rx_rule(priv);
938
+ if (err)
939
+ goto err_destroy_root_ft;
940
+
941
+ mlx5e_ethtool_init_steering(priv);
1024942
1025943 return 0;
1026944
945
+err_destroy_root_ft:
946
+ mlx5e_destroy_rep_root_ft(priv);
947
+err_destroy_ttc_table:
948
+ mlx5e_destroy_ttc_table(priv, &priv->fs.ttc);
1027949 err_destroy_direct_tirs:
1028
- mlx5e_destroy_direct_tirs(priv);
950
+ mlx5e_destroy_direct_tirs(priv, priv->direct_tir);
951
+err_destroy_indirect_tirs:
952
+ mlx5e_destroy_indirect_tirs(priv);
1029953 err_destroy_direct_rqts:
1030
- mlx5e_destroy_direct_rqts(priv);
954
+ mlx5e_destroy_direct_rqts(priv, priv->direct_tir);
955
+err_destroy_indirect_rqts:
956
+ mlx5e_destroy_rqt(priv, &priv->indir_rqt);
957
+err_close_drop_rq:
958
+ mlx5e_close_drop_rq(&priv->drop_rq);
1031959 return err;
1032960 }
1033961
1034962 static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv)
1035963 {
1036
- struct mlx5e_rep_priv *rpriv = priv->ppriv;
964
+ mlx5e_ethtool_cleanup_steering(priv);
965
+ rep_vport_rx_rule_destroy(priv);
966
+ mlx5e_destroy_rep_root_ft(priv);
967
+ mlx5e_destroy_ttc_table(priv, &priv->fs.ttc);
968
+ mlx5e_destroy_direct_tirs(priv, priv->direct_tir);
969
+ mlx5e_destroy_indirect_tirs(priv);
970
+ mlx5e_destroy_direct_rqts(priv, priv->direct_tir);
971
+ mlx5e_destroy_rqt(priv, &priv->indir_rqt);
972
+ mlx5e_close_drop_rq(&priv->drop_rq);
973
+}
1037974
1038
- mlx5_del_flow_rules(rpriv->vport_rx_rule);
1039
- mlx5e_destroy_direct_tirs(priv);
1040
- mlx5e_destroy_direct_rqts(priv);
975
+static int mlx5e_init_ul_rep_rx(struct mlx5e_priv *priv)
976
+{
977
+ mlx5e_create_q_counters(priv);
978
+ return mlx5e_init_rep_rx(priv);
979
+}
980
+
981
+static void mlx5e_cleanup_ul_rep_rx(struct mlx5e_priv *priv)
982
+{
983
+ mlx5e_cleanup_rep_rx(priv);
984
+ mlx5e_destroy_q_counters(priv);
985
+}
986
+
987
+static int mlx5e_init_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)
988
+{
989
+ struct mlx5_rep_uplink_priv *uplink_priv;
990
+ struct net_device *netdev;
991
+ struct mlx5e_priv *priv;
992
+ int err;
993
+
994
+ netdev = rpriv->netdev;
995
+ priv = netdev_priv(netdev);
996
+ uplink_priv = &rpriv->uplink_priv;
997
+
998
+ err = mlx5e_rep_tc_init(rpriv);
999
+ if (err)
1000
+ return err;
1001
+
1002
+ mlx5_init_port_tun_entropy(&uplink_priv->tun_entropy, priv->mdev);
1003
+
1004
+ mlx5e_rep_bond_init(rpriv);
1005
+ err = mlx5e_rep_tc_netdevice_event_register(rpriv);
1006
+ if (err) {
1007
+ mlx5_core_err(priv->mdev, "Failed to register netdev notifier, err: %d\n",
1008
+ err);
1009
+ goto err_event_reg;
1010
+ }
1011
+
1012
+ return 0;
1013
+
1014
+err_event_reg:
1015
+ mlx5e_rep_bond_cleanup(rpriv);
1016
+ mlx5e_rep_tc_cleanup(rpriv);
1017
+ return err;
10411018 }
10421019
10431020 static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
10441021 {
1022
+ struct mlx5e_rep_priv *rpriv = priv->ppriv;
10451023 int err;
10461024
10471025 err = mlx5e_create_tises(priv);
....@@ -1049,143 +1027,255 @@
10491027 mlx5_core_warn(priv->mdev, "create tises failed, %d\n", err);
10501028 return err;
10511029 }
1030
+
1031
+ if (rpriv->rep->vport == MLX5_VPORT_UPLINK) {
1032
+ err = mlx5e_init_uplink_rep_tx(rpriv);
1033
+ if (err)
1034
+ goto destroy_tises;
1035
+ }
1036
+
1037
+ return 0;
1038
+
1039
+destroy_tises:
1040
+ mlx5e_destroy_tises(priv);
1041
+ return err;
1042
+}
1043
+
1044
+static void mlx5e_cleanup_uplink_rep_tx(struct mlx5e_rep_priv *rpriv)
1045
+{
1046
+ mlx5e_rep_tc_netdevice_event_unregister(rpriv);
1047
+ mlx5e_rep_bond_cleanup(rpriv);
1048
+ mlx5e_rep_tc_cleanup(rpriv);
1049
+}
1050
+
1051
+static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)
1052
+{
1053
+ struct mlx5e_rep_priv *rpriv = priv->ppriv;
1054
+
1055
+ mlx5e_destroy_tises(priv);
1056
+
1057
+ if (rpriv->rep->vport == MLX5_VPORT_UPLINK)
1058
+ mlx5e_cleanup_uplink_rep_tx(rpriv);
1059
+}
1060
+
1061
+static void mlx5e_rep_enable(struct mlx5e_priv *priv)
1062
+{
1063
+ mlx5e_set_netdev_mtu_boundaries(priv);
1064
+}
1065
+
1066
+static int mlx5e_update_rep_rx(struct mlx5e_priv *priv)
1067
+{
10521068 return 0;
10531069 }
10541070
1055
-static int mlx5e_get_rep_max_num_channels(struct mlx5_core_dev *mdev)
1071
+static int uplink_rep_async_event(struct notifier_block *nb, unsigned long event, void *data)
10561072 {
1057
-#define MLX5E_PORT_REPRESENTOR_NCH 1
1058
- return MLX5E_PORT_REPRESENTOR_NCH;
1073
+ struct mlx5e_priv *priv = container_of(nb, struct mlx5e_priv, events_nb);
1074
+
1075
+ if (event == MLX5_EVENT_TYPE_PORT_CHANGE) {
1076
+ struct mlx5_eqe *eqe = data;
1077
+
1078
+ switch (eqe->sub_type) {
1079
+ case MLX5_PORT_CHANGE_SUBTYPE_DOWN:
1080
+ case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE:
1081
+ queue_work(priv->wq, &priv->update_carrier_work);
1082
+ break;
1083
+ default:
1084
+ return NOTIFY_DONE;
1085
+ }
1086
+
1087
+ return NOTIFY_OK;
1088
+ }
1089
+
1090
+ if (event == MLX5_DEV_EVENT_PORT_AFFINITY)
1091
+ return mlx5e_rep_tc_event_port_affinity(priv);
1092
+
1093
+ return NOTIFY_DONE;
1094
+}
1095
+
1096
+static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
1097
+{
1098
+ struct net_device *netdev = priv->netdev;
1099
+ struct mlx5_core_dev *mdev = priv->mdev;
1100
+ u16 max_mtu;
1101
+
1102
+ netdev->min_mtu = ETH_MIN_MTU;
1103
+ mlx5_query_port_max_mtu(priv->mdev, &max_mtu, 1);
1104
+ netdev->max_mtu = MLX5E_HW2SW_MTU(&priv->channels.params, max_mtu);
1105
+ mlx5e_set_dev_port_mtu(priv);
1106
+
1107
+ mlx5e_rep_tc_enable(priv);
1108
+
1109
+ mlx5_modify_vport_admin_state(mdev, MLX5_VPORT_STATE_OP_MOD_UPLINK,
1110
+ 0, 0, MLX5_VPORT_ADMIN_STATE_AUTO);
1111
+ mlx5_lag_add(mdev, netdev);
1112
+ priv->events_nb.notifier_call = uplink_rep_async_event;
1113
+ mlx5_notifier_register(mdev, &priv->events_nb);
1114
+ mlx5e_dcbnl_initialize(priv);
1115
+ mlx5e_dcbnl_init_app(priv);
1116
+}
1117
+
1118
+static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv)
1119
+{
1120
+ struct mlx5_core_dev *mdev = priv->mdev;
1121
+
1122
+ mlx5e_dcbnl_delete_app(priv);
1123
+ mlx5_notifier_unregister(mdev, &priv->events_nb);
1124
+ mlx5e_rep_tc_disable(priv);
1125
+ mlx5_lag_remove(mdev);
1126
+}
1127
+
1128
+static MLX5E_DEFINE_STATS_GRP(sw_rep, 0);
1129
+static MLX5E_DEFINE_STATS_GRP(vport_rep, MLX5E_NDO_UPDATE_STATS);
1130
+
1131
+/* The stats groups order is opposite to the update_stats() order calls */
1132
+static mlx5e_stats_grp_t mlx5e_rep_stats_grps[] = {
1133
+ &MLX5E_STATS_GRP(sw_rep),
1134
+ &MLX5E_STATS_GRP(vport_rep),
1135
+};
1136
+
1137
+static unsigned int mlx5e_rep_stats_grps_num(struct mlx5e_priv *priv)
1138
+{
1139
+ return ARRAY_SIZE(mlx5e_rep_stats_grps);
1140
+}
1141
+
1142
+/* The stats groups order is opposite to the update_stats() order calls */
1143
+static mlx5e_stats_grp_t mlx5e_ul_rep_stats_grps[] = {
1144
+ &MLX5E_STATS_GRP(sw),
1145
+ &MLX5E_STATS_GRP(qcnt),
1146
+ &MLX5E_STATS_GRP(vnic_env),
1147
+ &MLX5E_STATS_GRP(vport),
1148
+ &MLX5E_STATS_GRP(802_3),
1149
+ &MLX5E_STATS_GRP(2863),
1150
+ &MLX5E_STATS_GRP(2819),
1151
+ &MLX5E_STATS_GRP(phy),
1152
+ &MLX5E_STATS_GRP(eth_ext),
1153
+ &MLX5E_STATS_GRP(pcie),
1154
+ &MLX5E_STATS_GRP(per_prio),
1155
+ &MLX5E_STATS_GRP(pme),
1156
+ &MLX5E_STATS_GRP(channels),
1157
+ &MLX5E_STATS_GRP(per_port_buff_congest),
1158
+};
1159
+
1160
+static unsigned int mlx5e_ul_rep_stats_grps_num(struct mlx5e_priv *priv)
1161
+{
1162
+ return ARRAY_SIZE(mlx5e_ul_rep_stats_grps);
10591163 }
10601164
10611165 static const struct mlx5e_profile mlx5e_rep_profile = {
10621166 .init = mlx5e_init_rep,
1167
+ .cleanup = mlx5e_cleanup_rep,
10631168 .init_rx = mlx5e_init_rep_rx,
10641169 .cleanup_rx = mlx5e_cleanup_rep_rx,
10651170 .init_tx = mlx5e_init_rep_tx,
1066
- .cleanup_tx = mlx5e_cleanup_nic_tx,
1067
- .update_stats = mlx5e_rep_update_hw_counters,
1068
- .max_nch = mlx5e_get_rep_max_num_channels,
1069
- .update_carrier = NULL,
1070
- .rx_handlers.handle_rx_cqe = mlx5e_handle_rx_cqe_rep,
1071
- .rx_handlers.handle_rx_cqe_mpwqe = NULL /* Not supported */,
1171
+ .cleanup_tx = mlx5e_cleanup_rep_tx,
1172
+ .enable = mlx5e_rep_enable,
1173
+ .update_rx = mlx5e_update_rep_rx,
1174
+ .update_stats = mlx5e_stats_update_ndo_stats,
1175
+ .rx_handlers = &mlx5e_rx_handlers_rep,
10721176 .max_tc = 1,
1177
+ .rq_groups = MLX5E_NUM_RQ_GROUPS(REGULAR),
1178
+ .stats_grps = mlx5e_rep_stats_grps,
1179
+ .stats_grps_num = mlx5e_rep_stats_grps_num,
1180
+};
1181
+
1182
+static const struct mlx5e_profile mlx5e_uplink_rep_profile = {
1183
+ .init = mlx5e_init_rep,
1184
+ .cleanup = mlx5e_cleanup_rep,
1185
+ .init_rx = mlx5e_init_ul_rep_rx,
1186
+ .cleanup_rx = mlx5e_cleanup_ul_rep_rx,
1187
+ .init_tx = mlx5e_init_rep_tx,
1188
+ .cleanup_tx = mlx5e_cleanup_rep_tx,
1189
+ .enable = mlx5e_uplink_rep_enable,
1190
+ .disable = mlx5e_uplink_rep_disable,
1191
+ .update_rx = mlx5e_update_rep_rx,
1192
+ .update_stats = mlx5e_stats_update_ndo_stats,
1193
+ .update_carrier = mlx5e_update_carrier,
1194
+ .rx_handlers = &mlx5e_rx_handlers_rep,
1195
+ .max_tc = MLX5E_MAX_NUM_TC,
1196
+ .rq_groups = MLX5E_NUM_RQ_GROUPS(REGULAR),
1197
+ .stats_grps = mlx5e_ul_rep_stats_grps,
1198
+ .stats_grps_num = mlx5e_ul_rep_stats_grps_num,
10731199 };
10741200
10751201 /* e-Switch vport representors */
1076
-
1077
-static int
1078
-mlx5e_nic_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
1079
-{
1080
- struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1081
- struct mlx5e_priv *priv = netdev_priv(rpriv->netdev);
1082
-
1083
- int err;
1084
-
1085
- if (test_bit(MLX5E_STATE_OPENED, &priv->state)) {
1086
- err = mlx5e_add_sqs_fwd_rules(priv);
1087
- if (err)
1088
- return err;
1089
- }
1090
-
1091
- err = mlx5e_rep_neigh_init(rpriv);
1092
- if (err)
1093
- goto err_remove_sqs;
1094
-
1095
- /* init shared tc flow table */
1096
- err = mlx5e_tc_esw_init(&rpriv->tc_ht);
1097
- if (err)
1098
- goto err_neigh_cleanup;
1099
-
1100
- return 0;
1101
-
1102
-err_neigh_cleanup:
1103
- mlx5e_rep_neigh_cleanup(rpriv);
1104
-err_remove_sqs:
1105
- mlx5e_remove_sqs_fwd_rules(priv);
1106
- return err;
1107
-}
1108
-
1109
-static void
1110
-mlx5e_nic_rep_unload(struct mlx5_eswitch_rep *rep)
1111
-{
1112
- struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
1113
- struct mlx5e_priv *priv = netdev_priv(rpriv->netdev);
1114
-
1115
- if (test_bit(MLX5E_STATE_OPENED, &priv->state))
1116
- mlx5e_remove_sqs_fwd_rules(priv);
1117
-
1118
- /* clean uplink offloaded TC rules, delete shared tc flow table */
1119
- mlx5e_tc_esw_cleanup(&rpriv->tc_ht);
1120
-
1121
- mlx5e_rep_neigh_cleanup(rpriv);
1122
-}
1123
-
11241202 static int
11251203 mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
11261204 {
1127
- struct mlx5e_rep_priv *uplink_rpriv;
1205
+ const struct mlx5e_profile *profile;
11281206 struct mlx5e_rep_priv *rpriv;
1207
+ struct devlink_port *dl_port;
11291208 struct net_device *netdev;
1130
- struct mlx5e_priv *upriv;
1131
- int err;
1209
+ int nch, err;
11321210
11331211 rpriv = kzalloc(sizeof(*rpriv), GFP_KERNEL);
11341212 if (!rpriv)
11351213 return -ENOMEM;
11361214
1137
- netdev = mlx5e_create_netdev(dev, &mlx5e_rep_profile, rpriv);
1215
+ /* rpriv->rep to be looked up when profile->init() is called */
1216
+ rpriv->rep = rep;
1217
+
1218
+ nch = mlx5e_get_max_num_channels(dev);
1219
+ profile = (rep->vport == MLX5_VPORT_UPLINK) ?
1220
+ &mlx5e_uplink_rep_profile : &mlx5e_rep_profile;
1221
+ netdev = mlx5e_create_netdev(dev, profile, nch, rpriv);
11381222 if (!netdev) {
1139
- pr_warn("Failed to create representor netdev for vport %d\n",
1140
- rep->vport);
1223
+ mlx5_core_warn(dev,
1224
+ "Failed to create representor netdev for vport %d\n",
1225
+ rep->vport);
11411226 kfree(rpriv);
11421227 return -EINVAL;
11431228 }
11441229
1230
+ dev_net_set(netdev, mlx5_core_net(dev));
11451231 rpriv->netdev = netdev;
1146
- rpriv->rep = rep;
1147
- rep->rep_if[REP_ETH].priv = rpriv;
1232
+ rep->rep_data[REP_ETH].priv = rpriv;
11481233 INIT_LIST_HEAD(&rpriv->vport_sqs_list);
1234
+
1235
+ if (rep->vport == MLX5_VPORT_UPLINK) {
1236
+ err = mlx5e_create_mdev_resources(dev);
1237
+ if (err)
1238
+ goto err_destroy_netdev;
1239
+ }
11491240
11501241 err = mlx5e_attach_netdev(netdev_priv(netdev));
11511242 if (err) {
1152
- pr_warn("Failed to attach representor netdev for vport %d\n",
1153
- rep->vport);
1154
- goto err_destroy_netdev;
1243
+ netdev_warn(netdev,
1244
+ "Failed to attach representor netdev for vport %d\n",
1245
+ rep->vport);
1246
+ goto err_destroy_mdev_resources;
11551247 }
11561248
11571249 err = mlx5e_rep_neigh_init(rpriv);
11581250 if (err) {
1159
- pr_warn("Failed to initialized neighbours handling for vport %d\n",
1160
- rep->vport);
1251
+ netdev_warn(netdev,
1252
+ "Failed to initialized neighbours handling for vport %d\n",
1253
+ rep->vport);
11611254 goto err_detach_netdev;
11621255 }
11631256
1164
- uplink_rpriv = mlx5_eswitch_get_uplink_priv(dev->priv.eswitch, REP_ETH);
1165
- upriv = netdev_priv(uplink_rpriv->netdev);
1166
- err = tc_setup_cb_egdev_register(netdev, mlx5e_rep_setup_tc_cb_egdev,
1167
- upriv);
1168
- if (err)
1169
- goto err_neigh_cleanup;
1170
-
11711257 err = register_netdev(netdev);
11721258 if (err) {
1173
- pr_warn("Failed to register representor netdev for vport %d\n",
1174
- rep->vport);
1175
- goto err_egdev_cleanup;
1259
+ netdev_warn(netdev,
1260
+ "Failed to register representor netdev for vport %d\n",
1261
+ rep->vport);
1262
+ goto err_neigh_cleanup;
11761263 }
11771264
1265
+ dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
1266
+ if (dl_port)
1267
+ devlink_port_type_eth_set(dl_port, netdev);
11781268 return 0;
1179
-
1180
-err_egdev_cleanup:
1181
- tc_setup_cb_egdev_unregister(netdev, mlx5e_rep_setup_tc_cb_egdev,
1182
- upriv);
11831269
11841270 err_neigh_cleanup:
11851271 mlx5e_rep_neigh_cleanup(rpriv);
11861272
11871273 err_detach_netdev:
11881274 mlx5e_detach_netdev(netdev_priv(netdev));
1275
+
1276
+err_destroy_mdev_resources:
1277
+ if (rep->vport == MLX5_VPORT_UPLINK)
1278
+ mlx5e_destroy_mdev_resources(dev);
11891279
11901280 err_destroy_netdev:
11911281 mlx5e_destroy_netdev(netdev_priv(netdev));
....@@ -1199,18 +1289,18 @@
11991289 struct mlx5e_rep_priv *rpriv = mlx5e_rep_to_rep_priv(rep);
12001290 struct net_device *netdev = rpriv->netdev;
12011291 struct mlx5e_priv *priv = netdev_priv(netdev);
1202
- struct mlx5e_rep_priv *uplink_rpriv;
1292
+ struct mlx5_core_dev *dev = priv->mdev;
1293
+ struct devlink_port *dl_port;
12031294 void *ppriv = priv->ppriv;
1204
- struct mlx5e_priv *upriv;
12051295
1296
+ dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
1297
+ if (dl_port)
1298
+ devlink_port_type_clear(dl_port);
12061299 unregister_netdev(netdev);
1207
- uplink_rpriv = mlx5_eswitch_get_uplink_priv(priv->mdev->priv.eswitch,
1208
- REP_ETH);
1209
- upriv = netdev_priv(uplink_rpriv->netdev);
1210
- tc_setup_cb_egdev_unregister(netdev, mlx5e_rep_setup_tc_cb_egdev,
1211
- upriv);
12121300 mlx5e_rep_neigh_cleanup(rpriv);
12131301 mlx5e_detach_netdev(priv);
1302
+ if (rep->vport == MLX5_VPORT_UPLINK)
1303
+ mlx5e_destroy_mdev_resources(priv->mdev);
12141304 mlx5e_destroy_netdev(priv);
12151305 kfree(ppriv); /* mlx5e_rep_priv */
12161306 }
....@@ -1224,72 +1314,22 @@
12241314 return rpriv->netdev;
12251315 }
12261316
1227
-static void mlx5e_rep_register_vf_vports(struct mlx5e_priv *priv)
1228
-{
1229
- struct mlx5_core_dev *mdev = priv->mdev;
1230
- struct mlx5_eswitch *esw = mdev->priv.eswitch;
1231
- int total_vfs = MLX5_TOTAL_VPORTS(mdev);
1232
- int vport;
1317
+static const struct mlx5_eswitch_rep_ops rep_ops = {
1318
+ .load = mlx5e_vport_rep_load,
1319
+ .unload = mlx5e_vport_rep_unload,
1320
+ .get_proto_dev = mlx5e_vport_rep_get_proto_dev
1321
+};
12331322
1234
- for (vport = 1; vport < total_vfs; vport++) {
1235
- struct mlx5_eswitch_rep_if rep_if = {};
1236
-
1237
- rep_if.load = mlx5e_vport_rep_load;
1238
- rep_if.unload = mlx5e_vport_rep_unload;
1239
- rep_if.get_proto_dev = mlx5e_vport_rep_get_proto_dev;
1240
- mlx5_eswitch_register_vport_rep(esw, vport, &rep_if, REP_ETH);
1241
- }
1242
-}
1243
-
1244
-static void mlx5e_rep_unregister_vf_vports(struct mlx5e_priv *priv)
1245
-{
1246
- struct mlx5_core_dev *mdev = priv->mdev;
1247
- struct mlx5_eswitch *esw = mdev->priv.eswitch;
1248
- int total_vfs = MLX5_TOTAL_VPORTS(mdev);
1249
- int vport;
1250
-
1251
- for (vport = 1; vport < total_vfs; vport++)
1252
- mlx5_eswitch_unregister_vport_rep(esw, vport, REP_ETH);
1253
-}
1254
-
1255
-void mlx5e_register_vport_reps(struct mlx5e_priv *priv)
1256
-{
1257
- struct mlx5_core_dev *mdev = priv->mdev;
1258
- struct mlx5_eswitch *esw = mdev->priv.eswitch;
1259
- struct mlx5_eswitch_rep_if rep_if;
1260
- struct mlx5e_rep_priv *rpriv;
1261
-
1262
- rpriv = priv->ppriv;
1263
- rpriv->netdev = priv->netdev;
1264
-
1265
- rep_if.load = mlx5e_nic_rep_load;
1266
- rep_if.unload = mlx5e_nic_rep_unload;
1267
- rep_if.get_proto_dev = mlx5e_vport_rep_get_proto_dev;
1268
- rep_if.priv = rpriv;
1269
- INIT_LIST_HEAD(&rpriv->vport_sqs_list);
1270
- mlx5_eswitch_register_vport_rep(esw, 0, &rep_if, REP_ETH); /* UPLINK PF vport*/
1271
-
1272
- mlx5e_rep_register_vf_vports(priv); /* VFs vports */
1273
-}
1274
-
1275
-void mlx5e_unregister_vport_reps(struct mlx5e_priv *priv)
1276
-{
1277
- struct mlx5_core_dev *mdev = priv->mdev;
1278
- struct mlx5_eswitch *esw = mdev->priv.eswitch;
1279
-
1280
- mlx5e_rep_unregister_vf_vports(priv); /* VFs vports */
1281
- mlx5_eswitch_unregister_vport_rep(esw, 0, REP_ETH); /* UPLINK PF*/
1282
-}
1283
-
1284
-void *mlx5e_alloc_nic_rep_priv(struct mlx5_core_dev *mdev)
1323
+void mlx5e_rep_register_vport_reps(struct mlx5_core_dev *mdev)
12851324 {
12861325 struct mlx5_eswitch *esw = mdev->priv.eswitch;
1287
- struct mlx5e_rep_priv *rpriv;
12881326
1289
- rpriv = kzalloc(sizeof(*rpriv), GFP_KERNEL);
1290
- if (!rpriv)
1291
- return NULL;
1327
+ mlx5_eswitch_register_vport_reps(esw, &rep_ops, REP_ETH);
1328
+}
12921329
1293
- rpriv->rep = &esw->offloads.vport_reps[0];
1294
- return rpriv;
1330
+void mlx5e_rep_unregister_vport_reps(struct mlx5_core_dev *mdev)
1331
+{
1332
+ struct mlx5_eswitch *esw = mdev->priv.eswitch;
1333
+
1334
+ mlx5_eswitch_unregister_vport_reps(esw, REP_ETH);
12951335 }