Merge tag 'libnvdimm-for-4.15' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdim...
[sfrench/cifs-2.6.git] / drivers / net / ethernet / netronome / nfp / flower / main.c
1 /*
2  * Copyright (C) 2017 Netronome Systems, Inc.
3  *
4  * This software is dual licensed under the GNU General License Version 2,
5  * June 1991 as shown in the file COPYING in the top-level directory of this
6  * source tree or the BSD 2-Clause License provided below.  You have the
7  * option to license this software under the complete terms of either license.
8  *
9  * The BSD 2-Clause License:
10  *
11  *     Redistribution and use in source and binary forms, with or
12  *     without modification, are permitted provided that the following
13  *     conditions are met:
14  *
15  *      1. Redistributions of source code must retain the above
16  *         copyright notice, this list of conditions and the following
17  *         disclaimer.
18  *
19  *      2. Redistributions in binary form must reproduce the above
20  *         copyright notice, this list of conditions and the following
21  *         disclaimer in the documentation and/or other materials
22  *         provided with the distribution.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31  * SOFTWARE.
32  */
33
34 #include <linux/etherdevice.h>
35 #include <linux/pci.h>
36 #include <linux/skbuff.h>
37 #include <linux/vmalloc.h>
38 #include <net/devlink.h>
39 #include <net/dst_metadata.h>
40
41 #include "main.h"
42 #include "../nfpcore/nfp_cpp.h"
43 #include "../nfpcore/nfp_nffw.h"
44 #include "../nfpcore/nfp_nsp.h"
45 #include "../nfp_app.h"
46 #include "../nfp_main.h"
47 #include "../nfp_net.h"
48 #include "../nfp_net_repr.h"
49 #include "../nfp_port.h"
50 #include "./cmsg.h"
51
52 #define NFP_FLOWER_ALLOWED_VER 0x0001000000010000UL
53
54 static const char *nfp_flower_extra_cap(struct nfp_app *app, struct nfp_net *nn)
55 {
56         return "FLOWER";
57 }
58
59 static enum devlink_eswitch_mode eswitch_mode_get(struct nfp_app *app)
60 {
61         return DEVLINK_ESWITCH_MODE_SWITCHDEV;
62 }
63
64 static enum nfp_repr_type
65 nfp_flower_repr_get_type_and_port(struct nfp_app *app, u32 port_id, u8 *port)
66 {
67         switch (FIELD_GET(NFP_FLOWER_CMSG_PORT_TYPE, port_id)) {
68         case NFP_FLOWER_CMSG_PORT_TYPE_PHYS_PORT:
69                 *port = FIELD_GET(NFP_FLOWER_CMSG_PORT_PHYS_PORT_NUM,
70                                   port_id);
71                 return NFP_REPR_TYPE_PHYS_PORT;
72
73         case NFP_FLOWER_CMSG_PORT_TYPE_PCIE_PORT:
74                 *port = FIELD_GET(NFP_FLOWER_CMSG_PORT_VNIC, port_id);
75                 if (FIELD_GET(NFP_FLOWER_CMSG_PORT_VNIC_TYPE, port_id) ==
76                     NFP_FLOWER_CMSG_PORT_VNIC_TYPE_PF)
77                         return NFP_REPR_TYPE_PF;
78                 else
79                         return NFP_REPR_TYPE_VF;
80         }
81
82         return NFP_FLOWER_CMSG_PORT_TYPE_UNSPEC;
83 }
84
85 static struct net_device *
86 nfp_flower_repr_get(struct nfp_app *app, u32 port_id)
87 {
88         enum nfp_repr_type repr_type;
89         struct nfp_reprs *reprs;
90         u8 port = 0;
91
92         repr_type = nfp_flower_repr_get_type_and_port(app, port_id, &port);
93
94         reprs = rcu_dereference(app->reprs[repr_type]);
95         if (!reprs)
96                 return NULL;
97
98         if (port >= reprs->num_reprs)
99                 return NULL;
100
101         return reprs->reprs[port];
102 }
103
104 static int
105 nfp_flower_repr_netdev_open(struct nfp_app *app, struct nfp_repr *repr)
106 {
107         int err;
108
109         err = nfp_flower_cmsg_portmod(repr, true);
110         if (err)
111                 return err;
112
113         netif_carrier_on(repr->netdev);
114         netif_tx_wake_all_queues(repr->netdev);
115
116         return 0;
117 }
118
119 static int
120 nfp_flower_repr_netdev_stop(struct nfp_app *app, struct nfp_repr *repr)
121 {
122         netif_carrier_off(repr->netdev);
123         netif_tx_disable(repr->netdev);
124
125         return nfp_flower_cmsg_portmod(repr, false);
126 }
127
128 static void nfp_flower_sriov_disable(struct nfp_app *app)
129 {
130         struct nfp_flower_priv *priv = app->priv;
131
132         if (!priv->nn)
133                 return;
134
135         nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_VF);
136 }
137
138 static int
139 nfp_flower_spawn_vnic_reprs(struct nfp_app *app,
140                             enum nfp_flower_cmsg_port_vnic_type vnic_type,
141                             enum nfp_repr_type repr_type, unsigned int cnt)
142 {
143         u8 nfp_pcie = nfp_cppcore_pcie_unit(app->pf->cpp);
144         struct nfp_flower_priv *priv = app->priv;
145         enum nfp_port_type port_type;
146         struct nfp_reprs *reprs;
147         const u8 queue = 0;
148         int i, err;
149
150         port_type = repr_type == NFP_REPR_TYPE_PF ? NFP_PORT_PF_PORT :
151                                                     NFP_PORT_VF_PORT;
152
153         reprs = nfp_reprs_alloc(cnt);
154         if (!reprs)
155                 return -ENOMEM;
156
157         for (i = 0; i < cnt; i++) {
158                 struct nfp_port *port;
159                 u32 port_id;
160
161                 reprs->reprs[i] = nfp_repr_alloc(app);
162                 if (!reprs->reprs[i]) {
163                         err = -ENOMEM;
164                         goto err_reprs_clean;
165                 }
166
167                 /* For now we only support 1 PF */
168                 WARN_ON(repr_type == NFP_REPR_TYPE_PF && i);
169
170                 port = nfp_port_alloc(app, port_type, reprs->reprs[i]);
171                 if (repr_type == NFP_REPR_TYPE_PF) {
172                         port->pf_id = i;
173                         port->vnic = priv->nn->dp.ctrl_bar;
174                 } else {
175                         port->pf_id = 0;
176                         port->vf_id = i;
177                         port->vnic =
178                                 app->pf->vf_cfg_mem + i * NFP_NET_CFG_BAR_SZ;
179                 }
180
181                 eth_hw_addr_random(reprs->reprs[i]);
182
183                 port_id = nfp_flower_cmsg_pcie_port(nfp_pcie, vnic_type,
184                                                     i, queue);
185                 err = nfp_repr_init(app, reprs->reprs[i],
186                                     port_id, port, priv->nn->dp.netdev);
187                 if (err) {
188                         nfp_port_free(port);
189                         goto err_reprs_clean;
190                 }
191
192                 nfp_info(app->cpp, "%s%d Representor(%s) created\n",
193                          repr_type == NFP_REPR_TYPE_PF ? "PF" : "VF", i,
194                          reprs->reprs[i]->name);
195         }
196
197         nfp_app_reprs_set(app, repr_type, reprs);
198
199         return 0;
200 err_reprs_clean:
201         nfp_reprs_clean_and_free(reprs);
202         return err;
203 }
204
205 static int nfp_flower_sriov_enable(struct nfp_app *app, int num_vfs)
206 {
207         struct nfp_flower_priv *priv = app->priv;
208
209         if (!priv->nn)
210                 return 0;
211
212         return nfp_flower_spawn_vnic_reprs(app,
213                                            NFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF,
214                                            NFP_REPR_TYPE_VF, num_vfs);
215 }
216
217 static int
218 nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv)
219 {
220         struct nfp_eth_table *eth_tbl = app->pf->eth_tbl;
221         struct sk_buff *ctrl_skb;
222         struct nfp_reprs *reprs;
223         unsigned int i;
224         int err;
225
226         ctrl_skb = nfp_flower_cmsg_mac_repr_start(app, eth_tbl->count);
227         if (!ctrl_skb)
228                 return -ENOMEM;
229
230         reprs = nfp_reprs_alloc(eth_tbl->max_index + 1);
231         if (!reprs) {
232                 err = -ENOMEM;
233                 goto err_free_ctrl_skb;
234         }
235
236         for (i = 0; i < eth_tbl->count; i++) {
237                 unsigned int phys_port = eth_tbl->ports[i].index;
238                 struct nfp_port *port;
239                 u32 cmsg_port_id;
240
241                 reprs->reprs[phys_port] = nfp_repr_alloc(app);
242                 if (!reprs->reprs[phys_port]) {
243                         err = -ENOMEM;
244                         goto err_reprs_clean;
245                 }
246
247                 port = nfp_port_alloc(app, NFP_PORT_PHYS_PORT,
248                                       reprs->reprs[phys_port]);
249                 if (IS_ERR(port)) {
250                         err = PTR_ERR(port);
251                         goto err_reprs_clean;
252                 }
253                 err = nfp_port_init_phy_port(app->pf, app, port, i);
254                 if (err) {
255                         nfp_port_free(port);
256                         goto err_reprs_clean;
257                 }
258
259                 SET_NETDEV_DEV(reprs->reprs[phys_port], &priv->nn->pdev->dev);
260                 nfp_net_get_mac_addr(app->pf, port);
261
262                 cmsg_port_id = nfp_flower_cmsg_phys_port(phys_port);
263                 err = nfp_repr_init(app, reprs->reprs[phys_port],
264                                     cmsg_port_id, port, priv->nn->dp.netdev);
265                 if (err) {
266                         nfp_port_free(port);
267                         goto err_reprs_clean;
268                 }
269
270                 nfp_flower_cmsg_mac_repr_add(ctrl_skb, i,
271                                              eth_tbl->ports[i].nbi,
272                                              eth_tbl->ports[i].base,
273                                              phys_port);
274
275                 nfp_info(app->cpp, "Phys Port %d Representor(%s) created\n",
276                          phys_port, reprs->reprs[phys_port]->name);
277         }
278
279         nfp_app_reprs_set(app, NFP_REPR_TYPE_PHYS_PORT, reprs);
280
281         /* The MAC_REPR control message should be sent after the MAC
282          * representors are registered using nfp_app_reprs_set().  This is
283          * because the firmware may respond with control messages for the
284          * MAC representors, f.e. to provide the driver with information
285          * about their state, and without registration the driver will drop
286          * any such messages.
287          */
288         nfp_ctrl_tx(app->ctrl, ctrl_skb);
289
290         return 0;
291 err_reprs_clean:
292         nfp_reprs_clean_and_free(reprs);
293 err_free_ctrl_skb:
294         kfree_skb(ctrl_skb);
295         return err;
296 }
297
298 static int nfp_flower_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
299                                  unsigned int id)
300 {
301         if (id > 0) {
302                 nfp_warn(app->cpp, "FlowerNIC doesn't support more than one data vNIC\n");
303                 goto err_invalid_port;
304         }
305
306         eth_hw_addr_random(nn->dp.netdev);
307         netif_keep_dst(nn->dp.netdev);
308
309         return 0;
310
311 err_invalid_port:
312         nn->port = nfp_port_alloc(app, NFP_PORT_INVALID, nn->dp.netdev);
313         return PTR_ERR_OR_ZERO(nn->port);
314 }
315
316 static void nfp_flower_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
317 {
318         struct nfp_flower_priv *priv = app->priv;
319
320         if (app->pf->num_vfs)
321                 nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_VF);
322         nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PF);
323         nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PHYS_PORT);
324
325         priv->nn = NULL;
326 }
327
328 static int nfp_flower_vnic_init(struct nfp_app *app, struct nfp_net *nn)
329 {
330         struct nfp_flower_priv *priv = app->priv;
331         int err;
332
333         priv->nn = nn;
334
335         err = nfp_flower_spawn_phy_reprs(app, app->priv);
336         if (err)
337                 goto err_clear_nn;
338
339         err = nfp_flower_spawn_vnic_reprs(app,
340                                           NFP_FLOWER_CMSG_PORT_VNIC_TYPE_PF,
341                                           NFP_REPR_TYPE_PF, 1);
342         if (err)
343                 goto err_destroy_reprs_phy;
344
345         if (app->pf->num_vfs) {
346                 err = nfp_flower_spawn_vnic_reprs(app,
347                                                   NFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF,
348                                                   NFP_REPR_TYPE_VF,
349                                                   app->pf->num_vfs);
350                 if (err)
351                         goto err_destroy_reprs_pf;
352         }
353
354         return 0;
355
356 err_destroy_reprs_pf:
357         nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PF);
358 err_destroy_reprs_phy:
359         nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PHYS_PORT);
360 err_clear_nn:
361         priv->nn = NULL;
362         return err;
363 }
364
365 static int nfp_flower_init(struct nfp_app *app)
366 {
367         const struct nfp_pf *pf = app->pf;
368         struct nfp_flower_priv *app_priv;
369         u64 version;
370         int err;
371
372         if (!pf->eth_tbl) {
373                 nfp_warn(app->cpp, "FlowerNIC requires eth table\n");
374                 return -EINVAL;
375         }
376
377         if (!pf->mac_stats_bar) {
378                 nfp_warn(app->cpp, "FlowerNIC requires mac_stats BAR\n");
379                 return -EINVAL;
380         }
381
382         if (!pf->vf_cfg_bar) {
383                 nfp_warn(app->cpp, "FlowerNIC requires vf_cfg BAR\n");
384                 return -EINVAL;
385         }
386
387         version = nfp_rtsym_read_le(app->pf->rtbl, "hw_flower_version", &err);
388         if (err) {
389                 nfp_warn(app->cpp, "FlowerNIC requires hw_flower_version memory symbol\n");
390                 return err;
391         }
392
393         /* We need to ensure hardware has enough flower capabilities. */
394         if (version != NFP_FLOWER_ALLOWED_VER) {
395                 nfp_warn(app->cpp, "FlowerNIC: unsupported firmware version\n");
396                 return -EINVAL;
397         }
398
399         app_priv = vzalloc(sizeof(struct nfp_flower_priv));
400         if (!app_priv)
401                 return -ENOMEM;
402
403         app->priv = app_priv;
404         app_priv->app = app;
405         skb_queue_head_init(&app_priv->cmsg_skbs);
406         INIT_WORK(&app_priv->cmsg_work, nfp_flower_cmsg_process_rx);
407
408         err = nfp_flower_metadata_init(app);
409         if (err)
410                 goto err_free_app_priv;
411
412         return 0;
413
414 err_free_app_priv:
415         vfree(app->priv);
416         return err;
417 }
418
419 static void nfp_flower_clean(struct nfp_app *app)
420 {
421         struct nfp_flower_priv *app_priv = app->priv;
422
423         skb_queue_purge(&app_priv->cmsg_skbs);
424         flush_work(&app_priv->cmsg_work);
425
426         nfp_flower_metadata_cleanup(app);
427         vfree(app->priv);
428         app->priv = NULL;
429 }
430
431 static int nfp_flower_start(struct nfp_app *app)
432 {
433         return nfp_tunnel_config_start(app);
434 }
435
436 static void nfp_flower_stop(struct nfp_app *app)
437 {
438         nfp_tunnel_config_stop(app);
439 }
440
441 const struct nfp_app_type app_flower = {
442         .id             = NFP_APP_FLOWER_NIC,
443         .name           = "flower",
444         .ctrl_has_meta  = true,
445
446         .extra_cap      = nfp_flower_extra_cap,
447
448         .init           = nfp_flower_init,
449         .clean          = nfp_flower_clean,
450
451         .vnic_alloc     = nfp_flower_vnic_alloc,
452         .vnic_init      = nfp_flower_vnic_init,
453         .vnic_clean     = nfp_flower_vnic_clean,
454
455         .repr_open      = nfp_flower_repr_netdev_open,
456         .repr_stop      = nfp_flower_repr_netdev_stop,
457
458         .start          = nfp_flower_start,
459         .stop           = nfp_flower_stop,
460
461         .ctrl_msg_rx    = nfp_flower_cmsg_rx,
462
463         .sriov_enable   = nfp_flower_sriov_enable,
464         .sriov_disable  = nfp_flower_sriov_disable,
465
466         .eswitch_mode_get  = eswitch_mode_get,
467         .repr_get       = nfp_flower_repr_get,
468
469         .setup_tc       = nfp_flower_setup_tc,
470 };