1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. 3 */ 4 5 #include <linux/netdevice.h> 6 #include "rmnet_config.h" 7 #include "rmnet_map.h" 8 #include "rmnet_private.h" 9 #include "rmnet_vnd.h" 10 11 static u8 rmnet_map_do_flow_control(struct sk_buff *skb, 12 struct rmnet_port *port, 13 int enable) 14 { 15 struct rmnet_map_header *map_header = (void *)skb->data; 16 struct rmnet_endpoint *ep; 17 struct net_device *vnd; 18 u8 mux_id; 19 int r; 20 21 mux_id = map_header->mux_id; 22 23 if (mux_id >= RMNET_MAX_LOGICAL_EP) { 24 kfree_skb(skb); 25 return RX_HANDLER_CONSUMED; 26 } 27 28 ep = rmnet_get_endpoint(port, mux_id); 29 if (!ep) { 30 kfree_skb(skb); 31 return RX_HANDLER_CONSUMED; 32 } 33 34 vnd = ep->egress_dev; 35 36 /* Ignore the ip family and pass the sequence number for both v4 and v6 37 * sequence. User space does not support creating dedicated flows for 38 * the 2 protocols 39 */ 40 r = rmnet_vnd_do_flow_control(vnd, enable); 41 if (r) { 42 kfree_skb(skb); 43 return RMNET_MAP_COMMAND_UNSUPPORTED; 44 } else { 45 return RMNET_MAP_COMMAND_ACK; 46 } 47 } 48 49 static void rmnet_map_send_ack(struct sk_buff *skb, 50 unsigned char type, 51 struct rmnet_port *port) 52 { 53 struct rmnet_map_header *map_header = (void *)skb->data; 54 struct rmnet_map_control_command *cmd; 55 struct net_device *dev = skb->dev; 56 57 if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4) 58 skb_trim(skb, 59 skb->len - sizeof(struct rmnet_map_dl_csum_trailer)); 60 61 skb->protocol = htons(ETH_P_MAP); 62 63 /* Command data immediately follows the MAP header */ 64 cmd = (struct rmnet_map_control_command *)(map_header + 1); 65 cmd->cmd_type = type & 0x03; 66 67 netif_tx_lock(dev); 68 dev->netdev_ops->ndo_start_xmit(skb, dev); 69 netif_tx_unlock(dev); 70 } 71 72 /* Process MAP command frame and send N/ACK message as appropriate. Message cmd 73 * name is decoded here and appropriate handler is called. 74 */ 75 void rmnet_map_command(struct sk_buff *skb, struct rmnet_port *port) 76 { 77 struct rmnet_map_header *map_header = (void *)skb->data; 78 struct rmnet_map_control_command *cmd; 79 unsigned char command_name; 80 unsigned char rc = 0; 81 82 /* Command data immediately follows the MAP header */ 83 cmd = (struct rmnet_map_control_command *)(map_header + 1); 84 command_name = cmd->command_name; 85 86 switch (command_name) { 87 case RMNET_MAP_COMMAND_FLOW_ENABLE: 88 rc = rmnet_map_do_flow_control(skb, port, 1); 89 break; 90 91 case RMNET_MAP_COMMAND_FLOW_DISABLE: 92 rc = rmnet_map_do_flow_control(skb, port, 0); 93 break; 94 95 default: 96 rc = RMNET_MAP_COMMAND_UNSUPPORTED; 97 kfree_skb(skb); 98 break; 99 } 100 if (rc == RMNET_MAP_COMMAND_ACK) 101 rmnet_map_send_ack(skb, rc, port); 102 } 103