Re: [PATCH net-next 1/1 v3] drivers: net: rmnet: Initial implementation

2017-08-14 Thread Subash Abhinov Kasiviswanathan

+ */
+void rmnet_egress_handler(struct sk_buff *skb,
+ struct rmnet_logical_ep_conf_s *ep)
+{
+   struct rmnet_phys_ep_conf_s *config;
+   struct net_device *orig_dev;
+   int rc;
+
+   orig_dev = skb->dev;
+   skb->dev = ep->egress_dev;
+
+   config = (struct rmnet_phys_ep_conf_s *)
+   rcu_dereference(skb->dev->rx_handler_data);


This is certainly a misuse of dev->rx_handler_data. Dev private of a
function arg to carry the pointer around.



Hi Jiri

Sorry for the delay in posting a new series.
I have an additional query regarding this comment.

This dev (from skb->dev->rx_handler_data) corresponds to the real_dev to 
which
the rmnet devices are attached to. I had earlier setup a rx_handler on 
this
real_dev netdevice in rmnet_associate_network_device(). Would it still 
be
incorrect to use rx_handler_data of real_dev to have rmnet specific 
config

information?

Bridge is similarly storing the bridge information on the real_dev
rx_handler_data and retrieving it through br_port_get_rcu(). I am using 
that

as a reference.

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
Forum,

a Linux Foundation Collaborative Project


Re: [PATCH net-next 1/1 v3] drivers: net: rmnet: Initial implementation

2017-04-14 Thread Subash Abhinov Kasiviswanathan

+https://source.codeaurora.org/quic/la/platform/vendor/qcom-opensource/\
+dataservices/tree/rmnetctl


Don't split URL better to have long line.

diff --git a/drivers/net/rmnet/Kconfig b/drivers/net/rmnet/Kconfig


Since this is Qualcomm and Ethernet specific, maybe better to put
in drivers/net/ethernet/qualcom/rmnet


+config RMNET_DEBUG


Please use network device standard debug mechanism.
netif_msg_XXX


+   buffloc += snprintf(&buffer[buffloc], sizeof(buffer) - buffloc,
+   " %02x", skb->data[i]);


If you really have to do this. Use hex_dump_bytes API.


+   skb->mac_header = 0;
+   skb->mac_len = 0;
+}


Why not use sbk_set_mac_header(skb, 0)?


+static inline struct rmnet_phys_ep_conf_s *_rmnet_get_phys_ep_config
+   (struct net_device *dev)

awkward line break.
dev could be const


+   config = (struct rmnet_phys_ep_conf_s *)
+ rcu_dereference(dev->rx_handler_data);


Please don't directly reference rx_handler. There is already functions
like netdev_is_rx_handler_busy() to abstract that API.


+ * @epconfig:endpoint configuration structure to set
+ */


You are using docbook format here, but this is not a docbook comment.
ie.
/**
 * function - This is a docbook comment
 * @dev: this is a param
 */

Plus these are static functions so there is no point in documentating
internal API with docbook.


+   ASSERT_RTNL();
+
+   if (!dev || config_id < RMNET_LOCAL_LOGICAL_ENDPOINT ||
+   config_id >= RMNET_MAX_LOGICAL_EP)
+   return -EINVAL;


For internal API's you should validate parmeters at the external
entry point not in each call. Otherwise you have a multitude of
impossible error checks and dead code paths.


+   .next = 0,
+   .priority = 0
+};

Don't initialize fields that are not used or should be zero.



Hi Stephen

I'll make these changes.



Could just be:

static inline int _rmnet_is_physical_endpoint_associated(const struct
net_device *dev)
{
rx_handler_func_t *rx_handler
= rcu_dereference(dev->rx_handler);

return rx_handler == rmet_rx_handler;
}

But standard practice is to use ndo_ops to identify self in network 
drivers.

I.e
return dev->netdev_ops == &rmnet_device_ops;



The netdevice which is associated is the physical (real_dev). This 
device
can vary based on hardware and will have its own netdev_ops associated 
with it.

rmnet_device_ops applies to the rmnet devices only. I'll use the first
option you have suggested.


+   if (!data[IFLA_RMNET_MUX_ID])
+   return -EINVAL;


So you are inventing private link netlink attributes.
Why? Why can't you use device switch, bridge, or other master/slave 
model.




I would like to eventually add more configuration options for the
ingress & egress data formats as well as the endpoint configuration
(VND mode vs BRIDGE mode). I was able to re-use IFLA_VLAN_ID for
IFLA_RMNET_MUX_ID and test but it wasn't sufficient for the additional
parameters. I'll check the bridge attributes and try to reuse it.

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
Forum,

a Linux Foundation Collaborative Project


Re: [PATCH net-next 1/1 v3] drivers: net: rmnet: Initial implementation

2017-04-14 Thread Stephen Hemminger
On Fri, 14 Apr 2017 15:57:22 -0600
Subash Abhinov Kasiviswanathan  wrote:

> >> +  rmnet_kfree_skb
> >> +  (skb,
> >> +   RMNET_STATS_SKBFREE_INGRESS_NOT_EXPECT_MAPD);  
> > 
> > very odd formatting. Please fix.
> >   
> Checkpatch complains if it is over 80 chars in a line, so I had to do 
> this.
> I'll change to a single line.

Either ignore checkpatch, it is only a dumb script; or better yet refactor
the code so it isn't indented so much.


Re: [PATCH net-next 1/1 v3] drivers: net: rmnet: Initial implementation

2017-04-14 Thread Subash Abhinov Kasiviswanathan

No, please use standard facilities in order to do debug logging.


+static struct rmnet_logical_ep_conf_s *_rmnet_get_logical_ep


Dont use "_" at the start of a name without purpose


+static int rmnet_associate_network_device(struct net_device *dev)


I would expect to see here you making connection between real_dev and
rmnet dev. I don't see such thing. Name of the function is misleading.


+
+   config = kmalloc(sizeof(*config), GFP_ATOMIC);


kzalloc, and you don't have to zero the memory.


+static struct notifier_block rmnet_dev_notifier = {


You should add "__read_mostly"


+   .notifier_call = rmnet_config_notify_cb,
+   .next = 0,
+   .priority = 0


This initialization of 0s is not needed.

+/* rmnet_vnd_is_vnd() gives mux_id + 1, so subtract 1 to get the 
correct mux_id

+ */


Fix this comment format.
+void rmnet_print_packet(const struct sk_buff *skb, const char *dev, 
char dir)


No reason to have this function. One can use P_ALL tap to get skbs to
userspace.


+/* rmnet_bridge_handler() - Bridge related functionality
+ */


Fix the comment format (you have it on multiple places)


+static rx_handler_result_t rmnet_bridge_handler
+   (struct sk_buff *skb, struct rmnet_logical_ep_conf_s *ep)


The formatting is incorrect:

static rx_handler_result_t
rmnet_bridge_handler(struct sk_buff *skb, struct 
rmnet_logical_ep_conf_s *ep)




+   config = (struct rmnet_phys_ep_conf_s *)
+   rcu_dereference(skb->dev->rx_handler_data);
+
+   if (!config) {


Cannot happen. Please remove this.


+   .ndo_set_mac_address = 0,
+   .ndo_validate_addr = 0,


These are NULL by default. No need to init.


+   if ((id < 0) || (id >= RMNET_MAX_VND) || !rmnet_devices[id])


Unneeded inner "()"s. I see you have it on multiple places.


+
+   dev_conf = (struct rmnet_vnd_private_s *)netdev_priv(dev);


The typecast is not needed since netdev_priv is void*. You have it all
over the code.


+#define ETH_P_MAP  0xDA1A  /* Multiplexing and Aggregation Protocol
+*  NOT AN OFFICIALLY REGISTERED ID ]


Please push this and ARPHRD_RAWIP as separate patches, to increase the
visibility.


+enum {
+   IFLA_RMNET_UNSPEC,
+   IFLA_RMNET_MUX_ID,
+   __IFLA_RMNET_MAX,
+};


This belongs to include/uapi/linux/if_link.h
Please see IFLA_BOND_* as example

+#define RMNET_INIT_OK 0
+#define RMNET_INIT_ERROR  1


Please use common error codes (0/-ENOMEM/-EINVAL/...)


+   static u32 rmnet_mod_mask = X


Don't use this custom helpers. Use existing loggign facilities.


+   pr_notice("[RMNET:LOW] %s(): " fmt "\n", __func__, \
+   ##__VA_ARGS__); \
+   } while (0)


These look scarry. Please use netdev_err, dev_err and others instead.


+unsigned int rmnet_log_module_mask;
+module_param(rmnet_log_module_mask, uint, 0644);
+MODULE_PARM_DESC(rmnet_log_module_mask, "Logging module mask");


No module options please.


+   config = (struct rmnet_phys_ep_conf_s *)
+   rcu_dereference(skb->dev->rx_handler_data);


This is certainly a misuse of dev->rx_handler_data. Dev private of a
function arg to carry the pointer around.


+struct net_device *rmnet_devices[RMNET_MAX_VND];


Avoid this global variable.



Hi Jiri

I'll make these changes.


+   if (!data[IFLA_RMNET_MUX_ID])
+   return -EINVAL;
+
+   mux_id = nla_get_u16(data[IFLA_VLAN_ID]);


This is a bug I believe... ^^^
I'm pretty sure that you did not test this code.



Since both IFLA_VLAN_ID and IFLA_RMNET_MUX_ID are 1 from enum, this 
actually

works. I was using VLAN as a reference, so I missed to change this to
IFLA_RMNET_MUX_ID.




+   rmnet_kfree_skb
+   (skb,
+RMNET_STATS_SKBFREE_INGRESS_NOT_EXPECT_MAPD);


very odd formatting. Please fix.

Checkpatch complains if it is over 80 chars in a line, so I had to do 
this.

I'll change to a single line.

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora 
Forum,

a Linux Foundation Collaborative Project


Re: [PATCH net-next 1/1 v3] drivers: net: rmnet: Initial implementation

2017-04-14 Thread Stephen Hemminger
On Thu, 13 Apr 2017 23:05:29 -0600
Subash Abhinov Kasiviswanathan  wrote:

> RmNet driver provides a transport agnostic MAP (multiplexing and
> aggregation protocol) support in embedded module. Module provides
> virtual network devices which can be attached to any IP-mode
> physical device. This will be used to provide all MAP functionality
> on future hardware in a single consistent location.
> 
> Signed-off-by: Subash Abhinov Kasiviswanathan 

> 
> diff --git a/Documentation/networking/rmnet.txt 
> b/Documentation/networking/rmnet.txt
> new file mode 100644
> index 000..58d3ea2
> --- /dev/null
> +++ b/Documentation/networking/rmnet.txt
>
...

> +3. Userspace configuration
> +
> +rmnet userspace configuration is done through netlink library librmnetctl
> +and command line utility rmnetcli. Utility is hosted in codeaurora forum git.
> +The driver uses rtnl_link_ops for communication.
> +
> +https://source.codeaurora.org/quic/la/platform/vendor/qcom-opensource/\
> +dataservices/tree/rmnetctl

Don't split URL better to have long line.


> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index 98ed4d9..29b3945 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -74,3 +74,4 @@ obj-$(CONFIG_HYPERV_NET) += hyperv/
>  obj-$(CONFIG_NTB_NETDEV) += ntb_netdev.o
>  
>  obj-$(CONFIG_FUJITSU_ES) += fjes/
> +obj-$(CONFIG_RMNET) += rmnet/
> diff --git a/drivers/net/rmnet/Kconfig b/drivers/net/rmnet/Kconfig

Since this is Qualcomm and Ethernet specific, maybe better to put
in drivers/net/ethernet/qualcom/rmnet


> new file mode 100644
> index 000..63cd477
> --- /dev/null
> +++ b/drivers/net/rmnet/Kconfig
> @@ -0,0 +1,23 @@
> +#
> +# RMNET MAP driver
> +#
> +
> +menuconfig RMNET
> + depends on NETDEVICES
> + bool "RmNet MAP driver"
> + default n
> + ---help---
> +   If you say Y here, then the rmnet module will be statically
> +   compiled into the kernel. The rmnet module provides MAP
> +   functionality for embedded and bridged traffic.
> +if RMNET
> +
> +config RMNET_DEBUG
> + bool "RmNet Debug Logging"
> + default n
> + ---help---
> +   Say Y here if you want RmNet to be able to log packets in main
> +   system log. This should not be enabled on production builds as it can
> +   impact system performance. Note that simply enabling it here will not
> +   enable the logging; it must be enabled at run-time as well.


Please use network device standard debug mechanism.
netif_msg_XXX

> +endif # RMNET
> diff --git a/drivers/net/rmnet/Makefile b/drivers/net/rmnet/Makefile
> new file mode 100644
> index 000..2b6c9cf
> --- /dev/null
> +++ b/drivers/net/rmnet/Makefile
> @@ -0,0 +1,14 @@
> +#
> +# Makefile for the RMNET module
> +#
> +
> +rmnet-y   := rmnet_main.o
> +rmnet-y   += rmnet_config.o
> +rmnet-y   += rmnet_vnd.o
> +rmnet-y   += rmnet_handlers.o
> +rmnet-y   += rmnet_map_data.o
> +rmnet-y   += rmnet_map_command.o
> +rmnet-y   += rmnet_stats.o
> +obj-$(CONFIG_RMNET) += rmnet.o
> +
> +CFLAGS_rmnet_main.o := -I$(src)
> diff --git a/drivers/net/rmnet/rmnet_config.c 
> b/drivers/net/rmnet/rmnet_config.c
> new file mode 100644
> index 000..a4bc76b
> --- /dev/null
> +++ b/drivers/net/rmnet/rmnet_config.c
> @@ -0,0 +1,592 @@
> +/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * RMNET configuration engine
> + *
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include "rmnet_config.h"
> +#include "rmnet_handlers.h"
> +#include "rmnet_vnd.h"
> +#include "rmnet_private.h"
> +
> +RMNET_LOG_MODULE(RMNET_LOGMASK_CONFIG);
> +
> +/* Local Definitions and Declarations */
> +#define RMNET_LOCAL_LOGICAL_ENDPOINT -1
> +
> +/* _rmnet_is_physical_endpoint_associated() - Determines if device is 
> associated
> + * @dev:  Device to get check
> + *
> + * Compares device rx_handler callback pointer against known function
> + */
> +static inline int _rmnet_is_physical_endpoint_associated(struct net_device 
> *dev)
> +{
> + rx_handler_func_t *rx_handler;
> +
> + rx_handler = rcu_dereference(dev->rx_handler);
> +
> + if (rx_handler == rmnet_rx_handler)
> + return 1;
> + else
> + return 0;
> +}

Could just be:

static inline int _rmnet_is_physical_endpoint_associated(const struct 
net_device *dev)
{
rx_handler_func_t *rx_handler
= rcu_deref

Re: [PATCH net-next 1/1 v3] drivers: net: rmnet: Initial implementation

2017-04-14 Thread Jiri Pirko
Fri, Apr 14, 2017 at 07:05:29AM CEST, subas...@codeaurora.org wrote:
>RmNet driver provides a transport agnostic MAP (multiplexing and
>aggregation protocol) support in embedded module. Module provides
>virtual network devices which can be attached to any IP-mode
>physical device. This will be used to provide all MAP functionality
>on future hardware in a single consistent location.
>
>Signed-off-by: Subash Abhinov Kasiviswanathan 
>---
> Documentation/networking/rmnet.txt|  83 +
> drivers/net/Kconfig   |   2 +
> drivers/net/Makefile  |   1 +
> drivers/net/rmnet/Kconfig |  23 ++
> drivers/net/rmnet/Makefile|  14 +
> drivers/net/rmnet/rmnet_config.c  | 592 ++
> drivers/net/rmnet/rmnet_config.h  |  79 +
> drivers/net/rmnet/rmnet_handlers.c| 517 +
> drivers/net/rmnet/rmnet_handlers.h|  24 ++
> drivers/net/rmnet/rmnet_main.c|  52 +++
> drivers/net/rmnet/rmnet_map.h | 100 ++
> drivers/net/rmnet/rmnet_map_command.c | 180 +++
> drivers/net/rmnet/rmnet_map_data.c| 145 +
> drivers/net/rmnet/rmnet_private.h |  76 +
> drivers/net/rmnet/rmnet_stats.c   |  86 +
> drivers/net/rmnet/rmnet_stats.h   |  61 
> drivers/net/rmnet/rmnet_vnd.c | 353 
> drivers/net/rmnet/rmnet_vnd.h |  34 ++
> include/uapi/linux/Kbuild |   1 +
> include/uapi/linux/if_arp.h   |   1 +
> include/uapi/linux/if_ether.h |   4 +-
> include/uapi/linux/rmnet.h|  34 ++
> 22 files changed, 2461 insertions(+), 1 deletion(-)
> create mode 100644 Documentation/networking/rmnet.txt
> create mode 100644 drivers/net/rmnet/Kconfig
> create mode 100644 drivers/net/rmnet/Makefile
> create mode 100644 drivers/net/rmnet/rmnet_config.c
> create mode 100644 drivers/net/rmnet/rmnet_config.h
> create mode 100644 drivers/net/rmnet/rmnet_handlers.c
> create mode 100644 drivers/net/rmnet/rmnet_handlers.h
> create mode 100644 drivers/net/rmnet/rmnet_main.c
> create mode 100644 drivers/net/rmnet/rmnet_map.h
> create mode 100644 drivers/net/rmnet/rmnet_map_command.c
> create mode 100644 drivers/net/rmnet/rmnet_map_data.c
> create mode 100644 drivers/net/rmnet/rmnet_private.h
> create mode 100644 drivers/net/rmnet/rmnet_stats.c
> create mode 100644 drivers/net/rmnet/rmnet_stats.h
> create mode 100644 drivers/net/rmnet/rmnet_vnd.c
> create mode 100644 drivers/net/rmnet/rmnet_vnd.h
> create mode 100644 include/uapi/linux/rmnet.h
>
>diff --git a/Documentation/networking/rmnet.txt 
>b/Documentation/networking/rmnet.txt
>new file mode 100644
>index 000..58d3ea2
>--- /dev/null
>+++ b/Documentation/networking/rmnet.txt
>@@ -0,0 +1,83 @@
>+1. Introduction
>+
>+rmnet driver is used for supporting the Multiplexing and aggregation
>+Protocol (MAP). This protocol is used by all recent chipsets using Qualcomm
>+Technologies, Inc. modems.
>+
>+This driver can be used to register onto any physical network device in
>+IP mode. Physical transports include USB, HSIC, PCIe and IP accelerator.
>+
>+Multiplexing allows for creation of logical netdevices (rmnet devices) to
>+handle multiple private data networks (PDN) like a default internet, 
>tethering,
>+multimedia messaging service (MMS) or IP media subsystem (IMS). Hardware sends
>+packets with MAP headers to rmnet. Based on the multiplexer id, rmnet
>+routes to the appropriate PDN after removing the MAP header.
>+
>+Aggregation is required to achieve high data rates. This involves hardware
>+sending aggregated bunch of MAP frames. rmnet driver will de-aggregate
>+these MAP frames and send them to appropriate PDN's.
>+
>+2. Packet format
>+
>+a. MAP packet (data / control)
>+
>+MAP header has the same endianness of the IP packet.
>+
>+Packet format -
>+
>+Bit 0 1   2-7  8 - 15   16 - 31
>+Function   Command / Data   Reserved Pad   Multiplexer IDPayload 
>length
>+Bit32 - x
>+Function Raw  Bytes
>+
>+Command (1)/ Data (0) bit value is to indicate if the packet is a MAP command
>+or data packet. Control packet is used for transport level flow control. Data
>+packets are standard IP packets.
>+
>+Reserved bits are usually zeroed out and to be ignored by receiver.
>+
>+Padding is number of bytes to be added for 4 byte alignment if required by
>+hardware.
>+
>+Multiplexer ID is to indicate the PDN on which data has to be sent.
>+
>+Payload length includes the padding length but does not include MAP header
>+length.
>+
>+b. MAP packet (command specific)
>+
>+Bit 0 1   2-7  8 - 15   16 - 31
>+Function   Command Reserved Pad   Multiplexer IDPayload length
>+Bit  32 - 3940 - 4546 - 47   48 - 63
>+Function   Command nameReserved   Command Type   Reserved
>+Bit  64 - 95
>+Function   Transaction ID
>+Bit 

[PATCH net-next 1/1 v3] drivers: net: rmnet: Initial implementation

2017-04-13 Thread Subash Abhinov Kasiviswanathan
RmNet driver provides a transport agnostic MAP (multiplexing and
aggregation protocol) support in embedded module. Module provides
virtual network devices which can be attached to any IP-mode
physical device. This will be used to provide all MAP functionality
on future hardware in a single consistent location.

Signed-off-by: Subash Abhinov Kasiviswanathan 
---
 Documentation/networking/rmnet.txt|  83 +
 drivers/net/Kconfig   |   2 +
 drivers/net/Makefile  |   1 +
 drivers/net/rmnet/Kconfig |  23 ++
 drivers/net/rmnet/Makefile|  14 +
 drivers/net/rmnet/rmnet_config.c  | 592 ++
 drivers/net/rmnet/rmnet_config.h  |  79 +
 drivers/net/rmnet/rmnet_handlers.c| 517 +
 drivers/net/rmnet/rmnet_handlers.h|  24 ++
 drivers/net/rmnet/rmnet_main.c|  52 +++
 drivers/net/rmnet/rmnet_map.h | 100 ++
 drivers/net/rmnet/rmnet_map_command.c | 180 +++
 drivers/net/rmnet/rmnet_map_data.c| 145 +
 drivers/net/rmnet/rmnet_private.h |  76 +
 drivers/net/rmnet/rmnet_stats.c   |  86 +
 drivers/net/rmnet/rmnet_stats.h   |  61 
 drivers/net/rmnet/rmnet_vnd.c | 353 
 drivers/net/rmnet/rmnet_vnd.h |  34 ++
 include/uapi/linux/Kbuild |   1 +
 include/uapi/linux/if_arp.h   |   1 +
 include/uapi/linux/if_ether.h |   4 +-
 include/uapi/linux/rmnet.h|  34 ++
 22 files changed, 2461 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/networking/rmnet.txt
 create mode 100644 drivers/net/rmnet/Kconfig
 create mode 100644 drivers/net/rmnet/Makefile
 create mode 100644 drivers/net/rmnet/rmnet_config.c
 create mode 100644 drivers/net/rmnet/rmnet_config.h
 create mode 100644 drivers/net/rmnet/rmnet_handlers.c
 create mode 100644 drivers/net/rmnet/rmnet_handlers.h
 create mode 100644 drivers/net/rmnet/rmnet_main.c
 create mode 100644 drivers/net/rmnet/rmnet_map.h
 create mode 100644 drivers/net/rmnet/rmnet_map_command.c
 create mode 100644 drivers/net/rmnet/rmnet_map_data.c
 create mode 100644 drivers/net/rmnet/rmnet_private.h
 create mode 100644 drivers/net/rmnet/rmnet_stats.c
 create mode 100644 drivers/net/rmnet/rmnet_stats.h
 create mode 100644 drivers/net/rmnet/rmnet_vnd.c
 create mode 100644 drivers/net/rmnet/rmnet_vnd.h
 create mode 100644 include/uapi/linux/rmnet.h

diff --git a/Documentation/networking/rmnet.txt 
b/Documentation/networking/rmnet.txt
new file mode 100644
index 000..58d3ea2
--- /dev/null
+++ b/Documentation/networking/rmnet.txt
@@ -0,0 +1,83 @@
+1. Introduction
+
+rmnet driver is used for supporting the Multiplexing and aggregation
+Protocol (MAP). This protocol is used by all recent chipsets using Qualcomm
+Technologies, Inc. modems.
+
+This driver can be used to register onto any physical network device in
+IP mode. Physical transports include USB, HSIC, PCIe and IP accelerator.
+
+Multiplexing allows for creation of logical netdevices (rmnet devices) to
+handle multiple private data networks (PDN) like a default internet, tethering,
+multimedia messaging service (MMS) or IP media subsystem (IMS). Hardware sends
+packets with MAP headers to rmnet. Based on the multiplexer id, rmnet
+routes to the appropriate PDN after removing the MAP header.
+
+Aggregation is required to achieve high data rates. This involves hardware
+sending aggregated bunch of MAP frames. rmnet driver will de-aggregate
+these MAP frames and send them to appropriate PDN's.
+
+2. Packet format
+
+a. MAP packet (data / control)
+
+MAP header has the same endianness of the IP packet.
+
+Packet format -
+
+Bit 0 1   2-7  8 - 15   16 - 31
+Function   Command / Data   Reserved Pad   Multiplexer IDPayload length
+Bit32 - x
+Function Raw  Bytes
+
+Command (1)/ Data (0) bit value is to indicate if the packet is a MAP command
+or data packet. Control packet is used for transport level flow control. Data
+packets are standard IP packets.
+
+Reserved bits are usually zeroed out and to be ignored by receiver.
+
+Padding is number of bytes to be added for 4 byte alignment if required by
+hardware.
+
+Multiplexer ID is to indicate the PDN on which data has to be sent.
+
+Payload length includes the padding length but does not include MAP header
+length.
+
+b. MAP packet (command specific)
+
+Bit 0 1   2-7  8 - 15   16 - 31
+Function   Command Reserved Pad   Multiplexer IDPayload length
+Bit  32 - 3940 - 4546 - 47   48 - 63
+Function   Command nameReserved   Command Type   Reserved
+Bit  64 - 95
+Function   Transaction ID
+Bit  96 - 127
+Function   Command data
+
+Command 1 indicates disabling flow while 2 is enabling flow
+
+Command types -
+0 for MAP command request
+1 is to acknowledge the receipt of a co