1// SPDX-License-Identifier: GPL-2.0-only
2/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
3 *
4 * RMNET Data virtual network driver
5 */
6
7#include <linux/etherdevice.h>
8#include <linux/if_arp.h>
9#include <net/pkt_sched.h>
10#include "rmnet_config.h"
11#include "rmnet_handlers.h"
12#include "rmnet_private.h"
13#include "rmnet_map.h"
14#include "rmnet_vnd.h"
15
16/* RX/TX Fixup */
17
18void rmnet_vnd_rx_fixup(struct sk_buff *skb, struct net_device *dev)
19{
20	struct rmnet_priv *priv = netdev_priv(dev);
21	struct rmnet_pcpu_stats *pcpu_ptr;
22
23	pcpu_ptr = this_cpu_ptr(priv->pcpu_stats);
24
25	u64_stats_update_begin(&pcpu_ptr->syncp);
26	pcpu_ptr->stats.rx_pkts++;
27	pcpu_ptr->stats.rx_bytes += skb->len;
28	u64_stats_update_end(&pcpu_ptr->syncp);
29}
30
31void rmnet_vnd_tx_fixup(struct sk_buff *skb, struct net_device *dev)
32{
33	struct rmnet_priv *priv = netdev_priv(dev);
34	struct rmnet_pcpu_stats *pcpu_ptr;
35
36	pcpu_ptr = this_cpu_ptr(priv->pcpu_stats);
37
38	u64_stats_update_begin(&pcpu_ptr->syncp);
39	pcpu_ptr->stats.tx_pkts++;
40	pcpu_ptr->stats.tx_bytes += skb->len;
41	u64_stats_update_end(&pcpu_ptr->syncp);
42}
43
44/* Network Device Operations */
45
46static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb,
47					struct net_device *dev)
48{
49	struct rmnet_priv *priv;
50
51	priv = netdev_priv(dev);
52	if (priv->real_dev) {
53		rmnet_egress_handler(skb);
54	} else {
55		this_cpu_inc(priv->pcpu_stats->stats.tx_drops);
56		kfree_skb(skb);
57	}
58	return NETDEV_TX_OK;
59}
60
61static int rmnet_vnd_headroom(struct rmnet_port *port)
62{
63	u32 headroom;
64
65	headroom = sizeof(struct rmnet_map_header);
66
67	if (port->data_format & RMNET_FLAGS_EGRESS_MAP_CKSUMV4)
68		headroom += sizeof(struct rmnet_map_ul_csum_header);
69
70	return headroom;
71}
72
73static int rmnet_vnd_change_mtu(struct net_device *rmnet_dev, int new_mtu)
74{
75	struct rmnet_priv *priv = netdev_priv(rmnet_dev);
76	struct rmnet_port *port;
77	u32 headroom;
78
79	port = rmnet_get_port_rtnl(priv->real_dev);
80
81	headroom = rmnet_vnd_headroom(port);
82
83	if (new_mtu < 0 || new_mtu > RMNET_MAX_PACKET_SIZE ||
84	    new_mtu > (priv->real_dev->mtu - headroom))
85		return -EINVAL;
86
87	rmnet_dev->mtu = new_mtu;
88	return 0;
89}
90
91static int rmnet_vnd_get_iflink(const struct net_device *dev)
92{
93	struct rmnet_priv *priv = netdev_priv(dev);
94
95	return priv->real_dev->ifindex;
96}
97
98static int rmnet_vnd_init(struct net_device *dev)
99{
100	struct rmnet_priv *priv = netdev_priv(dev);
101	int err;
102
103	priv->pcpu_stats = alloc_percpu(struct rmnet_pcpu_stats);
104	if (!priv->pcpu_stats)
105		return -ENOMEM;
106
107	err = gro_cells_init(&priv->gro_cells, dev);
108	if (err) {
109		free_percpu(priv->pcpu_stats);
110		return err;
111	}
112
113	return 0;
114}
115
116static void rmnet_vnd_uninit(struct net_device *dev)
117{
118	struct rmnet_priv *priv = netdev_priv(dev);
119
120	gro_cells_destroy(&priv->gro_cells);
121	free_percpu(priv->pcpu_stats);
122}
123
124static void rmnet_get_stats64(struct net_device *dev,
125			      struct rtnl_link_stats64 *s)
126{
127	struct rmnet_priv *priv = netdev_priv(dev);
128	struct rmnet_vnd_stats total_stats = { };
129	struct rmnet_pcpu_stats *pcpu_ptr;
130	struct rmnet_vnd_stats snapshot;
131	unsigned int cpu, start;
132
133	for_each_possible_cpu(cpu) {
134		pcpu_ptr = per_cpu_ptr(priv->pcpu_stats, cpu);
135
136		do {
137			start = u64_stats_fetch_begin_irq(&pcpu_ptr->syncp);
138			snapshot = pcpu_ptr->stats;	/* struct assignment */
139		} while (u64_stats_fetch_retry_irq(&pcpu_ptr->syncp, start));
140
141		total_stats.rx_pkts += snapshot.rx_pkts;
142		total_stats.rx_bytes += snapshot.rx_bytes;
143		total_stats.tx_pkts += snapshot.tx_pkts;
144		total_stats.tx_bytes += snapshot.tx_bytes;
145		total_stats.tx_drops += snapshot.tx_drops;
146	}
147
148	s->rx_packets = total_stats.rx_pkts;
149	s->rx_bytes = total_stats.rx_bytes;
150	s->tx_packets = total_stats.tx_pkts;
151	s->tx_bytes = total_stats.tx_bytes;
152	s->tx_dropped = total_stats.tx_drops;
153}
154
155static const struct net_device_ops rmnet_vnd_ops = {
156	.ndo_start_xmit = rmnet_vnd_start_xmit,
157	.ndo_change_mtu = rmnet_vnd_change_mtu,
158	.ndo_get_iflink = rmnet_vnd_get_iflink,
159	.ndo_add_slave  = rmnet_add_bridge,
160	.ndo_del_slave  = rmnet_del_bridge,
161	.ndo_init       = rmnet_vnd_init,
162	.ndo_uninit     = rmnet_vnd_uninit,
163	.ndo_get_stats64 = rmnet_get_stats64,
164};
165
166static const char rmnet_gstrings_stats[][ETH_GSTRING_LEN] = {
167	"Checksum ok",
168	"Checksum valid bit not set",
169	"Checksum validation failed",
170	"Checksum error bad buffer",
171	"Checksum error bad ip version",
172	"Checksum error bad transport",
173	"Checksum skipped on ip fragment",
174	"Checksum skipped",
175	"Checksum computed in software",
176};
177
178static void rmnet_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
179{
180	switch (stringset) {
181	case ETH_SS_STATS:
182		memcpy(buf, &rmnet_gstrings_stats,
183		       sizeof(rmnet_gstrings_stats));
184		break;
185	}
186}
187
188static int rmnet_get_sset_count(struct net_device *dev, int sset)
189{
190	switch (sset) {
191	case ETH_SS_STATS:
192		return ARRAY_SIZE(rmnet_gstrings_stats);
193	default:
194		return -EOPNOTSUPP;
195	}
196}
197
198static void rmnet_get_ethtool_stats(struct net_device *dev,
199				    struct ethtool_stats *stats, u64 *data)
200{
201	struct rmnet_priv *priv = netdev_priv(dev);
202	struct rmnet_priv_stats *st = &priv->stats;
203
204	if (!data)
205		return;
206
207	memcpy(data, st, ARRAY_SIZE(rmnet_gstrings_stats) * sizeof(u64));
208}
209
210static const struct ethtool_ops rmnet_ethtool_ops = {
211	.get_ethtool_stats = rmnet_get_ethtool_stats,
212	.get_strings = rmnet_get_strings,
213	.get_sset_count = rmnet_get_sset_count,
214};
215
216/* Called by kernel whenever a new rmnet<n> device is created. Sets MTU,
217 * flags, ARP type, needed headroom, etc...
218 */
219void rmnet_vnd_setup(struct net_device *rmnet_dev)
220{
221	rmnet_dev->netdev_ops = &rmnet_vnd_ops;
222	rmnet_dev->mtu = RMNET_DFLT_PACKET_SIZE;
223	rmnet_dev->needed_headroom = RMNET_NEEDED_HEADROOM;
224	eth_random_addr(rmnet_dev->dev_addr);
225	rmnet_dev->tx_queue_len = RMNET_TX_QUEUE_LEN;
226
227	/* Raw IP mode */
228	rmnet_dev->header_ops = NULL;  /* No header */
229	rmnet_dev->type = ARPHRD_RAWIP;
230	rmnet_dev->hard_header_len = 0;
231	rmnet_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
232
233	rmnet_dev->needs_free_netdev = true;
234	rmnet_dev->ethtool_ops = &rmnet_ethtool_ops;
235
236	rmnet_dev->features |= NETIF_F_LLTX;
237
238	/* This perm addr will be used as interface identifier by IPv6 */
239	rmnet_dev->addr_assign_type = NET_ADDR_RANDOM;
240	eth_random_addr(rmnet_dev->perm_addr);
241}
242
243/* Exposed API */
244
245int rmnet_vnd_newlink(u8 id, struct net_device *rmnet_dev,
246		      struct rmnet_port *port,
247		      struct net_device *real_dev,
248		      struct rmnet_endpoint *ep,
249		      struct netlink_ext_ack *extack)
250
251{
252	struct rmnet_priv *priv = netdev_priv(rmnet_dev);
253	u32 headroom;
254	int rc;
255
256	if (rmnet_get_endpoint(port, id)) {
257		NL_SET_ERR_MSG_MOD(extack, "MUX ID already exists");
258		return -EBUSY;
259	}
260
261	rmnet_dev->hw_features = NETIF_F_RXCSUM;
262	rmnet_dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
263	rmnet_dev->hw_features |= NETIF_F_SG;
264
265	priv->real_dev = real_dev;
266
267	headroom = rmnet_vnd_headroom(port);
268
269	if (rmnet_vnd_change_mtu(rmnet_dev, real_dev->mtu - headroom)) {
270		NL_SET_ERR_MSG_MOD(extack, "Invalid MTU on real dev");
271		return -EINVAL;
272	}
273
274	rc = register_netdevice(rmnet_dev);
275	if (!rc) {
276		ep->egress_dev = rmnet_dev;
277		ep->mux_id = id;
278		port->nr_rmnet_devs++;
279
280		rmnet_dev->rtnl_link_ops = &rmnet_link_ops;
281
282		priv->mux_id = id;
283
284		netdev_dbg(rmnet_dev, "rmnet dev created\n");
285	}
286
287	return rc;
288}
289
290int rmnet_vnd_dellink(u8 id, struct rmnet_port *port,
291		      struct rmnet_endpoint *ep)
292{
293	if (id >= RMNET_MAX_LOGICAL_EP || !ep->egress_dev)
294		return -EINVAL;
295
296	ep->egress_dev = NULL;
297	port->nr_rmnet_devs--;
298	return 0;
299}
300
301int rmnet_vnd_do_flow_control(struct net_device *rmnet_dev, int enable)
302{
303	netdev_dbg(rmnet_dev, "Setting VND TX queue state to %d\n", enable);
304	/* Although we expect similar number of enable/disable
305	 * commands, optimize for the disable. That is more
306	 * latency sensitive than enable
307	 */
308	if (unlikely(enable))
309		netif_wake_queue(rmnet_dev);
310	else
311		netif_stop_queue(rmnet_dev);
312
313	return 0;
314}
315
316int rmnet_vnd_validate_real_dev_mtu(struct net_device *real_dev)
317{
318	struct hlist_node *tmp_ep;
319	struct rmnet_endpoint *ep;
320	struct rmnet_port *port;
321	unsigned long bkt_ep;
322	u32 headroom;
323
324	port = rmnet_get_port_rtnl(real_dev);
325
326	headroom = rmnet_vnd_headroom(port);
327
328	hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) {
329		if (ep->egress_dev->mtu > (real_dev->mtu - headroom))
330			return -1;
331	}
332
333	return 0;
334}
335
336int rmnet_vnd_update_dev_mtu(struct rmnet_port *port,
337			     struct net_device *real_dev)
338{
339	struct hlist_node *tmp_ep;
340	struct rmnet_endpoint *ep;
341	unsigned long bkt_ep;
342	u32 headroom;
343
344	headroom = rmnet_vnd_headroom(port);
345
346	hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) {
347		if (ep->egress_dev->mtu <= (real_dev->mtu - headroom))
348			continue;
349
350		if (rmnet_vnd_change_mtu(ep->egress_dev,
351					 real_dev->mtu - headroom))
352			return -1;
353	}
354
355	return 0;
356}
357