blob: 57ea06cc278a1e714b8fdc45d733d7527311223c [file] [log] [blame]
/******************************************************************************
* (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;
}