Loading core/qmi_rmnet.c +6 −57 Original line number Diff line number Diff line /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. 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 Loading @@ -25,7 +25,6 @@ #include <linux/moduleparam.h> #include <linux/ip.h> #include <linux/ipv6.h> #include <linux/alarmtimer.h> #define NLMSG_FLOW_ACTIVATE 1 #define NLMSG_FLOW_DEACTIVATE 2 Loading Loading @@ -612,7 +611,6 @@ qmi_rmnet_setup_client(void *port, struct qmi_info *qmi, struct tcmsg *tcm) if (!qmi) return -ENOMEM; qmi->ws = wakeup_source_register(NULL, "RMNET_DFC"); rmnet_init_qmi_pt(port, qmi); } Loading Loading @@ -661,7 +659,6 @@ __qmi_rmnet_delete_client(void *port, struct qmi_info *qmi, int idx) if (!qmi_rmnet_has_client(qmi) && !qmi_rmnet_has_pending(qmi)) { rmnet_reset_qmi_pt(port); wakeup_source_unregister(qmi->ws); kfree(qmi); return 0; } Loading Loading @@ -731,7 +728,6 @@ void qmi_rmnet_change_link(struct net_device *dev, void *port, void *tcm_pt) !qmi_rmnet_has_client(qmi) && !qmi_rmnet_has_pending(qmi)) { rmnet_reset_qmi_pt(port); wakeup_source_unregister(qmi->ws); kfree(qmi); } } else if (tcm->tcm_ifindex & FLAG_POWERSAVE_MASK) { Loading Loading @@ -1061,7 +1057,6 @@ static LIST_HEAD(ps_list); struct rmnet_powersave_work { struct delayed_work work; struct alarm atimer; void *port; u64 old_rx_pkts; u64 old_tx_pkts; Loading Loading @@ -1145,32 +1140,6 @@ static void qmi_rmnet_work_restart(void *port) rcu_read_unlock(); } static enum alarmtimer_restart qmi_rmnet_work_alarm(struct alarm *atimer, ktime_t now) { struct rmnet_powersave_work *real_work; real_work = container_of(atimer, struct rmnet_powersave_work, atimer); qmi_rmnet_work_restart(real_work->port); return ALARMTIMER_NORESTART; } static void dfc_wakelock_acquire(struct qmi_info *qmi) { if (qmi && !qmi->wakelock_active) { __pm_stay_awake(qmi->ws); qmi->wakelock_active = true; } } static void dfc_wakelock_release(struct qmi_info *qmi) { if (qmi && qmi->wakelock_active) { __pm_relax(qmi->ws); qmi->wakelock_active = false; } } static void qmi_rmnet_check_stats(struct work_struct *work) { struct rmnet_powersave_work *real_work; Loading @@ -1178,7 +1147,6 @@ static void qmi_rmnet_check_stats(struct work_struct *work) u64 rxd, txd; u64 rx, tx; bool dl_msg_active; bool use_alarm_timer = true; real_work = container_of(to_delayed_work(work), struct rmnet_powersave_work, work); Loading @@ -1190,8 +1158,6 @@ static void qmi_rmnet_check_stats(struct work_struct *work) if (unlikely(!qmi)) return; dfc_wakelock_release(qmi); rmnet_get_packets(real_work->port, &rx, &tx); rxd = rx - real_work->old_rx_pkts; txd = tx - real_work->old_tx_pkts; Loading Loading @@ -1226,10 +1192,8 @@ static void qmi_rmnet_check_stats(struct work_struct *work) * (likely in RLF), no need to enter powersave */ if (!dl_msg_active && !rmnet_all_flows_enabled(real_work->port)) { use_alarm_timer = false; !rmnet_all_flows_enabled(real_work->port)) goto end; } /* Deregister to suppress QMI DFC and DL marker */ if (qmi_rmnet_set_powersave_mode(real_work->port, 1) < 0) Loading @@ -1253,21 +1217,9 @@ static void qmi_rmnet_check_stats(struct work_struct *work) } end: rcu_read_lock(); if (!rmnet_work_quit) { if (use_alarm_timer) { /* Suspend will fail and get delayed for 2s if * alarmtimer expires within 2s. Hold a wakelock * for the actual timer duration to prevent suspend */ if (PS_INTERVAL_MS < 2000) dfc_wakelock_acquire(qmi); alarm_start_relative(&real_work->atimer, PS_INTERVAL_KT); } else { if (!rmnet_work_quit) queue_delayed_work(rmnet_ps_wq, &real_work->work, PS_INTERVAL); } } rcu_read_unlock(); } Loading Loading @@ -1302,8 +1254,7 @@ void qmi_rmnet_work_init(void *port) rmnet_ps_wq = NULL; return; } INIT_DEFERRABLE_WORK(&rmnet_work->work, qmi_rmnet_check_stats); alarm_init(&rmnet_work->atimer, ALARM_BOOTTIME, qmi_rmnet_work_alarm); INIT_DELAYED_WORK(&rmnet_work->work, qmi_rmnet_check_stats); rmnet_work->port = port; rmnet_get_packets(rmnet_work->port, &rmnet_work->old_rx_pkts, &rmnet_work->old_tx_pkts); Loading Loading @@ -1337,14 +1288,12 @@ void qmi_rmnet_work_exit(void *port) synchronize_rcu(); rmnet_work_inited = false; alarm_cancel(&rmnet_work->atimer); cancel_delayed_work_sync(&rmnet_work->work); destroy_workqueue(rmnet_ps_wq); qmi_rmnet_work_set_active(port, 0); rmnet_ps_wq = NULL; kfree(rmnet_work); rmnet_work = NULL; dfc_wakelock_release((struct qmi_info *)rmnet_get_qmi_pt(port)); } EXPORT_SYMBOL(qmi_rmnet_work_exit); Loading core/qmi_rmnet_i.h +1 −4 Original line number Diff line number Diff line /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. 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 Loading @@ -18,7 +18,6 @@ #include <linux/netdevice.h> #include <linux/skbuff.h> #include <linux/timer.h> #include <linux/pm_wakeup.h> #define MAX_MQ_NUM 16 #define MAX_CLIENT_NUM 2 Loading Loading @@ -110,8 +109,6 @@ struct qmi_info { bool ps_enabled; bool dl_msg_active; bool ps_ignore_grant; bool wakelock_active; struct wakeup_source *ws; }; enum data_ep_type_enum_v01 { Loading Loading
core/qmi_rmnet.c +6 −57 Original line number Diff line number Diff line /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. 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 Loading @@ -25,7 +25,6 @@ #include <linux/moduleparam.h> #include <linux/ip.h> #include <linux/ipv6.h> #include <linux/alarmtimer.h> #define NLMSG_FLOW_ACTIVATE 1 #define NLMSG_FLOW_DEACTIVATE 2 Loading Loading @@ -612,7 +611,6 @@ qmi_rmnet_setup_client(void *port, struct qmi_info *qmi, struct tcmsg *tcm) if (!qmi) return -ENOMEM; qmi->ws = wakeup_source_register(NULL, "RMNET_DFC"); rmnet_init_qmi_pt(port, qmi); } Loading Loading @@ -661,7 +659,6 @@ __qmi_rmnet_delete_client(void *port, struct qmi_info *qmi, int idx) if (!qmi_rmnet_has_client(qmi) && !qmi_rmnet_has_pending(qmi)) { rmnet_reset_qmi_pt(port); wakeup_source_unregister(qmi->ws); kfree(qmi); return 0; } Loading Loading @@ -731,7 +728,6 @@ void qmi_rmnet_change_link(struct net_device *dev, void *port, void *tcm_pt) !qmi_rmnet_has_client(qmi) && !qmi_rmnet_has_pending(qmi)) { rmnet_reset_qmi_pt(port); wakeup_source_unregister(qmi->ws); kfree(qmi); } } else if (tcm->tcm_ifindex & FLAG_POWERSAVE_MASK) { Loading Loading @@ -1061,7 +1057,6 @@ static LIST_HEAD(ps_list); struct rmnet_powersave_work { struct delayed_work work; struct alarm atimer; void *port; u64 old_rx_pkts; u64 old_tx_pkts; Loading Loading @@ -1145,32 +1140,6 @@ static void qmi_rmnet_work_restart(void *port) rcu_read_unlock(); } static enum alarmtimer_restart qmi_rmnet_work_alarm(struct alarm *atimer, ktime_t now) { struct rmnet_powersave_work *real_work; real_work = container_of(atimer, struct rmnet_powersave_work, atimer); qmi_rmnet_work_restart(real_work->port); return ALARMTIMER_NORESTART; } static void dfc_wakelock_acquire(struct qmi_info *qmi) { if (qmi && !qmi->wakelock_active) { __pm_stay_awake(qmi->ws); qmi->wakelock_active = true; } } static void dfc_wakelock_release(struct qmi_info *qmi) { if (qmi && qmi->wakelock_active) { __pm_relax(qmi->ws); qmi->wakelock_active = false; } } static void qmi_rmnet_check_stats(struct work_struct *work) { struct rmnet_powersave_work *real_work; Loading @@ -1178,7 +1147,6 @@ static void qmi_rmnet_check_stats(struct work_struct *work) u64 rxd, txd; u64 rx, tx; bool dl_msg_active; bool use_alarm_timer = true; real_work = container_of(to_delayed_work(work), struct rmnet_powersave_work, work); Loading @@ -1190,8 +1158,6 @@ static void qmi_rmnet_check_stats(struct work_struct *work) if (unlikely(!qmi)) return; dfc_wakelock_release(qmi); rmnet_get_packets(real_work->port, &rx, &tx); rxd = rx - real_work->old_rx_pkts; txd = tx - real_work->old_tx_pkts; Loading Loading @@ -1226,10 +1192,8 @@ static void qmi_rmnet_check_stats(struct work_struct *work) * (likely in RLF), no need to enter powersave */ if (!dl_msg_active && !rmnet_all_flows_enabled(real_work->port)) { use_alarm_timer = false; !rmnet_all_flows_enabled(real_work->port)) goto end; } /* Deregister to suppress QMI DFC and DL marker */ if (qmi_rmnet_set_powersave_mode(real_work->port, 1) < 0) Loading @@ -1253,21 +1217,9 @@ static void qmi_rmnet_check_stats(struct work_struct *work) } end: rcu_read_lock(); if (!rmnet_work_quit) { if (use_alarm_timer) { /* Suspend will fail and get delayed for 2s if * alarmtimer expires within 2s. Hold a wakelock * for the actual timer duration to prevent suspend */ if (PS_INTERVAL_MS < 2000) dfc_wakelock_acquire(qmi); alarm_start_relative(&real_work->atimer, PS_INTERVAL_KT); } else { if (!rmnet_work_quit) queue_delayed_work(rmnet_ps_wq, &real_work->work, PS_INTERVAL); } } rcu_read_unlock(); } Loading Loading @@ -1302,8 +1254,7 @@ void qmi_rmnet_work_init(void *port) rmnet_ps_wq = NULL; return; } INIT_DEFERRABLE_WORK(&rmnet_work->work, qmi_rmnet_check_stats); alarm_init(&rmnet_work->atimer, ALARM_BOOTTIME, qmi_rmnet_work_alarm); INIT_DELAYED_WORK(&rmnet_work->work, qmi_rmnet_check_stats); rmnet_work->port = port; rmnet_get_packets(rmnet_work->port, &rmnet_work->old_rx_pkts, &rmnet_work->old_tx_pkts); Loading Loading @@ -1337,14 +1288,12 @@ void qmi_rmnet_work_exit(void *port) synchronize_rcu(); rmnet_work_inited = false; alarm_cancel(&rmnet_work->atimer); cancel_delayed_work_sync(&rmnet_work->work); destroy_workqueue(rmnet_ps_wq); qmi_rmnet_work_set_active(port, 0); rmnet_ps_wq = NULL; kfree(rmnet_work); rmnet_work = NULL; dfc_wakelock_release((struct qmi_info *)rmnet_get_qmi_pt(port)); } EXPORT_SYMBOL(qmi_rmnet_work_exit); Loading
core/qmi_rmnet_i.h +1 −4 Original line number Diff line number Diff line /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. 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 Loading @@ -18,7 +18,6 @@ #include <linux/netdevice.h> #include <linux/skbuff.h> #include <linux/timer.h> #include <linux/pm_wakeup.h> #define MAX_MQ_NUM 16 #define MAX_CLIENT_NUM 2 Loading Loading @@ -110,8 +109,6 @@ struct qmi_info { bool ps_enabled; bool dl_msg_active; bool ps_ignore_grant; bool wakelock_active; struct wakeup_source *ws; }; enum data_ep_type_enum_v01 { Loading