1
2
3
4
5
6
7
8
9
10
11
12
13
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
27
28void 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
34void 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
41
42static 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
57static 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
66static 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
73static 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
80
81
82void 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
91 rmnet_dev->header_ops = NULL;
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
100
101int 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
128int 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
138u8 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
147
148
149struct 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
161int 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
165
166
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