ipq807x_v5.4: cooling daemon with configuration file support

Fixes: WIFI-14682
Signed-off-by: wingate5678 <wingate.chi@cybertan.com.tw>
This commit is contained in:
wingate5678
2025-06-12 09:02:19 +00:00
committed by John Crispin
parent b17db16c15
commit b061cc55ce
4 changed files with 216 additions and 94 deletions

View File

@@ -18,9 +18,11 @@ start() {
[ "$enabled" -gt 0 ] || return 1
case "$board" in
sonicfi,rap630c-311g|\
sonicfi,rap630c-311g)
service_start /usr/sbin/cooling -c /etc/cooling/sonicfi-rap630c-311g-cooling.conf
;;
sonicfi,rap630w-311g)
service_start /usr/sbin/cooling
service_start /usr/sbin/cooling -c /etc/cooling/sonicfi-rap630w-311g-cooling.conf
;;
esac

View File

@@ -28,99 +28,217 @@
#define CUR_STATE_PATH "/sys/devices/virtual/thermal/cooling_device%i/cur_state"
#define TEMPER_PATH "/sys/devices/virtual/thermal/thermal_zone%i/temp"
#define CPU_FREQ_PATH "/sys/devices/system/cpu/cpu0/cpufreq/%s"
#define PATH_MAX 256
#define BUF_MAX 8
#define THERSHOLD_MAX 20
#define BUF_MAX 32
#define PHY0 0
#define PHY1 1
#define NUM_VALUES 4
int load_config_file=0;
//#define ULOG_INFO(fmt, ...) ulog(LOG_INFO, fmt, ## __VA_ARGS__)
typedef unsigned char u8;
typedef unsigned long u32;
u8 w2g_threshold_level=0;
u8 w5g_threshold_level=0;
u8 w2g_cur_temper=0;
u8 w5g_cur_temper=0;
u32 level_cpu_freq=1008000;
/* default value of wifi thresholds*/
#ifdef PLATFORM_RAP630C_311G
u8 level_2g_lo[4]={0, 105, 110, 115};
u8 level_2g_hi[4]={105, 110, 115, 120};
u8 level_2g_limit[4]={0, 35, 50, 70};
u8 level_5g_lo[4]={0, 105, 110, 115};
u8 level_5g_hi[4]={105, 110, 115, 120};
u8 level_5g_limit[4]={0, 20, 30, 50};
u8 level_2g_high[4]={105, 110, 115, 120};
u8 level_2g_low[4]={0, 105, 110, 115};
u8 level_2g_mitigation[4]={0, 35, 50, 70};
u8 level_5g_high[4]={105, 110, 115, 120};
u8 level_5g_low[4]={0, 105, 110, 115};
u8 level_5g_mitigation[4]={0, 20, 30, 50};
u32 level_cpu_frequency[4]={1008000, 800000, 800000, 800000};
#endif
#ifdef PLATFORM_RAP630W_311G
u8 level_2g_lo[4]={0, 105, 110, 115};
u8 level_2g_hi[4]={105, 110, 115, 120};
u8 level_2g_limit[4]={0, 20, 50, 70};
u8 level_5g_lo[4]={0, 105, 110, 115};
u8 level_5g_hi[4]={105, 110, 115, 120};
u8 level_5g_limit[4]={0, 20, 50, 70};
u8 level_2g_high[4]={105, 110, 115, 120};
u8 level_2g_low[4]={0, 105, 110, 115};
u8 level_2g_mitigation[4]={0, 20, 50, 70};
u8 level_5g_high[4]={105, 110, 115, 120};
u8 level_5g_low[4]={0, 105, 110, 115};
u8 level_5g_mitigation[4]={0, 20, 50, 70};
u32 level_cpu_frequency[4]={1008000, 800000, 800000, 800000};
#endif
static char *config_file = NULL;
char temp[4][BUF_MAX];
#define ULOG_DBG(fmt, ...) ulog(LOG_DEBUG, fmt, ## __VA_ARGS__)
typedef struct {
int thresholds_high[NUM_VALUES];
int thresholds_low[NUM_VALUES];
int mitigation[NUM_VALUES];
int cpu_freq[NUM_VALUES];
} WifiConfig;
static void write_cur_state (char *filename, int state) {
WifiConfig wifi2g = {0}, wifi5g = {0};
static void set_cpu_freq (int freq) {
FILE * fp;
char filename[PATH_MAX];
snprintf(filename, PATH_MAX, CPU_FREQ_PATH, "scaling_governor");
ULOG_DBG("write_cur_state filename=[%s] [%d]\n", filename, state);
fp = fopen(filename, "w");
if (!fp) {
ULOG_ERR("some kind of error write cur_state\n");
ULOG_ERR("open scaling_governor error\n");
}
fprintf(fp, "%s", "userspace");
fclose(fp);
snprintf(filename, PATH_MAX, CPU_FREQ_PATH, "scaling_setspeed");
fp = fopen(filename, "w");
if (!fp) {
ULOG_ERR("open scaling_setspeed error\n");
}
fprintf(fp, "%d", freq);
fclose(fp);
}
void parse_line(const char* line, const char* key, int* array) {
char label[64];
int values[NUM_VALUES];
int i;
if (sscanf(line, "%s %d %d %d %d %d", label, &values[0], &values[1], &values[2], &values[3], &values[4]) == 5) {
for (i = 0; i < NUM_VALUES; ++i) {
array[i] = values[i];
}
}
}
int load_config() {
FILE * fp = fopen(config_file, "r");
if (!fp) {
ULOG_ERR("open config file error\n");
return 1;
}
WifiConfig* current_config = NULL;
char line[256];
while (fgets(line, sizeof(line), fp)) {
if (strstr(line, "[wifi2g]")) {
current_config = &wifi2g;
} else if (strstr(line, "[wifi5g]")) {
current_config = &wifi5g;
} else if (current_config) {
if (strstr(line, "thresholds_high")) {
parse_line(line, "thresholds_high", current_config->thresholds_high);
} else if (strstr(line, "thresholds_low")) {
parse_line(line, "thresholds_low", current_config->thresholds_low);
} else if (strstr(line, "mitigation")) {
parse_line(line, "mitigation", current_config->mitigation);
} else if (strstr(line, "CPU_freq")) {
parse_line(line, "CPU_freq", current_config->cpu_freq);
}
}
}
fclose(fp);
set_cpu_freq(wifi5g.cpu_freq[0]);
return 0;
}
int load_default_config(){
int i=0;
set_cpu_freq(1008000);
for (i = 0; i < NUM_VALUES; i++) {
wifi2g.thresholds_high[i]=level_2g_high[i];
wifi2g.thresholds_low[i]=level_2g_low[i];
wifi2g.mitigation[i]=level_2g_mitigation[i];
wifi2g.cpu_freq[i]=level_cpu_frequency[i];
wifi5g.thresholds_high[i]=level_5g_high[i];
wifi5g.thresholds_low[i]=level_5g_low[i];
wifi5g.mitigation[i]=level_5g_mitigation[i];
wifi5g.cpu_freq[i]=level_cpu_frequency[i];
}
return 0;
}
static void write_cur_state (const char *filename, int state) {
FILE * fp;
fp = fopen(filename, "w");
if (!fp){
ULOG_ERR("open %s file error\n",filename);
}
fprintf(fp, "%d", state);
fclose(fp);
}
static void read_cur_state (char *filename, char *buffer) {
int read_cur_state(const char *filename, char *buf, size_t buffer) {
FILE *fp;
fp = fopen(filename, "r");
if (!fp) {
ULOG_ERR("some kind of error write cur_state\n");
ULOG_ERR("open %s file error\n",filename);
return -1;
}
if (0 == fread(buffer, sizeof(char), 3, fp)) {
ULOG_ERR("some kind of error read value\n");
if (!fgets(buf, buffer, fp)) {
ULOG_ERR("Failed to read %s file\n", filename);
fclose(fp);
return -1;
}
fclose(fp);
return 0;
}
static void wifi_get_temperature() {
char filename[PATH_MAX];
FILE * fp;
int i = 0;
char buffer[BUF_MAX];
int i = 0;
// ULOG_INFO("=================================\n");
/* read cpuinfo_cur_freq*/
snprintf(filename, PATH_MAX, CPU_FREQ_PATH, "cpuinfo_cur_freq");
memset(buffer, 0, BUF_MAX);
read_cur_state(filename, buffer, sizeof(buffer));
// ULOG_INFO("CPU current frequency: %s\n", buffer);
/* get current phy cooling state*/
for (i=0; i <= 1; i++) {
memset(buffer, 0, BUF_MAX);
snprintf(filename, PATH_MAX, CUR_STATE_PATH, i);
read_cur_state(filename, buffer);
ULOG_DBG("read from Phy%i cur_state is %s\n", i, buffer);
read_cur_state(filename, buffer, sizeof(buffer));
// ULOG_INFO("Phy%i cur_state is: %s\n", i, buffer);
}
for (i=0; i <= 3; i++) {
memset(buffer, 0, BUF_MAX);
snprintf(filename, PATH_MAX, TEMPER_PATH, i);
fp = fopen(filename, "r");
if (!fp) {
ULOG_ERR("some kind of error open value\n");
}
memset(temp[i], 0, BUF_MAX);
if (0 == fread(temp[i], sizeof(char), 3, fp)) {
ULOG_ERR("some kind of error read value\n");
}
fclose(fp);
ULOG_DBG("thermal_zone%i cur_temp is %s\n", i, temp[i]);
read_cur_state(filename, buffer, sizeof(buffer));
// ULOG_INFO("thermal_zone%i cur_temp is: %s\n", i, buffer);
if (i == 0)
w2g_cur_temper=atoi(buffer);
else if (i == 3)
w5g_cur_temper=atoi(buffer);
}
w2g_cur_temper=atoi(temp[0]);
w5g_cur_temper=atoi(temp[3]);
if (w5g_cur_temper >= 120)
{
ULOG_ERR("!! Temperature is over %d degree, system will reboot\n", w5g_cur_temper);
sync();
if ( -1 != system("reboot &") ){
printf("sysyem reboot...\n");
}
}
}
static void wifi_set_cooling() {
@@ -128,43 +246,52 @@ static void wifi_set_cooling() {
int level;
for (level = 0; level <= 3; level++) {
if (w2g_cur_temper >= level_2g_lo[level] && w2g_cur_temper < level_2g_hi[level]) {
ULOG_DBG("2G at level %d , %d degree\n" ,level, w2g_cur_temper);
if (w2g_cur_temper >= wifi2g.thresholds_low[level] && w2g_cur_temper < wifi2g.thresholds_high[level]) {
// ULOG_INFO("2G at level %d , %d degree\n" ,level, w2g_cur_temper);
if (w2g_threshold_level != level) {
ULOG_DBG("setting 2G reduce %d percent\n" ,level_2g_limit[level]);
// ULOG_INFO("setting 2G reduce %d percent\n" ,wifi2g.mitigation[level]);
snprintf(filename, PATH_MAX, CUR_STATE_PATH, PHY0);
write_cur_state(filename, level_2g_limit[level]);
write_cur_state(filename, wifi2g.mitigation[level]);
w2g_threshold_level = level;
}
}
if (w5g_cur_temper >= level_5g_lo[level] && w5g_cur_temper < level_5g_hi[level]) {
ULOG_DBG("5G at level %d , %d degree\n" ,level, w5g_cur_temper);
if (w5g_cur_temper >= wifi5g.thresholds_low[level] && w5g_cur_temper < wifi5g.thresholds_high[level]) {
// ULOG_INFO("5G at level %d , %d degree\n" ,level, w5g_cur_temper);
if (w5g_threshold_level != level) {
ULOG_DBG("setting 5G reduce %d percent\n" ,level_5g_limit[level]);
// ULOG_INFO("setting 5G reduce %d percent\n" ,wifi5g.mitigation[level]);
snprintf(filename, PATH_MAX, CUR_STATE_PATH, PHY1);
write_cur_state(filename, level_5g_limit[level]);
write_cur_state(filename, wifi5g.mitigation[level]);
w5g_threshold_level = level;
}
set_cpu_freq(wifi5g.cpu_freq[level]);
}
}
}
}
static void cooling_init() {
char filename[256];
int i;
char filename[PATH_MAX];
int i,result=0;
for (i=0 ; i <= 1; i++) {
snprintf(filename, PATH_MAX, CUR_STATE_PATH, i);
write_cur_state(filename, 0);
}
if(load_config_file)
result = load_config();
if (result == 1 || load_config_file == 0)
load_default_config();
}
void print_usage(void)
{
printf("\nWifi-cooling daemon usage\n");
printf("Optional arguments:\n");
printf(" -c <file> config file\n");
printf(" -d debug output\n");
printf(" -c <file> setting with config file\n");
printf(" -d default setting\n");
printf(" -h this usage screen\n");
}
@@ -185,17 +312,18 @@ int main(int argc, char *argv[])
setpriority(PRIO_PROCESS, getpid(), -20);
ulog_open(ULOG_STDIO | ULOG_SYSLOG, LOG_DAEMON, "cooling");
ulog_threshold(LOG_INFO);
ulog_threshold(LOG_ERR);
// ulog_threshold(LOG_INFO);
while ((ch = getopt(argc, argv, "c:dh")) != -1) {
switch (ch) {
case 'c':
printf("wifi-cooling load configuration file %s\n", optarg);
config_file = optarg;
load_config_file=1;
break;
case 'd':
printf("wifi-cooling ulog_threshold set to debug level\n");
ulog_threshold(LOG_DEBUG);
printf("wifi-cooling set to default value\n");
break;
case 'h':
default:

View File

@@ -1,15 +1,11 @@
sampling 5000
[wifi2g]
thresholds_high 105 110 115 120
thresholds_low 0 105 110 115
mitigation 0 35 50 70
CPU_freq 1008000 800000 800000 800000
[tsens_tz_sensor1]
sampling 5000
thresholds 105 110 115 119 120
thresholds_clr 0 100 105 110 115
actions cooling cooling cooling cooling shutdown
action_info 0 35 50 70 800000
[tsens_tz_sensor4]
sampling 5000
thresholds 105 110 115 119 120
thresholds_clr 0 100 105 110 115
actions cooling cooling cooling cooling shutdown
action_info 0 20 30 50 800000
[wifi5g]
thresholds_high 105 110 115 120
thresholds_low 0 105 110 115
mitigation 0 20 30 50
CPU_freq 1008000 800000 800000 800000

View File

@@ -1,15 +1,11 @@
sampling 5000
[wifi2g]
thresholds_high 105 110 115 120
thresholds_low 0 105 110 115
mitigation 0 20 50 70
CPU_freq 1008000 800000 800000 800000
[tsens_tz_sensor1]
sampling 5000
thresholds 105 115 119 125
thresholds_clr 0 105 110 120
actions cooling cooling cooling cooling
action_info 0 20 50 70
[tsens_tz_sensor4]
sampling 5000
thresholds 105 115 119 125
thresholds_clr 0 105 110 120
actions cooling cooling cooling cooling
action_info 0 20 50 70
[wifi5g]
thresholds_high 105 110 115 120
thresholds_low 0 105 110 115
mitigation 0 20 50 70
CPU_freq 1008000 800000 800000 800000