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