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 <subashab@codeaurora.org>
This commit is contained in:
Subash Abhinov Kasiviswanathan 2020-12-02 10:58:52 -08:00 committed by Gerrit - the friendly Code Review server
parent c6b88d0bc9
commit b4d76675a6
3 changed files with 55 additions and 9 deletions

View File

@ -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);

18
core/rmnet_config.h Normal file → Executable file
View File

@ -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;

36
core/rmnet_handlers.c Normal file → Executable file
View File

@ -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: