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/io-64-nonatomic-hi-lo.h>
36 #include <linux/lockdep.h>
37 #include <net/dst_metadata.h>
38 #include <net/switchdev.h>
39 
40 #include "nfpcore/nfp_cpp.h"
41 #include "nfpcore/nfp_nsp.h"
42 #include "nfp_app.h"
43 #include "nfp_main.h"
44 #include "nfp_net_ctrl.h"
45 #include "nfp_net_repr.h"
46 #include "nfp_port.h"
47 
48 static void
49 nfp_repr_inc_tx_stats(struct net_device *netdev, unsigned int len,
50 		      int tx_status)
51 {
52 	struct nfp_repr *repr = netdev_priv(netdev);
53 	struct nfp_repr_pcpu_stats *stats;
54 
55 	if (unlikely(tx_status != NET_XMIT_SUCCESS &&
56 		     tx_status != NET_XMIT_CN)) {
57 		this_cpu_inc(repr->stats->tx_drops);
58 		return;
59 	}
60 
61 	stats = this_cpu_ptr(repr->stats);
62 	u64_stats_update_begin(&stats->syncp);
63 	stats->tx_packets++;
64 	stats->tx_bytes += len;
65 	u64_stats_update_end(&stats->syncp);
66 }
67 
68 void nfp_repr_inc_rx_stats(struct net_device *netdev, unsigned int len)
69 {
70 	struct nfp_repr *repr = netdev_priv(netdev);
71 	struct nfp_repr_pcpu_stats *stats;
72 
73 	stats = this_cpu_ptr(repr->stats);
74 	u64_stats_update_begin(&stats->syncp);
75 	stats->rx_packets++;
76 	stats->rx_bytes += len;
77 	u64_stats_update_end(&stats->syncp);
78 }
79 
80 static void
81 nfp_repr_phy_port_get_stats64(const struct nfp_app *app, u8 phy_port,
82 			      struct rtnl_link_stats64 *stats)
83 {
84 	u8 __iomem *mem;
85 
86 	mem = app->pf->mac_stats_mem + phy_port * NFP_MAC_STATS_SIZE;
87 
88 	/* TX and RX stats are flipped as we are returning the stats as seen
89 	 * at the switch port corresponding to the phys port.
90 	 */
91 	stats->tx_packets = readq(mem + NFP_MAC_STATS_RX_FRAMES_RECEIVED_OK);
92 	stats->tx_bytes = readq(mem + NFP_MAC_STATS_RX_IN_OCTETS);
93 	stats->tx_dropped = readq(mem + NFP_MAC_STATS_RX_IN_ERRORS);
94 
95 	stats->rx_packets = readq(mem + NFP_MAC_STATS_TX_FRAMES_TRANSMITTED_OK);
96 	stats->rx_bytes = readq(mem + NFP_MAC_STATS_TX_OUT_OCTETS);
97 	stats->rx_dropped = readq(mem + NFP_MAC_STATS_TX_OUT_ERRORS);
98 }
99 
100 static void
101 nfp_repr_vf_get_stats64(const struct nfp_app *app, u8 vf,
102 			struct rtnl_link_stats64 *stats)
103 {
104 	u8 __iomem *mem;
105 
106 	mem = app->pf->vf_cfg_mem + vf * NFP_NET_CFG_BAR_SZ;
107 
108 	/* TX and RX stats are flipped as we are returning the stats as seen
109 	 * at the switch port corresponding to the VF.
110 	 */
111 	stats->tx_packets = readq(mem + NFP_NET_CFG_STATS_RX_FRAMES);
112 	stats->tx_bytes = readq(mem + NFP_NET_CFG_STATS_RX_OCTETS);
113 	stats->tx_dropped = readq(mem + NFP_NET_CFG_STATS_RX_DISCARDS);
114 
115 	stats->rx_packets = readq(mem + NFP_NET_CFG_STATS_TX_FRAMES);
116 	stats->rx_bytes = readq(mem + NFP_NET_CFG_STATS_TX_OCTETS);
117 	stats->rx_dropped = readq(mem + NFP_NET_CFG_STATS_TX_DISCARDS);
118 }
119 
120 static void
121 nfp_repr_pf_get_stats64(const struct nfp_app *app, u8 pf,
122 			struct rtnl_link_stats64 *stats)
123 {
124 	u8 __iomem *mem;
125 
126 	if (pf)
127 		return;
128 
129 	mem = nfp_cpp_area_iomem(app->pf->data_vnic_bar);
130 
131 	stats->tx_packets = readq(mem + NFP_NET_CFG_STATS_RX_FRAMES);
132 	stats->tx_bytes = readq(mem + NFP_NET_CFG_STATS_RX_OCTETS);
133 	stats->tx_dropped = readq(mem + NFP_NET_CFG_STATS_RX_DISCARDS);
134 
135 	stats->rx_packets = readq(mem + NFP_NET_CFG_STATS_TX_FRAMES);
136 	stats->rx_bytes = readq(mem + NFP_NET_CFG_STATS_TX_OCTETS);
137 	stats->rx_dropped = readq(mem + NFP_NET_CFG_STATS_TX_DISCARDS);
138 }
139 
140 static void
141 nfp_repr_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
142 {
143 	struct nfp_repr *repr = netdev_priv(netdev);
144 	struct nfp_eth_table_port *eth_port;
145 	struct nfp_app *app = repr->app;
146 
147 	if (WARN_ON(!repr->port))
148 		return;
149 
150 	switch (repr->port->type) {
151 	case NFP_PORT_PHYS_PORT:
152 		eth_port = __nfp_port_get_eth_port(repr->port);
153 		if (!eth_port)
154 			break;
155 		nfp_repr_phy_port_get_stats64(app, eth_port->index, stats);
156 		break;
157 	case NFP_PORT_PF_PORT:
158 		nfp_repr_pf_get_stats64(app, repr->port->pf_id, stats);
159 		break;
160 	case NFP_PORT_VF_PORT:
161 		nfp_repr_vf_get_stats64(app, repr->port->vf_id, stats);
162 	default:
163 		break;
164 	}
165 }
166 
167 static bool
168 nfp_repr_has_offload_stats(const struct net_device *dev, int attr_id)
169 {
170 	switch (attr_id) {
171 	case IFLA_OFFLOAD_XSTATS_CPU_HIT:
172 		return true;
173 	}
174 
175 	return false;
176 }
177 
178 static int
179 nfp_repr_get_host_stats64(const struct net_device *netdev,
180 			  struct rtnl_link_stats64 *stats)
181 {
182 	struct nfp_repr *repr = netdev_priv(netdev);
183 	int i;
184 
185 	for_each_possible_cpu(i) {
186 		u64 tbytes, tpkts, tdrops, rbytes, rpkts;
187 		struct nfp_repr_pcpu_stats *repr_stats;
188 		unsigned int start;
189 
190 		repr_stats = per_cpu_ptr(repr->stats, i);
191 		do {
192 			start = u64_stats_fetch_begin_irq(&repr_stats->syncp);
193 			tbytes = repr_stats->tx_bytes;
194 			tpkts = repr_stats->tx_packets;
195 			tdrops = repr_stats->tx_drops;
196 			rbytes = repr_stats->rx_bytes;
197 			rpkts = repr_stats->rx_packets;
198 		} while (u64_stats_fetch_retry_irq(&repr_stats->syncp, start));
199 
200 		stats->tx_bytes += tbytes;
201 		stats->tx_packets += tpkts;
202 		stats->tx_dropped += tdrops;
203 		stats->rx_bytes += rbytes;
204 		stats->rx_packets += rpkts;
205 	}
206 
207 	return 0;
208 }
209 
210 static int
211 nfp_repr_get_offload_stats(int attr_id, const struct net_device *dev,
212 			   void *stats)
213 {
214 	switch (attr_id) {
215 	case IFLA_OFFLOAD_XSTATS_CPU_HIT:
216 		return nfp_repr_get_host_stats64(dev, stats);
217 	}
218 
219 	return -EINVAL;
220 }
221 
222 static netdev_tx_t nfp_repr_xmit(struct sk_buff *skb, struct net_device *netdev)
223 {
224 	struct nfp_repr *repr = netdev_priv(netdev);
225 	unsigned int len = skb->len;
226 	int ret;
227 
228 	skb_dst_drop(skb);
229 	dst_hold((struct dst_entry *)repr->dst);
230 	skb_dst_set(skb, (struct dst_entry *)repr->dst);
231 	skb->dev = repr->dst->u.port_info.lower_dev;
232 
233 	ret = dev_queue_xmit(skb);
234 	nfp_repr_inc_tx_stats(netdev, len, ret);
235 
236 	return ret;
237 }
238 
239 static int nfp_repr_stop(struct net_device *netdev)
240 {
241 	struct nfp_repr *repr = netdev_priv(netdev);
242 
243 	return nfp_app_repr_stop(repr->app, repr);
244 }
245 
246 static int nfp_repr_open(struct net_device *netdev)
247 {
248 	struct nfp_repr *repr = netdev_priv(netdev);
249 
250 	return nfp_app_repr_open(repr->app, repr);
251 }
252 
253 const struct net_device_ops nfp_repr_netdev_ops = {
254 	.ndo_open		= nfp_repr_open,
255 	.ndo_stop		= nfp_repr_stop,
256 	.ndo_start_xmit		= nfp_repr_xmit,
257 	.ndo_get_stats64	= nfp_repr_get_stats64,
258 	.ndo_has_offload_stats	= nfp_repr_has_offload_stats,
259 	.ndo_get_offload_stats	= nfp_repr_get_offload_stats,
260 	.ndo_get_phys_port_name	= nfp_port_get_phys_port_name,
261 	.ndo_setup_tc		= nfp_port_setup_tc,
262 };
263 
264 static void nfp_repr_clean(struct nfp_repr *repr)
265 {
266 	unregister_netdev(repr->netdev);
267 	dst_release((struct dst_entry *)repr->dst);
268 	nfp_port_free(repr->port);
269 }
270 
271 static struct lock_class_key nfp_repr_netdev_xmit_lock_key;
272 static struct lock_class_key nfp_repr_netdev_addr_lock_key;
273 
274 static void nfp_repr_set_lockdep_class_one(struct net_device *dev,
275 					   struct netdev_queue *txq,
276 					   void *_unused)
277 {
278 	lockdep_set_class(&txq->_xmit_lock, &nfp_repr_netdev_xmit_lock_key);
279 }
280 
281 static void nfp_repr_set_lockdep_class(struct net_device *dev)
282 {
283 	lockdep_set_class(&dev->addr_list_lock, &nfp_repr_netdev_addr_lock_key);
284 	netdev_for_each_tx_queue(dev, nfp_repr_set_lockdep_class_one, NULL);
285 }
286 
287 int nfp_repr_init(struct nfp_app *app, struct net_device *netdev,
288 		  u32 cmsg_port_id, struct nfp_port *port,
289 		  struct net_device *pf_netdev)
290 {
291 	struct nfp_repr *repr = netdev_priv(netdev);
292 	int err;
293 
294 	nfp_repr_set_lockdep_class(netdev);
295 
296 	repr->port = port;
297 	repr->dst = metadata_dst_alloc(0, METADATA_HW_PORT_MUX, GFP_KERNEL);
298 	if (!repr->dst)
299 		return -ENOMEM;
300 	repr->dst->u.port_info.port_id = cmsg_port_id;
301 	repr->dst->u.port_info.lower_dev = pf_netdev;
302 
303 	netdev->netdev_ops = &nfp_repr_netdev_ops;
304 	SWITCHDEV_SET_OPS(netdev, &nfp_port_switchdev_ops);
305 
306 	if (nfp_app_has_tc(app)) {
307 		netdev->features |= NETIF_F_HW_TC;
308 		netdev->hw_features |= NETIF_F_HW_TC;
309 	}
310 
311 	err = register_netdev(netdev);
312 	if (err)
313 		goto err_clean;
314 
315 	return 0;
316 
317 err_clean:
318 	dst_release((struct dst_entry *)repr->dst);
319 	return err;
320 }
321 
322 static void nfp_repr_free(struct nfp_repr *repr)
323 {
324 	free_percpu(repr->stats);
325 	free_netdev(repr->netdev);
326 }
327 
328 struct net_device *nfp_repr_alloc(struct nfp_app *app)
329 {
330 	struct net_device *netdev;
331 	struct nfp_repr *repr;
332 
333 	netdev = alloc_etherdev(sizeof(*repr));
334 	if (!netdev)
335 		return NULL;
336 
337 	repr = netdev_priv(netdev);
338 	repr->netdev = netdev;
339 	repr->app = app;
340 
341 	repr->stats = netdev_alloc_pcpu_stats(struct nfp_repr_pcpu_stats);
342 	if (!repr->stats)
343 		goto err_free_netdev;
344 
345 	return netdev;
346 
347 err_free_netdev:
348 	free_netdev(netdev);
349 	return NULL;
350 }
351 
352 static void nfp_repr_clean_and_free(struct nfp_repr *repr)
353 {
354 	nfp_info(repr->app->cpp, "Destroying Representor(%s)\n",
355 		 repr->netdev->name);
356 	nfp_repr_clean(repr);
357 	nfp_repr_free(repr);
358 }
359 
360 void nfp_reprs_clean_and_free(struct nfp_reprs *reprs)
361 {
362 	unsigned int i;
363 
364 	for (i = 0; i < reprs->num_reprs; i++)
365 		if (reprs->reprs[i])
366 			nfp_repr_clean_and_free(netdev_priv(reprs->reprs[i]));
367 
368 	kfree(reprs);
369 }
370 
371 void
372 nfp_reprs_clean_and_free_by_type(struct nfp_app *app,
373 				 enum nfp_repr_type type)
374 {
375 	struct nfp_reprs *reprs;
376 
377 	reprs = nfp_app_reprs_set(app, type, NULL);
378 	if (!reprs)
379 		return;
380 
381 	synchronize_rcu();
382 	nfp_reprs_clean_and_free(reprs);
383 }
384 
385 struct nfp_reprs *nfp_reprs_alloc(unsigned int num_reprs)
386 {
387 	struct nfp_reprs *reprs;
388 
389 	reprs = kzalloc(sizeof(*reprs) +
390 			num_reprs * sizeof(struct net_device *), GFP_KERNEL);
391 	if (!reprs)
392 		return NULL;
393 	reprs->num_reprs = num_reprs;
394 
395 	return reprs;
396 }
397