| /****************************************************************************** |
| * (C) Copyright 2014-2015 Marvell International Ltd. |
| * All Rights Reserved |
| *****************************************************************************/ |
| /*----------------------------------------------------------------------------- |
| * |
| * Filename: weh_util.c |
| * |
| * Description: The APIs to check WiFi over wifi drivers |
| * |
| * History: |
| * January 2014 - Vitaly Chernooky Creation of file |
| * July 2015 - Yan Markman |
| * |
| *****************************************************************************/ |
| |
| #include <errno.h> |
| #include <getopt.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <stdbool.h> |
| #include <string.h> |
| #include <time.h> |
| #include <unistd.h> |
| #include "eeh.h" |
| #include "EEHandler_config.h" |
| |
| #define DRIVER_STATE_FIELD_NAME "driver_state" |
| |
| #define WEH_MWLAN_EXEC_STOP "/etc/init.d/mwlan stop" |
| #define WEH_MWLAN_EXEC_START "/etc/init.d/mwlan start" |
| |
| static const char *node_name[] = /* idx=0 is default if */ |
| { |
| "/proc/mwlan/uap0/debug", |
| "/proc/mwlan/wlan0/debug", |
| /* mlan0, wfd0 .... */ |
| }; |
| |
| #define WEH_NUM_NODES (sizeof(node_name)/sizeof(node_name[0])) |
| #define WEH_IF_NAME(IDX) (node_name[IDX] + (sizeof("/proc/mwlan/") - 1)) |
| |
| static int get_curr_state(const char *file) |
| { |
| /* DRIVER_STATE_FIELD_NAME is always on the /proc beginning */ |
| const char *name = DRIVER_STATE_FIELD_NAME; |
| int name_len = sizeof(DRIVER_STATE_FIELD_NAME) - 1; |
| int max_len = name_len + 5; |
| char buf[max_len + 1]; |
| FILE *f; |
| int num, ret; |
| |
| f = fopen(file, "r"); |
| if (!f) |
| return -EHOSTDOWN; /* not running */ |
| |
| buf[0] = 0; |
| if (!fgets(buf, max_len, f)) { |
| fclose(f); |
| return -EHOSTDOWN; /* cannot read (may be down) */ |
| } |
| buf[max_len] = 0; |
| num = sscanf(buf, DRIVER_STATE_FIELD_NAME "=%d", &ret); |
| if (num != 1) { |
| ret = 0; /* wrong formatted output. Say OK! */ |
| } |
| fclose(f); |
| return ret; |
| } |
| |
| int weh_is_up_get_stat(void *name_or_idx, int *drv_stat, int flag) |
| { |
| unsigned i, max; |
| int len, state, one_node_req, flt_cnt = 0; |
| flag = flag; |
| |
| if ((unsigned)name_or_idx < WEH_NUM_NODES) { |
| i = max = (int)name_or_idx; |
| one_node_req = 1; |
| } else if ((unsigned)name_or_idx <= 256) { |
| i = 0; |
| max = WEH_NUM_NODES - 1; |
| one_node_req = 0; |
| } else { |
| /* brief name given. Look for idx in node_name[] */ |
| one_node_req = 1; |
| i = max = 0; |
| len = strlen(name_or_idx); |
| if (len > 8) |
| i = WEH_NUM_NODES; /*wrong name, bypass the for() */ |
| for (; i < WEH_NUM_NODES; i++) { |
| if (!strncmp(WEH_IF_NAME(i), name_or_idx, len)) { |
| max = i; |
| break; |
| } |
| } |
| i = max; /* if not found, set default idx=0 */ |
| } |
| |
| *drv_stat = 0; |
| do { |
| state = get_curr_state(node_name[i]); |
| if (state == -EHOSTDOWN) /* -112 */ |
| return -EHOSTDOWN; |
| if (state) |
| flt_cnt++; |
| } while (++i <= max); |
| |
| if (one_node_req) { |
| *drv_stat = state; |
| } else { |
| *drv_stat = flt_cnt; |
| } |
| return 0; /* DEV is UP, status is in the (*drv_stat) */ |
| } |
| |
| int weh_do_silent_reset(int do_0_1_both) |
| { |
| int ret, stat; |
| time_t tm; |
| |
| /** Power pin down/up */ |
| //system("exec psm_cmd set wlan_settings wlan_enable 0"); |
| if (do_0_1_both != 1) { |
| time(&tm); |
| eeh_event_prt_and_rec(1, 1, "WIFI recovery start at %s", ctime(&tm)); |
| ret = system(WEH_MWLAN_EXEC_STOP); /*always ok*/ |
| } |
| if (do_0_1_both != 0) { |
| ret = system(WEH_MWLAN_EXEC_START); |
| if (!ret) { |
| ret = weh_is_up_get_stat((void*)20, &stat, 0); |
| if (!ret) |
| ret = stat; |
| } else { |
| ret = -EHOSTDOWN; |
| } |
| time(&tm); |
| eeh_event_prt_and_rec(1, 1, "WIFI recovery=%d at %s", ret, ctime(&tm)); |
| } |
| return ret; |
| } |
| |
| int weh_init(int flag) |
| { |
| int ret, stat; |
| flag = flag; |
| ret = weh_is_up_get_stat((void*)20, &stat, 0); |
| if (!ret) |
| ret = stat; |
| ERRMSG("wifi = %d \n", ret); |
| return ret; |
| } |