1 /* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 and
5  * only version 2 as published by the Free Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  *
13  * RMNET Data virtual network driver
14  *
15  */
16 
17 #include <linux/etherdevice.h>
18 #include <linux/if_arp.h>
19 #include <net/pkt_sched.h>
20 #include "rmnet_config.h"
21 #include "rmnet_handlers.h"
22 #include "rmnet_private.h"
23 #include "rmnet_map.h"
24 #include "rmnet_vnd.h"
25 
26 /* RX/TX Fixup */
27 
28 void rmnet_vnd_rx_fixup(struct sk_buff *skb, struct net_device *dev)
29 {
30 	dev->stats.rx_packets++;
31 	dev->stats.rx_bytes += skb->len;
32 }
33 
34 void rmnet_vnd_tx_fixup(struct sk_buff *skb, struct net_device *dev)
35 {
36 	dev->stats.tx_packets++;
37 	dev->stats.tx_bytes += skb->len;
38 }
39 
40 /* Network Device Operations */
41 
42 static netdev_tx_t rmnet_vnd_start_xmit(struct sk_buff *skb,
43 					struct net_device *dev)
44 {
45 	struct rmnet_priv *priv;
46 
47 	priv = netdev_priv(dev);
48 	if (priv->local_ep.egress_dev) {
49 		rmnet_egress_handler(skb, &priv->local_ep);
50 	} else {
51 		dev->stats.tx_dropped++;
52 		kfree_skb(skb);
53 	}
54 	return NETDEV_TX_OK;
55 }
56 
57 static int rmnet_vnd_change_mtu(struct net_device *rmnet_dev, int new_mtu)
58 {
59 	if (new_mtu < 0 || new_mtu > RMNET_MAX_PACKET_SIZE)
60 		return -EINVAL;
61 
62 	rmnet_dev->mtu = new_mtu;
63 	return 0;
64 }
65 
66 static int rmnet_vnd_get_iflink(const struct net_device *dev)
67 {
68 	struct rmnet_priv *priv = netdev_priv(dev);
69 
70 	return priv->real_dev->ifindex;
71 }
72 
73 static const struct net_device_ops rmnet_vnd_ops = {
74 	.ndo_start_xmit = rmnet_vnd_start_xmit,
75 	.ndo_change_mtu = rmnet_vnd_change_mtu,
76 	.ndo_get_iflink = rmnet_vnd_get_iflink,
77 };
78 
79 /* Called by kernel whenever a new rmnet<n> device is created. Sets MTU,
80  * flags, ARP type, needed headroom, etc...
81  */
82 void rmnet_vnd_setup(struct net_device *rmnet_dev)
83 {
84 	rmnet_dev->netdev_ops = &rmnet_vnd_ops;
85 	rmnet_dev->mtu = RMNET_DFLT_PACKET_SIZE;
86 	rmnet_dev->needed_headroom = RMNET_NEEDED_HEADROOM;
87 	random_ether_addr(rmnet_dev->dev_addr);
88 	rmnet_dev->tx_queue_len = RMNET_TX_QUEUE_LEN;
89 
90 	/* Raw IP mode */
91 	rmnet_dev->header_ops = NULL;  /* No header */
92 	rmnet_dev->type = ARPHRD_RAWIP;
93 	rmnet_dev->hard_header_len = 0;
94 	rmnet_dev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
95 
96 	rmnet_dev->needs_free_netdev = true;
97 }
98 
99 /* Exposed API */
100 
101 int rmnet_vnd_newlink(u8 id, struct net_device *rmnet_dev,
102 		      struct rmnet_port *port,
103 		      struct net_device *real_dev)
104 {
105 	struct rmnet_priv *priv;
106 	int rc;
107 
108 	if (port->rmnet_devices[id])
109 		return -EINVAL;
110 
111 	rc = register_netdevice(rmnet_dev);
112 	if (!rc) {
113 		port->rmnet_devices[id] = rmnet_dev;
114 		port->nr_rmnet_devs++;
115 
116 		rmnet_dev->rtnl_link_ops = &rmnet_link_ops;
117 
118 		priv = netdev_priv(rmnet_dev);
119 		priv->mux_id = id;
120 		priv->real_dev = real_dev;
121 
122 		netdev_dbg(rmnet_dev, "rmnet dev created\n");
123 	}
124 
125 	return rc;
126 }
127 
128 int rmnet_vnd_dellink(u8 id, struct rmnet_port *port)
129 {
130 	if (id >= RMNET_MAX_LOGICAL_EP || !port->rmnet_devices[id])
131 		return -EINVAL;
132 
133 	port->rmnet_devices[id] = NULL;
134 	port->nr_rmnet_devs--;
135 	return 0;
136 }
137 
138 u8 rmnet_vnd_get_mux(struct net_device *rmnet_dev)
139 {
140 	struct rmnet_priv *priv;
141 
142 	priv = netdev_priv(rmnet_dev);
143 	return priv->mux_id;
144 }
145 
146 /* Gets the logical endpoint configuration for a RmNet virtual network device
147  * node. Caller should confirm that devices is a RmNet VND before calling.
148  */
149 struct rmnet_endpoint *rmnet_vnd_get_endpoint(struct net_device *rmnet_dev)
150 {
151 	struct rmnet_priv *priv;
152 
153 	if (!rmnet_dev)
154 		return NULL;
155 
156 	priv = netdev_priv(rmnet_dev);
157 
158 	return &priv->local_ep;
159 }
160 
161 int rmnet_vnd_do_flow_control(struct net_device *rmnet_dev, int enable)
162 {
163 	netdev_dbg(rmnet_dev, "Setting VND TX queue state to %d\n", enable);
164 	/* Although we expect similar number of enable/disable
165 	 * commands, optimize for the disable. That is more
166 	 * latency sensitive than enable
167 	 */
168 	if (unlikely(enable))
169 		netif_wake_queue(rmnet_dev);
170 	else
171 		netif_stop_queue(rmnet_dev);
172 
173 	return 0;
174 }
175