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