GNU Linux-libre 4.14.266-gnu1
[releases.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_REPR_TYPE_MAX;
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         if (repr_type > NFP_REPR_TYPE_MAX)
94                 return NULL;
95
96         reprs = rcu_dereference(app->reprs[repr_type]);
97         if (!reprs)
98                 return NULL;
99
100         if (port >= reprs->num_reprs)
101                 return NULL;
102
103         return reprs->reprs[port];
104 }
105
106 static int
107 nfp_flower_repr_netdev_open(struct nfp_app *app, struct nfp_repr *repr)
108 {
109         int err;
110
111         err = nfp_flower_cmsg_portmod(repr, true);
112         if (err)
113                 return err;
114
115         netif_carrier_on(repr->netdev);
116         netif_tx_wake_all_queues(repr->netdev);
117
118         return 0;
119 }
120
121 static int
122 nfp_flower_repr_netdev_stop(struct nfp_app *app, struct nfp_repr *repr)
123 {
124         netif_carrier_off(repr->netdev);
125         netif_tx_disable(repr->netdev);
126
127         return nfp_flower_cmsg_portmod(repr, false);
128 }
129
130 static void nfp_flower_sriov_disable(struct nfp_app *app)
131 {
132         struct nfp_flower_priv *priv = app->priv;
133
134         if (!priv->nn)
135                 return;
136
137         nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_VF);
138 }
139
140 static int
141 nfp_flower_spawn_vnic_reprs(struct nfp_app *app,
142                             enum nfp_flower_cmsg_port_vnic_type vnic_type,
143                             enum nfp_repr_type repr_type, unsigned int cnt)
144 {
145         u8 nfp_pcie = nfp_cppcore_pcie_unit(app->pf->cpp);
146         struct nfp_flower_priv *priv = app->priv;
147         struct nfp_reprs *reprs, *old_reprs;
148         enum nfp_port_type port_type;
149         const u8 queue = 0;
150         int i, err;
151
152         port_type = repr_type == NFP_REPR_TYPE_PF ? NFP_PORT_PF_PORT :
153                                                     NFP_PORT_VF_PORT;
154
155         reprs = nfp_reprs_alloc(cnt);
156         if (!reprs)
157                 return -ENOMEM;
158
159         for (i = 0; i < cnt; i++) {
160                 struct nfp_port *port;
161                 u32 port_id;
162
163                 reprs->reprs[i] = nfp_repr_alloc(app);
164                 if (!reprs->reprs[i]) {
165                         err = -ENOMEM;
166                         goto err_reprs_clean;
167                 }
168
169                 /* For now we only support 1 PF */
170                 WARN_ON(repr_type == NFP_REPR_TYPE_PF && i);
171
172                 port = nfp_port_alloc(app, port_type, reprs->reprs[i]);
173                 if (repr_type == NFP_REPR_TYPE_PF) {
174                         port->pf_id = i;
175                         port->vnic = priv->nn->dp.ctrl_bar;
176                 } else {
177                         port->pf_id = 0;
178                         port->vf_id = i;
179                         port->vnic =
180                                 app->pf->vf_cfg_mem + i * NFP_NET_CFG_BAR_SZ;
181                 }
182
183                 eth_hw_addr_random(reprs->reprs[i]);
184
185                 port_id = nfp_flower_cmsg_pcie_port(nfp_pcie, vnic_type,
186                                                     i, queue);
187                 err = nfp_repr_init(app, reprs->reprs[i],
188                                     port_id, port, priv->nn->dp.netdev);
189                 if (err) {
190                         nfp_port_free(port);
191                         goto err_reprs_clean;
192                 }
193
194                 nfp_info(app->cpp, "%s%d Representor(%s) created\n",
195                          repr_type == NFP_REPR_TYPE_PF ? "PF" : "VF", i,
196                          reprs->reprs[i]->name);
197         }
198
199         old_reprs = nfp_app_reprs_set(app, repr_type, reprs);
200         if (IS_ERR(old_reprs)) {
201                 err = PTR_ERR(old_reprs);
202                 goto err_reprs_clean;
203         }
204
205         return 0;
206 err_reprs_clean:
207         nfp_reprs_clean_and_free(reprs);
208         return err;
209 }
210
211 static int nfp_flower_sriov_enable(struct nfp_app *app, int num_vfs)
212 {
213         struct nfp_flower_priv *priv = app->priv;
214
215         if (!priv->nn)
216                 return 0;
217
218         return nfp_flower_spawn_vnic_reprs(app,
219                                            NFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF,
220                                            NFP_REPR_TYPE_VF, num_vfs);
221 }
222
223 static int
224 nfp_flower_spawn_phy_reprs(struct nfp_app *app, struct nfp_flower_priv *priv)
225 {
226         struct nfp_eth_table *eth_tbl = app->pf->eth_tbl;
227         struct nfp_reprs *reprs, *old_reprs;
228         struct sk_buff *ctrl_skb;
229         unsigned int i;
230         int err;
231
232         ctrl_skb = nfp_flower_cmsg_mac_repr_start(app, eth_tbl->count);
233         if (!ctrl_skb)
234                 return -ENOMEM;
235
236         reprs = nfp_reprs_alloc(eth_tbl->max_index + 1);
237         if (!reprs) {
238                 err = -ENOMEM;
239                 goto err_free_ctrl_skb;
240         }
241
242         for (i = 0; i < eth_tbl->count; i++) {
243                 unsigned int phys_port = eth_tbl->ports[i].index;
244                 struct nfp_port *port;
245                 u32 cmsg_port_id;
246
247                 reprs->reprs[phys_port] = nfp_repr_alloc(app);
248                 if (!reprs->reprs[phys_port]) {
249                         err = -ENOMEM;
250                         goto err_reprs_clean;
251                 }
252
253                 port = nfp_port_alloc(app, NFP_PORT_PHYS_PORT,
254                                       reprs->reprs[phys_port]);
255                 if (IS_ERR(port)) {
256                         err = PTR_ERR(port);
257                         goto err_reprs_clean;
258                 }
259                 err = nfp_port_init_phy_port(app->pf, app, port, i);
260                 if (err) {
261                         nfp_port_free(port);
262                         goto err_reprs_clean;
263                 }
264
265                 SET_NETDEV_DEV(reprs->reprs[phys_port], &priv->nn->pdev->dev);
266                 nfp_net_get_mac_addr(app->pf, port);
267
268                 cmsg_port_id = nfp_flower_cmsg_phys_port(phys_port);
269                 err = nfp_repr_init(app, reprs->reprs[phys_port],
270                                     cmsg_port_id, port, priv->nn->dp.netdev);
271                 if (err) {
272                         nfp_port_free(port);
273                         goto err_reprs_clean;
274                 }
275
276                 nfp_flower_cmsg_mac_repr_add(ctrl_skb, i,
277                                              eth_tbl->ports[i].nbi,
278                                              eth_tbl->ports[i].base,
279                                              phys_port);
280
281                 nfp_info(app->cpp, "Phys Port %d Representor(%s) created\n",
282                          phys_port, reprs->reprs[phys_port]->name);
283         }
284
285         old_reprs = nfp_app_reprs_set(app, NFP_REPR_TYPE_PHYS_PORT, reprs);
286         if (IS_ERR(old_reprs)) {
287                 err = PTR_ERR(old_reprs);
288                 goto err_reprs_clean;
289         }
290
291         /* The MAC_REPR control message should be sent after the MAC
292          * representors are registered using nfp_app_reprs_set().  This is
293          * because the firmware may respond with control messages for the
294          * MAC representors, f.e. to provide the driver with information
295          * about their state, and without registration the driver will drop
296          * any such messages.
297          */
298         nfp_ctrl_tx(app->ctrl, ctrl_skb);
299
300         return 0;
301 err_reprs_clean:
302         nfp_reprs_clean_and_free(reprs);
303 err_free_ctrl_skb:
304         kfree_skb(ctrl_skb);
305         return err;
306 }
307
308 static int nfp_flower_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
309                                  unsigned int id)
310 {
311         if (id > 0) {
312                 nfp_warn(app->cpp, "FlowerNIC doesn't support more than one data vNIC\n");
313                 goto err_invalid_port;
314         }
315
316         eth_hw_addr_random(nn->dp.netdev);
317         netif_keep_dst(nn->dp.netdev);
318
319         return 0;
320
321 err_invalid_port:
322         nn->port = nfp_port_alloc(app, NFP_PORT_INVALID, nn->dp.netdev);
323         return PTR_ERR_OR_ZERO(nn->port);
324 }
325
326 static void nfp_flower_vnic_clean(struct nfp_app *app, struct nfp_net *nn)
327 {
328         struct nfp_flower_priv *priv = app->priv;
329
330         if (app->pf->num_vfs)
331                 nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_VF);
332         nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PF);
333         nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PHYS_PORT);
334
335         priv->nn = NULL;
336 }
337
338 static int nfp_flower_vnic_init(struct nfp_app *app, struct nfp_net *nn)
339 {
340         struct nfp_flower_priv *priv = app->priv;
341         int err;
342
343         priv->nn = nn;
344
345         err = nfp_flower_spawn_phy_reprs(app, app->priv);
346         if (err)
347                 goto err_clear_nn;
348
349         err = nfp_flower_spawn_vnic_reprs(app,
350                                           NFP_FLOWER_CMSG_PORT_VNIC_TYPE_PF,
351                                           NFP_REPR_TYPE_PF, 1);
352         if (err)
353                 goto err_destroy_reprs_phy;
354
355         if (app->pf->num_vfs) {
356                 err = nfp_flower_spawn_vnic_reprs(app,
357                                                   NFP_FLOWER_CMSG_PORT_VNIC_TYPE_VF,
358                                                   NFP_REPR_TYPE_VF,
359                                                   app->pf->num_vfs);
360                 if (err)
361                         goto err_destroy_reprs_pf;
362         }
363
364         return 0;
365
366 err_destroy_reprs_pf:
367         nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PF);
368 err_destroy_reprs_phy:
369         nfp_reprs_clean_and_free_by_type(app, NFP_REPR_TYPE_PHYS_PORT);
370 err_clear_nn:
371         priv->nn = NULL;
372         return err;
373 }
374
375 static int nfp_flower_init(struct nfp_app *app)
376 {
377         const struct nfp_pf *pf = app->pf;
378         struct nfp_flower_priv *app_priv;
379         u64 version;
380         int err;
381
382         if (!pf->eth_tbl) {
383                 nfp_warn(app->cpp, "FlowerNIC requires eth table\n");
384                 return -EINVAL;
385         }
386
387         if (!pf->mac_stats_bar) {
388                 nfp_warn(app->cpp, "FlowerNIC requires mac_stats BAR\n");
389                 return -EINVAL;
390         }
391
392         if (!pf->vf_cfg_bar) {
393                 nfp_warn(app->cpp, "FlowerNIC requires vf_cfg BAR\n");
394                 return -EINVAL;
395         }
396
397         version = nfp_rtsym_read_le(app->pf->rtbl, "hw_flower_version", &err);
398         if (err) {
399                 nfp_warn(app->cpp, "FlowerNIC requires hw_flower_version memory symbol\n");
400                 return err;
401         }
402
403         /* We need to ensure hardware has enough flower capabilities. */
404         if (version != NFP_FLOWER_ALLOWED_VER) {
405                 nfp_warn(app->cpp, "FlowerNIC: unsupported firmware version\n");
406                 return -EINVAL;
407         }
408
409         app_priv = vzalloc(sizeof(struct nfp_flower_priv));
410         if (!app_priv)
411                 return -ENOMEM;
412
413         app->priv = app_priv;
414         app_priv->app = app;
415         skb_queue_head_init(&app_priv->cmsg_skbs);
416         INIT_WORK(&app_priv->cmsg_work, nfp_flower_cmsg_process_rx);
417
418         err = nfp_flower_metadata_init(app);
419         if (err)
420                 goto err_free_app_priv;
421
422         return 0;
423
424 err_free_app_priv:
425         vfree(app->priv);
426         return err;
427 }
428
429 static void nfp_flower_clean(struct nfp_app *app)
430 {
431         struct nfp_flower_priv *app_priv = app->priv;
432
433         skb_queue_purge(&app_priv->cmsg_skbs);
434         flush_work(&app_priv->cmsg_work);
435
436         nfp_flower_metadata_cleanup(app);
437         vfree(app->priv);
438         app->priv = NULL;
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         .ctrl_msg_rx    = nfp_flower_cmsg_rx,
459
460         .sriov_enable   = nfp_flower_sriov_enable,
461         .sriov_disable  = nfp_flower_sriov_disable,
462
463         .eswitch_mode_get  = eswitch_mode_get,
464         .repr_get       = nfp_flower_repr_get,
465
466         .setup_tc       = nfp_flower_setup_tc,
467 };