Linux Audio

Check our new training course

Loading...
v6.13.7
  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
 11static 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
 49static 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 */
 75void 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}
v5.4
 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
11static u8 rmnet_map_do_flow_control(struct sk_buff *skb,
12				    struct rmnet_port *port,
13				    int enable)
14{
 
15	struct rmnet_endpoint *ep;
16	struct net_device *vnd;
17	u8 mux_id;
18	int r;
19
20	mux_id = RMNET_MAP_GET_MUX_ID(skb);
21
22	if (mux_id >= RMNET_MAX_LOGICAL_EP) {
23		kfree_skb(skb);
24		return RX_HANDLER_CONSUMED;
25	}
26
27	ep = rmnet_get_endpoint(port, mux_id);
28	if (!ep) {
29		kfree_skb(skb);
30		return RX_HANDLER_CONSUMED;
31	}
32
33	vnd = ep->egress_dev;
34
35	/* Ignore the ip family and pass the sequence number for both v4 and v6
36	 * sequence. User space does not support creating dedicated flows for
37	 * the 2 protocols
38	 */
39	r = rmnet_vnd_do_flow_control(vnd, enable);
40	if (r) {
41		kfree_skb(skb);
42		return RMNET_MAP_COMMAND_UNSUPPORTED;
43	} else {
44		return RMNET_MAP_COMMAND_ACK;
45	}
46}
47
48static void rmnet_map_send_ack(struct sk_buff *skb,
49			       unsigned char type,
50			       struct rmnet_port *port)
51{
 
52	struct rmnet_map_control_command *cmd;
53	struct net_device *dev = skb->dev;
54
55	if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4)
56		skb_trim(skb,
57			 skb->len - sizeof(struct rmnet_map_dl_csum_trailer));
58
59	skb->protocol = htons(ETH_P_MAP);
60
61	cmd = RMNET_MAP_GET_CMD_START(skb);
 
62	cmd->cmd_type = type & 0x03;
63
64	netif_tx_lock(dev);
65	dev->netdev_ops->ndo_start_xmit(skb, dev);
66	netif_tx_unlock(dev);
67}
68
69/* Process MAP command frame and send N/ACK message as appropriate. Message cmd
70 * name is decoded here and appropriate handler is called.
71 */
72void rmnet_map_command(struct sk_buff *skb, struct rmnet_port *port)
73{
 
74	struct rmnet_map_control_command *cmd;
75	unsigned char command_name;
76	unsigned char rc = 0;
77
78	cmd = RMNET_MAP_GET_CMD_START(skb);
 
79	command_name = cmd->command_name;
80
81	switch (command_name) {
82	case RMNET_MAP_COMMAND_FLOW_ENABLE:
83		rc = rmnet_map_do_flow_control(skb, port, 1);
84		break;
85
86	case RMNET_MAP_COMMAND_FLOW_DISABLE:
87		rc = rmnet_map_do_flow_control(skb, port, 0);
88		break;
89
90	default:
91		rc = RMNET_MAP_COMMAND_UNSUPPORTED;
92		kfree_skb(skb);
93		break;
94	}
95	if (rc == RMNET_MAP_COMMAND_ACK)
96		rmnet_map_send_ack(skb, rc, port);
97}