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}
v6.2
  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}