Merge tag 'upstream-4.8-rc1' of git://git.infradead.org/linux-ubifs
[sfrench/cifs-2.6.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_rep.c
1 /*
2  * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32
33 #include <generated/utsrelease.h>
34 #include <linux/mlx5/fs.h>
35 #include <net/switchdev.h>
36 #include <net/pkt_cls.h>
37
38 #include "eswitch.h"
39 #include "en.h"
40 #include "en_tc.h"
41
42 static const char mlx5e_rep_driver_name[] = "mlx5e_rep";
43
44 static void mlx5e_rep_get_drvinfo(struct net_device *dev,
45                                   struct ethtool_drvinfo *drvinfo)
46 {
47         strlcpy(drvinfo->driver, mlx5e_rep_driver_name,
48                 sizeof(drvinfo->driver));
49         strlcpy(drvinfo->version, UTS_RELEASE, sizeof(drvinfo->version));
50 }
51
52 static const struct counter_desc sw_rep_stats_desc[] = {
53         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_packets) },
54         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, rx_bytes) },
55         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_packets) },
56         { MLX5E_DECLARE_STAT(struct mlx5e_sw_stats, tx_bytes) },
57 };
58
59 #define NUM_VPORT_REP_COUNTERS  ARRAY_SIZE(sw_rep_stats_desc)
60
61 static void mlx5e_rep_get_strings(struct net_device *dev,
62                                   u32 stringset, uint8_t *data)
63 {
64         int i;
65
66         switch (stringset) {
67         case ETH_SS_STATS:
68                 for (i = 0; i < NUM_VPORT_REP_COUNTERS; i++)
69                         strcpy(data + (i * ETH_GSTRING_LEN),
70                                sw_rep_stats_desc[i].format);
71                 break;
72         }
73 }
74
75 static void mlx5e_update_sw_rep_counters(struct mlx5e_priv *priv)
76 {
77         struct mlx5e_sw_stats *s = &priv->stats.sw;
78         struct mlx5e_rq_stats *rq_stats;
79         struct mlx5e_sq_stats *sq_stats;
80         int i, j;
81
82         memset(s, 0, sizeof(*s));
83         for (i = 0; i < priv->params.num_channels; i++) {
84                 rq_stats = &priv->channel[i]->rq.stats;
85
86                 s->rx_packets   += rq_stats->packets;
87                 s->rx_bytes     += rq_stats->bytes;
88
89                 for (j = 0; j < priv->params.num_tc; j++) {
90                         sq_stats = &priv->channel[i]->sq[j].stats;
91
92                         s->tx_packets           += sq_stats->packets;
93                         s->tx_bytes             += sq_stats->bytes;
94                 }
95         }
96 }
97
98 static void mlx5e_rep_get_ethtool_stats(struct net_device *dev,
99                                         struct ethtool_stats *stats, u64 *data)
100 {
101         struct mlx5e_priv *priv = netdev_priv(dev);
102         int i;
103
104         if (!data)
105                 return;
106
107         mutex_lock(&priv->state_lock);
108         if (test_bit(MLX5E_STATE_OPENED, &priv->state))
109                 mlx5e_update_sw_rep_counters(priv);
110         mutex_unlock(&priv->state_lock);
111
112         for (i = 0; i < NUM_VPORT_REP_COUNTERS; i++)
113                 data[i] = MLX5E_READ_CTR64_CPU(&priv->stats.sw,
114                                                sw_rep_stats_desc, i);
115 }
116
117 static int mlx5e_rep_get_sset_count(struct net_device *dev, int sset)
118 {
119         switch (sset) {
120         case ETH_SS_STATS:
121                 return NUM_VPORT_REP_COUNTERS;
122         default:
123                 return -EOPNOTSUPP;
124         }
125 }
126
127 static const struct ethtool_ops mlx5e_rep_ethtool_ops = {
128         .get_drvinfo       = mlx5e_rep_get_drvinfo,
129         .get_link          = ethtool_op_get_link,
130         .get_strings       = mlx5e_rep_get_strings,
131         .get_sset_count    = mlx5e_rep_get_sset_count,
132         .get_ethtool_stats = mlx5e_rep_get_ethtool_stats,
133 };
134
135 int mlx5e_attr_get(struct net_device *dev, struct switchdev_attr *attr)
136 {
137         struct mlx5e_priv *priv = netdev_priv(dev);
138         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
139         u8 mac[ETH_ALEN];
140
141         if (esw->mode == SRIOV_NONE)
142                 return -EOPNOTSUPP;
143
144         switch (attr->id) {
145         case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
146                 mlx5_query_nic_vport_mac_address(priv->mdev, 0, mac);
147                 attr->u.ppid.id_len = ETH_ALEN;
148                 memcpy(&attr->u.ppid.id, &mac, ETH_ALEN);
149                 break;
150         default:
151                 return -EOPNOTSUPP;
152         }
153
154         return 0;
155 }
156
157 int mlx5e_add_sqs_fwd_rules(struct mlx5e_priv *priv)
158
159 {
160         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
161         struct mlx5_eswitch_rep *rep = priv->ppriv;
162         struct mlx5e_channel *c;
163         int n, tc, err, num_sqs = 0;
164         u16 *sqs;
165
166         sqs = kcalloc(priv->params.num_channels * priv->params.num_tc, sizeof(u16), GFP_KERNEL);
167         if (!sqs)
168                 return -ENOMEM;
169
170         for (n = 0; n < priv->params.num_channels; n++) {
171                 c = priv->channel[n];
172                 for (tc = 0; tc < c->num_tc; tc++)
173                         sqs[num_sqs++] = c->sq[tc].sqn;
174         }
175
176         err = mlx5_eswitch_sqs2vport_start(esw, rep, sqs, num_sqs);
177
178         kfree(sqs);
179         return err;
180 }
181
182 int mlx5e_nic_rep_load(struct mlx5_eswitch *esw, struct mlx5_eswitch_rep *rep)
183 {
184         struct mlx5e_priv *priv = rep->priv_data;
185
186         if (test_bit(MLX5E_STATE_OPENED, &priv->state))
187                 return mlx5e_add_sqs_fwd_rules(priv);
188         return 0;
189 }
190
191 void mlx5e_remove_sqs_fwd_rules(struct mlx5e_priv *priv)
192 {
193         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
194         struct mlx5_eswitch_rep *rep = priv->ppriv;
195
196         mlx5_eswitch_sqs2vport_stop(esw, rep);
197 }
198
199 void mlx5e_nic_rep_unload(struct mlx5_eswitch *esw,
200                           struct mlx5_eswitch_rep *rep)
201 {
202         struct mlx5e_priv *priv = rep->priv_data;
203
204         if (test_bit(MLX5E_STATE_OPENED, &priv->state))
205                 mlx5e_remove_sqs_fwd_rules(priv);
206
207         /* clean (and re-init) existing uplink offloaded TC rules */
208         mlx5e_tc_cleanup(priv);
209         mlx5e_tc_init(priv);
210 }
211
212 static int mlx5e_rep_get_phys_port_name(struct net_device *dev,
213                                         char *buf, size_t len)
214 {
215         struct mlx5e_priv *priv = netdev_priv(dev);
216         struct mlx5_eswitch_rep *rep = priv->ppriv;
217         int ret;
218
219         ret = snprintf(buf, len, "%d", rep->vport - 1);
220         if (ret >= len)
221                 return -EOPNOTSUPP;
222
223         return 0;
224 }
225
226 static int mlx5e_rep_ndo_setup_tc(struct net_device *dev, u32 handle,
227                                   __be16 proto, struct tc_to_netdev *tc)
228 {
229         struct mlx5e_priv *priv = netdev_priv(dev);
230
231         if (TC_H_MAJ(handle) != TC_H_MAJ(TC_H_INGRESS))
232                 return -EOPNOTSUPP;
233
234         switch (tc->type) {
235         case TC_SETUP_CLSFLOWER:
236                 switch (tc->cls_flower->command) {
237                 case TC_CLSFLOWER_REPLACE:
238                         return mlx5e_configure_flower(priv, proto, tc->cls_flower);
239                 case TC_CLSFLOWER_DESTROY:
240                         return mlx5e_delete_flower(priv, tc->cls_flower);
241                 case TC_CLSFLOWER_STATS:
242                         return mlx5e_stats_flower(priv, tc->cls_flower);
243                 }
244         default:
245                 return -EOPNOTSUPP;
246         }
247 }
248
249 static const struct switchdev_ops mlx5e_rep_switchdev_ops = {
250         .switchdev_port_attr_get        = mlx5e_attr_get,
251 };
252
253 static const struct net_device_ops mlx5e_netdev_ops_rep = {
254         .ndo_open                = mlx5e_open,
255         .ndo_stop                = mlx5e_close,
256         .ndo_start_xmit          = mlx5e_xmit,
257         .ndo_get_phys_port_name  = mlx5e_rep_get_phys_port_name,
258         .ndo_setup_tc            = mlx5e_rep_ndo_setup_tc,
259         .ndo_get_stats64         = mlx5e_get_stats,
260 };
261
262 static void mlx5e_build_rep_netdev_priv(struct mlx5_core_dev *mdev,
263                                         struct net_device *netdev,
264                                         const struct mlx5e_profile *profile,
265                                         void *ppriv)
266 {
267         struct mlx5e_priv *priv = netdev_priv(netdev);
268         u8 cq_period_mode = MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ?
269                                          MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
270                                          MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
271
272         priv->params.log_sq_size           =
273                 MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE;
274         priv->params.rq_wq_type = MLX5_WQ_TYPE_LINKED_LIST;
275         priv->params.log_rq_size = MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE;
276
277         priv->params.min_rx_wqes = mlx5_min_rx_wqes(priv->params.rq_wq_type,
278                                             BIT(priv->params.log_rq_size));
279
280         priv->params.rx_am_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
281         mlx5e_set_rx_cq_mode_params(&priv->params, cq_period_mode);
282
283         priv->params.tx_max_inline         = mlx5e_get_max_inline_cap(mdev);
284         priv->params.num_tc                = 1;
285
286         priv->params.lro_wqe_sz            =
287                 MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;
288
289         priv->mdev                         = mdev;
290         priv->netdev                       = netdev;
291         priv->params.num_channels          = profile->max_nch(mdev);
292         priv->profile                      = profile;
293         priv->ppriv                        = ppriv;
294
295         mutex_init(&priv->state_lock);
296
297         INIT_DELAYED_WORK(&priv->update_stats_work, mlx5e_update_stats_work);
298 }
299
300 static void mlx5e_build_rep_netdev(struct net_device *netdev)
301 {
302         netdev->netdev_ops = &mlx5e_netdev_ops_rep;
303
304         netdev->watchdog_timeo    = 15 * HZ;
305
306         netdev->ethtool_ops       = &mlx5e_rep_ethtool_ops;
307
308 #ifdef CONFIG_NET_SWITCHDEV
309         netdev->switchdev_ops = &mlx5e_rep_switchdev_ops;
310 #endif
311
312         netdev->features         |= NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_TC;
313         netdev->hw_features      |= NETIF_F_HW_TC;
314
315         eth_hw_addr_random(netdev);
316 }
317
318 static void mlx5e_init_rep(struct mlx5_core_dev *mdev,
319                            struct net_device *netdev,
320                            const struct mlx5e_profile *profile,
321                            void *ppriv)
322 {
323         mlx5e_build_rep_netdev_priv(mdev, netdev, profile, ppriv);
324         mlx5e_build_rep_netdev(netdev);
325 }
326
327 static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
328 {
329         struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
330         struct mlx5_eswitch_rep *rep = priv->ppriv;
331         struct mlx5_core_dev *mdev = priv->mdev;
332         struct mlx5_flow_rule *flow_rule;
333         int err;
334         int i;
335
336         err = mlx5e_create_direct_rqts(priv);
337         if (err) {
338                 mlx5_core_warn(mdev, "create direct rqts failed, %d\n", err);
339                 return err;
340         }
341
342         err = mlx5e_create_direct_tirs(priv);
343         if (err) {
344                 mlx5_core_warn(mdev, "create direct tirs failed, %d\n", err);
345                 goto err_destroy_direct_rqts;
346         }
347
348         flow_rule = mlx5_eswitch_create_vport_rx_rule(esw,
349                                                       rep->vport,
350                                                       priv->direct_tir[0].tirn);
351         if (IS_ERR(flow_rule)) {
352                 err = PTR_ERR(flow_rule);
353                 goto err_destroy_direct_tirs;
354         }
355         rep->vport_rx_rule = flow_rule;
356
357         err = mlx5e_tc_init(priv);
358         if (err)
359                 goto err_del_flow_rule;
360
361         return 0;
362
363 err_del_flow_rule:
364         mlx5_del_flow_rule(rep->vport_rx_rule);
365 err_destroy_direct_tirs:
366         mlx5e_destroy_direct_tirs(priv);
367 err_destroy_direct_rqts:
368         for (i = 0; i < priv->params.num_channels; i++)
369                 mlx5e_destroy_rqt(priv, &priv->direct_tir[i].rqt);
370         return err;
371 }
372
373 static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv)
374 {
375         struct mlx5_eswitch_rep *rep = priv->ppriv;
376         int i;
377
378         mlx5e_tc_cleanup(priv);
379         mlx5_del_flow_rule(rep->vport_rx_rule);
380         mlx5e_destroy_direct_tirs(priv);
381         for (i = 0; i < priv->params.num_channels; i++)
382                 mlx5e_destroy_rqt(priv, &priv->direct_tir[i].rqt);
383 }
384
385 static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
386 {
387         int err;
388
389         err = mlx5e_create_tises(priv);
390         if (err) {
391                 mlx5_core_warn(priv->mdev, "create tises failed, %d\n", err);
392                 return err;
393         }
394         return 0;
395 }
396
397 static int mlx5e_get_rep_max_num_channels(struct mlx5_core_dev *mdev)
398 {
399 #define MLX5E_PORT_REPRESENTOR_NCH 1
400         return MLX5E_PORT_REPRESENTOR_NCH;
401 }
402
403 static struct mlx5e_profile mlx5e_rep_profile = {
404         .init                   = mlx5e_init_rep,
405         .init_rx                = mlx5e_init_rep_rx,
406         .cleanup_rx             = mlx5e_cleanup_rep_rx,
407         .init_tx                = mlx5e_init_rep_tx,
408         .cleanup_tx             = mlx5e_cleanup_nic_tx,
409         .update_stats           = mlx5e_update_sw_rep_counters,
410         .max_nch                = mlx5e_get_rep_max_num_channels,
411         .max_tc                 = 1,
412 };
413
414 int mlx5e_vport_rep_load(struct mlx5_eswitch *esw,
415                          struct mlx5_eswitch_rep *rep)
416 {
417         rep->priv_data = mlx5e_create_netdev(esw->dev, &mlx5e_rep_profile, rep);
418         if (!rep->priv_data) {
419                 pr_warn("Failed to create representor for vport %d\n",
420                         rep->vport);
421                 return -EINVAL;
422         }
423         return 0;
424 }
425
426 void mlx5e_vport_rep_unload(struct mlx5_eswitch *esw,
427                             struct mlx5_eswitch_rep *rep)
428 {
429         struct mlx5e_priv *priv = rep->priv_data;
430
431         mlx5e_destroy_netdev(esw->dev, priv);
432 }