mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-11-01 10:57:47 +00:00
Wifi-3309: Fix Tx power reporting
- AP was not reporting the Channel Tx power currently set in the firmware. This patch reads the Tx power from debugFS stats and reports it to cloud through Wifi_Radio_State table Signed-off-by: Yashvardhan <yashvardhan@netexperience.com>
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
#include <libubox/blobmsg.h>
|
#include <libubox/blobmsg.h>
|
||||||
|
|
||||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
|
#define ATH_DRIVER_NAME_LEN 16
|
||||||
|
|
||||||
struct mode_map {
|
struct mode_map {
|
||||||
int fiveg;
|
int fiveg;
|
||||||
@@ -44,4 +45,5 @@ extern char* get_max_channel_bw_channel(int channel_freq, const char* htmode);
|
|||||||
int phy_find_hwmon_helper(char *dir, char *file, char *hwmon);
|
int phy_find_hwmon_helper(char *dir, char *file, char *hwmon);
|
||||||
extern double dBm_to_mwatts(double dBm);
|
extern double dBm_to_mwatts(double dBm);
|
||||||
extern double mWatts_to_dBm(double mW);
|
extern double mWatts_to_dBm(double mW);
|
||||||
|
extern int phy_get_ath_driver_name(char *phy, char *ath_driver);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -216,6 +216,76 @@ static void update_channel_max_power(char* phy, struct schema_Wifi_Radio_State *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_channel_tx_power_debugfs(char *stats_path, int *tx_power)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
char str[512];
|
||||||
|
FILE * fp = NULL;
|
||||||
|
int txpower = -1;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
fp = fopen(stats_path, "r");
|
||||||
|
if (!fp) {
|
||||||
|
LOGE("%s: Failed to get tx power, stats file does not exist", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *substr = "Channel TX power";
|
||||||
|
|
||||||
|
while(fgets(str, 512, fp)) {
|
||||||
|
if((strstr(str, substr)) != NULL) {
|
||||||
|
char * plast = NULL, * pcur = str;
|
||||||
|
while ((pcur = strtok( pcur, " "))) {
|
||||||
|
plast = pcur;
|
||||||
|
pcur = NULL;
|
||||||
|
}
|
||||||
|
txpower = atoi(plast);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
LOGE("%s: Unable to find Tx Power in stats", __func__);
|
||||||
|
} else {
|
||||||
|
/* txpower is set as 2 units per dBm in FW */
|
||||||
|
*tx_power = txpower/2;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
if (fp)
|
||||||
|
fclose(fp);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_channel_tx_power(char* phy, int *tx_power)
|
||||||
|
{
|
||||||
|
char ath_driver[ATH_DRIVER_NAME_LEN] = {'\0'};
|
||||||
|
char stats_path[128];
|
||||||
|
|
||||||
|
if (phy_get_ath_driver_name(phy, ath_driver)) {
|
||||||
|
LOGE("%s: Failed to get ATH driver name", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!strncmp(ath_driver, "ath10k", ATH_DRIVER_NAME_LEN)) {
|
||||||
|
snprintf(stats_path, sizeof(stats_path),
|
||||||
|
"/sys/kernel/debug/ieee80211/%s/%s/fw_stats", phy,
|
||||||
|
ath_driver);
|
||||||
|
} else if (!strncmp(ath_driver, "ath11k", ATH_DRIVER_NAME_LEN)) {
|
||||||
|
snprintf(stats_path, sizeof(stats_path),
|
||||||
|
"/sys/kernel/debug/ieee80211/%s/%s/fw_stats/pdev_stats", phy,
|
||||||
|
ath_driver);
|
||||||
|
} else {
|
||||||
|
LOGE("%s: Unknown ATH driver", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_channel_tx_power_debugfs(stats_path, tx_power)) {
|
||||||
|
LOGE("%s: Failed to get Channel Tx Power", __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const struct uci_blob_param_list wifi_device_param = {
|
const struct uci_blob_param_list wifi_device_param = {
|
||||||
.n_params = __WDEV_ATTR_MAX,
|
.n_params = __WDEV_ATTR_MAX,
|
||||||
.params = wifi_device_policy,
|
.params = wifi_device_policy,
|
||||||
@@ -227,6 +297,7 @@ static bool radio_state_update(struct uci_section *s, struct schema_Wifi_Radio_C
|
|||||||
struct schema_Wifi_Radio_State rstate;
|
struct schema_Wifi_Radio_State rstate;
|
||||||
char phy[6];
|
char phy[6];
|
||||||
int antenna;
|
int antenna;
|
||||||
|
int tx_power = -1;
|
||||||
uint32_t chan = 0;
|
uint32_t chan = 0;
|
||||||
|
|
||||||
LOGT("%s: get state", s->e.name);
|
LOGT("%s: get state", s->e.name);
|
||||||
@@ -267,13 +338,14 @@ static bool radio_state_update(struct uci_section *s, struct schema_Wifi_Radio_C
|
|||||||
else
|
else
|
||||||
SCHEMA_SET_INT(rstate.enabled, 1);
|
SCHEMA_SET_INT(rstate.enabled, 1);
|
||||||
|
|
||||||
if (tb[WDEV_ATTR_TXPOWER]) {
|
if (!get_channel_tx_power(phy, &tx_power)) {
|
||||||
SCHEMA_SET_INT(rstate.tx_power, blobmsg_get_u32(tb[WDEV_ATTR_TXPOWER]));
|
SCHEMA_SET_INT(rstate.tx_power, tx_power);
|
||||||
/* 0 means max in UCI, 32 is max in OVSDB */
|
} else {
|
||||||
if (rstate.tx_power == 0)
|
LOGE("%s: Failed to update Channel Tx Power", __func__);
|
||||||
rstate.tx_power = 32;
|
/* Set Tx Power to max OVSDB value */
|
||||||
} else
|
|
||||||
SCHEMA_SET_INT(rstate.tx_power, 32);
|
SCHEMA_SET_INT(rstate.tx_power, 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (tb[WDEV_ATTR_BEACON_INT])
|
if (tb[WDEV_ATTR_BEACON_INT])
|
||||||
SCHEMA_SET_INT(rstate.bcn_int, blobmsg_get_u32(tb[WDEV_ATTR_BEACON_INT]));
|
SCHEMA_SET_INT(rstate.bcn_int, blobmsg_get_u32(tb[WDEV_ATTR_BEACON_INT]));
|
||||||
|
|||||||
@@ -418,6 +418,22 @@ int phy_lookup(char *name)
|
|||||||
return atoi(buf);
|
return atoi(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int phy_get_ath_driver_name(char *phy, char *ath_driver)
|
||||||
|
{
|
||||||
|
glob_t gl;
|
||||||
|
char path[128];
|
||||||
|
snprintf(path, sizeof(path),
|
||||||
|
"/sys/kernel/debug/ieee80211/%s/[ath]*", phy);
|
||||||
|
if (glob(path, GLOB_NOSORT | GLOB_MARK, NULL, &gl))
|
||||||
|
return -1;
|
||||||
|
if (gl.gl_pathc) {
|
||||||
|
memset(ath_driver, '\0', ATH_DRIVER_NAME_LEN);
|
||||||
|
strncpy(ath_driver, basename(gl.gl_pathv[0]), ATH_DRIVER_NAME_LEN - 1);
|
||||||
|
}
|
||||||
|
globfree(&gl);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int vif_get_mac(char *vap, char *mac)
|
int vif_get_mac(char *vap, char *mac)
|
||||||
{
|
{
|
||||||
int sz = ETH_ALEN * 3;
|
int sz = ETH_ALEN * 3;
|
||||||
|
|||||||
Reference in New Issue
Block a user