From b4d76675a6feeb57f7188d5354e1cf82b7adb012 Mon Sep 17 00:00:00 2001 From: Subash Abhinov Kasiviswanathan Date: Wed, 2 Dec 2020 10:58:52 -0800 Subject: [PATCH] rmnet_core: Add support for qmap steering Change SHS hooks to allow for potential qmap steering. CR-Fixed: 2851435 Change-Id: I86c49b7b2634a66606c536166b15ce5e2e629061 Signed-off-by: Subash Abhinov Kasiviswanathan --- core/rmnet_config.c | 10 +++++++++- core/rmnet_config.h | 18 +++++++++++++++++- core/rmnet_handlers.c | 36 +++++++++++++++++++++++++++++------- 3 files changed, 55 insertions(+), 9 deletions(-) mode change 100644 => 100755 core/rmnet_config.h mode change 100644 => 100755 core/rmnet_handlers.c diff --git a/core/rmnet_config.c b/core/rmnet_config.c index 4448a8efaf3b0..b341099c15b7b 100644 --- a/core/rmnet_config.c +++ b/core/rmnet_config.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2021, 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 @@ -30,6 +30,9 @@ #define CONFIG_QTI_QMI_DFC 1 #define CONFIG_QTI_QMI_POWER_COLLAPSE 1 +#define QMAP_SHS_MASK 0xFF +#define QMAP_SHS_PKT_LIMIT 200 + /* Locking scheme - * The shared resource which needs to be protected is realdev->rx_handler_data. * For the writer path, this is using rtnl_lock(). The writer paths are @@ -122,6 +125,11 @@ static int rmnet_register_real_device(struct net_device *real_dev) return -ENOMEM; port->dev = real_dev; + port->phy_shs_cfg.config = RMNET_SHS_NO_DLMKR | RMNET_SHS_NO_PSH | + RMNET_SHS_STMP_ALL; + port->phy_shs_cfg.map_mask = QMAP_SHS_MASK; + port->phy_shs_cfg.max_pkts = QMAP_SHS_PKT_LIMIT; + rc = netdev_rx_handler_register(real_dev, rmnet_rx_handler, port); if (rc) { kfree(port); diff --git a/core/rmnet_config.h b/core/rmnet_config.h old mode 100644 new mode 100755 index 7d8fb8ef7f725..4bb68eec3349c --- a/core/rmnet_config.h +++ b/core/rmnet_config.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2014, 2016-2020 The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, 2016-2021 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 @@ -22,6 +22,19 @@ #define RMNET_MAX_LOGICAL_EP 255 #define RMNET_MAX_VEID 4 +#define RMNET_SHS_STMP_ALL BIT(0) +#define RMNET_SHS_NO_PSH BIT(1) +#define RMNET_SHS_NO_DLMKR BIT(2) + +struct rmnet_shs_clnt_s { + u16 config; + u16 map_mask; + u16 max_pkts; + union { + struct rmnet_port *port; + } info; +}; + struct rmnet_endpoint { u8 mux_id; struct net_device *egress_dev; @@ -96,6 +109,9 @@ struct rmnet_port { struct list_head dl_list; struct rmnet_port_priv_stats stats; int dl_marker_flush; + /* Port Config for shs */ + struct rmnet_shs_clnt_s shs_cfg; + struct rmnet_shs_clnt_s phy_shs_cfg; /* Descriptor pool */ spinlock_t desc_pool_lock; diff --git a/core/rmnet_handlers.c b/core/rmnet_handlers.c old mode 100644 new mode 100755 index 4f005583c07a9..0399116017f62 --- a/core/rmnet_handlers.c +++ b/core/rmnet_handlers.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2021, 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 @@ -51,6 +51,8 @@ EXPORT_TRACEPOINT_SYMBOL(rmnet_freq_update); EXPORT_TRACEPOINT_SYMBOL(rmnet_freq_reset); EXPORT_TRACEPOINT_SYMBOL(rmnet_freq_boost); + + /* Helper Functions */ void rmnet_set_skb_proto(struct sk_buff *skb) @@ -86,12 +88,17 @@ EXPORT_SYMBOL(rmnet_slow_start_on); /* Shs hook handler */ int (*rmnet_shs_skb_entry)(struct sk_buff *skb, - struct rmnet_port *port) __rcu __read_mostly; + struct rmnet_shs_clnt_s *cfg) __rcu __read_mostly; EXPORT_SYMBOL(rmnet_shs_skb_entry); +int (*rmnet_shs_switch)(struct sk_buff *skb, + struct rmnet_shs_clnt_s *cfg) __rcu __read_mostly; +EXPORT_SYMBOL(rmnet_shs_switch); + + /* Shs hook handler for work queue*/ int (*rmnet_shs_skb_entry_wq)(struct sk_buff *skb, - struct rmnet_port *port) __rcu __read_mostly; + struct rmnet_shs_clnt_s *cfg) __rcu __read_mostly; EXPORT_SYMBOL(rmnet_shs_skb_entry_wq); /* Generic handler */ @@ -99,7 +106,8 @@ EXPORT_SYMBOL(rmnet_shs_skb_entry_wq); void rmnet_deliver_skb(struct sk_buff *skb, struct rmnet_port *port) { - int (*rmnet_shs_stamp)(struct sk_buff *skb, struct rmnet_port *port); + int (*rmnet_shs_stamp)(struct sk_buff *skb, + struct rmnet_shs_clnt_s *cfg); trace_rmnet_low(RMNET_MODULE, RMNET_DLVR_SKB, 0xDEF, 0xDEF, 0xDEF, 0xDEF, (void *)skb, NULL); @@ -113,7 +121,7 @@ rmnet_deliver_skb(struct sk_buff *skb, struct rmnet_port *port) rcu_read_lock(); rmnet_shs_stamp = rcu_dereference(rmnet_shs_skb_entry); if (rmnet_shs_stamp) { - rmnet_shs_stamp(skb, port); + rmnet_shs_stamp(skb, &port->shs_cfg); rcu_read_unlock(); return; } @@ -128,7 +136,8 @@ void rmnet_deliver_skb_wq(struct sk_buff *skb, struct rmnet_port *port, enum rmnet_packet_context ctx) { - int (*rmnet_shs_stamp)(struct sk_buff *skb, struct rmnet_port *port); + int (*rmnet_shs_stamp)(struct sk_buff *skb, + struct rmnet_shs_clnt_s *cfg); struct rmnet_priv *priv = netdev_priv(skb->dev); trace_rmnet_low(RMNET_MODULE, RMNET_DLVR_SKB, 0xDEF, 0xDEF, @@ -147,7 +156,7 @@ rmnet_deliver_skb_wq(struct sk_buff *skb, struct rmnet_port *port, rmnet_shs_stamp = (!ctx) ? rcu_dereference(rmnet_shs_skb_entry) : rcu_dereference(rmnet_shs_skb_entry_wq); if (rmnet_shs_stamp) { - rmnet_shs_stamp(skb, port); + rmnet_shs_stamp(skb, &port->shs_cfg); rcu_read_unlock(); return; } @@ -386,6 +395,8 @@ rx_handler_result_t rmnet_rx_handler(struct sk_buff **pskb) struct sk_buff *skb = *pskb; struct rmnet_port *port; struct net_device *dev; + int (*rmnet_core_shs_switch)(struct sk_buff *skb, + struct rmnet_shs_clnt_s *cfg); if (!skb) goto done; @@ -405,6 +416,17 @@ rx_handler_result_t rmnet_rx_handler(struct sk_buff **pskb) switch (port->rmnet_mode) { case RMNET_EPMODE_VND: + + rcu_read_lock(); + rmnet_core_shs_switch = rcu_dereference(rmnet_shs_switch); + if (rmnet_core_shs_switch && !skb->cb[1]) { + skb->cb[1] = 1; + rmnet_core_shs_switch(skb, &port->phy_shs_cfg); + rcu_read_unlock(); + return RX_HANDLER_CONSUMED; + } + rcu_read_unlock(); + rmnet_map_ingress_handler(skb, port); break; case RMNET_EPMODE_BRIDGE: