Loading drivers/soc/qcom/qmi_rmnet.c +27 −3 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ #include <trace/events/dfc.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 @@ -43,6 +44,7 @@ unsigned int rmnet_wq_frequency __read_mostly = 1000; #define PS_INTERVAL (((!rmnet_wq_frequency) ? \ 1 : rmnet_wq_frequency/10) * (HZ/100)) #define NO_DELAY (0x0000 * HZ) #define PS_INTERVAL_KT (ms_to_ktime(1000)) #ifdef CONFIG_QCOM_QMI_DFC static unsigned int qmi_rmnet_scale_factor = 5; Loading Loading @@ -917,6 +919,7 @@ 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 @@ -1001,6 +1004,16 @@ 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 qmi_rmnet_check_stats(struct work_struct *work) { struct rmnet_powersave_work *real_work; Loading @@ -1008,6 +1021,7 @@ 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 Loading @@ -1053,8 +1067,10 @@ 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)) !rmnet_all_flows_enabled(real_work->port)) { use_alarm_timer = false; goto end; } /* Deregister to suppress QMI DFC and DL marker */ if (qmi_rmnet_set_powersave_mode(real_work->port, 1) < 0) Loading @@ -1078,8 +1094,14 @@ static void qmi_rmnet_check_stats(struct work_struct *work) } end: rcu_read_lock(); if (!rmnet_work_quit) queue_delayed_work(rmnet_ps_wq, &real_work->work, PS_INTERVAL); if (!rmnet_work_quit) { if (use_alarm_timer) alarm_start_relative(&real_work->atimer, PS_INTERVAL_KT); else queue_delayed_work(rmnet_ps_wq, &real_work->work, PS_INTERVAL); } rcu_read_unlock(); } Loading Loading @@ -1115,6 +1137,7 @@ void qmi_rmnet_work_init(void *port) return; } INIT_DEFERRABLE_WORK(&rmnet_work->work, qmi_rmnet_check_stats); alarm_init(&rmnet_work->atimer, ALARM_BOOTTIME, qmi_rmnet_work_alarm); rmnet_work->port = port; rmnet_get_packets(rmnet_work->port, &rmnet_work->old_rx_pkts, &rmnet_work->old_tx_pkts); Loading Loading @@ -1146,6 +1169,7 @@ void qmi_rmnet_work_exit(void *port) rmnet_work_quit = true; synchronize_rcu(); alarm_cancel(&rmnet_work->atimer); cancel_delayed_work_sync(&rmnet_work->work); destroy_workqueue(rmnet_ps_wq); qmi_rmnet_work_set_active(port, 0); Loading Loading
drivers/soc/qcom/qmi_rmnet.c +27 −3 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ #include <trace/events/dfc.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 @@ -43,6 +44,7 @@ unsigned int rmnet_wq_frequency __read_mostly = 1000; #define PS_INTERVAL (((!rmnet_wq_frequency) ? \ 1 : rmnet_wq_frequency/10) * (HZ/100)) #define NO_DELAY (0x0000 * HZ) #define PS_INTERVAL_KT (ms_to_ktime(1000)) #ifdef CONFIG_QCOM_QMI_DFC static unsigned int qmi_rmnet_scale_factor = 5; Loading Loading @@ -917,6 +919,7 @@ 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 @@ -1001,6 +1004,16 @@ 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 qmi_rmnet_check_stats(struct work_struct *work) { struct rmnet_powersave_work *real_work; Loading @@ -1008,6 +1021,7 @@ 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 Loading @@ -1053,8 +1067,10 @@ 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)) !rmnet_all_flows_enabled(real_work->port)) { use_alarm_timer = false; goto end; } /* Deregister to suppress QMI DFC and DL marker */ if (qmi_rmnet_set_powersave_mode(real_work->port, 1) < 0) Loading @@ -1078,8 +1094,14 @@ static void qmi_rmnet_check_stats(struct work_struct *work) } end: rcu_read_lock(); if (!rmnet_work_quit) queue_delayed_work(rmnet_ps_wq, &real_work->work, PS_INTERVAL); if (!rmnet_work_quit) { if (use_alarm_timer) alarm_start_relative(&real_work->atimer, PS_INTERVAL_KT); else queue_delayed_work(rmnet_ps_wq, &real_work->work, PS_INTERVAL); } rcu_read_unlock(); } Loading Loading @@ -1115,6 +1137,7 @@ void qmi_rmnet_work_init(void *port) return; } INIT_DEFERRABLE_WORK(&rmnet_work->work, qmi_rmnet_check_stats); alarm_init(&rmnet_work->atimer, ALARM_BOOTTIME, qmi_rmnet_work_alarm); rmnet_work->port = port; rmnet_get_packets(rmnet_work->port, &rmnet_work->old_rx_pkts, &rmnet_work->old_tx_pkts); Loading Loading @@ -1146,6 +1169,7 @@ void qmi_rmnet_work_exit(void *port) rmnet_work_quit = true; synchronize_rcu(); alarm_cancel(&rmnet_work->atimer); cancel_delayed_work_sync(&rmnet_work->work); destroy_workqueue(rmnet_ps_wq); qmi_rmnet_work_set_active(port, 0); Loading